#include "CT107D.h"
#include "PCF8591.h"
#include "AT24C02.h"
#define LED_SPEED_LOW 70
#define LED_SPEED_MED 60
#define LED_SPEED_HIG 50
#define LED_SPEED_VERY_HIG 40
#define SMG_OFF 10
sbit SET_KEY=P3^0;
sbit ADD_KEY=P3^1;
sbit DEL_KEY=P3^2;
sbit START_KEY=P3^3;
/*******************LED相关变量**********************/
unsigned char code led_dis_mod1[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned char code led_dis_mod2[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
unsigned char code led_dis_mod3[8]={0xe7,0xdb,0xbd,0x7e,0xe7,0xdb,0xbd,0x7e};
unsigned char code led_dis_mod4[8]={0x7e,0xbd,0xdb,0xe7,0x7e,0xbd,0xdb,0xe7};
unsigned char led_dis_buf;
unsigned char we_init_val=0x01,du_val_count=0;
/*******************数码管相关变量**********************/
unsigned char code smg_code[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; //正常显示模式
//10 熄灭 11 -
unsigned char display_buf[8]={11,10,11,10,10,10,10,10};
unsigned char smg_special_buf[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0xff}; //特殊显示模式
// - 1 - 4 0 0
bit smg_display_flag=0; //0 notdis 1 dis
unsigned int smg_flash_counter=0; //数码管闪烁计数
bit smg_flash_flag=0; //0 不闪烁 1 闪烁
/********************定时器相关变量***********************/
unsigned char timer_counter1;
unsigned int timer_counter0;
/********************LED调光变量************************/
unsigned char led_dis_speed_buf[4];
unsigned char led_dis_speed=40; //40 50 60 70 。。。。120
unsigned char LED_PWM_VAL; //0~100
/********************LED模式**************************/
unsigned char led_mod_flag=0; //0 1 2 3
/********************按键相关变量************************/
bit setting_flag=0;
unsigned char setting_counter=0; // 1 mod 2 time 0 display
bit start_stop_led_dis=0; //0 stop 1 start
/**********开灯**************/
void LED_ON(){
switch_138(4);
P0=led_dis_buf;
switch_138(5);
P0=0X00;
}
/***********关灯*************/
void LED_OFF(){
switch_138(4);
P0=0xff;
switch_138(5);
P0=0X00;
}
void smg_display(){
switch_138(6); //WE
P0=we_init_val;
switch_138(7); //DAT
P0=smg_code[display_buf[du_val_count]];
switch_138(5);
P0=0x00;
du_val_count++;
if(du_val_count==8){
du_val_count=0;
}
we_init_val=_crol_(we_init_val,1);
}
void smg_special_dis(unsigned char n){
unsigned char i;
for(i=0;i<8;i++){
smg_special_buf[7]=smg_code[n]; //10 分 4 份
switch_138(6); //WE
P0=1<<i;
switch_138(7); //DAT
P0=smg_special_buf[i];
delay_ms(2);
}
}
// mod =10 熄灭 time=
void smg_reload_dat(unsigned char mod,unsigned char time){
display_buf[1]=mod; //流水模式
//速度
if(time>=100){
display_buf[4]=time/100;
}else{
display_buf[4]=SMG_OFF;
}
display_buf[5]=time%100/10;
display_buf[6]=time%10;
display_buf[7]=0;
}
void smg_off(unsigned char choose){
if(choose==1){
display_buf[1]=SMG_OFF;
}else if(choose==2){
display_buf[4]=SMG_OFF;
display_buf[5]=SMG_OFF;
display_buf[6]=SMG_OFF;
display_buf[7]=SMG_OFF;
}
}
void keysCan(){
if(SET_KEY==0){
setting_counter++;
if(setting_counter>=3)setting_counter=0;
}while(SET_KEY==0);
if(START_KEY==0){
start_stop_led_dis=~start_stop_led_dis;
}while(START_KEY==0);
}
/**********上传数据到AT24C02************************/
void upload_dat(){
switch(led_mod_flag){
case 0:AT_write_dat(0x00,led_dis_speed);break;
case 1:AT_write_dat(0x01,led_dis_speed);break;
case 2:AT_write_dat(0x02,led_dis_speed);break;
case 3:AT_write_dat(0x03,led_dis_speed);break;
default:break;
}
}
/***********下载数据到单片机*************************/
void download_dat(){
unsigned char i;
for(i=0;i<4;i++){
led_dis_speed_buf[i]=AT_read_dat(i);
delay_ms(5);
}
}
void timer_init(){
TMOD=0x11;
TL0 = 0xA4; //设置定时初值
TH0 = 0xFF; //设置定时初值
TL1 = 0xCD; //设置定时初值
TH1 = 0xF8; //设置定时初值 2MS
TR0=1;
TR1=1;
EA=1;
ET0=1;
ET1=1;
}
void main(){
all_init();
download_dat();
switch(led_mod_flag){
case 0:led_dis_speed=led_dis_speed_buf[0];break;
case 1:led_dis_speed=led_dis_speed_buf[1];break;
case 2:led_dis_speed=led_dis_speed_buf[2];break;
case 3:led_dis_speed=led_dis_speed_buf[3];break;
default:break;
}
/*
while(1){
if(START_KEY==0){
break;
}
}
*/
while(1){
if(START_KEY==0){
delay_ms(50);
break;
}
}
timer_init();
while(1){
keysCan();
if(setting_counter>0){
setting_flag=1;
}else{
setting_flag=0;
}
if(setting_flag){
if(setting_counter==1){ //流水灯模式
if(ADD_KEY==0){
led_mod_flag++;
if(led_mod_flag>3)led_mod_flag=0;
}while(ADD_KEY==0);
if(DEL_KEY==0){
led_mod_flag--;
if(led_mod_flag==0)led_mod_flag=3;
}while(DEL_KEY==0);
}else if(setting_counter==2){ //流水灯速度
switch(led_mod_flag){
case 0:led_dis_speed=led_dis_speed_buf[0];break;
case 1:led_dis_speed=led_dis_speed_buf[1];break;
case 2:led_dis_speed=led_dis_speed_buf[2];break;
case 3:led_dis_speed=led_dis_speed_buf[3];break;
default:break;
}
if(ADD_KEY==0){
led_dis_speed+=10;
if(led_dis_speed>120)led_dis_speed=40;
}while(ADD_KEY==0);
if(DEL_KEY==0){
led_dis_speed-=10;
if(led_dis_speed<40)led_dis_speed=120;
}while(DEL_KEY==0);
switch(led_mod_flag){
case 0:led_dis_speed_buf[0]=led_dis_speed;break;
case 1:led_dis_speed_buf[1]=led_dis_speed;break;
case 2:led_dis_speed_buf[2]=led_dis_speed;break;
case 3:led_dis_speed_buf[3]=led_dis_speed;break;
default:break;
}
}
}else{
if(ADD_KEY==0){
}while(ADD_KEY==0){
smg_display_flag=1;
}
if(start_stop_led_dis){
TR0=0;
ET0=0;
LED_OFF();
}else{
TR0=1;
ET0=1;
}
}
smg_display_flag=0; //数码管开显示
}
}
/****************display*******************/
void timer0() interrupt 1{
TL0 = 0xA4; //设置定时初值
TH0 = 0xFF; //设置定时初值
timer_counter0++;
if(timer_counter0<=(LED_PWM_VAL*2)){ //PWM调光
LED_ON();
}else{
LED_OFF();
}
if(timer_counter0>=8)timer_counter0=0;
}
/****************control******************/
void timer1() interrupt 3{
unsigned char i;
TL1 = 0xCD; //设置定时初值
TH1 = 0xF8; //设置定时初值 2MS
if(start_stop_led_dis){
LED_OFF();
}
timer_counter1++;
if(!smg_display_flag){
smg_display(); //数码管显示
}else{
smg_special_dis(LED_PWM_VAL);
}
smg_flash_counter++;
if(smg_flash_counter>=100){ //200ms
smg_flash_counter=0;
smg_flash_flag=~smg_flash_flag;
}
switch(setting_counter){ //数码管闪烁控制 和是否闪烁
case 0:smg_reload_dat(led_mod_flag+1,led_dis_speed);break;
case 1:{if(smg_flash_flag)smg_off(1);else smg_reload_dat(led_mod_flag+1,led_dis_speed);}break;
case 2:{if(smg_flash_flag)smg_off(2);else smg_reload_dat(led_mod_flag+1,led_dis_speed);}break;
default:break;
}
if(!start_stop_led_dis){
switch(led_mod_flag){ //装入LED数据
case 0:led_dis_buf=led_dis_mod1[i];break;
case 1:led_dis_buf=led_dis_mod2[i];break;
case 2:led_dis_buf=led_dis_mod3[i];break;
case 3:led_dis_buf=led_dis_mod4[i];break;
default:break;
}
}else{
led_dis_buf=0xff;
}
//数码管装入数据 与显示不冲突
if(timer_counter1==led_dis_speed){ //更新数据速度 随便写的,可调
timer_counter1=0;
i++;
if(i==8)i=0;
}
LED_PWM_VAL=(AD_read_dat(0x03)>>6)+1; //转 10
upload_dat();
}
【四】说在最后的话,其实这个例程还是有一点点的小BUG 的,就是 关闭流水灯显示的时候,流水灯还是会微微亮那么一点点....个人推断是程序里没有消隐之类的东西把(其实是懒得写了),但是总的来说是基本完全实现的(接近完美的了);当然,如果还让我再写一遍,我可能还会采取其它不同的方法,总之实现的方法有很多,只要功能实现就OK;个人水平还是有待提高了,也请各个dalao们也多多给出一些指导意见的啦。蟹蟹~