彩灯控制系统要求

遇到的问题
1.led_slowdown 若想减速500次1ms,要使用unsigned int
2.unsigned char 0-255 在0时减一会变成255
3.定时器初始化:STC-ISP
4.仿真图的红蓝点代表0/1,观察变化可分析哪个模块有问题

Note
1.流水灯的实现
2.Key函数封装与四行消抖
3.数码管动态显示
4.用定时器取代delay
5.主函数框架
1.流水灯的实现
P1 = 0xFE;//1111 1110
Delay500ms();
P1 = 0xFD;//1111 1101
Delay500ms();
P1 = Led;
Delay500ms();
Led = _crol_(Led,1);
//_crol_()循环左移 _cror_()循环右移 所属库:<INRINS.H>`
2.Key函数封装与四行消抖
unsigned char Key_Read()
{
unsigned char temp = 0;
if(P3_4 == 0) temp = 1;
if(P3_5 == 0) temp = 2;
if(P3_6 == 0) temp = 3;
if(P3_7 == 0) temp = 4;
return temp;
}
unsigned char Key_Val,Key_Down,Key_Up,Key_Old;
Key_Val = Key_Read();//读取键码值
Key_Down = Key_Val &(Key_Val^Key_Old);//检测下降沿
Key_Up = ~Key_Val &(Key_Val^Key_Old);//检测上升沿
Key_Old = Key_Val;//扫描辅助变量
switch(Key_Down)
{
case 1:
break;
case 2:
break;
......
}
3.数码管动态显示
//共阴极数码管 0 1 2 3 4 5 6 7 8 9 熄灭 A B
unsigned char code seg_dula[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x77,0x7c};
unsigned char code seg_wela[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
void seg_disp(unsigned char wela,dula)
{
//数码管的位选和段选都连接在P0口会引脚冲突,需开关锁存器
锁存器SEG_WLE控制位选,SEG_DLE控制段选,给0打开,给1关闭.
//消影
P0=0x00; //消影 准备好数据
P2_6=1; //开门
P2_6=0; //关门 数据存入
//位选
P0=seg_wela[wela];
P2_7=1;
P2_7=0;
//段选
P0=seg_dula[dula];
P2_6=1;
P2_6=0;
}
//
unsigned char seg_pos;
unsigned char seg_buf[6]={10,10,10,10,10,10}; //此处数码管有6位
void seg_proc()
{
if(seg_slowdown) return;
seg_slowdown=1;
seg_buf[0]=led_mode;
seg_buf[5]=12-(unsigned char)led_flag;
}
4.用定时器取代delay
//系统频率12Mhz,定时长度1ms,定时器模式16位,定时器闹钟12T
void Timer0Init(void) //1毫秒@12.000MHz
{
//沙子
//AUXR &= 0x7F; //定时器时钟12T模式 STC-ISP生成的 删去这行
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
//闹钟
ET0=1;
EA=1;
}
void Timer0_server() interrupt 1
{
//再赋初值 再装沙子
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
if(++led_slowdown==500) led_slowdown=0;
if(++key_slowdown==10) key_slowdown=0;
if(++seg_slowdown==500) seg_slowdown=0;
if(++seg_pos==6) seg_pos=0;
seg_disp(seg_pos,seg_buf[seg_pos]);
}
5.主函数框架
#include <REGX52.H>
#include "key.h"
#include "seg.h"
unsigned char led_flag=1;
unsigned char led_mode=1;
unsigned char i=0;
unsigned char key_slowdown; // 10ms
unsigned int led_slowdown; // unsigned char 0-255
unsigned int seg_slowdown; //500ms使用int
unsigned char key_val,key_old,key_up,key_down;
unsigned char seg_pos;
unsigned char seg_buf[6]={10,10,10,10,10,10}; //输入标号去选择seg.c中seg_dula中的值
void key_proc()
{
if(key_slowdown) return;
key_slowdown=1;
key_val=key_read(); //识别按下的键码
key_down=key_val & (key_val ^ key_old); //捕捉下降沿
key_up = ~key_val & (key_old ^ key_val); //捕捉上升沿
key_old=key_val; //辅助扫描
switch(key_down)
{
}
}
void seg_proc()
{
if(seg_slowdown) return;
seg_slowdown=1;
seg_buf[0]=led_mode;
seg_buf[5]=12-(unsigned char)led_flag;
}
void led_proc()
{
if(led_slowdown) return;
led_slowdown=1;
if(led_flag)
{
switch(led_mode)
{
}
}
}
void Timer0Init(void) //1毫秒@12.000MHz
{
//沙子
//AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
//闹钟
ET0=1;
EA=1;
}
void Timer0_server() interrupt 1
{
//再赋初值 再装沙子
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
if(++led_slowdown==500) led_slowdown=0;
if(++key_slowdown==10) key_slowdown=0;
if(++seg_slowdown==500) seg_slowdown=0;
if(++seg_pos==6) seg_pos=0;
seg_disp(seg_pos,seg_buf[seg_pos]);
}
void main()
{
Timer0Init();
while(1)
{
key_proc();
led_proc();
seg_proc();
}
}

被折叠的 条评论
为什么被折叠?



