吉林大学单片机实验课代码.docx
- 文档编号:10350938
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:40
- 大小:25.57KB
吉林大学单片机实验课代码.docx
《吉林大学单片机实验课代码.docx》由会员分享,可在线阅读,更多相关《吉林大学单片机实验课代码.docx(40页珍藏版)》请在冰点文库上搜索。
吉林大学单片机实验课代码
实验四LED点阵显示屏
一、实验目的和要求
了解LED点阵显示的基本原理和实现方法。
掌握点阵汉字库的编码和从标准字库中提取汉字编码的方法。
二、实验内容
了解16*16点阵电路的原理,编写汇编语言程序。
编写一行汉字字符(至少三个字)的显示程序。
能够从左到右(或从右到左)循环显示(要求显示过程中字的大小与屏幕尺寸相适应)。
三、思考题
1.如何使用软件调整和控制LED点阵的亮度
调整扫描频率
2.如何尽量避免显示过程中的闪烁
提高扫描频率,根据人眼的停留效应,一般刷新频率提高到24HZ以上时基本可以消除闪烁。
3.如何将本实验的软硬件推广到多行多列的LED显示屏(如64*1280)
硬件放面可以通过添加新的LED发光管,以及74HC595器件实现;软件方面,将控制行扫描的16为数字0FFFEH修改为64位数0FFFFFFFFFFFFFFFEH.
四、程序代码
ORG0000H
LJMPSTART
ORG000BH
LJMPEINT0
ORG0040H
START:
OE1EQUP0.7;存储器x方向使能端口
OE2EQUP0.4;存储器y方向使能端口
SER1EQUP0.0;移位寄存器串行行输入口Dx
SER2EQUP0.3;移位寄存器串行列输入口Dy
SRCK1EQUP0.1;移位寄存器x方向时钟输入口
SRCK2EQUP0.5;移位寄存器y方向时钟输入口
RCK1EQUP0.2;存储器x方向时钟输入口
RCK2EQUP0.6;存储器y方向时钟输入口
MOVDPTR,#TABLE1;表首地址
MOVTMOD,#01H;定时器控制字,选择定时器工作方式为定时
MOVIE,#82H;中断允许屏蔽控制字,中断设置,定时器0允许中断
L0:
MOVR4,#0;偏移
L2:
MOVR3,#01FH;时间控制,一个屏幕的时间<40ms
S0:
MOVR0,#15;行控制
S00:
CLRSRCK1;行清零
CLRSER1;行数据清零
SETBSRCK1;上升沿读入数据
DJNZR0,S00;自减一,循环
S1:
MOVR0,#0
CLRSRCK1;从第一开始选中
SETBSER1
SETBSRCK1
S2:
MOVA,R0;计数器
ADDA,R4
MOVCA,@A+DPTR;寻址,将R0,R4控制的地址取出
MOVR1,#8;前8位,循环控制
S3:
CLRSRCK2
RRCA;向右移
MOVSER2,C;溢出一位给C
SETBSRCK2;上升沿输出数据
DJNZR1,S3;R1!
=0,则跳转S3
INCR0
;重复第二组8位
MOVA,R0
ADDA,R4
MOVCA,@A+DPTR
MOVR1,#8
S4:
CLRSRCK2
RRCA
MOVSER2,C
SETBSRCK2
DJNZR1,S4
INCR0
S5:
CLRRCK1
SETBRCK1
CLRRCK2
SETBRCK2
CLROE1;使能段有效
CLROE2
LCALLTIME;长跳转
SETBOE1
SETBOE2
CLRSRCK1;下一行
CLRSER1
SETBSRCK1
CJNER0,#32,S2;不相等跳转,一个屏幕的32个8
DJNZR3,S0;不等于零跳转窗口大小固定
MOVA,R4
ADDA,#2
MOVR4,A
CJNER4,#128,L2;四个字,4×32,32个8位是一个字,结束之后,循环回到开始。
LJMPL0
TIME:
;延迟实现
MOVTH0,#0FFH
MOVTL0,#3CH;0.2ms
SETBTR0
MOVR7,#0H
T11:
CJNER7,#1H,T11
RET
;定时器0中断处理程序
EINT0:
MOVR7,#1H
RETI
TABLE1:
DB20H,00H,24H,00H,24H,0FCH,24H,88H,24H,88H,24H,88H,0FCH,88H;
DB24H,88H,24H,88H,24H,88H,24H,0FCH,24H,00H,20H,00H,00H,00H;"?
",0
DB10H,40H,11H,80H,16H,00H,0FFH,0FCH,12H,00H,11H,00H,00H,20H;
DB10H,0C0H,13H,00H,0FFH,0FCH,13H,00H,10H,0C0H,10H,20H,00H,00H;"?
",1
DB08H,04H,08H,04H,08H,08H,08H,10H,08H,60H,0BH,80H,0FCH,00H;
DB0BH,80H,08H,60H,08H,10H,08H,08H,08H,04H,08H,04H,00H,00H;"?
",2
DB1CH,40H,10H,40H,92H,40H,52H,40H,12H,44H,92H,44H,52H,0FCH;
DB12H,0C0H,33H,40H,52H,40H,90H,40H,10H,40H,1CH,40H,00H,00H;"?
",3
END
五、实验改进
将实验现象从左到右显示改为从上到下显示。
改进方法:
将SER1和SER2以及SRCK1和SRCK2调换。
步进电机
ORG0000H;复位起始地址
LJMPSTART
ORG000BH;中间地址保留给中断向量表,定时器0中断程序入口地址
LJMPEINT0
ORG0040H;程序实际起始地址
START:
P4EQU0C0H;单片机P4口地址
P4SWEQU0BBH
CLKEQUP4.4;移位寄存器的时钟线接单片机模拟串口时钟
DATEQUP4.5;移位寄存器的数据线接单片机模拟串口数据
MOVP4SW,#70H
MOVDPTR,#TAB;将段码表首地址传给数据指针寄存器s=23869--5D3E
LP:
MOVR3,#0;数码管显示用,代表个位
MOVR4,#0;数码管显示用,代表十位
MOVR5,#0;数码管显示用,代表百位
I1:
MOVTMOD,#01H;选择定时工作方式,即对TMOD赋初值。
T0工作在方式1,16位的计数器,GATE(门控位)等于0,C/T等于0表示定时方式
MOVIE,#82H;中断允许寄存器IE,中断总体允许控制位置EA置1,定时器T0溢出中断允许控制位置1
ORLIP,#2H;优先级寄存器IP,设置定时器T0中断优先级高
SETBP1.1;步进电机驱动芯片的CE1置高
SETBP1.4;步进电机驱动芯片的CE2置高
NEXT:
JBP3.7,OPP;单片机的P3.7位接S2开关,如果P3.7等于1,即S2按下,则跳转
MOVR0,#00101101B;松开S2,步进电机逆时针转动
MOV20H,R0;将步进电机的脉冲时序保存到20H地址中
LJMPSS1
OPP:
MOVR0,#01111000B;按下S2,步进电机顺时针转动
MOV20H,R0;将步进电机的脉冲时序保存到20H地址中
SS1:
JBP3.6,SPD;单片机的P3.6接S1开关,如果P3.6等于1,即S1按下,则跳转
MOVR2,#0H;松开S1,步进电机慢速旋转;238705D3E
LJMPL0
SPD:
MOVR2,#1H;按下S1,步进电机快速旋转
L0:
MOVR1,#4;根据步进电机的双四拍工作模式,将对应的循环次数4保存到R1中
MOVR0,20H;取出步进电机的脉冲时序(顺时针/逆时针),存入R0中
L1:
MOVA,R0;将R0保存的脉冲时序(顺时针/逆时针),存入累加器A中
RLCA;累加器A循环左移,进位位C受到影响
MOVP3.2,C;将脉冲的高一位送入步进电机驱动芯片与单片机P3.2相连的IN1中
RLCA;累加器A循环左移,进位位C受到影响
MOVP1.0,C;将脉冲的低一位送入步进电机驱动芯片与单片机P1.0相连的IN2中
MOVR0,A;将累加器A循环左移两次后的结果保存到R0中
LCALLNUM;调用LED显示器的子程序,显示步进电机已转动的次数
LCALLTIME;调用定时器的子程序
DJNZR1,L1;R4先减1,若不等于0,则跳转,否则顺次执行下一条指令
LJMPNEXT;重新判断开关是否按下,这是一个死循环
;定时器子程序
TIME:
CJNER2,#1,SLOW;R2表示步进电机转速,等于0慢速,跳转到SLOW;等于1快速,顺次执行下一条指令
MOVTH0,#5DH;快速,60转/分
MOVTL0,#3EH
SETBTR0;TR0置1,定时器0启动
MOVR7,#0H;R7为中断判断标志,置0
TIM1:
CJNER7,#1H,TIM1;R7若小于1则跳转,等待定时器中断产生;若等于0则顺次执行下一条指令
LJMPOUT
SLOW:
MOVR6,#6;慢速,10转/分,设置嵌套循环6次
TIM2:
MOVTH0,#5DH
MOVTL0,#3EH
SETBTR0;TR0置1,定时器0启动
MOVR7,#0H;R7为中断判断标志,置0
TIM3:
CJNER7,#1H,TIM3;R7若小于1则跳转,等待定时器中断产生;若等于0则顺次执行下一条指令
DJNZR6,TIM2;先将R6减1,若不为0则跳转,否则顺次执行下一条指令
OUT:
RET;返回主程序处
;定时器0中断处理程序
EINT0:
MOVR7,#1;中断标志置1
RETI
;调用LED显示器的子程序,显示步进电机已转动的次数
NUM:
S0:
MOVA,R3;将R3表示的个位传给累加器A
CALLEXP;调用数码管显示子程序,显示个位
MOVA,R4;将R4表示的十位传给累加器A
CALLEXP;调用数码管显示子程序,显示十位
MOVA,R5;将R5表示的百位传给累加器A
CALLEXP;调用数码管显示子程序,显示百位
CJNER3,#9,S1;R3表示的个位若等于9,表示要进位,则顺次执行下一条指令,否则跳转
MOVR3,#0;个位清零
CJNER4,#9,S2;R4表示的十位若等于9,表示要进位,则顺次执行下一条指令,否则跳转
MOVR4,#0;十位清零
CJNER5,#9,S3;R5表示的百位若等于9,表示要进位,则顺次执行下一条指令,否则跳转
MOVR5,#0;百位清零
S1:
INCR3
LJMPSTOP
S2:
INCR4
LJMPSTOP
S3:
INCR5
LJMPSTOP
STOP:
RET
EXP:
MOV21H,R0;相当于压栈,保存调用该子程序前R0的值,防止修改R0的值
MOVCA,@A+DPTR;变址寻址方式,将累加器(变址寄存器)与数据指针寄存器(基址寄存器)保存的数相加,并将该数(地址)的内容传给累加器A,得到要显示在某一发光管上的字段码
MOVR0,#8;设置循环8次,从高位到低位依次向移位寄存器输出8个比特
CLY:
CLRCLK;P4.4;CLR清0,移位寄存器的时钟线给低电平
RLCA;累加器A的逻辑左移,C进位位置0或1
MOVDAT,C;P4.5位,即将C所表示的0或1送入移位寄存器中(给相应的字段码低电平或高电平,即相应的数码管不亮或亮)
SETBCLK;P4.4位置1,即时钟线给高电平,产生上升沿,移位寄存器向低位右移一位(当8位都输入后,74HC164并行输出到相应数码管)
DJNZR0,CLY;R0先减1,若不等于0,则跳转
MOVR0,21H;相当于出栈,还原R0原来的值
RET;返回主程序
TAB:
DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90;共阴极发光二极管0到9的段选码
END
实验六
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
//数码管初始化
sfrP4=0xC0;
sfrP4SW=0xBB;
sbitsclk=P4^4;//数码管移位寄存器的时钟线
sbitsdata=P4^5;//数码管移位寄存器的数据线
//液晶屏初始化
sbitCS1=P1^7;//片选信号,液晶左半屏显示
sbitCS2=P1^6;//片选信号,液晶右半屏显示
sbitE=P3^3;//液晶屏使能
sbitRW=P3^4;//读/写选择器引脚(R/W)
sbitRS=P3^5;//数据/命令选择器引脚(R/S)
sbitRES=P1^5;//复位低电平有效
sbitBUSY=P2^7;//当前为运行状态
//直流电机初始化
sbitswh1=P3^6;//开关1
sbitswh2=P3^7;//开关2
sbitmotor=P1^1;
ucharcodezima[10][32]=
{
0x00,0x00,0xC0,0xE0,0x30,0x10,0x08,0x08,0x08,0x08,0x08,0x18,0x30,0xE0,0xC0,0x00,
0x00,0x00,0x07,0x0F,0x18,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x18,0x0F,0x07,0x00,///*"0"*0/
0x00,0x00,0x00,0x10,0x10,0x10,0x10,0xF0,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x3F,0x3F,0x20,0x20,0x20,0x20,0x00,0x00,0x00,///*"1"*1/
0x00,0x00,0x60,0x50,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x98,0xF0,0x70,0x00,0x00,
0x00,0x00,0x20,0x30,0x28,0x28,0x24,0x24,0x22,0x22,0x21,0x20,0x30,0x18,0x00,0x00,///*"2"*2/
0x00,0x00,0x30,0x30,0x08,0x08,0x88,0x88,0x88,0x88,0x58,0x70,0x30,0x00,0x00,0x00,
0x00,0x00,0x18,0x18,0x20,0x20,0x20,0x20,0x20,0x20,0x31,0x11,0x1F,0x0E,0x00,0x00,///*"3"*3/
0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x10,0xF0,0xF8,0xF8,0x00,0x00,0x00,0x00,
0x00,0x04,0x06,0x05,0x05,0x04,0x24,0x24,0x24,0x3F,0x3F,0x3F,0x24,0x24,0x24,0x00,///*"4"*4/
0x00,0x00,0x00,0xC0,0x38,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x08,0x08,0x00,0x00,
0x00,0x00,0x18,0x29,0x21,0x20,0x20,0x20,0x20,0x20,0x30,0x11,0x1F,0x0E,0x00,0x00,///*"5"*5/
0x00,0x00,0x80,0xE0,0x30,0x10,0x98,0x88,0x88,0x88,0x88,0x88,0x98,0x10,0x00,0x00,
0x00,0x00,0x07,0x0F,0x19,0x31,0x20,0x20,0x20,0x20,0x20,0x20,0x11,0x1F,0x0E,0x00,///*"6"*6/
0x00,0x00,0x30,0x18,0x08,0x08,0x08,0x08,0x08,0x88,0x48,0x28,0x18,0x08,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x3E,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,///*"7"*7/
0x00,0x00,0x70,0x70,0xD8,0x88,0x88,0x08,0x08,0x08,0x08,0x98,0x70,0x70,0x00,0x00,
0x00,0x0C,0x1E,0x12,0x21,0x21,0x20,0x21,0x21,0x21,0x23,0x12,0x1E,0x0C,0x00,0x00,///*"8"*8/
0x00,0xE0,0xF0,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x18,0x10,0xF0,0xC0,0x00,0x00,
0x00,0x00,0x11,0x33,0x22,0x22,0x22,0x22,0x22,0x32,0x11,0x1D,0x0F,0x03,0x00,0x00,///*"9"*9/
};
uchartab[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0x0F8,0x80,0x90};//0-9
uchartspeed=0;//脉冲计数
ucharcspeed=0;//当前转速
ucharxspeed=130;//预期转速
ucharspeedUp=160;//最高转速
ucharspeedLow=100;//最低转速
uchart1_cnt=0;///1s=50ms*20,进入定时器1中断次数清0
//占空比设置
intN=50;//累加变量每次加N
intM=256;//实验中取M=256可以使程序更简单
intX=0;//累加变量
voidsend_byte(uchardat,ucharcs1,ucharcs2);//写一个数据
voidsend_all(uintpage,uintlie,uintoffset);//写一个数据串
voidinit();//数码管和中断初始化
voidclearscreen();
voidinit_yejing();
voidsendbyte(ucharch);
voiddisplay(ucharn);
voiddelay1();
voiddelay2();
voiddelay(uintx)
{
while(x--);
}
voidmain()
{
init();
init_yejing();
motor=0;
while
(1)
{
clearscreen();
send_all(1,3,speedLow/100);//最低值百位
send_all(1,4,(speedLow/10)%10);//最低值十位
send_all(1,5,speedLow%10);//最低值个位
send_all(3,3,cspeed/100);//当前值百位
send_all(3,4,(cspeed/10)%10);//当前值十位
send_all(3,5,cspeed%10);//当前值个位
send_all(5,3,speedUp/100);//最高值百位
send_all(5,4,(speedUp/10)%10);//最高值十位
send_all(5,5,speedUp%10);//最高值个位
delay1();
display(cspeed);//数码管显示
delay(50000);
}
}
//数码管和中断初始化
voidinit()
{
P4SW=0x30;
IT0=1;//外部中断0边沿触发方式
EA=1;//中断使能
ET1=1;//定时器1
ET0=1;//定时器0
EX0=1;//外部中断INT0
TMOD=0x11;//16位寄存器,模式1
//初始化1定时器1时间
TH1=0x3C;
TL1=0xB0;//50ms:
65536-50000=15536
//初始化定时器0时间
TH0=0xFF;
TL0=0x9C;//0.1ms:
65536-100=65436
TR0=1;//启动定时器0
TR1=1;//启动定时器1
}
//外部中断0
voidex_int0()interrupt0///每次中断意味着转了一圈
{
tspeed++;//脉冲计数值加1
}
//计时器中断0
voidt0_int()interrupt1///每0.1ms进入此中断程序一次,在中断程序中继续启动,为了稳定电机的转速
{///定时器,这样就能持续给直流电机供电了
TH0=0xFF;
TL0=0x9C;
//累加进位法
X+=N;
if(X>M)
{
motor=0;
X-=M;
}
else
motor=1;
}
//计时器中断1
voidt1_int()interrupt3///50ms,每1s测量转速,调整一次速度
{
if(++t1_cnt<20)
{
TH1=0x3C;
TL1=0xB0;
///每50ms进入此中断程序一次,进入20次后统计转了多少圈
if(swh1==0)//S1按下
{
xspeed=speedLow;//xspeed预期转速为低目标转速
}
if(swh2==0)//S2按下
{
xspeed=speedUp;//xspeed预期转速为高目标转速
}
return;
}
t1_cnt=0;//进入定时器1中断次数清0
cspeed=tspeed;//当前转速为脉冲计数
tspeed=0;//脉冲计数清0
if(cspeed>xspeed)N--;//如果当前转速高于预期转速,则降低速度
if(cspeed } //液晶屏初始化 voidinit_yejing() { send_byte(192,1,1);//设置起始行 send_byte(63,1,1);//打开显示开关 } //送8位数 voidsend_byte(uchardat,ucharcs1,ucharcs2) { P2=0xff; CS1=cs1;//左右屏点亮 CS2=cs2; RS=0;//读状态字,RS=0数字,RS=1指令 RW=1;//RW=0写,RW=1读
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 吉林大学 单片机 实验 代码
![提示](https://static.bingdoc.com/images/bang_tan.gif)