1、 DSP原理及应用 课程设计 交通灯综合控制 学院 电气信息工程 专业 电子信息工程 班级 学号 分组成员 指导教师 2013 年 6 月 目 录 1 引言 3 2 课程设计的目标 4 2.1 课程设计的背景 4 2.2 设计要求 4 2.3 设计思路简介 4 2.4 交通灯控制要求 5 2.5 交通灯模拟 5 2.6 计时 6 2.7 紧急情况 6 2.8 程序设计 6 3 DSP定时器的算法原理 8 3.1 CPU定时器的原理 8 3.2 CPU定时寄存器原理 8 4 系统程序设计
2、9 4.1 流程图 9 4.2 试验程序 10 5 心得体会 21 1 引言 随着计算机和信息技术的飞速发展数字信号处理技术得到迅速的发展。DSP (Digital Signal Processing)是一门涉及许多学科和领域的新兴学科。数字信号处理是一种通过数字信号处理器来处理现实信号的方法这些信号由数字序列表示。在过去的二十多年时间里数字信号处理已经在通信等领域得到极为广泛的应用。本次设计是基于DSP来实现交通灯的控制利用发光二级管来模拟交通信号利用数码管显示倒计时时间利用TMS320VC5416DSP片上定时器定时产生时钟计数来模拟实际生活中十字路
3、口交通灯。 关键词:DSPTMS320VC5416;交通灯;发光二极管 2 课程设计的目标 2.1 课程设计的背景 DSP是一种将处理器的计算核心和一定的外部设备集成在一个单片芯片上而构成的类似于单片机的一种处理器芯片。不同于一般单片机的是由于DSP 采用了特殊的总线结构和体系因此它在执行数字信号处理计算方面具有更高的性能。数字信号处理已经在通信、信号处理等领域得到极为广泛的应用。十字路口交通灯在我们的日常生活中随处可见它为繁忙的道路交通及人们的安全提供了较好的保障。然而我们只知道交通灯在红、黄、绿三色之间交替更换来控制人车流量去对其内部的工作原理及软硬件的设计了解很少
4、因此要通过此次简单道路交通灯控制系统软硬件设计来进一步研究交通灯的内部结构。最重要的是将学习到的DSP系统的组成与原理应用到交通灯的设计当中。 通过《DSP技术及应用》课程设计,是学生能够将学到的DSP系统的组成与原理用到具体的实际系统中,加深对DSP系统的理解,是将该门课程与实际问题相连接的关键步骤。通过课程设计,能够提高学生分析问题,解决问题,从而运用所学知识解决实际问题的能力,并培养基本的、良好的软硬件射进能力。 2.2 设计要求 利用C语言在CCS环境中编写一个交通灯综合控制程序,并能通过硬件仿真对所编写的程序及其应用性、可行性进行验证。 2.3 设计思路简介 在TMS32
5、0C54x系统开发环境CCS(Code Composer Studio)下对交通灯综合控制的实现原理进行讨论。通过实验仿真,可以在硬件实验箱上看到对交通灯的模拟控制。 交通等综合控制的控制原理 2.4 交通灯控制要求 利用ICETEK-S60 实验箱提供的设备,设计模拟实际生活中十字路口交通灯控制的程序。要 求如下: - 交通灯分红黄绿三色,东、南、西、北各一组,用灯光信号实现对交通的控制:绿灯信号 表示通行,黄灯表示警告,红灯禁止通行,灯光闪烁表示信号即将改变。 - 计时显示:液晶屏幕上8×8 点阵显示0-9 计数。 - 正常交通控制信号顺序:正常交通灯信号自动变换: ⑴
6、南北方向绿灯,东西红灯(20 秒)。 ⑵ 南北方向绿灯闪烁。 ⑶ 南北方向黄灯。 ⑷ 南北方向红灯,东西方向黄灯。 ⑸ 东西方向绿灯(20 秒)。 ⑹ 东西方向绿灯闪烁。 ⑺ 东西方向黄灯。 ⑻ 返回⑴循环控制。 - 紧急情况处理:模仿紧急情况(重要车队通过、急救车通过等)发生时,交通警察手动控制 ⑴ 当任意方向通行剩余时间多于10 秒,将时间改成10 秒。 ⑵ 正常变换到四面红灯(20 秒)。 ⑶ 直接返回正常信号顺序的下一个通行信号(跳过闪烁绿灯、黄灯状态)。 2.5 交通灯模拟 利用ICETEK-CTR 上的一组发光二极管(共12 只,分为东西南北四组、红黄绿三
7、色)的亮 灭实现交通信号的模拟。 发光二极管的控制方法可参见第二部分、第二章、二、2。 2.6 计时 使用TMS320VC5416DSP 片上定时器,定时产生时钟计数,再利用此计数对应具体时间。 定时器控制及中断编程可参考实验3.3 程序。 2.7 紧急情况 利用ICETEK-CTR 上键盘产生外中断,中断正常信号顺序,模拟突发情况。 外中断编程控制可参考实验3.4 程序。 2.8 程序设计 根据设计要求,由于控制是由不同的各种状态按顺序发生的,我们可以采用状态机制控制 方法来解决此问题。这种方法是:首先列举所有可能发生的状态;然后将这些状态编号,按顺 序产生这些状态;
8、状态延续的时间用程序控制。对于突发情况,可采用在正常顺序的控制中插 入特殊控制序列的方式完成。 时钟计数:采用250ms 一次中断进行累加计数。 表格 1 状态编号 信号灯状态 状态定义 保持时间(计数值,起始时间,结束时间) 计数显示 1 南北绿灯,东西红灯 statusNSGreenEWRed 20秒(160,0,159) 20-0 2 南北绿灯闪烁,东西红灯 statusNSFlashEWRed 6秒(24,160,183) 0 3 南北黄灯,东西红灯 statusNSYellowEWRed 4秒(16,184,199) 20 4 南北红
9、灯,东西黄灯 statusNSRedEWYellow 4秒(16,200,215) 20 5 南北红灯,东西绿灯 statusNSRedEWGreen 20秒(160,216,375) 20-1 6 南北红灯,东西绿灯闪烁 statusNSRedEWFlash 6秒(24,376,399) 0 7 南北红灯,东西黄灯 statusNSRedEWYellow 4秒(16,400,415) 20 8 南北黄灯,东西红灯 statusNSYellowEWRed 4秒(16,416,431) 20 * 南北红灯,东西红灯 StatusHold 20
10、秒(160,0,159) 20-1 其中,正常顺序每112 秒(计数值448)为一个循环,状态“*”为非顺序状态。 这样,只要根据计数值就可确定当前状态,根据状态再分情况处理。 对于计数显示,当处于状态1、5、*中时需要进行倒计时,需要计算在此状态中的计数值 增量,根据增量判断是否更新计数显示。 3 DSP定时器的算法原理 3.1 CPU定时器的原理 本次设计主要用的是F2812器件上的3个32位CPU定时器(TIMER0/1/2)。其中定时器1和定时器2预留给实时操作系统使用(如 DSP-BIOS),只有定时器0用户可以在应用程序中使用。定时器功能框图如下: 3.
11、2 CPU定时寄存器原理 定时器在工作过程中,首先把周期寄存器(PRDH:PRD)的值装入32位计数寄存器。计数寄存器根据SYSCLKOUT时钟递减计数。当计数寄存器等于0时,定时器中断输出产生一个中断脉冲。 (1)定时器计数寄存器(TIMERxTIM和TIMERxTIMH) (2)定时器控制寄存器(TIMERxTCR):使能中断,定时功能; (3)定时器周期寄存器(TIMERxPRD):符合条件则周期性重新装载并保存周期值 (4)定时器预定标寄存器(TIMERxTPR和TIMERxTPRH):控制多久减1。 4 系统程序设计 4.1 流程图 图 41
12、实验程序流程图 图 42设计总流程图 设计总流程图 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
13、 //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 nS
14、tatusNSRedEWFlash 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 #defin
15、e statusNSRedEWFlash 5 #define statusHold 6 #define LCDDELAY 1 #define LCDCMDTURNON 0x3f #define LCDCMDTURNOFF 0x3e #define LCDCMDSTARTLINE 0xc0 #define LCDCMDPAGE 0xb8 #define LCDCMDVERADDRESS 0x40 ioport unsigned int port3004; // CTR扩展寄存器定义 ioport unsigned int port8000; ioport unsign
16、ed 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:发光二极管显示阵列控制寄存器地址 #def
17、ine 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 port8007 void InitDSP(); //void表示此函数为空类型,
18、执行此函数后不产生函数值 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); uns
19、igned 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
20、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},
21、{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,nWork
22、2,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(); // 初始化显示/控制模块 InitTime
23、r(); // 设置定时器中断
// 根据计时器计数切换状态
// 根据状态设置计数和交通灯状态
while ( 1 )
{
if ( bHold && nNowStatus==statusHold )
{
if ( nTimeCount>=nStatusHold )
{
nNowStatus=nSaveStatus;
nTimeCount=nSaveTimeCount;
bHold=0;
}
}
else if ( nTimeCount 24、Status=statusNSGreenEWRed;
else if ( nTimeCount 25、Green ) nNowStatus=statusNSRedEWGreen;
else if ( nTimeCount 26、Status )
{
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 )
uLightStatus 27、SN=( (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 && 28、 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 )
{
29、 nTimeCount=nWork1*10;
nWork2=10;
}
}
if ( nOldTimeCount!=nWork2 )
{
nOldTimeCount=nWork2;
SetLEDArray(nWork2);
}
}
break;
case statusNSRedEWGreen:
nWork1=(nStatusNSRedEWGreen-nStatusNSRedEWYellow)/20;
i 30、f ( nWork1>0 )
{
nWork2=20-(nTimeCount-nStatusNSRedEWYellow)/nWork1;
if ( bHold )
{
if ( nWork2>10 )
{
nTimeCount=nStatusNSRedEWYellow+nWork1*10;
nWork2=10;
}
}
if ( nOldTimeCount!=nWork2 )
{
nOldTimeCo 31、unt=nWork2;
SetLEDArray(nWork2);
}
}
break;
case statusHold:
nWork1=nStatusHold/20;
if ( nWork1>0 )
{
nWork2=20-nTimeCount/nWork1;
if ( nOldTimeCount!=nWork2 )
{
nOldTimeCount=nWork2;
SetLEDArray(nWork2);
} 32、
}
break;
}
}
else
{
if ( bHold )
{
nSaveStatus=nNowStatus;
nSaveTimeCount=nTimeCount;
nNowStatus=statusHold;
nTimeCount=0;
if ( nSaveStatus==statusNSFlashEWRed || nSaveStatus==statusNSYellowEWRed )
{
nSaveStatus=statusNSRedEWGreen 33、
nSaveTimeCount=nStatusNSRedEWYellow;
}
else if ( nSaveStatus==statusNSRedEWFlash || nSaveStatus==statusNSRedEWYellow )
{
nSaveStatus=statusNSGreenEWRed;
nSaveTimeCount=0;
}
}
nOldStatus=nNowStatus;
switch ( nNowStatus )
{
case statusNSGree 34、nEWRed:
uLightStatusEW=0x24; uLightStatusSN=0x49;
SetLEDArray(20);
break;
case statusNSFlashEWRed:
uLightStatusEW=0x24; uLightStatusSN=0x49;
SetLEDArray(0);
break;
case statusNSYellowEWRed:
uLightStatusEW=0x24; uLightStatusSN=0x52;
SetLEDArra 35、y(20);
break;
case statusNSRedEWYellow:
uLightStatusEW=0x12; uLightStatusSN=0x64;
SetLEDArray(20);
break;
case statusNSRedEWGreen:
uLightStatusEW=0x09; uLightStatusSN=0x64;
SetLEDArray(20);
break;
case statusNSRedEWFlash:
uLightStatusEW= 36、0x09; uLightStatusSN=0x64;
SetLEDArray(0);
break;
case statusHold:
uLightStatusEW=0x24; uLightStatusSN=0x64;
SetLEDArray(20);
break;
}
}
CTRLR=uLightStatusEW; CTRLR=uLightStatusSN; // 设置交通灯状态
RefreshLEDArray(); // 刷新发光二极管显示
nScanCode=port8001; // 读 37、键盘扫描码
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;
ShowNu 38、mber=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];
D 39、elay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
}
}
// 将缓存中点阵送发光二极管显示
void RefreshLEDArray()
{
int i;
for ( i=0;i<8;i++ )
{
CTRGR=ledx[i];
CTRLA=ledbuf[i];
}
}
// 初始化DSP,设置运行速度=8MHz
void InitDSP()
{
REGISTERCLKMD=0; // 复位PLL
REGISTERCLKMD=0x1007; // 速度设置=16MHz
}
// 设 40、置定时器参数、允许中断
void InitTimer()
{
unsigned int k;
asm(" ssbx INTM"); // 关中断,进行关键设置时不许打扰
// 设置通用定时器
k=PMST; // 设置PMST寄存器
PMST =k&0xff; // 中断向量表起始地址=80H
IMR = 0x0c; // 使能TINT
TCR = 0x41f; // 预分频系数为16
TIM = 0; // 时钟计数器清0
PRD = 0x0f423; // 周期寄存器为0ffH
TCR = 0x42f; // 复位、启动
IFR = 41、0x0c; // 清中断标志位
port3004=0; // 使能XINT2
asm(" rsbx INTM"); // 开中断
}
// 初始化ICETEK-CTR板上设备
void InitICETEKCTR()
{
int k;
CTRGR=0; // 初始化ICETEK-CTR
CTRGR=0x80;
CTRGR=0;
CTRLR=0; // 关闭东西方向的交通灯
CTRLR=0x40; // 关闭南北方向的交通灯
CTRLR=0x0c1; // 开启发光二极管显示阵列
CTRLR=0xc8; //使能外部中断
for 42、 ( 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( 43、)
{
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(L 44、CDDELAY);
}
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;
45、
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);
46、 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






