当前位置:文档之家› DSP交通灯综合控制

DSP交通灯综合控制

DSP原理及应用课程设计交通灯综合控制学院电气信息工程专业电子信息工程班级学号分组成员指导教师2013 年 6 月目录1引言 (1)2课程设计的目标 (2)2.1课程设计的背景 (2)2.2设计要求 (2)2.3设计思路简介 (2)2.4交通灯控制要求 (3)2.5交通灯模拟 (3)2.6计时 (4)2.7紧急情况 (4)2.8程序设计 (4)3DSP定时器的算法原理 (6)3.1CPU定时器的原理 (6)3.2CPU定时寄存器原理 (6)4系统程序设计 (7)4.1流程图 (7)4.2试验程序 (7)5心得体会 (18)1引言随着计算机和信息技术的飞速发展数字信号处理技术得到迅速的发展。

DSP (Digital Signal Processing)是一门涉及许多学科和领域的新兴学科。

数字信号处理是一种通过数字信号处理器来处理现实信号的方法这些信号由数字序列表示。

在过去的二十多年时间里数字信号处理已经在通信等领域得到极为广泛的应用。

本次设计是基于DSP来实现交通灯的控制利用发光二级管来模拟交通信号利用数码管显示倒计时时间利用TMS320VC5416DSP片上定时器定时产生时钟计数来模拟实际生活中十字路口交通灯。

关键词:DSPTMS320VC5416;交通灯;发光二极管2课程设计的目标2.1课程设计的背景DSP是一种将处理器的计算核心和一定的外部设备集成在一个单片芯片上而构成的类似于单片机的一种处理器芯片。

不同于一般单片机的是由于DSP 采用了特殊的总线结构和体系因此它在执行数字信号处理计算方面具有更高的性能。

数字信号处理已经在通信、信号处理等领域得到极为广泛的应用。

十字路口交通灯在我们的日常生活中随处可见它为繁忙的道路交通及人们的安全提供了较好的保障。

然而我们只知道交通灯在红、黄、绿三色之间交替更换来控制人车流量去对其内部的工作原理及软硬件的设计了解很少因此要通过此次简单道路交通灯控制系统软硬件设计来进一步研究交通灯的内部结构。

最重要的是将学习到的DSP系统的组成与原理应用到交通灯的设计当中。

通过《DSP技术及应用》课程设计,是学生能够将学到的DSP系统的组成与原理用到具体的实际系统中,加深对DSP系统的理解,是将该门课程与实际问题相连接的关键步骤。

通过课程设计,能够提高学生分析问题,解决问题,从而运用所学知识解决实际问题的能力,并培养基本的、良好的软硬件射进能力。

2.2设计要求利用C语言在CCS环境中编写一个交通灯综合控制程序,并能通过硬件仿真对所编写的程序及其应用性、可行性进行验证。

2.3设计思路简介在TMS320C54x系统开发环境CCS(Code Composer Studio)下对交通灯综合控制的实现原理进行讨论。

通过实验仿真,可以在硬件实验箱上看到对交通灯的模拟控制。

交通等综合控制的控制原理2.4交通灯控制要求利用ICETEK-S60 实验箱提供的设备,设计模拟实际生活中十字路口交通灯控制的程序。

要求如下:- 交通灯分红黄绿三色,东、南、西、北各一组,用灯光信号实现对交通的控制:绿灯信号表示通行,黄灯表示警告,红灯禁止通行,灯光闪烁表示信号即将改变。

- 计时显示:液晶屏幕上8×8 点阵显示0-9 计数。

- 正常交通控制信号顺序:正常交通灯信号自动变换:⑴南北方向绿灯,东西红灯(20 秒)。

⑵南北方向绿灯闪烁。

⑶南北方向黄灯。

⑷南北方向红灯,东西方向黄灯。

⑸东西方向绿灯(20 秒)。

⑹东西方向绿灯闪烁。

⑺东西方向黄灯。

⑻返回⑴循环控制。

- 紧急情况处理:模仿紧急情况(重要车队通过、急救车通过等)发生时,交通警察手动控制⑴当任意方向通行剩余时间多于10 秒,将时间改成10 秒。

⑵正常变换到四面红灯(20 秒)。

⑶直接返回正常信号顺序的下一个通行信号(跳过闪烁绿灯、黄灯状态)。

2.5交通灯模拟利用ICETEK-CTR 上的一组发光二极管(共12 只,分为东西南北四组、红黄绿三色)的亮灭实现交通信号的模拟。

发光二极管的控制方法可参见第二部分、第二章、二、2。

2.6计时使用TMS320VC5416DSP 片上定时器,定时产生时钟计数,再利用此计数对应具体时间。

定时器控制及中断编程可参考实验3.3 程序。

2.7紧急情况利用ICETEK-CTR 上键盘产生外中断,中断正常信号顺序,模拟突发情况。

外中断编程控制可参考实验3.4 程序。

2.8程序设计根据设计要求,由于控制是由不同的各种状态按顺序发生的,我们可以采用状态机制控制方法来解决此问题。

这种方法是:首先列举所有可能发生的状态;然后将这些状态编号,按顺序产生这些状态;状态延续的时间用程序控制。

对于突发情况,可采用在正常顺序的控制中插入特殊控制序列的方式完成。

时钟计数:采用250ms 一次中断进行累加计数。

表格 1其中,正常顺序每112 秒(计数值448)为一个循环,状态“*”为非顺序状态。

这样,只要根据计数值就可确定当前状态,根据状态再分情况处理。

对于计数显示,当处于状态1、5、*中时需要进行倒计时,需要计算在此状态中的计数值增量,根据增量判断是否更新计数显示。

3DSP定时器的算法原理3.1CPU定时器的原理本次设计主要用的是F2812器件上的3个32位CPU定时器(TIMER0/1/2)。

其中定时器1和定时器2预留给实时操作系统使用(如DSP-BIOS),只有定时器0用户可以在应用程序中使用。

定时器功能框图如下:3.2CPU定时寄存器原理定时器在工作过程中,首先把周期寄存器(PRDH:PRD)的值装入32位计数寄存器。

计数寄存器根据SYSCLKOUT时钟递减计数。

当计数寄存器等于0时,定时器中断输出产生一个中断脉冲。

(1)定时器计数寄存器(TIMERxTIM和TIMERxTIMH)(2)定时器控制寄存器(TIMERxTCR):使能中断,定时功能;(3)定时器周期寄存器(TIMERxPRD):符合条件则周期性重新装载并保存周期值(4)定时器预定标寄存器(TIMERxTPR和TIMERxTPRH):控制多久减1。

4系统程序设计4.1流程图图4-1实验程序流程图图4-2设计总流程图设计总流程图4.2试验程序#include "scancode.h"#define SPSA0 *(unsigned int *)0x38#define SPSD0 *(unsigned int *)0x39#define REGISTERCLKMD (*(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 nStatusNSYellowEWRed 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 statusNSYellowEWRed 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;// CTR扩展寄存器定义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; //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();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 uLightStatusEW,uLightStatusSN;unsigned int bHold;unsigned char ledbuf[8],ledx[8];unsigned char led[40]={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 ledkey[10][8]={{0x00,0x00,0x7C,0x82,0x82,0x82,0x7C,0x00}, //0{0x00,0x00,0x00,0x84,0xFE,0x80,0x00,0x00}, //1{0x00,0x00,0x84,0xC2,0xA2,0x92,0x8C,0x00}, //2{0x00,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},{0x00,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=uLightStatusSN=0;nNowStatus=0; nOldStatus=1; nOldTimeCount=0;InitDSP(); // 初始化DSP,设置运行速度InitICETEKCTR(); // 初始化显示/控制模块InitTimer(); // 设置定时器中断// 根据计时器计数切换状态// 根据状态设置计数和交通灯状态while ( 1 ){if ( bHold && nNowStatus==statusHold ){if ( nTimeCount>=nStatusHold ){nNowStatus=nSaveStatus;nTimeCount=nSaveTimeCount;bHold=0;}}else if ( nTimeCount<nStatusNSGreenEWRed ) nNowStatus=statusNSGreenEWRed;else if ( nTimeCount<nStatusNSFlashEWRed ) nNowStatus=statusNSFlashEWRed;else if ( nTimeCount<nStatusNSYellowEWRed ) nNowStatus=statusNSYellowEWRed;else if ( nTimeCount<nStatusNSRedEWYellow ) nNowStatus=statusNSRedEWYellow;else if ( nTimeCount<nStatusNSRedEWGreen ) nNowStatus=statusNSRedEWGreen;else if ( nTimeCount<nStatusNSRedEWFlash ) nNowStatus=statusNSRedEWFlash;else if ( nTimeCount<nStatusNSRedEWYellow1 ) nNowStatus=statusNSRedEWYellow;else if ( nTimeCount<nStatusNSYellowEWRed1 ) nNowStatus=statusNSYellowEWRed;if ( nNowStatus==nOldStatus ){switch ( nNowStatus ){case statusNSFlashEWRed:nWork1=nTimeCount-nStatusNSGreenEWRed;nWork2=nStatusNSYellowEWRed-nStatusNSFlashEWRed;nWork3=nWork2/3;nWork4=nWork3/2;if ( nWork1>=0 && nWork2>0 && nWork3>0 && nWork4>0 )uLightStatusSN=( (nWork1%nWork3)<=nWork4 )?(0x49):(0x40); //满足条件,取0x49地址的值,否则,取0x48的值break;case statusNSRedEWFlash:nWork1=nTimeCount-nStatusNSRedEWGreen;nWork2=nStatusNSRedEWYellow1-nStatusNSRedEWFlash;nWork3=nWork2/3;nWork4=nWork3/2;if ( nWork1>=0 && nWork2>0 && nWork3>0 && nWork4>0 )uLightStatusEW=( (nWork1%nWork3)<=nWork4 )?(0x09):(0x00);break;case statusNSGreenEWRed:nWork1=nStatusNSGreenEWRed/20;if ( nWork1>0 ){nWork2=20-nTimeCount/nWork1;if ( bHold ){if ( nWork2>10 ){nTimeCount=nWork1*10;nWork2=10;}}if ( nOldTimeCount!=nWork2 ){nOldTimeCount=nWork2;SetLEDArray(nWork2);}}break;case statusNSRedEWGreen:nWork1=(nStatusNSRedEWGreen-nStatusNSRedEWYellow)/20;if ( nWork1>0 ){nWork2=20-(nTimeCount-nStatusNSRedEWYellow)/nWork1;if ( bHold ){if ( nWork2>10 ){nTimeCount=nStatusNSRedEWYellow+nWork1*10;nWork2=10;}}if ( nOldTimeCount!=nWork2 ){nOldTimeCount=nWork2;SetLEDArray(nWork2);}}break;case statusHold:nWork1=nStatusHold/20;if ( nWork1>0 ){nWork2=20-nTimeCount/nWork1;if ( nOldTimeCount!=nWork2 ){nOldTimeCount=nWork2;SetLEDArray(nWork2);}}break;}}else{if ( bHold ){nSaveStatus=nNowStatus;nSaveTimeCount=nTimeCount;nNowStatus=statusHold;nTimeCount=0;if ( nSaveStatus==statusNSFlashEWRed || nSaveStatus==statusNSYellowEWRed ){nSaveStatus=statusNSRedEWGreen;nSaveTimeCount=nStatusNSRedEWYellow;}else if ( nSaveStatus==statusNSRedEWFlash || nSaveStatus==statusNSRedEWYellow ){nSaveStatus=statusNSGreenEWRed;nSaveTimeCount=0;}}nOldStatus=nNowStatus;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 statusNSRedEWYellow: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=0x64;SetLEDArray(20);break;}}CTRLR=uLightStatusEW; CTRLR=uLightStatusSN; // 设置交通灯RefreshLEDArray(); // 刷新发光二极管显示nScanCode=port8001; // 读键盘扫描码nScanCode&=0x0ff;tKey=CTRCLKEY;if ( nScanCode==SCANCODE_9 ) break;}EndICETEKCTR();exit(0);}// 定时器中断服务程序,进行时钟计数void interrupt time(void){nTimeCount++;nTimeCount%=nTotalTime;}// 设置发光二极管显示内容void SetLEDArray(int nNumber){int i,ShowNumber;ShowNumber=nNumber/2;if(ShowNumber>9) ShowNumber=0; CTRLCDCMDR=LCDCMDPAGE; // 设置操作页=0 Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);CTRLCDCMDR=LCDCMDVERADDRESS; // 起始列=0 Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);for ( i=0;i<8;i++ ){CTRLCDLCR=ledkey[ShowNumber][i];Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);}}// 将缓存中点阵送发光二极管显示void RefreshLEDArray(){int i;for ( i=0;i<8;i++ )CTRGR=ledx[i];CTRLA=ledbuf[i];}}// 初始化DSP,设置运行速度=8MHzvoid InitDSP(){REGISTERCLKMD=0; // 复位PLLREGISTERCLKMD=0x1007; // 速度设置=16MHz}// 设置定时器参数、允许中断void InitTimer(){unsigned int k;asm(" ssbx INTM"); // 关中断,进行关键设置时不许打扰// 设置通用定时器k=PMST; // 设置PMST寄存器PMST =k&0xff; // 中断向量表起始地址=80HIMR = 0x0c; // 使能TINTTCR = 0x41f; // 预分频系数为16TIM = 0; // 时钟计数器清0PRD = 0x0f423; // 周期寄存器为0ffHTCR = 0x42f; // 复位、启动IFR = 0x0c; // 清中断标志位port3004=0; // 使能XINT2asm(" rsbx I NTM"); // 开中断}// 初始化ICETEK-CTR板上设备void InitICETEKCTR(){int k;CTRGR=0; // 初始化ICETEK-CTRCTRGR=0x80;CTRGR=0;CTRLR=0; // 关闭东西方向的交通灯CTRLR=0x40; // 关闭南北方向的交通灯CTRLR=0x0c1; // 开启发光二极管显示阵列CTRLR=0xc8; //使能外部中断for ( k=0;k<8;k++ ){ledbuf[k]=0x0ff; // 显示为空白ledx[k]=(k<<4); // 生成显示列控制字k=CTRCLKEY; // 清除键盘缓冲区TurnOnLCD(); // 打开显示LCDCLS(); // 清除显示内存CTRLCDCMDR=LCDCMDSTARTLINE; // 设置显示起始行CTRLCDCR=0;}void interrupt xint2(void) // XINT2中断服务程序{bHold=1;}void EndICETEKCTR(){int k;CTRLR=0; // 关闭东西方向的交通灯CTRLR=0x40; // 关闭南北方向的交通灯CTRLR=0x0c0; // 关闭发光二极管显示阵列k=CTRCLKEY; // 清除键盘缓冲区}void TurnOnLCD(){CTRLCDCMDR=LCDCMDTURNON;Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);CTRLCDCMDR=LCDCMDSTARTLINE;Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);}void LCDCLS(){int i,j;CTRLCDCMDR=LCDCMDSTARTLINE;Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);for ( i=0;i<8;i++ ){CTRLCDCMDR=LCDCMDPAGE+i;Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);CTRLCDCMDR=LCDCMDVERADDRESS;Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);for ( j=0;j<64;j++ ){CTRLCDLCR=0;Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);}CTRLCDCMDR=LCDCMDPAGE+i;Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);CTRLCDCMDR=LCDCMDVERADDRESS;Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);for ( j=0;j<64;j++ ){CTRLCDRCR=0;Delay(LCDDELAY);CTRLCDCR=0;Delay(LCDDELAY);}}}void Delay(unsigned int nDelay){int ii,jj,kk=0;for ( ii=0;ii<nDelay;ii++ ){for ( jj=0;jj<1024;jj++ ){kk++;}}}5心得体会这次DSP课程设计前前后后一共用了一周左右的时间,期间也遇到了很多的困难,主要是对DSP的中断不够熟悉,以及对课上老师讲过的知识点的掌握还不够深刻,所幸通过查阅大量的资料,以及同老师同学的讨论,最终问题得以顺利解决,收获颇丰,有一种柳暗花明的感觉。

相关主题