单片机综合控制器实验.docx
- 文档编号:10243122
- 上传时间:2023-02-09
- 格式:DOCX
- 页数:25
- 大小:116.02KB
单片机综合控制器实验.docx
《单片机综合控制器实验.docx》由会员分享,可在线阅读,更多相关《单片机综合控制器实验.docx(25页珍藏版)》请在冰豆网上搜索。
单片机综合控制器实验
单片机综合性设计性实验报告
实验项目名称:
单片机综合控制器实验
实验室(中心):
电子实验室
实验完成时间:
09年11月25日
一.实验目的与要求
通过仿真搭建和实物搭建相结合,完成灵活可变的单片机最小系统设计,并掌握地址空
间的分配操作。
通过仿真搭建和实物搭建相结合,万用交叉口交通灯控制器系统设计,并掌握C51编程
操作。
2.实验内容
(1)以6264或6116为扩展的存储芯片,8255或8155芯片为键盘显示控制芯片,建立基本
的串行口,普通的I/O口,A/D转换,D/A转换口功能。
(2)用Proteus仿真软件搭建仿真硬件电路图。
验证编制软件。
(3)用protel99s布原理图、建PCB板图。
(4)实物器件焊接搭建。
模拟控制就是以红、绿、黄色4组12个发光二极管表示交通信号灯。
每组灯有两位数
码倒倒计时显示。
假设一个十字路口为东西南北走向。
初始状态0为东西红灯,南北红灯。
然后转状态1,
东西方向的绿灯亮,东西方向可通车,而南北方向的红灯亮,南北方向的车禁止通行。
过一
段时间转状态2,东西绿灯灭后,黄灯亮,延时几秒,南北仍然红灯。
再转状态3,南北方向
的绿灯亮,南北方向可以通车,而东西方向的红灯亮,东西方向禁止车辆通行。
过一段时间
转状态4,南北绿灯灭后亮黄灯,延时几秒,东西方向仍然红灯亮。
最后循环至状态1。
用Proteus仿真软件搭建仿真硬件电路图。
验证编制软件。
三.实验原理及实验线路
4.实验器材
表2.5.2最小系统的硬件元件清单:
单片机AT89C52瓷片电容CAP30pF晶振CRYSTAL12MHz
电解电容CAP-ELEC电阻RES按钮BUTTON
发光二极管LED-BIRG发光二极管LED-BIBY开关SWITCH
排阻RESPACK-8发光二极管LED-BIGY发光二极管LED-YELLOW
按键16个8255芯片74LS138芯片74LS373DAC0809
5.系统流程图
开始
延时等待系统准备好
系统初始化初始化
N
N
N
P32==0?
P35==0?
P31==0?
P34==0?
Y
Y
Y
Y
启动键盘扫描
启动波形发生器
启动模拟交通灯
启动AD转换
产生锯齿波
N
‘0’键按下
初始化计数变量
采样频率0.5Hz
Y
N
P32==0?
调用彩灯功能
显示当前计数变量初值
将转化的数字量转换成十进制数
N
Y
产生方波
显示按键值
1秒到了?
显示测量的结果
N
Y
P32==0?
计数变量减1
N
Y
满足下一种状态的条件?
Y
6、硬件设计框图
显示
输出
AT89C51
键盘
扫描
8255A
AD
转换
模拟
交通灯
波形
发生器
七、软件设计
#include
#include
#defineDAC0832XBYTE[0XDFFF]
#defineCOM8255XBYTE[0X7FFF]
#definePA8255XBYTE[0X7FCF]
#definePB8255XBYTE[0X7FDF]
#definePC8255XBYTE[0X7FEF]
#defineIN0XBYTE[0XBFF8]//设置AD0809的通道0的地址
#defineucharunsignedchar//宏定义
#defineuintunsignedint//宏定义
uintaa,bai,shi,ge,bb;//定义变量
doublejieguo;
unsignedchara0[4];
uchari,j,m,n;//用于循环
sbitP32=P3^2;
sbitP31=P3^1;
sbitP30=P3^0;//ADC0809转换状态
sbitP33=P3^3;//键盘中断
sbitP34=P3^4;
sbitP35=P3^5;
sbitP17=P1^7;//产生AD转换时钟的引脚
unsignedcharcount=-1;//键盘值计数
unsignedcharsta;//读取键盘状态的变量
unsignedcharkey;//功能选择键
staticunsignedcharidataad[1];//AD转换结果存储
codeunsignedchartable[20]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xff,0x00,0xff,0x00};
codeunsignedchartable0[16]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0E};
unsignedchartablea[6]={0xfe,0xfd,0xfb,0xfF};//用于键盘扫描
unsignedchartableb[4]={0XE0,0XD0,0XB0,0X70};//用于键盘扫描
codeunsignedchartablec[]={0xfe,0xfd,0xfb,0xdf,0xef,0xf7,0xf6,0xf5,
0xf3,0xd7,0xe7,0xe6,0xe5,0xe3,0xc7,0xc6,
0xc5,0xc3,0xc2,0xc1,0xc0,0xc1,0xc2,0xc4,
0xe0,0xd0,0xc8,0xc9,0xca,0xcc,0xe8,0xd8,
0xd9,0xda,0xdc,0xf8,0xf9,0xfa,0xfc,0xfd,
0xfe,0xff,0xfe,0xfd,0xfb,0xdf,0xef,0xf7,
0xf7,0xdf,0xfb,0xfd,0xfe,0xfe,0xfd,0xfb,
0xdf,0xef,0xf7,0xf7,0xef,0xdf,0xfb,0xfd,
0xfe,0xfe,0xfd,0xfb,0xdf,0xef,0xf7,0xfe,
0xfd,0xfb,0xdf,0xef,0xf7,0xfe,0xfd,0xfb,
0xdf,0xef,0xf7,0xfe,0xf7,0xfd,0xef,0xfb,
0xdf,0xde,0xd7,0xdd,0xcf,0xdb,0xda,0xd3,
0xd9,0xcb,0xca,0xc3,0xc9,0xc8,0xc1,0xc0,
0xff,0xf6,0xed,0xdb,0xf6,0xed,0xdb,0xf6,
0xed,0xdb,0xf6,0xed,0xdb,0xf6,0xed,0xdb,
0xf3,0xed,0xde,0xf3,0xed,0xde,0xf3,0xed,
0xde,0xf3,0xed,0xde,0xf3,0xed,0xde,0xfe,
0xfd,0xfa,0xdd,0xea,0xd5,0xea,0xd5,0xea,
0xd5,0xea,0xd5,0xea,0xd5,0xea,0xd5,0xea,
0xd5,0xea,0xd5,0xea,0xd5,0xff,0xc0,0xff,
0xc0,0xff,0xc0,0xff,0xc0,0xff,0xff,0xff};//用于彩灯显示
voiddelay100us(void)//------------------------延时100us
{
unsignedchara,b;
for(b=2;b>0;b--)
for(a=47;a>0;a--);
}
voiddelay6ms(void)//----------------------延时6ms键盘去抖
{
unsignedchara,b,c;
for(c=1;c>0;c--)
for(b=222;b>0;b--)
for(a=12;a>0;a--);
}
voiddelay0(unsignedintz)//----------------------------动态显示LED延时子函数
{
unsignedinti,j;
for(i=0;i for(j=0;j<110;j++); } voidad0809(unsignedcharidata*x)//-------------A/D采样函数 { unsignedcharxdata*ad_adr; //unsignedchari; ad_adr=&IN0; //for(i=0;i<8;i++) //{ *ad_adr=0;//启动转换 delay100us();//延时100us等待EOC变低 while(P32==0);//查询等待转换结束 x[0]=*ad_adr;//储存结果 //ad_adr++;//读取下一个通道 //} } voidint1(void)//--------------------------------------键值扫描函数 { for(i=0;i<3;i++) for(j=0;j<3;j++) { P1=tablea[i]; sta=P1&0xf0; if(sta==tableb[j]) { delay6ms(); if(sta==tableb[j]) count=i*3+j; } } } /**************************************************************/ /**/ /*第1个状态: 主干道亮绿灯30S、支干道亮红灯*/ /*第2个状态: 主干道绿灯闪3次转亮黄灯、支干道亮红灯3S*/ /*第3个状态: 主干道亮红灯、支干道亮绿灯25S*/ /*第4个状态: 主干道亮红灯、支干道绿灯闪3次转亮黄灯3S*/ /*返回到第1个状态*/ /**/ /***************************************************************/ /*--------------显示子函数----------------------------*/ voiddisplay(uinttemp) { shi=temp%100/10;//显示十位 ge=temp%10;//显示个位 PC8255=0x01; PA8255=table[shi];//显示十位 delay0(5); PC8255=0x02; PA8255=table[ge];//显示个位 delay0(5); PC8255=0x04; PA8255=table[shi];//显示十位 delay0(5); PC8255=0x08; PA8255=table[ge];//显示个位 delay0(5); } voidinit1()//---------------------第1个状态: 主干道亮绿灯30S、支干道亮红灯 { uinttemp; temp=20;//变量赋初值 aa=0; TMOD=0x01;//定时器0工作于方式1 TH0=0x4C; TL0=0x00;//定时器赋初值 ET0=1;//开定时中断 TR0=1;//开定时器0 while (1) { PB8255=0XF3;//第二个状态: 主干道亮绿灯30S、支干道亮红灯 if(aa==20)//定时20*50MS=1S { aa=0;//定时完成一次后清0 temp--;//变量自增 if(temp==3)//定时 { break; } } display(temp); } } voidinit2()//----------------------第2个状态: 主干道绿灯闪3次转亮黄灯、支干道亮红灯3S { uinttemp; temp=3;//变量赋初值 aa=0; TMOD=0x01;//定时器0工作于方式1 TH0=0x4C; TL0=0x00;//定时器赋初值 ET0=1;//开定时中断 TR0=1;//开定时器0 while (1) { PB8255=0XF5; if(aa==20)//定时20*50MS=1S { aa=0;//定时完成一次后清0 temp--;//变量自增 if((temp+1)==0)// { break; } } display(temp); PB8255=0XF7; display(temp); } } voidinit3()//-----------------------第3个状态: 主干道亮红灯、支干道亮绿灯25S {uinttemp; temp=15;//变量赋初值 aa=0; TMOD=0x01;//定时器0工作于方式1 TH0=0x4C; TL0=0x00;//定时器赋初值 ET0=1;//开定时中断 TR0=1;//开定时器0 while (1) { PB8255=0XDE; if(aa==20)//定时20*50MS=1S { aa=0;//定时完成一次后清0 temp--;//变量自增 if(temp==3)//定时100S { break; } } display(temp); } } voidinit4()//-----------------------第4个状态: 主干道亮红灯、支干道绿灯闪3次转亮黄灯3S { uinttemp; temp=3;//变量赋初值 aa=0; TMOD=0x01;//定时器0工作于方式1 TH0=0x4C; TL0=0x00;//定时器赋初值 ET0=1;//开定时中断 TR0=1;//开定时器0 while (1) { PB8255=0XFE; if(aa==20)//定时20*50MS=1S { aa=0;//定时完成一次后清0 temp--;//变量自增 if((temp+1)==0)//定时100S { break; } } display(temp); PB8255=0XEE; display(temp); } } voidinit5()//-----------------------第五个状态: 主干道和支干道亮红灯、 { aa=0;//恢复软件定时初值 PB8255=0XDB; PA8255=0XFF; delay6ms(); } voidxint0()interrupt2//-------------------外部中断1,这里用2是INT1的优先级为0 { init5(); } /*-------------定时中断子函数-----------------*/ voidxtimer0()interrupt1 { TF0=0; TH0=0x4C; TL0=0x00;//定时器赋初值 aa++; } voidchange(void)//----------------------AD数字量转换成十进制码显示 { jieguo=ad[0]; jieguo=(jieguo/255.0)*5; a0[0]=(int)jieguo/10.0; a0[1]=(int)(jieguo)%10; a0[2]=(int)(jieguo*10)%10; a0[3]=(int)(jieguo*100)%10; PC8255=0X01; PA8255=table[a0[0]]; delay0(5); PC8255=0X02; PA8255=table0[a0[1]]; delay0(5); PC8255=0X04; PA8255=table[a0[2]]; delay0(5); PC8255=0X08; PA8255=table[a0[3]]; delay0(5); } /*voidTimer1Interrupt(void)interrupt3//-----------------中断产生脉冲 { TH1=0xFF; TL1=0xFF; P17=~P17; }*/ voidsend(void)///////////////////////发送数据子程序 { unsignedchari; for(i=0;i<4;i++) { TB8=P; SBUF=a0[i]; while(TI==0); TI=0; while(RI==0); RI=0; if(SBUF==0xff) i--; } } voidstart(void) { for(i=0;i<20;i++) { PC8255=0XFF; PA8255=table[i]; delay0(200); } } voidintial(void)//------------------------初始化函数 { delay0(1000); //TMOD=0x01; //TH1=0xFF; //TL1=0xFF; //ET1=1; SCON=0x90; PCON=0X80; COM8255=0X80; PB8255=0XFF; EA=1;//打开外部中断 key=-1; } /*---------------------主函数-------------------*/ voidmain(void) { intial(); start(); while (1) { count=-1; PB8255=0XFF; int1(); PC8255=0XFF; if(count! =-1) PA8255=table[count]; key=-1; if(count==0)key=0;//0键按下闪烁彩灯 if(count==1)key=1;//AD转换功能 if(count==2)key=2;//交通灯功能 if(count==3)key=3;//DA转换 while(key==3) { while (1)//DA转换 {for(i=0;i<255;i++)//输出锯齿波 { DAC0832=i; } if(P32==0||P35==0)break; } while (1) { DAC0832=0X00; delay0(1000); DAC0832=0XFF; delay0(1000); if(P32==0||P35==0)break;//输出方波 } if(P35==0)break; } while(key==1) { PB8255=0XFF; ad0809(ad);//启动AD转换 change(); if(P32==0)send(); if(P35==0)break; } while(key==2)//交通灯功能 { EX1=1; IT1=0;//INT0为沿触发方式 if(P35==0)break; init1();//第1个状态 if(P35==0)break; init2();//第2个状态 if(P35==0)break; init3();//第3个状态 if(P35==0)break; init4();//第4个状态 EX1=0; ET0=0;//关闭定时中断 } while(key==0)//0键按下闪烁彩灯,其它键按下显示键值 { for(i=0;i<168;i++) {PB8255=tablec[i]; delay0(150); if(P35==0)break; } if(P35==0)break; }}} 八、实验总结及心得 1、通过这次实验,让我对电路设计有了全新的认识,也对课堂上的知识有了更深的理解和记忆, 2、实验中,我学会了端口地址的概念,原理以及其使用的规则,尤其是端口地址在实际电路中的应用,显得尤为重要,没有端口地址,就不可能实现对外围器件的操作。 3、然就就是软件设计知识,,这个不能在很短的时间内学会,所以要多练习和多思考,慢慢的积累,养成设计计算机语言的习惯,使其具有可读性,且逻辑设计也要合理。 4、在设计程序前都要有大概想好程序设计的步骤和语言的结构,以便于在调试的时候方便,如果在开始编程的时候不注意这些,就会使得下次调试的时候更容易上手。 5、由于这次实验是软结合硬件来实现的,在调试的时候如果能掌握一定的方法就很荣翻译将调试好的成 6、在设计好硬件的时候,可以用万用表的二极管档来测试连线的连通性。 我说说几个自己出现的错误和改正的方法。 在设计交通灯时钟时,在按下紧急红灯之后,交通灯的计数器就停止,无法恢正常,原来是在紧急中断时,定时器还在计数(我采用的软件和硬件结合的定时方式),于是计数值过大,超过了判定计数减一时的范围。 就产生了死循环。 化,也有可能是没有足够的驱动电流,然后考虑怎样才能修改错误。 比如加上拉电阻来增加驱动能力。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 综合 控制器 实验