基于SmartArm2200的交通灯

     五一期间和同学尹静、杨力做了一个及交通灯。这个交通灯是用 Arm 控制的,它能能模仿城 十字 路口交通灯的功能, 并能进行特 殊控制。基本实现了以下功能:

1. 1.该设计能控制东、西、南、北四个道口的红、黄、绿信号灯正常工作。
2. 2.当东西方向准行、南北方向禁行时,东西方向亮绿       灯,南北方向亮红灯。
3. 3.当南北方向准行、东西方向禁行时,南北方向亮绿灯,东西方向亮红灯。
4. 4.两垂直方向的准行时间均为 20 秒。 准行方向亮绿灯 15 秒后, 四个道口同时加亮一盏黄 灯, 以警告车辆及行人,准行方 
  向与禁行方向即改变 ( 准行变为禁行,禁行 变为准行 )
6. 四个道口均用数码管显示准行 ( 或禁行 ) 的剩余时间。
7. 按下 K1 键,开始南北方向准行、东西方向禁行,并且 关掉数码管的显示,直至按下 START 键,交通灯又开 始正常工作。
8. 按下 K2 键,开始东西方向准行、南北方向禁 行,并且 关掉数码管的显示,直至按下 START 键,交通灯又开 始正常工作。
9. 按下 START 键, 四个方向的信号灯开始正常工作。
10. 按下 STOP 键,四个方向均亮红灯,并且关掉数码管 的显示,直至按下 START 键,交通灯又开始正常作。
   
基本思想: 为了达到上述功能可以用 SmartArm2200 控制。用 2200 P1.16~p1.18 控制南北方向的 红黄绿, P1.19~P1.21 控制东西方向红黄绿; 再用 P2.28 接控制按键 KEY1 P1.23 接控按键 KEY2 P1.24 STOP 按键, P1.25 接按键 START, 分别起特殊的控制作用; 数码管的显示采用动态动态显示的方法实现,   P0.17~P0.20 作为四个数码位选信号, P2.26~P2.23 为数码管的段选信号。
 

程序代码:
#include "config.h" #define COM0 1<<17 // P0.17-P0.20口控制数码管工作 #define COM1 1<<18 #define COM2 1<<19 #define COM3 1<<20 #define LEDCON 0x003f0000 // P1.16-18南北红、黄、绿 P1.19-21东西红、黄、绿 #define NUMCON 0x00ff0000 // P2.16-P2.23口对应数码管显示数字 16-23对应a-g.dot #define KEY1 1<<28 // KEY1键 P2.28(注意) #define KEY2 1<<23 // KEY2键 P1.23 #define KEY_STOP 1<<24 // STOP键 P1.24 #define KEY_START 1<<25 // START键 P1.25 //int index[4] = {0, 1, 2, 1}; // LED[]数组的下标 int index; int32 LED[4] = {0x21, 0x12, 0x0c, 0x12}; // 分别表示南北禁行、东西准行;黄灯亮;南北准行、东西禁行 int32 NUM[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; // 数码管显示的数字0-9 int flag; // 控制数码管显示 int num; int shiwei; // 显示位 int gewei; int32 i; // 刷新次数 void Time0Init(void) { T0TC = 0; T0PR = 0; // 时钟不分频 T0MCR = 0x03; // 匹配通道0匹配后复位T0TC,并产生中断标志 T0MR0 = Fpclk / 400; // 比较值(0.005S定时值) T0TCR = 0x03; // 启动并复位T0TC T0TCR = 0x01; } void QueryKey(void) { if( (IO2PIN&KEY1) == 0) //KEY1按下,南北方向准行,东西方向禁行,关掉数码管显示 { T0TCR = 0x00; //停止定时器0 IO1SET = 0x000c0000; // 南北亮绿灯,东西亮红灯 IO1CLR = 0x00330000; //其余灯灭 IO0SET = 0x001e0000; //关掉数码管显示 flag = 0; } else if((IO1PIN&KEY2) == 0) //KEY2按下,东西方向准行,南北方向禁行,关掉数码管显示 { T0TCR = 0x00; //停止定时器0 IO1SET = 0x00210000; //东西亮绿灯,南北亮红灯 IO1CLR = 0x001e0000; IO0SET = 0x001e0000; //关掉数码管显示 flag = 0; } else if( (IO1PIN&KEY_STOP) == 0) //STOP键按下,四个方向均亮红灯,并且关掉数码管显示 { T0TCR = 0x00; //停止定时器0 IO1SET = 0x00090000; // 四个方向红灯亮 IO1CLR = 0x00360000; IO0SET = 0x001e0000; //关掉数码管显示 flag = 0; } else if( (IO1PIN&KEY_START) == 0) //按下START键, 四个方向的信号灯开始正常工作 { Time0Init(); //定时器初始化并启动 flag = 1; //数码管动态显示 i = index = 0; // IO1PIN = LED[0]<<16; num = 15; shiwei = num / 10; gewei = num % 10; } } void NormalDisplay(void) { if(flag == 1) { while((T0IR & 0x01) != 0){ //等待定时时间到 T0IR = 0x01; // 清除中断标志 if(i >= 400) { i = 0; num--; if(num < 0){ // 数码管显示的数字0-9 index++; if(index > 3) index = 0; if( (index % 2) == 1) num = 5; else num = 15; IO1PIN = LED[index]<<16; } shiwei = num / 10; gewei = num % 10; } switch((i++) % 4){ //扫描显示 case 0: IO0SET = COM1; //将其他数码管熄灭 IO0SET = COM2; IO0SET = COM3; IO2PIN = NUM[shiwei] << 16; //写入数据 IO0CLR = COM0; //使数码管0工作 break; case 1: IO0SET = COM0; IO0SET = COM2; IO0SET = COM3; IO2PIN = NUM[gewei] << 16; IO0CLR = COM1; //使数码管1工作 break; case 2: IO0SET = COM0; IO0SET = COM1; IO0SET = COM3; IO2PIN = NUM[shiwei] << 16; IO0CLR = COM2; //使数码管2工作 break; case 3: IO0SET = COM0; IO0SET = COM1; IO0SET = COM2; IO2PIN = NUM[gewei] << 16; IO0CLR = COM3; //使数码管3工作 break; } } } } int main (void) { PINSEL0 = 0X00000000; // 设置管脚连接GPIO IO0DIR = COM0 | COM1 | COM2 |COM3; // 设置数码管公共管脚I/O为输出 PINSEL1 = 0X00000000; // 设置管脚连接GPIO IO1DIR = LEDCON; // 设置led灯I/O为输出 IO2DIR = NUMCON; // 设置I/O为输出 Time0Init(); //IO1SET = KEY1 | KEY2 | KEY_STOP | KEY_START; i = index = 0; //i控制数码管,j为 index[]下标 flag = 1; //为1数码管亮,为0数码管不亮 IO1PIN = LED[0]<<16; //初始路灯状态 num = 15; //初始路灯亮状态的值 shiwei = num / 10; //取出十位值 gewei = num % 10; //取出个位值 while(1) { NormalDisplay(); //扫描显示数码管 QueryKey(); //查询按键 } retu

你可能感兴趣的:(基于SmartArm2200的交通灯)