《电子系统设计——第5章以单片机为核心的智能型电子系统设计1(讲稿)ppt课件.ppt》由会员分享,可在线阅读,更多相关《电子系统设计——第5章以单片机为核心的智能型电子系统设计1(讲稿)ppt课件.ppt(89页珍藏版)》请在三一办公上搜索。
1、1、AT89S5x单片机开发板应用,1、AT89S5x单片机开发板设计及应用,(1)任务:点亮LED灯,在Keil软件编辑窗口输入以下程序:#include sbit P3_0=P30;void main(void) while(1) P3_0=0; ,Easy51Pro v2.0 软件的使用硬件连接,Easy51Pro v2.0 软件的使用软件操作,(2)AT89S51单片机最小系统介绍,单片机要工作必须具备以下条件:(1)+5V电源;(2)起振电路;(3)复位电路;(4)一块正常的单片机。,注意:另外P0 口要加上拉电阻,才有足够的驱动能力驱动外围器件工作;EA接高电平,表示单片机使用的是
2、片内FLASH ROM。,(3)任务:闪烁灯,#include void delay02s(void) unsigned char i,j,k; for(i=20;i0;i-) for(j=20;j0;j-) for(k=248;k0;k-); void main(void) while(1) P3_0=0; delay02s(); P3_0=1; delay02s(); ,要求:前面例子是让LED灯亮,现在实现LED灯的闪烁。,(4)任务:流水灯,要求:做广告灯的左移右移,八个发光二极管分别接在单片机的P3.0P3.7 接口上,输出“0”时,发光二极管亮,左移右移按D1D2D3D4D8D7D
3、6 D1 亮,重复循环。,(4)任务:流水灯,程序:#include unsigned char i; unsigned char temp; void delay(void) /延时子程序 unsigned char m,n,s; for(m=20;m0;m-) for(n=20;n0;n-) for(s=248;s0;s-); void main(void) /主程序 while(1) /循环条件永远为真,以下程序一直执行下去。,续前页: temp=0 x7f; P3=temp; /直接对I/O口P3赋值,使P3.0输出低点平。delay(); /延时for(i=1;i1)|0 x80;
4、P3=temp;delay(); temp=0 xfe; P3=temp;delay(); for(i=1;i8;i+) /实现广告灯的从D7到D1移动 temp=(temp1)|0 x01; P3=temp;delay(); ,思考:如何实现更为复杂的花样灯?,参考程序:#include reg51.h#define uchar unsigned charconst uchar tab= 0 xfe,0 xfd,0 xfb,0 xf7,0 xef,0 xdf,0 xbf,0 x7f, /下移 0 xbf,0 xdf,0 xef,0 xf7,0 xfb,0 xfd,0 xfe, /上移 0 x
5、ef,0 xbd,0 xdb,0 xfe, /两边向中间移 0 xdb,0 xbd,0 xef, /中间向两边移 0 xaa,0 x55,0 xaa,0 x55,0 xaa,0 x55, /1357,2468交替3次 0 xf0,0 x0f,0 xf0,0 x0f, /1234,5678交替2次 0 x33,0 xcc,0 x33,0 xcc,0 x33,0 xcc, /1256,3478交替3次 0 x00 ; /结束码uchar t=0;/以下初始化子函数/void sys_init(void) TMOD=0 x01; TH0=0 xd8;,续前页: TL0=0 xef; ET0=1; E
6、A=1; TR0=1;/以下主函数/void main(void) uchar i=0; P3=tabi;i+; sys_init(); while(1) while(t100); t=0; if(tabi=0 x00) i=0; P3=tabi;i+; ,续左页:/以下定时器0中断函数/void timer0(void) interrupt 1 TR0=0; TH0=0 xd8; TL0=0 xef; t+; TR0=1;,(5)任务:按键识别,要求:通过按下一次按键INT0,使小灯D1 亮灭交替变换。,实验原理:只要判断P3.2 的电平就可以知道按键是否被按下;而在按键按下的过程中,由于机
7、械抖动,将产生干扰,电平高低变化。可以采用软件滤波的方法去除这些干扰信号,在程序设计时,一旦发现P3.2 为低电平,进入按键判断状态,软件延时10-20ms,从而避开了干扰信号区域,再重新检测P3.2 状态,看按键是否真的已经按下。,参考程序:include sbit INT_0=P32; /定义按键的输入端 sbit D1=P30; /D1小灯定义void delay10ms(void) /延时程序 unsigned char i,j; for(i=20;i0;i-) for(j=248;j0;j-); key( ) /按键判断程序 if(INT_0=0) /判断是否按下键盘 delay10
8、ms( ); /延时,软件去干扰if(INT_0=0) /确认按键按下 D1=!D1; /D1亮灭交替变化 while(INT_0=0);/按键锁定,每按一次D1只变化一次,续前页: main()while(1) /永远循环,扫描判断按键是否按下 key(); /对于此处CPU只按键判断 一直扫描;,课后请实践:1.用两个按键来控制D1 的亮灭;2. 使用一个按键,控制小灯亮的顺序D1D2D3D4D8D7D0 亮重复循环;,(6)任务:数码管静态显示,要求:用数码管LED 的个位,静态显示数字“4”字样;,注意:因采用共阴数码显示管,故此图P0口还应接1K或10K的排阻作为上拉电阻。,参考程序
9、:#include sbit GE=P13;code unsigned char seg7code10=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f; /显示段码main() unsigned char display_date=4; /定义并赋值要显示的数据while(1) P0=seg7codedisplay_date; /查表,输出 GE=0; /P13为低电平,相当于把数码管的4H端接地,课后请实践:1.让显示的数据动起来,比如做一个0 到9 的秒表(用软件延时);2.和按键判断程序结合,用按键控制数字变化;,(
10、7)任务:数码管动态显示,要求:用数码管LED 的显示四位数据,比如显示数字“1234”;,参考程序:#include sbit qian=P10;sbit bai=P11;sbit shi=P12;sbit ge=P13;code unsigned char seg7code10=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f; /显示段码void Delay(unsigned int tc) /延时程序while( tc != 0 )/如果tc为0则终止延时unsigned int i;/局部正整数变量 ifor(i=
11、0; i100; i+);/执行400次将耗时1毫秒tc-;/tc计数减一,续前页:void Led(int date) /显示函数qian=0; /P1.0输出低电平,选通千位数P0=seg7codedate/1000; /取出千位数,查表,输出。Delay(10); /延时qian=1; /销隐bai=0; /P1.1输出低电平,选通百位数P0=seg7codedate%1000/100; /取出百位数,查表,输出。Delay(10); /延时bai=1; /销隐shi=0; /P1.2输出低电平,选通十位数P0=seg7codedate%100/10; /取出十位数,查表,输出。Dela
12、y(10); /延时shi=1; /销隐ge=0;/P1.3输出低电平,选通十位数P0=seg7codedate%10; /取出个位数,查表,输出。Delay(10);ge=1;,续前页:main() int display_date=1234; /定义并赋值要显示的数据 while(1) Led(display_date);/调用显示函数显示数据display_date ,上述数码管动态显示程序的另一种写法,参考程序:#include unsigned char datebit=0 xfe,0 xfd,0 xfb,0 xf7;/存储数码管的位选值unsigned char tvdate=0
13、x3f,0 x06,0 x5b,0 x4f,0 x66, 0 x6d,0 x7d,0 x07,0 x7f,0 x6f,;unsigned int disdata; /定义要显示的数据unsigned char disdat4; /存储要显示的四位数据void delay(time) unsigned char i,j; for(j=0;jtime;j+) for(i=0;i250;i+); display(void)unsigned char k;disdata=1234;/显示1234,续前页: disdat0=disdat/1000;/取出千位disdat1=disdat%1000/100
14、; /取出百位disdat2=disdat%100/10;/取出十位disdat3=disdat%10;/取出个位for(k=0;k4;k+) /显示四位数据 P0=tvdatedisdatk; /送出要显示数据的段码P1=datebitk;/P2位选delay(10);/延时 main() while(1) display(); ,这种写法比上一种复杂,占用空间要多一些.但是使用方便,可以在此基础上方便的加上比如显示小数点,指定某位数码管闪烁等。课后思考:如何用软件延时来做一个0 到60 秒的计数器吗?,(8)任务:4X4矩阵键盘识别,要求:用AT89S51 的并行口P2 接44 矩阵键盘,
15、以P3.0P3.3 作输入线,以P3.4P3.7 作输出线;在每一个数码管上显示每个按键的“0F”序号。,实验原理每个按键有它的行值和列值,行值和列值的组合就是识别这个按键的编码。矩阵的行线和列线分别通过两并行接口和CPU 通信。键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断开时的抖动。两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。,键盘识别的两种方法,逐行扫描法:(1)首先判断有无键按下:令矩阵行线输出全0信号,检测列线状态,若有一列电平为
16、低,则有键按下。(2)确定闭合键位置:依次将各行线置为低电平,逐行检测各列线的电平状态,若某列为低,则该行线和列线交叉处按键就是闭合键。线反转法:(1)令矩阵键盘列线输出全0信号,行线作为输入接口接收信号,可判断按键处于哪一行。(2)令矩阵键盘行线输出全0信号,列线作为输入接口接收信号,可判断按键处于哪一列。(3)将输入信号相或后形成键盘的唯一键码。,程序:(线反转法)#include unsigned char code seg7code=0 x3f,0 x06,0 x5b,0 x4f, 0 x66,0 x6d,0 x7d,0 x07, 0 x7f,0 x6f,0 x77,0 x7c, 0
17、x39,0 x5e,0 x79,0 x71; unsigned char k;void delay10ms(void) /延时程序 unsigned char i,j; for(i=20;i0;i-) for(j=248;j0;j-); void Getch ( ) unsigned char X,Y,Z; P2=0 xff; P2=0 x0f; /先对P2置数 行扫描if(P2!=0 x0f) /判断是否有键按下 delay10ms(); /延时,软件去干扰 if(P2!=0 x0f) /确认按键按下X = P2; ,续前页: X=P2; /保存行扫描时有键按下时状态P2=0 xf0; /列
18、扫描Y=P2; /保存列扫描时有键按下时状态Z=X|Y; /取出键值switch ( Z ) /判断键值(那一个键按下)case 0 x77: k=0; break; /对键值赋值case 0 x7b: k=1; break; case 0 x7d: k=2; break; case 0 x7e: k=3; break; case 0 xb7: k=4; break; case 0 xbb: k=5; break; case 0 xbd: k=6; break; case 0 xbe: k=7; break; case 0 xd7: k=8; break; case 0 xdb: k=9; b
19、reak; case 0 xdd: k=10;break; case 0 xde: k=11;break; case 0 xe7: k=12;break; case 0 xeb: k=13;break;,续前页: case 0 xed: k=14;break; case 0 xee: k=15;break; void main(void) while(1) P2=0 xff; Getch( ); P0=seg7codek; /查表LED输出 P1=0 xf0; /输出相同的四位数据。 ,(9)任务:按键中断识别,要求:采用中断技术,每按一下按键,计数器加1,并用LED 显示出来,注意只显示2位
20、十进制数。原理:以上的两个关于按键识别的实验的程序都是采用扫描的方式来实现的,CPU的利用率比较低;按键判断还可以用中断方式来判断。中断方式可以满足快速响应的要求。,程序:#include unsigned char code table=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f;unsigned char dispcount=0; /计数sbit gewei=P13; /个位选通定义sbit shiwei=P12; /十位选通定义void Delay(unsigned int tc) /延时程序while( tc
21、!= 0 )unsigned int i;for(i=0; i100; i+);tc-;void ExtInt0() interrupt 0 /中断服务程序,续前页:dispcount+; /每按一次中断按键,计数加一if (dispcount=100) /计数范围0-99dispcount=0;void LED( ) /LED 显示函数if(dispcount=10) /显示两位数shiwei=0;P0=tabledispcount/10;Delay(8);shiwei=1;gewei=0;P0=tabledispcount%10;Delay(5);gewei=1;else /显示一位数,续
22、前页:shiwei=1;gewei=0;P0=tabledispcount;Delay(8); void main() TCON=0 x01; /下降沿触发 IE=0 x81; /开总中断和允许外部中断 while(1) /循环执行 LED( ); /调用显示函数/*课后思考:在程序在硬件运行过程中,有时候按一下键会加几个数,是因为没有去除按键干扰请您想一想怎么消除抖动./*/,(10)任务:定时器T0的应用9.9秒计时设计,要求:开始时,显示“00”,第1 次按下INT0 后就开始计时。第2 次按INT0 后,计时停止。第3 次按INT0 后,计时归零。,程序:#include unsign
23、ed char code table=0 x3f,0 x06,0 x5b,0 x4f,0 x66, 0 x6d,0 x7d,0 x07, 0 x7f,0 x6f, ;unsigned char sec; /定义计数值,每过1/10 秒,sec 加一unsigned char keycnt=1; /键值判断unsigned int tcnt; /中断次数计数器 sbit gewei=P13; /个位选通定义sbit shiwei=P12; /十位选通定义sbit INT_0=P32; /按键定义位void Delay(unsigned int tc) /延时程序while( tc != 0 )u
24、nsigned int i;for(i=0; i100; i+);tc-;,续前页:void LED( ) /LED 显示函数shiwei=0;P0=tablesec/10|0 x80;/十位加上小数点Delay(5);shiwei=1;gewei=0;P0=tablesec%10;Delay(5);gewei=1;void KEY() /按键扫描程序unsigned char i,j;if(INT_0=0)for(i=20;i0;i-) /延时去干扰for(j=248;j0;j-);,续前页:if(INT_0=0)switch(keycnt) /按下次数判断case 1: /第一次按下TH0
25、=0 x06; /对TH0 TL0 赋值TL0=0 x06;TR0=1; /开始定时keycnt=2; /为第二次做准备break;case 2: /第二次按下TR0=0; /定时结束keycnt=3; /为第三次按下做准备break;case 3: /第三次按下keycnt=1; /重新开始判断键值sec=0; /计数重新从零开始break;,续前页:while(INT_0=0);void t0(void) interrupt 1 using 0 /定时中断服务函数tcnt+; /每过250us,tcnt 加一if(tcnt=400) /计满400 次(0.1 秒)时tcnt=0; /重新再
26、计sec+;if(sec=100) /定时10 秒,在从零开始计时sec=0;,续前页:void main(void)TMOD=0 x02; /定时器工作在方式2 自动重装方式ET0=1; /允许T0 产生中断EA=1; /开总中断sec=0;while(1)KEY();LED();,电子钟电路及程序示例:,电路原理图:,C语言源程序:,#includeunsigned char code dis_code11=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07, 0 x7f,0 x6f,0 x80;unsigned char data dis5;s
27、ec=0,min=11,hou=17,cou=0,sec_flag=0,sansuo_flag=0,dis_r=0;/*void main() P0=0 x00; P2=0 xff;TMOD=0 x11; TH0=0 xec;TL0=0 x78; /T0十毫秒定时 TH1=0 xfe; TL1=0 x0c; /T1一毫秒定时 EA=1; ET0=1;ET1=1; TR0=1; TR1=1; while(1) if(sec_flag=1) sec_flag=0; ,续前页:void time0(void) interrupt 1 cou+; if(cou=50) sansuo_flag=sans
28、uo_flag; if(cou=100) sec_flag=1;cou=0;sec+; if(sec=60) sec=0; min+; if(min=60) min=0; hou+; if(hou=23) hou=0; TH0=0 xec; TL0=0 x78;,续前页:void time1(void) interrupt 3dis0=min%10;dis1=min/10;dis2=10;dis3=hou%10;dis4=hou/10; P0=dis_codedisdis_r; switch(dis_r) case 0:P2=0 xef;dis_r+;break; case 1:P2=0 xd
29、f;dis_r+;break; case 2: if(sansuo_flag=0) P2=0 xcf; else P2=0 xff; dis_r+;break; case 3:P2=0 xbf;dis_r+;break; case 4:P2=0 x7f;dis_r+;break; default:dis_r=0;P2=0 xff; TH1=0 xfe; TL1=0 x0c;,如何加入按键校时程序并用Proteus软件仿真,含校时功能的数字电子钟完整C语言源程序代码,#includeunsigned char code dis_code10=0 x3f,0 x06,0 x5b,0 x4f,0 x
30、66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f;unsigned char data dis4;unsigned char sec=0,min=59,hou=22,cou=0,sansuo_flag=0,dis_r=0;unsigned char int0_flag,int1_flag;/以下10ms延时函数/void delay10ms(void) unsigned char i,j; for(i=20;i0;i-) for(j=248;j0;j-); /以下为主函数/void main(void) P0=0 x00; P2=0 xff;TMOD=0 x11; TH0=0
31、xec;TL0=0 x78; /T0十毫秒定时 TH1=0 xfe;TL1=0 x0c; /T1一毫秒定时码 EA=1;EX0=1;EX1=1; IT0=1;IT1=1;ET0=1;ET1=1;TR0=1;TR1=1;,续前页:while(1) /先判断是否有分钟校时键按下/ if(int0_flag=1) EX0=0;int0_flag=0; delay10ms(); if(P3_2=0) min+;EX0=1; if(min=60) min=0; /再判断是否有小时校时键按下/ if(int1_flag=1) EX1=0;int1_flag=0; delay10ms(); if(P3_3=
32、0) hou+;EX1=1; if(hou=24) hou=0; ,续前页:void int0(void) interrupt 0 /外部中断0函数/ int0_flag=1;void time0(void) interrupt 1 /定时器0中断函数/ cou+; if(cou=50) sansuo_flag=sansuo_flag; if(cou=100) cou=0;sec+; if(sec=60) sec=0; min+; if(min=60) min=0; hou+; if(hou=24) hou=0; TH0=0 xec; TL0=0 x78;,续前页:void int1(void
33、) interrupt 2 /外部中断1函数/ int1_flag=1;/以下为定时器1中断函数/void time1(void) interrupt 3dis0=min%10;dis1=min/10;dis2=hou%10;dis3=hou/10; switch(dis_r) case 0:P2=0 xef;P0=dis_codedisdis_r;dis_r+;break; case 1:P2=0 xdf;P0=dis_codedisdis_r;dis_r+;break; case 2:P2=0 xbf; if(sansuo_flag=0) P0=dis_codedisdis_r|0 x80
34、; else P0=dis_codedisdis_r; dis_r+;break; case 3:P2=0 x7f;P0=dis_codedisdis_r;dis_r+;break; default:dis_r=0;P2=0 xff; TH1=0 xfe; TL1=0 x0c;,(11)任务:PC机与单片机通信,要求:单片机串口通信的应用,通过串口,电脑和单片机系统进行通信。电脑作为上位机,向下位机单片机系统发送十六进制或者ASCLL码,单片机系统接收后,用LED 显示接收到的数据和向上位机发回原样数据。,单片机串口相关知识回顾,(1) MCS-51串行口的原理结构图,单片机串口相关知识回顾,
35、(2) 串行口控制寄存器SCON,D7 D6 D5 D4 D3 D2 D1 D0,D7 D6 D5 D4 D3 D2 D1 D0,(3) 特殊功能寄存器PCON,单片机串口相关知识回顾,(4) 串口通信的波特率,对于方式0,波特率是固定的,为单片机时钟的1/12,即fosc/12。对于方式2,波特率有两种可供选择,即fosc/32和fosc/64。对应于以下公式: 波特率=fosc(2SMOD)/64 对于方式1和方式3,波特率都由定时器T1的溢出率来决定,对应于以下公式: 波特率=(2SMOD/32)(定时器T1的溢出率)而定时器T1的溢出率则和所采用的定时器工作方式有关,并可用以下公式表示
36、: 定时器T1的溢出率=fosc/12(2n-X),程序:#include unsigned char dat; /用于存储单片机接收发送缓冲寄存器SBUF 里面的内容sbit gewei=P13; /个位选通定义sbit shiwei=P12; /十位选通定义unsigned char code table=0 x3f,0 x06,0 x5b,0 x4f,0 x66, 0 x6d,0 x7d,0 x07, 0 x7f,0 x6f;void Delay(unsigned int tc) /延时程序while( tc != 0 )unsigned int i;for(i=0; i100; i+)
37、;tc-;void LED( ) /LED 显示接收到的数据(十进制)shiwei=0;P0=tabledat/10;Delay(5);,续前页:shiwei=1;gewei=0;P0=tabledat%10;Delay(5);gewei=1;void Init_Com(void)/功能:串口初始化,波特率9600,方式1TMOD = 0 x20;PCON = 0 x00;SCON = 0 x50;TH1 = 0 xFd;TL1 = 0 xFd;TR1 = 1;,续前页:void main() /实现接收数据并把接收到的数据原样发送回去/Init_Com(); /串口初始化while(1)if
38、 ( RI ) /扫描判断是否接收到数据,dat = SBUF; /接收数据SBUF 赋与datRI=0; /RI 清零(必须用软件清零)SBUF = dat; /再原样把数据发送回去LED( ); /显示接收到的数据,(12)任务:数模转换器ADC0804的应用(扩展),要求:从ADC0804的通道IN+输入05V 之间的模拟量,通过ADC0804 转换成数字量在数码管上以十进制形成显示出来。,程序:#include code unsigned char seg7code10=0 x3f,0 x06,0 x5b,0 x4f,0 x66, 0 x6d,0 x7d,0 x07,0 x7f,0 x
39、6f; /显示段码sbit int1=P33; /定义管脚功能sbit cs=P32;sbit wr=P36;sbit rd=P37;void Delay(unsigned int tc) /显示延时程序while( tc != 0 )unsigned int i;for(i=0; i100; i+);tc-;unsigned char adc0804( void ) /读AD0804 子程序 unsigned char addata,i;rd=1;wr=1;int1=1; /读ADC0804 前准备P1=0 xff; /P1 全部置一准备cs=0;wr=0;wr=1; /启动ADC0804
40、开始测电压while(int1=1); /查询等待A/D 转换完毕产生的INT(低电平有效)信号rd=0; /开始读转换后数据,续前页:i=i; i=i; /无意义语句,用于延时等待ADC0804 读数完毕addata=P1; /读出的数据赋与addatard=1;cs=1; /读数完毕return(addata); /返回最后读出的数据unsigned int datpro(void) /ADC0804 读出的数据处理 unsigned char x;unsigned int dianyah,dianyal; /用于存储读出数据的高字节和低字节unsigned int dianya=0; /
41、存储最后处理完的结果注意数据类型for(x=0;x4; /右移四位取出高四位dianyal=dianya /返回最后处理结果,续前页:void Led() unsigned int date;date=datpro(); /调用数据处理最后结果P2=P2 /只需调用显示函数,(13)任务:模数转换器DAC0832的应用,要求:用两个按键通过单片机控制DAC0832 的输出,使OUT 端可以输出05V 的幅值,频率为1KHZ 的锯齿波和三角波两种波形。通上电源后;按下INT1 则输出三角波,再按下INT0 输出锯齿波。,实验原理DAC0832是8 位全MOS 中速D/A 转换器,采用R2RT 形
42、电阻解码网络,转换结果为一对差动电流输出,转换时间大约为1us。使用单电源+5V+15V 供电。参考电压为-10V+10V。在此我们直接选择+5V 作为参考电压。DAC0832 有三种工作方式:直通方式,单缓冲方式,双缓冲方式;在此我们选择直通的工作方式,将XFER、WR1、WR2和CS管脚全部接数字地。管脚8 接参考电压,在此我们接的参考电压是+5V。那么经过第一级运放后,输出电压将是-5V0V,在经过第二级运放反相放大1 倍以后将可以输出0V5V 了。再控制P1 口输出数据有规律的变化将可以产生三角波,锯齿波,梯型波等波形了。,程序:#include unsigned char keycn
43、t=0; /波形标志unsigned char tcnt=0; /键值判断bit sjz=0; /产生三角波时上升、下降用到的标志void delayl( ) /延时子程序 unsigned char i,j;for(i=20;i0;i-)for(j=248;j0;j-); void KEY( ) /按键扫描程序if(P3_2=0)delayl( ); /延时跳过按下时的抖动if(P3_2=0)keycnt=0; /定时器产生锯齿波标志TR0=0; /暂时停止波形输出TH0=0 x256-40; /对TH0 TL0 赋值TL0=0 x256-40;TR0=1; /开始定时,产生锯齿波,续前页:
44、while(P3_2=0); /如果一直按着键,则等待键松开delayl( ); /延时跳过松开后的抖动 if(P3_3=0)delayl( ); /延时跳过按下时的抖动if(P3_3=0)keycnt=1; /定时器产生三角波标志TR0=0; /暂时停止波形输出TH0=0 x256-40; /对TH0、TL0 赋值TL0=0 x256-40;TR0=1; /开始定时产生三角波while(P3_2=0); /如果一直按着键,则等待松键开delayl( ); /延时跳过松开后的抖动,续前页:void t0(void) interrupt 1 using 0 /定时中断服务函数if(keycnt=
45、0) /产生锯齿波P0=tcnt;tcnt=+0 x0a; /步进0.2V/一次中断if(tcnt=0 xfb)tcnt=0;if(keycnt=1) /产生三角波 if(sjz=0)P0=tcnt;tcnt=+0 x0a; /步进0.2V/一次中断if(tcnt=0 xfa)sjz=1;if(sjz=1),续前页:P0=tcnt;tcnt=-0 x0a;if(tcnt=0)sjz=0;void main(void)TMOD=0 x02; /定时器工作在方式2ET0=1;EA=1;while(1) KEY( ); ,(14)任务:24C08的读写操作,要求:利用24C08断电以后存储的数据不消
46、失的特点,可以做一个断电保护装置。首先利用单片机做一个099秒的自动计时器。然后随机关断电源,在通电以后计时器接着断电前的状态继续计时。,实验原理引脚图,实验原理总线协议,实验原理写周期时序和起始、停止时序,实验原理器件寻址,实验原理器件寻址,实验原理写操作,注意:I2C总线数据都是高位在前,低位在后!,实验原理写操作,实验原理读操作,实验原理读操作,实验原理读操作,程序:#include #include #include unsigned char code table=0 x3f,0 x06,0 x5b,0 x4f,0 x66, 0 x6d,0 x7d,0 x07, 0 x7f,0 x6
47、f;unsigned char sec; /定义计数值,每过1 秒,sec 加1unsigned int tcnt; /定时中断次数bit write=0; /写24C08 的标志;sbit gewei=P13; /个位选通定义sbit shiwei=P12; /十位选通定义/24C08 读写驱动程序开始/sbit scl=P36; / 24c08 SCLsbit sda=P37; / 24c08 SDAvoid delay1(unsigned char x) unsigned int i;for(i=0;ix;i+);void flash() /延时2us ; ; ,void x24c08_
48、init() /24c08 初始化子程序scl=1;flash();sda=1;flash();void start() /启动I2C 总线sda=1;flash();scl=1;flash();sda=0;flash();scl=0;flash();void stop() /停止I2C 总线sda=0;flash();scl=1;flash();sda=1;flash();void writex(unsigned char j) /写一个字节unsigned char i,temp;temp=j;for (i=0;i8;i+)temp=temp1;scl=0;flash();sda=CY;f
49、lash();scl=1;flash();scl=0;flash();sda=1;flash();,unsigned char readx( ) /读一个字节unsigned char i,j,k=0;scl=0;flash( );sda=1;for (i=0;i8;i+)flash( );scl=1;flash( );if (sda=1) j=1;else j=0;k=(k1)|j;scl=0;flash();return(k);void clock( ) / I2C 总线时钟,确认应答信号unsigned char i=0;scl=1;flash( );while (sda=1),/从24
50、c08 的地址address 中读取一个字节数据/unsigned char x24c08_read(unsigned char address)unsigned char i;/先发写命令、写地址start( );writex(0 xa0);clock( );writex(address);clock( ); /再发读命令,读数据start( );writex(0 xa1);clock( );i=readx( ); stop( );delay1(10);return(i);/向24c08 的address 地址中写入一字节数据info/void x24c08_write(unsigned c