单片机课程设计双机通信交通灯

时间:2022-06-24 10:20:10 浏览量:

  《单片机课程设计》 设 殳计报告 题目 双机通信 专业:

 电子信息工程 班级:

 班 学号:

 631

 姓名: 指导老师: 重庆交通大学信息科学与工程学院 设计时间:年 1 月 1 日到年 1 月 9 号

 2 / 14

 1 .设计任务说明 在课程实验(交通灯)的基础上,实现双机通信:

 1、 可以是 PC 机与单片机的通信,通过 PC 机上的软件(如串口调试助手等)

 控制单片机交通灯的设置(如改变不同路口红绿灯时间等参数的设置)

 ; 2、 也可通过一个单片机系统控制另一个单片机系统交通灯的设置(如改变不 同路口红绿灯时间等参数的设置)。

 3、 也可完成经指导老师批准的其它题目,如:

 (1)

 用单片机及 A/D 转换芯片实现的数字电压表 (2)

 用单片机及 D/A 转换芯片实现的波形发生器 2. 总体设计 本人选择做双机通信---交通灯,通过两个按键分别设置红灯、绿灯的时 间参数。当然,设置时间参数的是其中一块单片机, 控制数码管和红绿灯亮暗的 的变化又是另外一块单片机。

 3. 详细设计 总设计图如下:

 R1 22] "£・ .届 ESP 兀冏 LD-IED . D1

 「/ Mru i rULlHiUU ML1AD1 PD2MD2 金 L2 PD 耶 旳 bDJAbi

 PQ®WP6 RST PDJ^iCT

 P2.1JCR9

 pai^in P&EN 卩刊川 A IE P2.^%12 EA P2SM.13 陋加*

 P2JA15 PH P3H/RX& P3.1/D<CiP1^ P3Z/1N1E PL? Pt* F33/fRrTT Pd.RD P15 叮屯 L P1J6 P3OHR Pk? PS . T / R N -

  CUM ; 昨丘』》临 5 IL£D-g D2 a? 3L- £ -Z2. _2J_ n

 LI Zl 12 21 35 口 25 _3L . . . 26_ _2L . . . 3— LD 111 12 13 li _|i —LL f 讎」绿灯时间•…控制红灯时间 J2_ 13 .ii_ .JS_ ,d pomo 口 XTAL1 * ■L1AD1

  XTA12 PD.i^bi

 PE.S^05

 PDTMT IRSrT

  卩 211 陶

 p 士訓 jn

 P2.3W^11 FSEW P2.UW.12 ALE P2£^ll3 Eft 帆础*

  P2TJIK15

 p^nmxD pin P3/I/TVD P1.1 P^lSINTTn P1^

  柑测 TT F1J P3.4/TIi F1.4 旧旳_ F15 旧 JEW 尺 P1£

 Pl.T

 LED-VfeLLQWL 18 FG IDF 1

  2

 J

  *

 5

  6

  T

  丄. B ID r- i£i J :« * in

  31 ABCDE

 3 / 14

  LED-RED D1 R2 220 I Et> GREEN I IH LrIX YELLOW CLOCK=12.0MHz 30C51< 乙机)

 4.程序及说明 流程图:

 开始 乙单片机循环运行红绿灯, 分别对应 60 秒, 30 秒 等待中断

 4 / 14

 中断处理: 进入中断 甲机按键按下,对应的红绿灯时间自动减一 甲机将数据通过串行端口传送给乙单片机 乙单片机短暂地显示刚设置好的红绿灯时间参数 乙单片机进入下一次循环显示的时候,重新取新的时间参数

  甲单片机程序代码如下:

 #in elude <reg51.h> #defi ne uchar un sig ned char #defi ne uint un sig ned int uchar x=100;〃 红灯最长时间设置为 99 秒 uchar y=51; //绿灯最长时间设置为 50 秒 uchar t; /*********** 串行 口发送与接收中断处理函数 **********************************************/ void ini t() { IP=0x02; // 中断优先级设置(T0 中断为最高优先级 , 然后是 INT0,最 后是 INT1) TMOD=0X21; //T1 定时计数器工作于方式 2,作为波特率发生器,SMOD 此处默认取 0 //T0 工作方式 1,16 位计数 TH 仁 0Xe6;TL1=0Xe6; //8 位自动重装 , 波特率设置为 1200 TR1=1; // 启动 T1 定时计数器 SCON=0x40; //串行方式 1,串行接收禁止

 5 / 14

 EX0=1; // 打开外部中断 0 EX1=1; // 打开外部中断 1 IT0=1; //INT0 ,外部中断 0 ,下降沿触发 IT1=1; //INT1 ,外部中断 1 ,下降沿触发 EA=1; // 开总中断 }

 void timer1() interrupt 1 {

 // TMOD=0x01; TR0=0; TH0=(65536-10000)/256; // 对于 12MHz 的晶振,此处定时 50ms 赋值 0X3cb0 TL0=(65536-10000)%256; // 若定时 10ms,赋值 0XD8F05m§ 赋值 0Xec78 TR0=1; //启动定时器 T0 工作 t--; }

 /*********** 外 部 中 断 0 函 数 **********************************************/ void int0() interrupt 0 // 对应红灯时间参数设置 {

 TH0=(65536-10000)/256; // 对于 12MHz 的晶振,此处定时 50ms 赋值 0X3cb0 TL0=(65536-10000)%256; // 若定时 10ms,赋值 0XD8F05m§ 赋值 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;

  定 时 器 0 函数 // 工作方式 1,16 位计数 外 部 中 断 1 函数 }

 6 / 14

 **********************************************/ void int1() interrupt 2 // 对应绿灯时间参数设置 {

 TH0=(65536-10000)/256; // 对于 12MHz 的晶振,此处定时 50ms 赋值 0X3cb0 TL0=(65536-10000)%256; // 若定时 10ms,赋值 0XD8F05m§ 赋值 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 <reg51.h> #define uchar unsigned char #define uint unsigned int uchar t=0; // 用于 timer0 函数, 设置数码管显示的数字跳变的时间间 隔 uchar w=0; // 切换红绿灯标志位 uchar k=255; // 用于串口中断处理,甲机的按键按一次,则向乙机发送 两个单字节数据 // 前一个数据用于辨识将要设置的时间参数属于红灯还是绿灯 // 后一个数据是想要设置的时间参数,直接赋值给相应的色灯 uchar f1; // 用于串口中断处理,辨识设置的时间参数属于红灯还是 绿灯

 函数

 7 / 14

 uchar f2=0; // 标志位,表示有串行中断发生时,要将已设置好的时间 参数显示出来, 1 有效 uint n; // 用于设定要设置的时间参数在数码管上显示停留的时间 长短 code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 阴 //code tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};// 阳 作为高位数码管的公共端 作为低位数码管 红灯数据输出位设置 sbit green=P2A3; sbit yellow=P2A4; //sbit r_ed=P0A5; //sbit g_reen=P0A6; //sbit y_ellow=P0A7; //uchar r_g_y;

  void init() {

 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; I // 启动定时器 TO 工作

 }

 /********** 延 时 函 数 二个是绿灯的时长参数 uchar g; // 作为数组的下标,如 data_2[g]

  uint i; // 用于动态显示字符

  uint j; // 用于动态显示字符

  /*********** 初始化 函 数 uchar a=60; // 直接赋值给数码管的数据 uchar data_2[]={60,30}; // 数组的第一个数据是红灯的时长参数, 第 uchar 数码管共 uchar 数码管共 sbit d 仁 P2P; 〃d1 sbit d2=P2 A 1; 〃d2 sbit red=P2A2; //

 8/ 14

 ********************************************" void delay(uint z) { uint i; for(i=0;i<z;i++); void display(uchar c) { uchar a=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; P1=tab[j]; delay(30); P1=0; delay(30); }

 *********** */ void timer0() interrupt 1 {

 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];

 数码 管动态 // 若是共阳,位选 d1,d2 取值相反 定时 }

 9/ 14

 else a=data_2[0]; }

 /*********** 串 行 口 发 送 与 接 收 中 断 处 理 函 数 **********************************************/ void t_r() interrupt 4 {

 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; // 辨识将要设置的时间参数属于红灯还是绿灯, 此 处为红灯 else g=1; // 此处为绿灯。

 }

 else // 模除 2 ,余 1,为奇数,则本次中断的目的是 { // 把要设置的时间参数赋值给相应的色灯。

 data_2[g]=SBUF; // 接收数据,设置相应色灯的时间参数 // while(n--) // 短暂延时, 显示您所设置的时间参数 , 【在串行中断处理函数中不要停留太久,如 100us】

 // display(data_2[g]);// 【防止中断处理中串行数据接收出 错】

 }

 TR0=1; // 重新打开定时器 主函

 void main() {}

 10 / 14

 green=0; yellow=0; red=1; init(); while(1) { if(f2==1) {

 ET0=0; // 作用如下一行 // TR0=0; // 暂停定时器工作 ,( 主函数中怎么将 TR0 清零无 效,??????) /** switch(g) //switch 语句用来处理发送给乙单片机的 LED 灯变化数据 {

 case 0:{red=1;green=0;yellow=0;}break; case 1:{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.系统测试

 11 / 14

  程序初始化红灯最长显示时间 EI-HECi . . "4 t>1 rto< :[U - ■■…苔二由- lHl a ^9RBH d :

 . i. ■ ■• •■ • " * nj n

 •■ 1

 " ■ ■ * ■ ■ ■* Ii.| — ^l-WI Bill y ! cLpc ^iz»Hi 科=氨; i .. ri ■ 卩 pgm p匚祁 PC-SfA»S F&V A M

 PQ7UI I 7 pmjAS PS/ 昭 PZ2TA1D Pl 小 F 孟祁阿 FZJ*AO r»Ai 4 P^T^JLtC P^JQ"PCI FZinxi 60 秒(图如上)

 红灯最后 5 秒钟黄灯闪烁(如上图)

 .LEDABD :<TAL3 ■& ^|.|..|.|||.|.|.. ^.| - FZ-Wlfff LE&-C.ELUW^. 产訓 Q 耳即 I j ABCDEFG DF 12 :<TAL1 J— .LED^HE^M ©… PQnADiC 卩 04* 人站 PD3A&7 FDaAfrl PDL^AD* P6S 瞋 祐 RDKAGMi pni^A&v P2ITA3 F2.IW P23A1C P3 3TAH1 F2.4 ! A13 陀來口 R.srr 红灯 60 秒钟完后,绿灯显示 30 秒钟(如上图)

 12 / 14

 绿灯最后 5 秒钟时,黄灯闪烁(如上图)

 任何时刻,皆可以设置红灯的时间参数(如上图)

 分析:本程序为了不至于红灯时间太短时, 就直接导致黄灯 5 秒闪烁,而 将红灯时间参数设置范围定位 10 到 99 秒钟,按键每按一次时间参数自动减一, 数码管显示刚刚设置好的时间参数 1 至 2 秒钟,然后回到断点,继续显示之前的 交通灯状态;等到下一次循环到来时,显示新的已设置好的时间参数。FD^AbCl H.1MD1 FD^ADZ ruj - L"j RD.Mpi FDS"ADf HAADC F3.7/AD7 XTA11 ■: — 口 pWQ.fr,1^(1 . . SKSH^fl). l.UAB 23*11 2 耳/ P.^T P8EM AlE Tft s !

 R1 * j

 *

 ---- 1 l-=- ■ IR2 鼻口 IWADD XTALU 1 PQiWVI

 PO^ABZ

 ・口主畑 yrAQ 怛出什

 FnarAOif

 FDj&fAD6

 PD.7*AB7 ■UtfT fZDTAE

 甩网帼

 FZJWA11 P3EN FZ.WAII ALE

 玄 F7FWA-IA.

  . ・ LEb-«.€b ・ , "■ DT L1 ‘・尺吗• I .■ IliD-YELbaW.-... PK-C.K-.12JMH3 . aKSIt^J. -■ ,,LED-QP.EEH D2 空 ■31

 13 / 14

  实物图(如上)帕 5 阳 ■口,呗 1 P □环 DE 旳驷旧 ELI 」■ )CTAL3 PDSKDS •口 .mfr? WT nsikm F2.W/L1Z ■ -?CA M P&EH ALE 绿灯最长时间设置范围 10 到 50 秒 ..... &IJDGK P JZIILIH I .

 . ■S

 14 / 14

 红灯显示 88 秒 绿灯显示 38 秒 分析:数码管第一位的段 g 坏掉,段 c 亮度很弱;第二位的段 c 也坏掉, 故数码显示有些问题。

 6.总结与体会 本次课程设计难点在程序编写调试。得到经验:串行中断处理程序处理 时间不得太长,防止数据接收出错;按键的程序编写要注意消抖延时,防止按键 按一次产生太多外部中断,导致数码管显示的数值不是连续变化; 当用到多种中 断时,注意中断优先级的设置;只有串行中断需要软件清中断标志, 定时器中断 和外部中断都是硬件自动清中断请求标志。

相关热词搜索: 双机 交通灯 单片机