1、交通灯控制实验一、实验目的1. 熟悉 2812 的指令系统。2. 熟悉 74HC573 的使用方法。3. 熟悉 DSP 的 IO 操作使用方法。二、实验设备1. 一台装有 CCS3.3 软件的计算机;2. 插上 2812 主控板的 DSP 实验箱;3. DSP 硬件仿真器。三、实验原理交通灯的显示有很多方式,如十字路口、丁字路口等,而对于同一个路口又有很多不同的显示要求,比如十字路口,车辆如果只要东西和南北方向通行就很简单,而如果车子可以左右转弯的通行就比较复杂,本实验仅针对最简单的南北和东西直行的情况。要完成本实验,首先必须了解交通路灯的燃灭规律。本实验需要用到实验箱上交通灯模块中的发光二极
2、管,即红、黄、绿各三个。依人们的交通常规, “红灯停,绿灯行,黄灯提醒” 。其交通灯的燃灭规律为:初始态是两个路口的红灯全亮,之后,东西路口的绿灯亮,南北路口的红灯亮,东西方向通车,延时一段时间后,东西路口绿灯灭,黄灯开始闪烁。闪烁若干次后,东西路口红灯亮,而同时南北路口的绿灯亮,南北方向开始通车,延时一段时间后,南北路口的绿灯灭,黄灯开始闪烁。闪烁若干次后,再切换到东西路口方向,重复上述过程。本实验要完成任务就是设计一个简单的交通灯控制器,交通灯显示用实验箱的交通灯模块显示。此模块由发光二极管和一个锁存器组成。数据由 2812 模块的低八位输入,锁存器的控制信号由 2812 模块输出,但经由
3、 74LS00译码后再控制锁存器。交通灯原理图四、程序设计思路根据设计要求,由于控制是由不同的各种状态按顺序发生的,我们可以采用状态机制控制方法来解决此问题。这种方法是:首先列举所有可能发生的状态;然后将这些状态编号,按顺序产生这些状态;状态延续的时间用程序控制。对于突发情况,可采用在正常顺序的控制中插入特殊控制序列的方式完成。时钟计数:采用 250ms 一次中断进行累加计数。表格 1状态编号信号灯状态 状态定义保持时间(计数值,起始时间,结束时间)计数显示1南北绿灯,东西红灯statusNSGreenEWRed20 秒(160,0,159)20-02南北绿灯闪烁,东西红灯statusNSFl
4、ashEWRed6 秒(24, 160,183)03南北黄灯,东西红灯statusNSYellowEWRed4 秒(16, 184,199)204南北红灯,东西黄灯statusNSRedEWYellow4 秒(16, 200,215)205南北红灯,东西绿灯statusNSRedEWGreen20 秒(160,216,375)20-16南北红灯,东西绿灯闪烁statusNSRedEWFlash6 秒(24, 376,399)07南北红灯,东西黄灯statusNSRedEWYellow4 秒(16, 400,415)208南北黄灯,东西红灯statusNSYellowEWRed4 秒(16, 4
5、16,431)20*南北红灯,东西红灯StatusHold20 秒(160,0,159)20-1其中,正常顺序每 112 秒(计数值 448)为一个循环,状态 “*”为非顺序状态。这样,只要根据计数值就可确定当前状态,根据状态再分情况处理。对于计数显示,当处于状态 1、5、*中时需要进行倒计时,需要计算在此状态中的计数值增量,根据增量判断是否更新计数显示。五、试验程序#include “scancode.h“#define SPSA0 *(unsigned int *)0x38#define SPSD0 *(unsigned int *)0x39#define REGISTERCLKMD (*
6、(unsigned int *)0x58)#define TIM *(int *)0x24#define PRD *(int *)0x25#define TCR *(int *)0x26#define IMR *(int *)0x0 /IM R 中断屏蔽寄存器#define IFR *(int *)0x1 /IFR 中断标志寄存器#define PMST *(int *)0x1d /PMST 处理器模式状态寄存器(地址 1dh)#define nStatusNSGreenEWRed 160 /状态 1 计数结束时间#define nStatusNSFlashEWRed 184#define n
7、StatusNSYellowEWRed 200#define nStatusNSRedEWYellow 216#define nStatusNSRedEWGreen 376#define nStatusNSRedEWFlash 400#define nStatusNSRedEWYellow1 416#define nStatusNSYellowEWRed1 432#define nTotalTime 448#define nStatusHold 160#define statusNSGreenEWRed 0#define statusNSFlashEWRed 1#define statusNS
8、YellowEWRed 2#define statusNSRedEWYellow 3#define statusNSRedEWGreen 4#define statusNSRedEWFlash 5#define statusHold 6#define LCDDELAY 1#define LCDCMDTURNON 0x3f#define LCDCMDTURNOFF 0x3e#define LCDCMDSTARTLINE 0xc0#define LCDCMDPAGE 0xb8#define LCDCMDVERADDRESS 0x40ioport unsigned int port3004;/ CT
9、R 扩展寄存器定义ioport unsigned int port8000; ioport unsigned int port8001; /8001:读键盘扫描值,写液晶控制寄存器地址ioport unsigned int port8002; /8002:液晶控制寄存器地址ioport unsigned int port8003; /8003,8004:液晶显示数据寄存器地址ioport unsigned int port8004; /ioport unsigned int port8005; /8005:发光二极管显示阵列控制寄存器地址ioport unsigned int port8007
10、; /8007:发光二极管显示阵列控制寄存器地址#define CTRGR port8000#define CTRLCDCMDR port8001#define CTRKEY port8001#define CTRCLKEY port8002#define CTRLCDCR port8002#define CTRLCDLCR port8003#define CTRLCDRCR port8004#define CTRLA port8005#define CTRLR port8007void InitDSP(); /void 表示此函数为空类型,执行此函数后不产生函数值void InitTimer
11、();void InitICETEKCTR();void interrupt time(void);void interrupt xint2(void); / XINT2 中断服务程序void SetLEDArray(int nNumber); / 修改显示内容void RefreshLEDArray(); / 刷新显示void EndICETEKCTR();void TurnOnLCD();void LCDCLS();void Delay(unsigned int nDelay);unsigned int uWork,nTimeCount;unsigned int uLightStatusE
12、W,uLightStatusSN;unsigned int bHold;unsigned char ledbuf8,ledx8;unsigned char led40=0x7E,0x81,0x81,0x7E,0x00,0x02,0xFF,0x00,0xE2,0x91,0x91,0x8E,0x42,0x89,0x89,0x76,0x38,0x24,0x22,0xFF,0x4F,0x89,0x89,0x71,0x7E,0x89,0x89,0x72,0x01,0xF1,0x09,0x07,0x76,0x89,0x89,0x76,0x4E,0x91,0x91,0x7E;unsigned char le
13、dkey108=0x00,0x00,0x7C,0x82,0x82,0x82,0x7C,0x00, /00x00,0x00,0x00,0x84,0xFE,0x80,0x00,0x00, /10x00,0x00,0x84,0xC2,0xA2,0x92,0x8C,0x00, /20x00,0x00,0x44,0x92,0x92,0x92,0x6C,0x00,0x00,0x00,0x30,0x28,0x24,0xFE,0x20,0x00,0x00,0x00,0x4E,0x92,0x92,0x92,0x62,0x00,0x00,0x00,0x7C,0x92,0x92,0x92,0x64,0x00,0x0
14、0,0x00,0x02,0xC2,0x32,0x0A,0x06,0x00,0x00,0x00,0x6C,0x92,0x92,0x92,0x6C,0x00,0x00,0x00,0x4C,0x92,0x92,0x92,0x7C,0x00;main()int nWork1,nWork2,nWork3,nWork4,tKey;int nNowStatus,nOldStatus,nOldTimeCount,nSaveTimeCount,nSaveStatus;unsigned int nScanCode;nTimeCount=0; bHold=0;uLightStatusEW=uLightStatusS
15、N=0;nNowStatus=0; nOldStatus=1; nOldTimeCount=0;InitDSP(); / 初始化 DSP,设置运行速度InitICETEKCTR(); / 初始化显示/控制模块InitTimer(); / 设置定时器中断/ 根据计时器计数切换状态/ 根据状态设置计数和交通灯状态while ( 1 )if ( bHold nTimeCount=nSaveTimeCount;bHold=0;else if ( nTimeCount=0 if ( bHold )if ( nWork210 )nTimeCount=nWork1*10;nWork2=10;if ( nOl
16、dTimeCount!=nWork2 )nOldTimeCount=nWork2;SetLEDArray(nWork2);break;case statusNSRedEWGreen:nWork1=(nStatusNSRedEWGreen-nStatusNSRedEWYellow)/20;if ( nWork10 )nWork2=20-(nTimeCount-nStatusNSRedEWYellow)/nWork1;if ( bHold )if ( nWork210 )nTimeCount=nStatusNSRedEWYellow+nWork1*10;nWork2=10;if ( nOldTim
17、eCount!=nWork2 )nOldTimeCount=nWork2;SetLEDArray(nWork2);break;case statusHold:nWork1=nStatusHold/20;if ( nWork10 )nWork2=20-nTimeCount/nWork1;if ( nOldTimeCount!=nWork2 )nOldTimeCount=nWork2;SetLEDArray(nWork2);break;elseif ( bHold )nSaveStatus=nNowStatus;nSaveTimeCount=nTimeCount;nNowStatus=status
18、Hold;nTimeCount=0;if ( nSaveStatus=statusNSFlashEWRed | nSaveStatus=statusNSYellowEWRed )nSaveStatus=statusNSRedEWGreen;nSaveTimeCount=nStatusNSRedEWYellow;else if ( nSaveStatus=statusNSRedEWFlash | nSaveStatus=statusNSRedEWYellow )nSaveStatus=statusNSGreenEWRed;nSaveTimeCount=0;nOldStatus=nNowStatu
19、s;switch ( nNowStatus )case statusNSGreenEWRed:uLightStatusEW=0x24; uLightStatusSN=0x49;SetLEDArray(20);break;case statusNSFlashEWRed:uLightStatusEW=0x24; uLightStatusSN=0x49;SetLEDArray(0);break;case statusNSYellowEWRed:uLightStatusEW=0x24; uLightStatusSN=0x52;SetLEDArray(20);break;case statusNSRed
20、EWYellow:uLightStatusEW=0x12; uLightStatusSN=0x64;SetLEDArray(20);break;case statusNSRedEWGreen:uLightStatusEW=0x09; uLightStatusSN=0x64;SetLEDArray(20);break;case statusNSRedEWFlash:uLightStatusEW=0x09; uLightStatusSN=0x64;SetLEDArray(0);break;case statusHold:uLightStatusEW=0x24; uLightStatusSN=0x6
21、4;SetLEDArray(20);break;CTRLR=uLightStatusEW; CTRLR=uLightStatusSN; / 设置交通灯状态RefreshLEDArray(); / 刷新发光二极管显示nScanCode=port8001; / 读键盘扫描码nScanCodetKey=CTRCLKEY;if ( nScanCode=SCANCODE_9 ) break;EndICETEKCTR();exit(0);/ 定时器中断服务程序,进行时钟计数void interrupt time(void)nTimeCount+;nTimeCount%=nTotalTime;/ 设置发光二
22、极管显示内容void SetLEDArray(int nNumber)int i,ShowNumber;ShowNumber=nNumber/2;if(ShowNumber9) ShowNumber=0;CTRLCDCMDR=LCDCMDPAGE; / 设置操作页 =0Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);CTRLCDCMDR=LCDCMDVERADDRESS; / 起始列 =0Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);for ( i=0;i8;i+ )CTRLCDLCR=ledkeyShowNumberi;