DSP实验

更新时间:2024-05-17 18:31:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

交通灯控制实验

一、实验目的

1. 熟悉2812的指令系统。 2. 熟悉74HC573的使用方法。 3. 熟悉DSP的IO操作使用方法。

二、实验设备

1. 一台装有CCS3.3软件的计算机;

2. 插上2812主控板的DSP实验箱; 3. DSP硬件仿真器。

三、实验原理

交通灯的显示有很多方式,如十字路口、丁字路口等,而对于同一个路口又有很多不同的显示要求,比如十字路口,车辆如果只要东西和南北方向通行就很简单,而如果车子可以左右转弯的通行就比较复杂,本实验仅针对最简单的南北和东西直行的情况。

要完成本实验,首先必须了解交通路灯的燃灭规律。本实验需要用到实验箱上交通灯模块中的发光二极管,即红、黄、绿各三个。依人们的交通常规,“红灯停,绿灯行,黄灯提醒”。其交通灯的燃灭规律为:初始态是两个路口的红灯全亮,之后,东西路口的绿灯亮,南北路口的红灯亮,东西方向通车,延时一段时间后,东西路口绿灯灭,黄灯开始闪烁。闪烁若干次后,东西路口红灯亮,而同时南北路口的绿灯亮,南北方向开始通车,延时一段时间后,南北路口的绿灯灭,黄灯开始闪烁。闪烁若干次后,再切换到东西路口方向,重复上述过程。

本实验要完成任务就是设计一个简单的交通灯控制器,交通灯显示用实验箱的交通灯模块显示。此模块由发光二极管和一个锁存器组成。

数据由2812模块的低八位输入,锁存器的控制信号由2812模块输出,但经由74LS00译码后再控制锁存器。

交通灯原理图

四、程序设计思路

根据设计要求,由于控制是由不同的各种状态按顺序发生的,我们可以采用状态机制控制方法来解决此问题。这种方法是:首先列举所有可能发生的状态;然后将这些状态编号,按顺序产生这些状态;状态延续的时间用程序控制。对于突发情况,可采用在正常顺序的控制中插入特殊控制序列的方式完成。

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

表格 1

保持时间计数显示 20-编状号态信号灯状态 状态定义 (计数值,起始时间,结束时间) 1 南北绿灯,东西红灯 statusNSGreenEWRed 20秒(160,0,159)

0 南北绿灯闪烁,东西2 红灯 statusNSFlashEWRed statusNSY3 南北黄灯,东西红灯 ellowEWRed 南北红灯,东西黄灯 statusNSRedEWYellow statusNSRedEWGree绿灯 n statusNSRedEWFlash statusNSR7 南北红灯,东西黄灯 edEWYellow statusNSY8 南北黄灯,东西红灯 ellowEWRed 6秒(24,160,183) 4秒(16,184,199) 0 20 4 4秒(16,200,215) 20 2南北红灯,东西5 20秒(160,216,375) 0-1 南北红灯,东西绿灯6 闪烁 6秒(24,376,399) 0 4秒(16,400,415) 20 4秒(16,416,431) 20 2* 南北红灯,东西红灯 StatusHold 20秒(160,0,159) 0-1

其中,正常顺序每112 秒(计数值448)为一个循环,状态“*”为非顺序状态。 这样,只要根据计数值就可确定当前状态,根据状态再分情况处理。

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

五、试验程序

#include \

#define SPSA0 *(unsigned int *)0x38 #define SPSD0 *(unsigned int *)0x39

#define REGISTERCLKMD (*(unsigned int *)0x58) #define TIM #define TCR #define IMR #define IFR #define PMST

*(int *)0x24 *(int *)0x26

*(int *)0x0 //IM R中断屏蔽寄存器 *(int *)0x1

//IFR中断标志寄存器

*(int *)0x1d //PMST处理器模式状态寄存器(地址1dh)

#define PRD *(int *)0x25

#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]= { };

unsigned char ledkey[10][8]= {

// 修改显示内容

// 刷新显示

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

{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

nTimeCount

else

if

( nTimeCount

)))))))

nNowStatus=statusNSRedEWYellow;

else

if

(

nTimeCount

)

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;

nWork1=nTimeCount-nStatusNSRedEWGreen;

nWork2=nStatusNSRedEWYellow1-nStatusNSRedEWFlash; nWork3=nWork2/3; nWork4=nWork3/2;

if ( nWork1>=0 && nWork2>0 && nWork3>0 && break;

nWork1=nStatusNSGreenEWRed/20; if ( nWork1>0 ) {

nWork2=20-nTimeCount/nWork1; if ( bHold ) { }

if ( nOldTimeCount!=nWork2 ) {

if ( nWork2>10 ) { }

nTimeCount=nWork1*10; nWork2=10;

case statusNSRedEWFlash:

nWork4>0 )

uLightStatusEW=( (nWork1%nWork3)<=nWork4 )?(0x09):(0x00);

case statusNSGreenEWRed:

} else

}

}

}

nOldTimeCount=nWork2; SetLEDArray(nWork2);

break;

case statusNSRedEWGreen:

nWork1=(nStatusNSRedEWGreen-nStatusNSRedEWYellow)/20;

} break;

nWork1=nStatusHold/20; if ( nWork1>0 ) { } break;

nWork2=20-nTimeCount/nWork1; if ( nOldTimeCount!=nWork2 ) { }

nOldTimeCount=nWork2; SetLEDArray(nWork2); if ( bHold ) { }

if ( nOldTimeCount!=nWork2 ) { }

nOldTimeCount=nWork2; SetLEDArray(nWork2); }

nWork2=10; if ( nWork2>10 ) {

if ( nWork1>0 ) {

nWork2=20-(nTimeCount-nStatusNSRedEWYellow)/nWork1;

nTimeCount=nStatusNSRedEWYellow+nWork1*10;

case statusHold:

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

uLightStatusEW=0x24; uLightStatusSN=0x64; SetLEDArray(20); break;

case statusHold:

CTRLR=uLightStatusEW; CTRLR=uLightStatusSN; // 设置交通灯状态RefreshLEDArray(); nScanCode&=0x0ff; tKey=CTRCLKEY;

if ( nScanCode==SCANCODE_9 )

break;

// 刷新发光二极管显示

nScanCode=port8001; // 读键盘扫描码

EndICETEKCTR(); exit(0);

// 定时器中断服务程序,进行时钟计数 void interrupt time(void) { }

// 设置发光二极管显示内容 void SetLEDArray(int nNumber) {

int i,ShowNumber; ShowNumber=nNumber/2;

if(ShowNumber>9) ShowNumber=0;

nTimeCount++;

nTimeCount%=nTotalTime;

CTRLCDCMDR=LCDCMDPAGE; Delay(LCDDELAY); CTRLCDCR=0; Delay(LCDDELAY);

// 设置操作页=0

CTRLCDCMDR=LCDCMDVERADDRESS; Delay(LCDDELAY); CTRLCDCR=0; Delay(LCDDELAY); for ( i=0;i<8;i++ ) {

// 起始列=0

}

}

CTRLCDLCR=ledkey[ShowNumber][i]; Delay(LCDDELAY); CTRLCDCR=0; Delay(LCDDELAY);

// 将缓存中点阵送发光二极管显示 void RefreshLEDArray() { }

// 初始化DSP,设置运行速度=8MHz void InitDSP() { }

// 设置定时器参数、允许中断 void InitTimer() { }

// 初始化ICETEK-CTR板上设备 void InitICETEKCTR() {

int i;

for ( i=0;i<8;i++ ) { }

CTRGR=ledx[i]; CTRLA=ledbuf[i];

REGISTERCLKMD=0; // 复位PLL REGISTERCLKMD=0x1007;

// 速度设置=16MHz

unsigned int k; asm(\

ssbx INTM\// 关中断,进行关键设置时不许打扰

// 设置PMST寄存器 // 中断向量表起始地址=80H // 使能TINT

// 设置通用定时器 k=PMST; PMST =k&0xff; IMR = 0x0c; TIM = 0;

TCR = 0x41f; // 预分频系数为16

// 时钟计数器清0

// 周期寄存器为0ffH // 清中断标志位

// 使能XINT2

PRD = 0x0f423; IFR = 0x0c; port3004=0; asm(\

TCR = 0x42f; // 复位、启动

rsbx INTM\// 开中断

int k;

}

CTRGR=0; CTRGR=0; CTRLR=0;

// 初始化ICETEK-CTR

CTRGR=0x80;

// 关闭东西方向的交通灯 // 关闭南北方向的交通灯 // 开启发光二极管显示阵列

CTRLR=0x40; CTRLR=0x0c1;

CTRLR=0xc8; //使能外部中断 for ( k=0;k<8;k++ ) { }

k=CTRCLKEY; TurnOnLCD(); LCDCLS(); CTRLCDCR=0;

// XINT2中断服务程序 // 清除键盘缓冲区

// 打开显示

// 设置显示起始行

// 清除显示内存

ledbuf[k]=0x0ff; ledx[k]=(k<<4);

// 显示为空白 // 生成显示列控制字

CTRLCDCMDR=LCDCMDSTARTLINE;

void interrupt xint2(void) { }

void EndICETEKCTR() { }

void TurnOnLCD() { }

void LCDCLS() {

bHold=1;

int k; CTRLR=0;

// 关闭东西方向的交通灯 // 关闭南北方向的交通灯 // 关闭发光二极管显示阵列 // 清除键盘缓冲区

CTRLR=0x40; CTRLR=0x0c0; k=CTRCLKEY;

CTRLCDCMDR=LCDCMDTURNON; Delay(LCDDELAY); CTRLCDCR=0; Delay(LCDDELAY);

CTRLCDCMDR=LCDCMDSTARTLINE; Delay(LCDDELAY); CTRLCDCR=0; Delay(LCDDELAY);

}

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++ ) { }

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); CTRLCDLCR=0; Delay(LCDDELAY); CTRLCDCR=0; Delay(LCDDELAY);

void Delay(unsigned int nDelay) {

int ii,jj,kk=0;

for ( ii=0;ii

}

{ }

for ( jj=0;jj<1024;jj++ ) { }

kk++;

六、实验步骤

1. 把2812主控板插到实验箱底板相应接口上,把交通灯模块插到底板外设区; 2. 在CCS3.3环境中打开本实验的工程Example_Crossled,生成输出文件,通过仿真

器把执行代码下载到DSP芯片;

3. 运行程序,发光二极管按交通灯方式点亮熄灭;

4. 参考源代码,自行修改程序,实现不同的交通灯控制方式。

七、实验体会

通过这次DSP实验,对DSP的中断有所熟悉,以及对课上老师讲过的知识点的掌握有了深刻体会,通过查阅大量的资料,以及同老师同学的讨论,收获颇丰,有一种柳暗花明的感觉。同时,通过这次仿真,更加深刻的了解了DSP开发的软硬件平台:CCS及其硬件试验箱,使我基本上了解了DSP系统软件开发的基本过程,这也是本次实验收获最大的地方。

本文来源:https://www.bwwdw.com/article/89e7.html

Top