单片机课程设计双机通信交通灯.docx
- 文档编号:29532350
- 上传时间:2023-07-24
- 格式:DOCX
- 页数:18
- 大小:697.50KB
单片机课程设计双机通信交通灯.docx
《单片机课程设计双机通信交通灯.docx》由会员分享,可在线阅读,更多相关《单片机课程设计双机通信交通灯.docx(18页珍藏版)》请在冰豆网上搜索。
单片机课程设计双机通信交通灯
《单片机课程设计》
设计报告
题目:
双机通信
专业:
电子信息工程
班级:
班
学号:
631
姓名:
指导老师:
重庆交通大学信息科学与工程学院
设计时间:
年1月1日到年1月9号
1.设计任务说明
在课程实验(交通灯)的基础上,实现双机通信:
1、可以是PC机与单片机的通信,通过PC机上的软件(如串口调试助手等)控制单片机交通灯的设置(如改变不同路口红绿灯时间等参数的设置);
2、也可通过一个单片机系统控制另一个单片机系统交通灯的设置(如改变不同路口红绿灯时间等参数的设置)。
3、也可完成经指导老师批准的其它题目,如:
(1)用单片机及A/D转换芯片实现的数字电压表
(2)用单片机及D/A转换芯片实现的波形发生器
2.总体设计
本人选择做双机通信---交通灯,通过两个按键分别设置红灯、绿灯的时间参数。
当然,设置时间参数的是其中一块单片机,控制数码管和红绿灯亮暗的的变化又是另外一块单片机。
3.详细设计
总设计图如下:
4.程序及说明
流程图:
中断处理:
中断结束
甲单片机程序代码如下:
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharx=100;//红灯最长时间设置为99秒
uchary=51;//绿灯最长时间设置为50秒
uchart;
/***********串行口发送与接收中断处理函数**********************************************/
voidinit()
{
IP=0x02;//中断优先级设置(T0中断为最高优先级,然后是INT0,最后是INT1)
TMOD=0X21;//T1定时计数器工作于方式2,作为波特率发生器,SMOD此处默认取0
//T0工作方式1,16位计数
TH1=0Xe6;TL1=0Xe6;//8位自动重装,波特率设置为1200
TR1=1;//启动T1定时计数器
SCON=0x40;//串行方式1,串行接收禁止
EX0=1;//打开外部中断0
EX1=1;//打开外部中断1
IT0=1;//INT0,外部中断0,下降沿触发
IT1=1;//INT1,外部中断1,下降沿触发
EA=1;//开总中断
}
/***********定时器0函数**********************************************/
voidtimer1()interrupt1
{
//TMOD=0x01;//工作方式1,16位计数
TR0=0;
TH0=(65536-10000)/256;//对于12MHz的晶振,此处定时50ms,赋值0X3cb0
TL0=(65536-10000)%256;//若定时10ms,赋值0XD8F0;5ms,赋值0Xec78
TR0=1;//启动定时器T0工作
t--;
}
/***********外部中断0函数**********************************************/
voidint0()interrupt0//对应红灯时间参数设置
{
TH0=(65536-10000)/256;//对于12MHz的晶振,此处定时50ms,赋值0X3cb0
TL0=(65536-10000)%256;//若定时10ms,赋值0XD8F0;5ms,赋值0Xec78
ET0=1;//开T0中断请求
t=6;//设定延时长短
TR0=1;//启动定时器T0工作
while(t);//延时消抖
TR0=0;//禁止T0定时器工作,防止后面程序运行时被中断
IE0=0;//再次清外部中断0请求标志
x--;
if(x==10)x=99;
TI=0;//清发送中断请求标志,先发再查
SBUF=1;//作为标识标志,发送给乙机
while(!
TI);//查询方式
TI=0;
SBUF=x;
}
/***********外部中断1函数**********************************************/
voidint1()interrupt2//对应绿灯时间参数设置
{
TH0=(65536-10000)/256;//对于12MHz的晶振,此处定时50ms,赋值0X3cb0
TL0=(65536-10000)%256;//若定时10ms,赋值0XD8F0;5ms,赋值0Xec78
ET0=1;//开T0中断请求
TR0=1;//启动定时器T0工作
t=6;
while(t);//延时消抖
TR0=0;
IE1=0;//再次清外部中断1请求标志
y--;
if(y==10)y=50;
TI=0;
SBUF=0;
while(!
TI);//查询方式
TI=0;
SBUF=y;
}
/***********主函数**********************************************/
main()
{
init();
while
(1);
}
乙单片机代码如下:
#include
#defineucharunsignedchar
#defineuintunsignedint
uchart=0;//用于timer0函数,设置数码管显示的数字跳变的时间间隔
ucharw=0;//切换红绿灯标志位
uchark=255;//用于串口中断处理,甲机的按键按一次,则向乙机发送两个单字节数据
//前一个数据用于辨识将要设置的时间参数属于红灯还是绿灯
//后一个数据是想要设置的时间参数,直接赋值给相应的色灯
ucharf1;//用于串口中断处理,辨识设置的时间参数属于红灯还是绿灯
ucharf2=0;//标志位,表示有串行中断发生时,要将已设置好的时间参数显示出来,1有效
uintn;//用于设定要设置的时间参数在数码管上显示停留的时间长短
codeuchartab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管共阴
//codeuchartab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//数码管共阳
sbitd1=P2^0;//d1作为高位数码管的公共端
sbitd2=P2^1;//d2作为低位数码管
sbitred=P2^2;//红灯数据输出位设置
sbitgreen=P2^3;
sbityellow=P2^4;
//sbitr_ed=P0^5;
//sbitg_reen=P0^6;
//sbity_ellow=P0^7;
//ucharr_g_y;
uchara=60;//直接赋值给数码管的数据
uchardata_2[]={60,30};//数组的第一个数据是红灯的时长参数,第二个是绿灯的时长参数
ucharg;//作为数组的下标,如data_2[g]
uinti;//用于动态显示字符
uintj;//用于动态显示字符
/***********初始化函数**********************************************/
voidinit()
{
IP=0x10;//中断优先级设置(串口中断为最高优先级)
TMOD=0X21;//T1定时计数器工作于方式2,作为波特率发生器,SMOD此处默认取0
//T0定时计数器工作于方式1,用于定时
TH1=0Xe6;TL1=0Xe6;//8位自动重装
TR1=1;//启动T1定时计数器
SCON=0x50;//串行方式1,串行接收允许
TH0=(65536-50000)/256;//定时50ms
TL0=(65536-50000)%256;
EA=1;//开总中断
ET0=1;//开T0中断请求
ES=1;//允许串行口中断
TR0=1;//启动定时器T0工作
}
/***********延时函数**********************************************/
voiddelay(uintz)
{uinti;
for(i=0;i } /***********数码管动态显示**********************************************/ voiddisplay(ucharc) {uchara=c; i=a/10; j=a%10; //以下是动态显示, d1=0;d2=1;//若是共阳,位选d1,d2取值相反 P1=tab[i]; delay(30); P1=0; delay(30); d1=1;d2=0;//若是共阳,位选d1,d2取值相反 P1=tab[j]; delay(30); P1=0; delay(30); } /***********定时器0**********************************************/ voidtimer0()interrupt1 { TR0=0; TH0=(65536-50000)/256; TL0=(65536-50000)%256; TR0=1; t++; if(t==7) { a=a-1;t=0; } if(a<=5&&t%2==0) { yellow=~yellow; if(a==0) {w++; red=~red;green=~green;yellow=0; if(w%2==1)a=data_2[1]; elsea=data_2[0]; } } } /***********串行口发送与接收中断处理函数**********************************************/ voidt_r()interrupt4 { TR0=0;//暂停定时器工作,进入红绿灯时间设置状态 //写接收数据的程序 f2=1; n=1000;//设置改变后的时间参数在数码管上显示停留的时间,每次中断后,n必须重新赋值, //保证其在数码管上的显示数据停留一个固定的时间段显示处理程序写在主函数中 RI=0;//清接收中断请求标志 //r_ed=red; //g_reen=green; //y_ellow=yellow; //r_g_y=P1; k++;//奇数,偶数次的接收数据,存放于不同位置 if(k%2==0)//全局变量k初值为255,上一条指令自加后,为0;模除2,余0,为偶数, {//则本次中断的目的是辨识将要设置的时间参数属于红灯还是绿灯 f1=SBUF; if(f1==1)g=0;//辨识将要设置的时间参数属于红灯还是绿灯,此处为红灯 elseg=1;//此处为绿灯。 } else//模除2,余1,为奇数,则本次中断的目的是 {//把要设置的时间参数赋值给相应的色灯。 data_2[g]=SBUF;//接收数据,设置相应色灯的时间参数 //while(n--)//短暂延时,显示您所设置的时间参数,【在串行中断处理函数中不要停留太久,如100us】 //display(data_2[g]);//【防止中断处理中串行数据接收出错】 } TR0=1;//重新打开定时器 } /***********主函数**********************************************/ voidmain() { green=0; yellow=0; red=1; init(); while (1) { if(f2==1) { ET0=0;//作用如下一行 //TR0=0;//暂停定时器工作,(主函数中怎么将TR0清零无效,? ? ? ? ? ? ) /**switch(g)//switch语句用来处理发送给乙单片机的LED灯变化数据 { case0: {red=1;green=0;yellow=0;}break; case1: {red=0;green=1;yellow=0;}break; default: ; } **/ while(n--) display(data_2[g]);//短暂延时,显示您所设置的时间参数 //red=r_ed;green=g_reen;yellow=y_ellow; //P1=r_g_y;、//单步调试都可以,proteus仿真就不行? ? why f2=0; //TR0=1;//重新打开定时器 ET0=1; } display(a);//始终点亮数码管,并等待定时中断和串行口中断 } } 5.系统测试 程序初始化红灯最长显示时间60秒(图如上) 红灯最后5秒钟黄灯闪烁(如上图) 红灯60秒钟完后,绿灯显示30秒钟(如上图) 绿灯最后5秒钟时,黄灯闪烁(如上图) 任何时刻,皆可以设置红灯的时间参数(如上图) 分析: 本程序为了不至于红灯时间太短时,就直接导致黄灯5秒闪烁,而将红灯时间参数设置范围定位10到99秒钟,按键每按一次时间参数自动减一,数码管显示刚刚设置好的时间参数1至2秒钟,然后回到断点,继续显示之前的交通灯状态;等到下一次循环到来时,显示新的已设置好的时间参数。 绿灯最长时间设置范围10到50秒 实物图(如上) 红灯显示88秒绿灯显示38秒 分析: 数码管第一位的段g坏掉,段c亮度很弱;第二位的段c也坏掉,故数码显示有些问题。 6.总结与体会 本次课程设计难点在程序编写调试。 得到经验: 串行中断处理程序处理时间不得太长,防止数据接收出错;按键的程序编写要注意消抖延时,防止按键按一次产生太多外部中断,导致数码管显示的数值不是连续变化;当用到多种中断时,注意中断优先级的设置;只有串行中断需要软件清中断标志,定时器中断和外部中断都是硬件自动清中断请求标志。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 课程设计 双机 通信 交通灯