首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

,单片机数码管闪烁程序

2012-09-27 
求助,单片机数码管闪烁程序小弟新学单片机,用ds1302和单片机做了一个时钟,采用24小时模式,一共六个数码管,

求助,单片机数码管闪烁程序
小弟新学单片机,用ds1302和单片机做了一个时钟,采用24小时模式,一共六个数码管,显示时分秒,并可调整时间!显示已经正常,就是在做调整时间那一部分的时候,当按下set_mod_key的时候时钟停止读取,定格在最后显示上面,秒部分清零;然后按下sel_led_key的时候选择对哪个数码管进行调整,并且要调整的数码管进行闪烁(只调整小时和分钟);当按下display_inc_key的时候当前闪烁的数码管会加一;当按下ok_set键的时候就会把修改的数据写入ds1302中,并启动时钟,目前遇到的情况就是不能实现闪烁,并且不能进行调整!程序如下,求高手帮助,感激,谢谢!
#include <at89x52.h>
#include <intrins.h>

#defineucharunsigned char
#defineuintunsigned int

void write_byte(uchar byte); //向ds1302中写入一个字节
uchar read_byte(uchar byte);//从ds1302中读出一个字节
void init_ds1302();//对ds1302中存放的时、分、秒进行初始化
void display();//在数码管上进行显示
void read_to_exchange();//把从ds1302中读取的数据转换为数码管输出需要的数据
void key_set();//四个按键设置
void write_data(uchar addr,uchar w_data);//写入寄存器地址并写入数据
uchar read_data(uchar addr);//写入一个寄存器地址并读取其中数据
void delay1ms(uint time); //约延时time微秒

sbitCE = P1^0;//复位总线,用P1的第零位进行操作
sbitSCLK = P1^1; //时钟控制总线,用P1的第一位来进行操作
sbitIO_DATA = P1^2;//数据传送线
sbitsel_mod_key = P3^0;//开始进行时间设置
sbitdisplay_inc_key = P3^2;//数码管显示的数据循环加一
sbitok_key = P3^3;//确定修改
sbitsel_led_key = P3^1;//选择要修改的数码管
bitC = 0;
//数字0~9在数码管上显示时代替的值
uchar disbuf_code[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//从ds1302中读取信息并转换成数码管显示的值
uchar disbuf[6] = {0x00};
//选择哪个数码管显示
uchar sel_chip[6] = {0x01,0x02,0x04,0x08,0x10,0x20};
//读命令地址
uchar read_add[3] = {0x81,0x83,0x85};
//写命令地址
uchar write_add[3] = {0x80,0x82,0x84};
uchar time_sbuf[3] = {0x00}; //暂时存放读取的时,分,秒数据
uchar position = 0;//用来控制显示数码管
uchar set_flag = 0;//用来确定进行调整,当其按下时,开始进行时间调整
uchar mod_flag = 3;//标志位,用来确定哪个数码管闪烁,并对其进行调整
uchar k = 0;
/*void uartinit()
{
 TMOD=0x20;//T1方式2
 TH1=0xFD;//24M 9600F3
 TL1=0xFD;
 SCON=0xd8;//d8
// PCON=0x80;//80
 TR1=1;
// ES = 1;
}
void uartsendchar(uchar a)  
{
 SBUF=a;
 while(TI==0);
 TI=0;
} */



void main()
{
CE = 0;
SCLK = 0;
init_ds1302();
TMOD = 0x01;//设置定时器T0为方式1,并写入初值,以及定时器允许设置和启动
TH0 = 0xfd;
TL0 = 0xcc;
EA = 1;
ET0 = 1;
TR0 = 1; 
//uartinit();
while(1)
{

read_to_exchange();
key_set();

}  
}
void read_to_exchange()//从ds1302中读取数据,并转化成可在数码管上显示的数据
{
//write_data(0x8e,0x00);
time_sbuf[2] = read_data(read_add[0]);
time_sbuf[1] = read_data(read_add[1]);
time_sbuf[0] = read_data(read_add[2]); 
//write_data(0x8e, 0x80);
disbuf[0] = disbuf_code[time_sbuf[0]>>4];
disbuf[1] = disbuf_code[time_sbuf[0]&0x0f] | 0x80;
disbuf[2] = disbuf_code[time_sbuf[1]>>4];
disbuf[3] = disbuf_code[time_sbuf[1]&0x0f] | 0x80;
disbuf[4] = disbuf_code[time_sbuf[2]>>4];
disbuf[5] = disbuf_code[time_sbuf[2]&0x0f];
}

uchar read_byte()
{
uchar receive_data = 0;
uchar k;
EA = 0;
IO_DATA = 1;
for(k = 0; k < 8; k++)
 {
receive_data >>= 1;

SCLK = 1;
_nop_();
_nop_();
SCLK = 0;
C = IO_DATA;
_nop_();
if(C == 1)
{
receive_data |= 0x80;
}
else
{
receive_data &= 0x7f;
}
SCLK = 1;
_nop_();
_nop_();
}
SCLK = 0;
_nop_();
_nop_();
EA = 1;
return receive_data;
}  
void write_byte(uchar byte)
{
uchar j;
EA=0;
for(j = 0; j < 8; j++)
{
SCLK = 0;
_nop_();
_nop_();
if(byte & 0x01)
{
C = 1;
}
else
{
C = 0;
}
IO_DATA = C;
_nop_();
_nop_();
SCLK = 1;
_nop_();
_nop_();
byte = byte >> 1;
}
EA=1;
}
uchar read_data(uchar addr)
{
uchar r_data;


SCLK = 0;
CE = 1;
write_byte(addr);
r_data = read_byte();
CE = 0;
SCLK = 0;
returnr_data; 
}
void write_data(uchar addr,uchar w_data)
{
SCLK = 0;
CE = 1;
write_byte(addr);
write_byte(w_data);
CE = 0;
SCLK = 0;
}
void init_ds1302()
{
write_data(0x8e, 0);//允许对ds1302进行读写
write_data(write_add[0], 0x00);
write_data(write_add[1], 0x11);
write_data(write_add[2], 0x11); 
//write_data(0x8e, 0x80);//禁止对ds1302读写
}
void display()
{
if(position == mod_flag)
{
if(k < 100)
{
k++;
}
else if(k >= 100)
{
P0 = sel_chip[position];
P2 = disbuf[position];
}
if(k == 200)
{
k = 0;
}
}
else
{
P0 = sel_chip[position]; //用P0来选片
P2 = disbuf[position]; //用P2来控制数码管的显示
}

if(position == 5)
{
position = 0;
}
else
position++;
}

void T0_int() interrupt 1
{
display();
 TH0 = 0xfd;
TL0 = 0xcc;

}  

void delay1ms(uint time)
{
 uint i;
for(; time > 0; time--)
for(i = 0; i < 333; i++)
{
;
}
}

/*********以下是蜂鸣器响一声函数********/
/*void beep()
{
  BEEP1=0; //蜂鸣器响
  Delay_ms(100); 
  BEEP1=1; //关闭蜂鸣器
  Delay_ms(100);  
}*/

void key_set()
{
if(sel_mod_key == 0)
{
delay1ms(5);
if(sel_mod_key == 0)
{
while(!sel_mod_key);
write_data(0x80,0x80);
write_data(0x8e,0x80);

set_flag = 1;
}
}
if(sel_led_key == 0)
{
delay1ms(5);
if(sel_led_key == 0)
{
while(!sel_led_key);
if(set_flag == 1)
{

//闪烁函数
if(mod_flag == 3)
{
mod_flag = 0;
}
else
{
mod_flag++;
}

}

}
}
if(display_inc_key == 0)
{
uchar a = 0,b = 0;
delay1ms(5);
if(display_inc_key == 0)
{
while(!display_inc_key == 0);
if(set_flag == 1)
{
if(mod_flag == 0)
{
a = time_sbuf[0] >> 4;
b = time_sbuf[0] & 0x0f;
if(a == 2)
{
a = 0;
}
else
{
a += 1;
}
time_sbuf[0] = (a << 4) | b;
}
if(mod_flag == 1)
{
a = time_sbuf[0] >> 4;
b = time_sbuf[0] & 0x0f;
if(b == 9)
{
b = 0;
}
else
{
b += 1;
}
time_sbuf[0] = (a << 4) | b;
}
if(mod_flag == 2)
{
a = time_sbuf[1] >> 4;
b = time_sbuf[1] & 0x0f;
if(a == 5)
{
a = 0;
}
else
{
a += 1;
}
time_sbuf[1] = (a << 4) | b;
}
if(mod_flag == 3)
{
a = time_sbuf[1] >> 4;
b = time_sbuf[1] & 0x0f;
if(b == 9)
{
b = 0;
}
else
{
b += 1;
}
time_sbuf[1] = (a << 4) | b;
}

}


}

}
if(ok_key == 0)
{
delay1ms(5);
if(ok_key == 0)
{
while(!ok_key);
write_data(0x8e,0);
//write_data(write_add[0], time_sbuf[2]);
write_data(write_add[1], time_sbuf[1]);
write_data(write_add[2], time_sbuf[0]); 
write_data(0x80,0);
set_flag = 0;
mod_flag = 3;
}

}


}







[解决办法]
这个网上很多的吧
[解决办法]
定义一个时间变量t,t++,当t等于一个时间值time的时候,对应的数码管就亮,然后t清0,继续t++,当再等于time时,数码管就灭,这样循环的话,就实现闪烁了嘛。呵呵
[解决办法]

探讨

引用:
定义一个时间变量t,t++,当t等于一个时间值time的时候,对应的数码管就亮,然后t清0,继续t++,当再等于time时,数码管就灭,这样循环的话,就实现闪烁了嘛。呵呵
你没看到我也是这样用的么?但是实现不了的!

[解决办法]
人眼识别闪烁的时间至少为30ms左右。
[解决办法]
怎么说呢??我前几周也做过,不过当时想不出,睡了两觉,有空又调调程序,就行了。。。所以的话,这么多天过去了,你应该弄好了吧。。。
要记住自己的失败。。。
[解决办法]
我用FPGA做过类似的实验。
当时我使用的闪烁频率为2Hz。
提供给楼主做参考吧。

热点排行