DSP

DSP中的综合交通灯演示实例的算法

2019-07-13 12:09发布

DSP中的综合交通灯演示实例的算法 DSP中的综合交通灯演示实例的算法,基于TI公司的5509这款芯片

#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
#define IFR *(int *)0x1
#define PMST *(int *)0x1d

#define nStatusNSGreenEWRed 160
#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


ioport unsigned int port3004;
ioport unsigned int port8000;
ioport unsigned char port8001;
ioport unsigned char port8002;
ioport unsigned int port8005;
ioport unsigned int port8007;

void InitDSP();
void InitTimer();
void InitICETEKCTR();
void interrupt time(void);
void interrupt xint2(void); // XINT2
中断服务程序
void SetLEDArray(int nNumber); //
修改显示内容
void RefreshLEDArray();  //
刷新显示
void EndICETEKCTR();

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
};
main()
{
int nWork1,nWork2,nWork3,nWork4;
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 ( nTimeCountelse if ( nTimeCountelse if ( nTimeCountelse if ( nTimeCountelse if ( nTimeCountelse if ( nTimeCountelse if ( nTimeCountelse if ( nTimeCountif ( 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);
   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;
  }
}
port8007=uLightStatusEW; port8007=uLightStatusSN; //
设置交通灯状态
RefreshLEDArray(); //
刷新发光二极管显示

nScanCode=port8001; //
读键盘扫描码
nScanCode&=0x0ff;
if ( nScanCode==SCANCODE_Enter ) break;
}
EndICETEKCTR();
exit(0);
}

//
定时器中断服务程序,进行时钟计数
void interrupt time(void)
{
nTimeCount++;
nTimeCount%=nTotalTime;
}

//
设置发光二极管显示内容
void SetLEDArray(int nNumber)
{
int i,k,kk,kkk;

kkk=nNumber;
k=kkk/10*4; kk=kkk%10*4;
for ( i=0;i<4;i++ )
{
ledbuf[7-i]=~led[k+i];
ledbuf[3-i]=~led[kk+i];
}
}

//
将缓存中点阵送发光二极管显示
void RefreshLEDArray()
{
int i;
for ( i=0;i<8;i++ )
{
port8000=ledx
;
port8005=ledbuf;
}
}

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

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

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;

port8000=0; //
初始化ICETEK-CTR
port8000=0x80;
port8000=0;
port8007=0; //
关闭东西方向的交通灯

port8007=0x40; //
关闭南北方向的交通灯
port8007=0x0c1; //
开启发光二极管显示阵列
for ( k=0;k<8;k++ )
{
ledbuf[k]=0x0ff; //
显示为空白
ledx[k]=(k<<4); //
生成显示列控制字
}
k=port8002; //
清除键盘缓冲区
}

void interrupt xint2(void) // XINT2
中断服务程序
{
bHold=1;
}

void EndICETEKCTR()
{
int k;
port8007=0; //
关闭东西方向的交通灯
port8007=0x40; //
关闭南北方向的交通灯
port8007=0x0c0; //
关闭发光二极管显示阵列
k=port8002; //
清除键盘缓冲区
}