电子系统设计-第5章以单片机为核心的智能型电子系统设计1(讲稿)课件_第1页
电子系统设计-第5章以单片机为核心的智能型电子系统设计1(讲稿)课件_第2页
电子系统设计-第5章以单片机为核心的智能型电子系统设计1(讲稿)课件_第3页
电子系统设计-第5章以单片机为核心的智能型电子系统设计1(讲稿)课件_第4页
电子系统设计-第5章以单片机为核心的智能型电子系统设计1(讲稿)课件_第5页
已阅读5页,还剩84页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

电子系统设计——第5章以单片机为核心的智能型电子系统设计1(讲稿)ppt课件1、AT89S5x单片机开发板应用1、AT89S5x单片机开发板应用1、AT89S5x单片机开发板设计及应用(1)任务:点亮LED灯在Keil软件编辑窗口输入以下程序:#include<AT89x51.H>sbitP3_0=P3^0;voidmain(void){while(1){P3_0=0;}}1、AT89S5x单片机开发板设计及应用(1)任务:点亮LEEasy51Prov2.0

软件的使用——硬件连接Easy51Prov2.0软件的使用——硬件连接Easy51Prov2.0

软件的使用——软件操作Easy51Prov2.0软件的使用——软件操作(2)AT89S51单片机最小系统介绍单片机要工作必须具备以下条件:(1)+5V电源;(2)起振电路;(3)复位电路;(4)一块正常的单片机。注意:另外P0口要加上拉电阻,才有足够的驱动能力驱动外围器件工作;EA接高电平,表示单片机使用的是片内FLASHROM。(2)AT89S51单片机最小系统介绍单片机要工作必须具备以(3)任务:闪烁灯#include<AT89X51.H>voiddelay02s(void){unsignedchari,j,k;for(i=20;i>0;i--)for(j=20;j>0;j--)for(k=248;k>0;k--);}voidmain(void){while(1){P3_0=0;delay02s();P3_0=1;delay02s();}}要求:前面例子是让LED灯亮,现在实现LED灯的闪烁。(3)任务:闪烁灯#include<AT89X51.H>(4)任务:流水灯要求:做广告灯的左移右移,八个发光二极管分别接在单片机的P3.0-P3.7接口上,输出“0”时,发光二极管亮,左移右移按D1→D2→D3→D4→┅→D8→D7→D6→┅→D1亮,重复循环。(4)任务:流水灯要求:做广告灯的左移右移,八个发光二极管分(4)任务:流水灯程序:#include<AT89X52.H>unsignedchari;unsignedchartemp;voiddelay(void)//延时子程序{ unsignedcharm,n,s; for(m=20;m>0;m--) for(n=20;n>0;n--) for(s=248;s>0;s--);}voidmain(void)//主程序{ while(1)//循环条件永远为真,以下程序一直执行下去。

{

(4)任务:流水灯程序:续前页:temp=0x7f; P3=temp;//直接对I/O口P3赋值,使P3.0输出低点平。

delay();//延时

for(i=1;i<8;i++)//实现广告灯的从D1到D7移动

{ temp=(temp>>1)|0x80;

P3=temp; delay(); } temp=0xfe; P3=temp; delay(); for(i=1;i<8;i++)//实现广告灯的从D7到D1移动

{ temp=(temp<<1)|0x01;

P3=temp; delay(); } }}

续前页:思考:如何实现更为复杂的花样灯?参考程序:#include"reg51.h"#defineucharunsignedcharconstuchartab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,//下移

0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,//上移

0xef,0xbd,0xdb,0xfe,//两边向中间移

0xdb,0xbd,0xef,//中间向两边移

0xaa,0x55,0xaa,0x55,0xaa,0x55,//1357,2468交替3次

0xf0,0x0f,0xf0,0x0f,//1234,5678交替2次

0x33,0xcc,0x33,0xcc,0x33,0xcc,//1256,3478交替3次

0x00};//结束码

uchart=0;////以下初始化子函数////voidsys_init(void){TMOD=0x01;TH0=0xd8;思考:如何实现更为复杂的花样灯?参考程序:续前页:TL0=0xef;ET0=1;EA=1;TR0=1;}////以下主函数////voidmain(void){uchari=0;P3=tab[i];i++;sys_init();while(1){while(t<100);t=0;if(tab[i]==0x00){i=0;}P3=tab[i];i++;}}续左页:////以下定时器0中断函数////voidtimer0(void)interrupt1{TR0=0;TH0=0xd8;TL0=0xef;t++;TR0=1;}续前页:续左页:(5)任务:按键识别要求:通过按下一次按键INT0,使小灯D1亮灭交替变换。实验原理:只要判断P3.2的电平就可以知道按键是否被按下;而在按键按下的过程中,由于机械抖动,将产生干扰,电平高低变化。可以采用软件滤波的方法去除这些干扰信号,在程序设计时,一旦发现P3.2为低电平,进入按键判断状态,软件延时10-20ms,从而避开了干扰信号区域,再重新检测P3.2状态,看按键是否真的已经按下。(5)任务:按键识别要求:通过按下一次按键INT0,使小灯D参考程序:include<AT89X52.H>sbitINT_0=P3^2;//定义按键的输入端sbitD1=P3^0;

//D1小灯定义voiddelay10ms(void)//延时程序{

unsignedchari,j;

for(i=20;i>0;i--)

for(j=248;j>0;j--);}key(

)

//按键判断程序{ if(INT_0==0)//判断是否按下键盘 { delay10ms(

);//延时,软件去干扰 if(INT_0==0)//确认按键按下 {

D1=!D1;//D1亮灭交替变化 }

while(INT_0==0);//按键锁定,每按一次D1只变化一次 }参考程序:续前页:}main(){while(1)

//永远循环,扫描判断按键是否按下 { key();

//对于此处CPU只按键判断一直扫描; }}

课后请实践:1.用两个按键来控制D1的亮灭;2.使用一个按键,控制小灯亮的顺序D1→D2→D3→D4→┅→D8→D7→→┅D0亮重复循环;续前页:课后请实践:(6)任务:数码管静态显示要求:用数码管LED的个位,静态显示数字“4”字样;注意:因采用共阴数码显示管,故此图P0口还应接1K或10K的排阻作为上拉电阻。(6)任务:数码管静态显示要求:用数码管LED的个位,静态参考程序:#include<AT89X52.H>sbitGE=P1^3;codeunsignedcharseg7code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

//显示段码main(){ unsignedchardisplay_date=4;//定义并赋值要显示的数据 while(1) { P0=seg7code[display_date];

//查表,输出 GE=0;//P1^3为低电平,相当于把数码管的4H端接地 }}课后请实践:1.让显示的数据动起来,比如做一个0到9的秒表(用软件延时);2.和按键判断程序结合,用按键控制数字变化;参考程序:课后请实践:(7)任务:数码管动态显示要求:用数码管LED的显示四位数据,比如显示数字“1234”;参考程序:#include<AT89X52.H>sbitqian=P1^0;sbitbai=P1^1;sbitshi=P1^2;sbitge=P1^3;codeunsignedcharseg7code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示段码voidDelay(unsignedinttc)//延时程序{ while(tc!=0) //如果tc为0则终止延时 { unsignedinti; //局部正整数变量i for(i=0;i<100;i++); //执行400次将耗时1毫秒 tc--; //tc计数减一 }}(7)任务:数码管动态显示要求:用数码管LED的显示四位数续前页:voidLed(intdate)//显示函数{ qian=0;//P1.0输出低电平,选通千位数 P0=seg7code[date/1000];//取出千位数,查表,输出。 Delay(10);//延时 qian=1;//销隐 bai=0;//P1.1输出低电平,选通百位数 P0=seg7code[date%1000/100];//取出百位数,查表,输出。 Delay(10);//延时 bai=1;//销隐 shi=0;//P1.2输出低电平,选通十位数 P0=seg7code[date%100/10];//取出十位数,查表,输出。 Delay(10);//延时 shi=1;//销隐 ge=0; //P1.3输出低电平,选通十位数 P0=seg7code[date%10];//取出个位数,查表,输出。 Delay(10); ge=1;}

续前页:续前页:main(){intdisplay_date=1234;//定义并赋值要显示的数据while(1){Led(display_date);//调用显示函数显示数据display_date}}

续前页:上述数码管动态显示程序的另一种写法参考程序:#include<AT89X51.H>unsignedchardatebit[]={0xfe,0xfd,0xfb,0xf7};//存储数码管的位选值unsignedchartvdate[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f,};unsignedintdisdata;//定义要显示的数据unsignedchardisdat[4];//存储要显示的四位数据voiddelay(time){unsignedchari,j;for(j=0;j<time;j++)for(i=0;i<250;i++);}display(void){ unsignedchark; disdata=1234;//显示1234

上述数码管动态显示程序的另一种写法参考程序:续前页:

disdat[0]=disdat/1000; //取出千位 disdat[1]=disdat%1000/100;

//取出百位 disdat[2]=disdat%100/10; //取出十位 disdat[3]=disdat%10; //取出个位 for(k=0;k<4;k++)

//显示四位数据 { P0=tvdate[disdat[k]];

//送出要显示数据的段码 P1=datebit[k]; //P2位选 delay(10); //延时 }}main(){while(1){display();}}

这种写法比上一种复杂,占用空间要多一些.但是使用方便,可以在此基础上方便的加上比如显示小数点,指定某位数码管闪烁等。课后思考:如何用软件延时来做一个0到60秒的计数器吗?续前页:这种写法比上一种复杂,占用空间要多一些.但是使(8)任务:4X4矩阵键盘识别要求:用AT89S51的并行口P2接4×4矩阵键盘,以P3.0-P3.3作输入线,以P3.4-P3.7作输出线;在每一个数码管上显示每个按键的“0-F”序号。[实验原理]每个按键有它的行值和列值,行值和列值的组合就是识别这个按键的编码。矩阵的行线和列线分别通过两并行接口和CPU通信。键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断开时的抖动。两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。(8)任务:4X4矩阵键盘识别要求:用AT89S51的并行键盘识别的两种方法逐行扫描法:(1)首先判断有无键按下:令矩阵行线输出全0信号,检测列线状态,若有一列电平为低,则有键按下。(2)确定闭合键位置:依次将各行线置为低电平,逐行检测各列线的电平状态,若某列为低,则该行线和列线交叉处按键就是闭合键。线反转法:(1)令矩阵键盘列线输出全0信号,行线作为输入接口接收信号,可判断按键处于哪一行。(2)令矩阵键盘行线输出全0信号,列线作为输入接口接收信号,可判断按键处于哪一列。(3)将输入信号相或后形成键盘的唯一键码。键盘识别的两种方法逐行扫描法:程序:(线反转法)#include<reg52.h>unsignedcharcodeseg7code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};unsignedchark;voiddelay10ms(void)//延时程序{ unsignedchari,j; for(i=20;i>0;i--) for(j=248;j>0;j--);}voidGetch(){ unsignedcharX,Y,Z;

P2=0xff;

P2=0x0f;

//先对P2置数行扫描 if(P2!=0x0f)//判断是否有键按下 {

delay10ms();//延时,软件去干扰

if(P2!=0x0f)

//确认按键按下X=P2;

{

程序:(线反转法)续前页:

X=P2;//保存行扫描时有键按下时状态 P2=0xf0;//列扫描 Y=P2;//保存列扫描时有键按下时状态 Z=X|Y;//取出键值 switch(Z)//判断键值(那一个键按下) { case0x77:k=0;break;//对键值赋值 case0x7b:k=1;break; case0x7d:k=2;break; case0x7e:k=3;break; case0xb7:k=4;break; case0xbb:k=5;break; case0xbd:k=6;break; case0xbe:k=7;break; case0xd7:k=8;break; case0xdb:k=9;break; case0xdd:k=10;break; case0xde:k=11;break; case0xe7:k=12;break; case0xeb:k=13;break; 续前页:续前页:

case0xed:k=14;break;

case0xee:k=15;break; } } }}voidmain(void){while(1){P2=0xff;Getch(

);P0=seg7code[k];//查表LED输出P1=0xf0;//输出相同的四位数据。}}

续前页:(9)任务:按键中断识别要求:采用中断技术,每按一下按键,计数器加1,并用LED显示出来,注意只显示2位十进制数。原理:以上的两个关于按键识别的实验的程序都是采用扫描的方式来实现的,CPU的利用率比较低;按键判断还可以用中断方式来判断。中断方式可以满足快速响应的要求。(9)任务:按键中断识别要求:采用中断技术,每按一下按键,计程序:#include<AT89X51.H>unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};unsignedchardispcount=0;//计数sbitgewei=P1^3;//个位选通定义sbitshiwei=P1^2;//十位选通定义voidDelay(unsignedinttc)//延时程序{while(tc!=0){unsignedinti;for(i=0;i<100;i++);tc--;}}voidExtInt0()interrupt0//中断服务程序{程序:续前页:dispcount++;//每按一次中断按键,计数加一if(dispcount==100)//计数范围0-99{dispcount=0;}}voidLED()//LED显示函数{if(dispcount>=10)//显示两位数{shiwei=0;P0=table[dispcount/10];Delay(8);shiwei=1;gewei=0;P0=table[dispcount%10];Delay(5);gewei=1;}else//显示一位数{

续前页:续前页:shiwei=1;gewei=0;P0=table[dispcount];Delay(8);}}

voidmain(){TCON=0x01;

//下降沿触发

IE=0x81;

//开总中断和允许外部中断

while(1)

//循环执行{LED(

);}

//调用显示函数}/*******************************************************************课后思考:在程序在硬件运行过程中,有时候按一下键会加几个数,是因为没有去除按键干扰请您想一想怎么消除抖动./***************************************************************************************/

续前页:(10)任务:定时器T0的应用——9.9秒计时设计要求:开始时,显示“00”,第1次按下INT0后就开始计时。第2次按INT0后,计时停止。第3次按INT0后,计时归零。(10)任务:定时器T0的应用——9.9秒计时设计要求:开始程序:#include<AT89X51.H>unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,};unsignedcharsec;//定义计数值,每过1/10秒,sec加一unsignedcharkeycnt=1;//键值判断unsignedinttcnt;//中断次数计数器

sbitgewei=P1^3;//个位选通定义sbitshiwei=P1^2;//十位选通定义sbitINT_0=P3^2;//按键定义位voidDelay(unsignedinttc)//延时程序{while(tc!=0){unsignedinti;for(i=0;i<100;i++);tc--;}}程序:续前页:voidLED(

)//LED显示函数{shiwei=0;P0=table[sec/10]|0x80;//十位加上小数点Delay(5);shiwei=1;gewei=0;P0=table[sec%10];Delay(5);gewei=1;}voidKEY()//按键扫描程序{unsignedchari,j;if(INT_0==0){for(i=20;i>0;i--)//延时去干扰for(j=248;j>0;j--);续前页:续前页:if(INT_0==0){switch(keycnt)

//按下次数判断{case1:

//第一次按下TH0=0x06;

//对TH0TL0赋值TL0=0x06;TR0=1;

//开始定时keycnt=2;

//为第二次做准备break;case2:

//第二次按下TR0=0;

//定时结束keycnt=3;

//为第三次按下做准备break;case3:

//第三次按下keycnt=1;

//重新开始判断键值sec=0;

//计数重新从零开始break;}

续前页:续前页:while(INT_0==0);}}}voidt0(void)interrupt1using0//定时中断服务函数{tcnt++;//每过250us,tcnt加一if(tcnt==400)//计满400次(0.1秒)时{tcnt=0;//重新再计sec++;if(sec==100)//定时10秒,在从零开始计时{sec=0;}}}续前页:续前页:voidmain(void){TMOD=0x02;//定时器工作在方式2自动重装方式ET0=1;//允许T0产生中断EA=1;//开总中断sec=0;while(1){KEY();LED();}}续前页:电子钟电路及程序示例:电路原理图:电子钟电路及程序示例:电路原理图:C语言源程序:#include<AT89X52.h>unsignedcharcodedis_code[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x80};unsignedchardatadis[5];sec=0,min=11,hou=17,cou=0,sec_flag=0,sansuo_flag=0,dis_r=0;//***voidmain(){P0=0x00;P2=0xff;TMOD=0x11;TH0=0xec;TL0=0x78;//T0十毫秒定时TH1=0xfe;TL1=0x0c;//T1一毫秒定时

EA=1;ET0=1;ET1=1;TR0=1;TR1=1;while(1){if(sec_flag==1)sec_flag=0;}}C语言源程序:#include<AT89X52.h>续前页:voidtime0(void)interrupt1{cou++;if(cou==50)sansuo_flag=~sansuo_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=0xec;TL0=0x78;}续前页:续前页:voidtime1(void)interrupt3{dis[0]=min%10;dis[1]=min/10;dis[2]=10;dis[3]=hou%10;dis[4]=hou/10;P0=dis_code[dis[dis_r]];switch(dis_r){case0:P2=0xef;dis_r++;break;case1:P2=0xdf;dis_r++;break;case2:if(sansuo_flag==0){P2=0xcf;}else{P2=0xff;}dis_r++;break;case3:P2=0xbf;dis_r++;break;case4:P2=0x7f;dis_r++;break;default:dis_r=0;P2=0xff;}TH1=0xfe;TL1=0x0c;}续前页:如何加入按键校时程序并用Proteus软件仿真如何加入按键校时程序并用Proteus软件仿真含校时功能的数字电子钟完整C语言源程序代码#include<AT89X52.h>unsignedcharcodedis_code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};unsignedchardatadis[4];unsignedcharsec=0,min=59,hou=22,cou=0,sansuo_flag=0,dis_r=0;unsignedcharint0_flag,int1_flag;//以下10ms延时函数///voiddelay10ms(void){unsignedchari,j;for(i=20;i>0;i--)for(j=248;j>0;j--);}//以下为主函数///voidmain(void){P0=0x00;P2=0xff;TMOD=0x11;TH0=0xec;TL0=0x78;//T0十毫秒定时

TH1=0xfe;TL1=0x0c;//T1一毫秒定时码EA=1;EX0=1;EX1=1;IT0=1;IT1=1;ET0=1;ET1=1;TR0=1;TR1=1;含校时功能的数字电子钟完整C语言源程序代码#include<续前页: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==0){hou++;EX1=1;if(hou==24){hou=0;}}}}}续前页:续前页:voidint0(void)interrupt0

//外部中断0函数//{int0_flag=1;}voidtime0(void)interrupt1//定时器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=0xec;TL0=0x78;}续前页:续前页:voidint1(void)interrupt2//外部中断1函数//{int1_flag=1;}//以下为定时器1中断函数//voidtime1(void)interrupt3{dis[0]=min%10;dis[1]=min/10;dis[2]=hou%10;dis[3]=hou/10;switch(dis_r){case0:P2=0xef;P0=dis_code[dis[dis_r]];dis_r++;break;case1:P2=0xdf;P0=dis_code[dis[dis_r]];dis_r++;break;case2:P2=0xbf;if(sansuo_flag==0){P0=dis_code[dis[dis_r]]|0x80;}else{P0=dis_code[dis[dis_r]];}dis_r++;break;case3:P2=0x7f;P0=dis_code[dis[dis_r]];dis_r++;break;default:dis_r=0;P2=0xff;}TH1=0xfe;TL1=0x0c;}续前页:(11)任务:PC机与单片机通信要求:单片机串口通信的应用,通过串口,电脑和单片机系统进行通信。电脑作为上位机,向下位机单片机系统发送十六进制或者ASCLL码,单片机系统接收后,用LED显示接收到的数据和向上位机发回原样数据。(11)任务:PC机与单片机通信要求:单片机串口通信的应用,单片机串口相关知识回顾(1)MCS-51串行口的原理结构图

单片机串口相关知识回顾(1)MCS-51串行口的原理结构图单片机串口相关知识回顾(2)串行口控制寄存器SCON

SM0SM1SM2RENTB8RB8TIRI

D7D6D5D4D3D2D1D0

SMODGF1GF0PDIDL

D7D6D5D4D3D2D1D0

(3)特殊功能寄存器PCON

单片机串口相关知识回顾(2)串行口控制寄存器SCONSM单片机串口相关知识回顾(4)串口通信的波特率

对于方式0,波特率是固定的,为单片机时钟的1/12,即fosc/12。对于方式2,波特率有两种可供选择,即fosc/32和fosc/64。对应于以下公式:

波特率=fosc×(2^SMOD)/64对于方式1和方式3,波特率都由定时器T1的溢出率来决定,对应于以下公式:

波特率=(2^SMOD/32)×(定时器T1的溢出率)

而定时器T1的溢出率则和所采用的定时器工作方式有关,并可用以下公式表示:

定时器T1的溢出率=fosc/12×(2^n-X)单片机串口相关知识回顾(4)串口通信的波特率对于方式0,程序:#include<AT89X51.H>unsignedchardat;//用于存储单片机接收发送缓冲寄存器SBUF里面的内容sbitgewei=P1^3;//个位选通定义sbitshiwei=P1^2;//十位选通定义unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};voidDelay(unsignedinttc)//延时程序{while(tc!=0){unsignedinti;for(i=0;i<100;i++);tc--;}}voidLED()//LED显示接收到的数据(十进制){shiwei=0;P0=table[dat/10];Delay(5);程序:续前页:shiwei=1;gewei=0;P0=table[dat%10];Delay(5);gewei=1;}voidInit_Com(void)//功能:串口初始化,波特率9600,方式1{TMOD=0x20;PCON=0x00;SCON=0x50;TH1=0xFd;TL1=0xFd;TR1=1;}续前页:续前页:voidmain()//实现接收数据并把接收到的数据原样发送回去///////{Init_Com();//串口初始化while(1){if(RI)//扫描判断是否接收到数据,{dat=SBUF;//接收数据SBUF赋与datRI=0;//RI清零(必须用软件清零)SBUF=dat;//再原样把数据发送回去}LED();//显示接收到的数据}}续前页:(12)任务:数模转换器ADC0804的应用(扩展)要求:从ADC0804的通道IN+输入0-5V之间的模拟量,通过ADC0804转换成数字量在数码管上以十进制形成显示出来。(12)任务:数模转换器ADC0804的应用(扩展)要求:从程序:#include<reg52.h>codeunsignedcharseg7code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示段码sbitint1=P3^3;//定义管脚功能sbitcs=P3^2;sbitwr=P3^6;sbitrd=P3^7;voidDelay(unsignedinttc)//显示延时程序{while(tc!=0){unsignedinti;for(i=0;i<100;i++);tc--;}}unsignedcharadc0804(void)//读AD0804子程序{unsignedcharaddata,i;rd=1;wr=1;int1=1;//读ADC0804前准备P1=0xff;//P1全部置一准备cs=0;wr=0;wr=1;//启动ADC0804开始测电压while(int1==1);//查询等待A/D转换完毕产生的INT(低电平有效)信号rd=0;//开始读转换后数据程序:续前页:i=i;i=i;//无意义语句,用于延时等待ADC0804读数完毕addata=P1;//读出的数据赋与addatard=1;cs=1;//读数完毕return(addata);//返回最后读出的数据}unsignedintdatpro(void)

//ADC0804读出的数据处理{unsignedcharx;unsignedintdianyah,dianyal;

//用于存储读出数据的高字节和低字节unsignedintdianya=0;

//存储最后处理完的结果注意数据类型for(x=0;x<10;x++)

//将10次测得的结果存储在dianya中{dianya=adc0804()+dianya;}dianya=dianya/10;

//求平均值dianyah=dianya&0xf0;

//屏蔽低四位dianyah=dianyah>>4;

//右移四位取出高四位dianyal=dianya&0x0f;

//屏蔽高四位取出低四位dianya=dianyal*20+dianyah*320;

//最后的结果是一个四位数,便于显示return(dianya);//返回最后处理结果}续前页:续前页:voidLed(){unsignedintdate;date=datpro();//调用数据处理最后结果P2=P2&0xef;P0=seg7code[date/1000]|0x80;//输出个位数和小数点Delay(8);P2=P2|0xf0;P2=P2&0xdf;P0=seg7code[date%1000/100];//输出小数点后第一位Delay(8);P2=P2|0xf0;P2=P2&0xbf;P0=seg7code[date%100/10];//输出小数点后第二位Delay(8);P2=P2|0xf0;P2=P2&0x7f;P0=seg7code[date%10];//输出小数点后第三位Delay(8);P2=P2|0xf0;}main(){while(1){Led();//只需调用显示函数}}续前页:(13)任务:模数转换器DAC0832的应用要求:用两个按键通过单片机控制DAC0832的输出,使OUT端可以输出0—5V的幅值,频率为1KHZ的锯齿波和三角波两种波形。通上电源后;按下INT1则输出三角波,再按下INT0输出锯齿波。(13)任务:模数转换器DAC0832的应用要求:用两个按键[实验原理]DAC0832是8位全MOS中速D/A转换器,采用R—2RT形电阻解码网络,转换结果为一对差动电流输出,转换时间大约为1us。使用单电源+5V―+15V供电。参考电压为-10V-+10V。在此我们直接选择+5V作为参考电压。DAC0832有三种工作方式:直通方式,单缓冲方式,双缓冲方式;在此我们选择直通的工作方式,将XFER、WR1、WR2和CS管脚全部接数字地。管脚8接参考电压,在此我们接的参考电压是+5V。那么经过第一级运放后,输出电压将是-5V-0V,在经过第二级运放反相放大1倍以后将可以输出0V—5V了。再控制P1口输出数据有规律的变化将可以产生三角波,锯齿波,梯型波等波形了。[实验原理]程序:#include<AT89X51.H>unsignedcharkeycnt=0;//波形标志unsignedchartcnt=0;//键值判断bitsjz=0;//产生三角波时上升、下降用到的标志voiddelayl()

//延时子程序{unsignedchari,j;for(i=20;i>0;i--)for(j=248;j>0;j--);}voidKEY()

//按键扫描程序{if(P3_2==0){delayl();//延时跳过按下时的抖动if(P3_2==0){keycnt=0;

//定时器产生锯齿波标志TR0=0;

//暂时停止波形输出TH0=0x256-40;

//对TH0TL0赋值TL0=0x256-40;TR0=1;

//开始定时,产生锯齿波程序:续前页:while(P3_2==0);//如果一直按着键,则等待键松开delayl();//延时跳过松开后的抖动}}if(P3_3==0){delayl();//延时跳过按下时的抖动if(P3_3==0){keycnt=1;//定时器产生三角波标志TR0=0;//暂时停止波形输出TH0=0x256-40;//对TH0、TL0赋值TL0=0x256-40;TR0=1;//开始定时产生三角波}while(P3_2==0);//如果一直按着键,则等待松键开delayl();//延时跳过松开后的抖动}}续前页:续前页:voidt0(void)interrupt1using0//定时中断服务函数{if(keycnt==0)//产生锯齿波{P0=tcnt;tcnt=+0x0a;//步进0.2V/一次中断if(tcnt==0xfb){tcnt=0;}}if(keycnt==1)//产生三角波{if(sjz==0){P0=tcnt;tcnt=+0x0a;//步进0.2V/一次中断if(tcnt==0xfa){sjz=1;}}if(sjz==1)续前页:续前页:{P0=tcnt;tcnt=-0x0a;if(tcnt==0){sjz=0;}}}}voidmain(void){TMOD=0x02;//定时器工作在方式2ET0=1;EA=1;while(1){KEY();}}续前页:(14)任务:24C08的读写操作要求:利用24C08断电以后存储的数据不消失的特点,可以做一个断电保护装置。首先利用单片机做一个0—99秒的自动计时器。然后随机关断电源,在通电以后计时器接着断电前的状态继续计时。(14)任务:24C08的读写操作要求:利用24C08断电以[实验原理——引脚图][实验原理——引脚图][实验原理——总线协议][实验原理——总线协议][实验原理——写周期时序和起始、停止时序][实验原理——写周期时序和起始、停止时序][实验原理——器件寻址][实验原理——器件寻址][实验原理——器件寻址][实验原理——器件寻址][实验原理——写操作]注意:I2C总线数据都是高位在前,低位在后!![实验原理——写操作]注意:I2C总线数据都是高位在前,低位[实验原理——写操作][实验原理——写操作][实验原理——读操作][实验原理——读操作][实验原理——读操作][实验原理——读操作][实验原理——读操作][实验原理——读操作]程序:#include<AT89X52.H>#include<stdio.h>#include<absacc.h>unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};unsignedcharsec;//定义计数值,每过1秒,sec加1unsignedinttcnt;//定时中断次数bitwrite=0;//写24C08的标志;sbitgewei=P1^3;//个位选通定义sbitshiwei=P1^2;//十位选通定义/////////24C08读写驱动程序开始////////////////////sbitscl=P3^6;//24c08SCLsbitsda=P3^7;//24c08SDAvoiddelay1(unsignedcharx){unsignedinti;for(i=0;i<x;i++);;}voidflash()

//延时2us{;;}程序:voidx24c08_init()//24c08初始化子程序{scl=1;flash();sda=1;flash();}voidstart()//启动I2C总线{sda=1;flash();scl=1;flash();sda=0;flash();scl=0;flash();}voidstop()//停止I2C总线{sda=0;flash();scl=1;flash();sda=1;flash();}voidwritex(unsignedcharj)//写一个字节{unsignedchari,temp;temp=j;for(i=0;i<8;i++){temp=temp<<1;scl=0;flash();sda=CY;flash();scl=1;flash();}scl=0;flash();sda=1;flash();}voidx24c08_init()unsignedcharreadx()//读一个字节{unsignedchari,j,k=0;scl=0;flash();sda=1;for(i=0;i<8;i++){flash();scl=1;flash();if(sda==1)j=1;elsej=0;k=(k<<1)|j;scl=0;}flash();return(k);}voidclock()//I2C总线时钟,确认应答信号{unsignedchari=0;scl=1;flash();while((sda==1)&&(i<255))i++;scl=0;flash();}unsignedcharreadx()////////从24c08的地址address中读取一个字节数据/////unsignedcharx24c08_read(unsignedcharaddress){unsignedchari;//先发写命令、写地址start();writex(0xa0);clock();writex(address);clock();//再发读命令,读数据start();writex(0xa1);clock();i=readx();stop();delay1(10);return(i);}//////向24c08的address地址中写入一字节数据info/////voidx24c08_write(unsignedcharaddress,unsignedcharinfo){EA=0;start();

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论