文档库 最新最全的文档下载
当前位置:文档库 › DSP交通灯综合控制

DSP交通灯综合控制

DSP交通灯综合控制
DSP交通灯综合控制

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)

3DSP定时器的算法原理 (8)

3.1CPU定时器的原理 (8)

3.2CPU定时寄存器原理 (8)

4系统程序设计 (9)

4.1流程图 (9)

4.2试验程序 (10)

5心得体会 (21)

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流程图

图5-1实验程序流程图

设计总流程图

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

图 4-1设计总流程图

#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 0x40

ioport 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 port8007

void 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,nSaveStatu s;

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

else if ( nTimeCount

else if ( nTimeCount

else if ( nTimeCount

else if ( nTimeCount

else if ( nTimeCount

else if ( nTimeCount

else if ( nTimeCount

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%=nT otalTime;

}

// 设置发光二极管显示容

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,设置运行速度=8MHz

void InitDSP()

{

REGISTERCLKMD=0; // 复位PLL REGISTERCLKMD=0x1007; // 速度设置=16MHz

}

// 设置定时器参数、允许中断

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 = 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 ( 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

{

相关文档