C语言单片机如果使用键盘改变数码管秒表数据时,如何先使被改变的数据闪烁,然后执行改变数据的加减

89c52的单片机

闪烁其实就是选择哪些部分的数码管先正常显示然后400ms左右再关闭,然后400ms再正常显示。
那么怎么选择这些数码管呢?可有数码管闪烁控制的起始位ID和闪烁长度len就可以了。比如从第1个数码管开始的2个数码管都闪烁显示,就是ID=1,len=2;比如将4个数码管分成时钟和分钟两部分,一个按键选择这些部分,第一次按键是ID=1,len=2选择时钟,第二次按键是ID=3,len=2选择分钟,而且按键也同时使得程序进入了时钟或者分钟修改模块,只要改变时钟数值如12然后将修改值写入数码管显示缓冲就显示了你的修改。如此就完成了你的数码管选择与修改。使用ID=0就停止闪烁功能,也就是你退出设置时钟功能后停止闪烁。对于一个好的数码管显示程序来说是独立的,它只需提供接口就可以(ID、len以及显示缓冲地址)。独立的显示程序监视ID和len,只要ID不为零,那么对应ID以及len所属的数码管就进入到闪烁显示而其他数码管不受影响,在正常显示期间所有数码管都显示,而在关闭期间ID所对应的数码管就关闭显示。
---------------------
#define DPORT P0 //数据输入端口
sbit SEG_LE = P2^0; //段码寄存器锁存端,高电平有效
sbit DIG_LE = P2^1; //位码寄存器锁存端,高电平有效

unsigned char F_ID = 0; //闪动的数码管ID或起始位ID,也作闪动允许控制[0,1-8]
unsigned char F_LEN = 1; //闪动数码管的长度[1-8]
unsigned char D_BUF[ 8 ]; //显示缓存,缓存字形码

unsigned char code NIXIE_CC[ ] = //字形码库
{
0x3f, 0x06, 0x5b, 0x4f, 0x66, //0-4
0x6d, 0x7d, 0x07, 0x7f, 0x6f, //5-9
0x77, 0x76, 0x39, 0x5E, 0x79, 0x71, //A, B, C, D, E, F
0x00, 0x40, 0x38, 0x31, 0x58, 0x08 //OFF, -, L, T, c, _
};

void display( void )
{
static bit EN_FLASH = 0; //闪烁交替控制
static char COUNTER = 0; //闪动时间计时,计数display调用次数从而积累时间
unsigned char i;
unsigned char temp;
unsigned char F_DIG;
unsigned char F_CON;
unsigned char DIGCODE = 0x01;

if( F_ID != 0 )
{
F_DIG = F_ID - 1;
F_CON = F_LEN;
if( ++COUNTER == 35 )
{
COUNTER = 0;
EN_FLASH ~= EN_FLASH;
}
}
else
{
EN_FLASH = 0;
COUNTER = 0;
}

for( i = 0; i != 8; i++ )
{
DIG_LE = 1; DPORT = 0xff; DIG_LE = 0;
SEG_LE = 1; DPORT = D_BUF[ i ]; SEG_LE = 0;
if( EN_FLASH && F_DIG == i )
{
temp = 0xff;
if( --F_CON != 0 ) F_DIG++;
}
else
{
temp = ~DIGCODE;
}
DIGCODE <<= 1;
DIG_LE = 1; DPORT = temp; DIG_LE = 0;
delay1ms( );
}
}
http://hi.baidu.com/worldwill/item/f6eb87bd6d52de4a2aebe32d追问

我的是没有任何别的芯片的 只有单片机

追答

呵呵,只是一个示例。但是原理是类似的。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-11-01
单片机 C语言秒表程序 修改
#include"reg51.h"
unsigned char i,j,m,x,a[4];
unsigned char table1[]={0x01,0x02,0x04,0x08};
unsigned char table2[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
main()
{
TMOD=0x01;
TF0=1;
TR0=1;
IE=0x82;
EX0=1;
m=0;
while(1);
}
timer1() interrupt 1
{
TH0=0x3C;
TL0=0xB0;
i++;
if(i==20)
{
i=0;
m++;
a[3]=m/1000;
a[2]=m/100%10;
a[1]=m/10%10;
a[0]=m%10;
for(j=0;j<4;j++)
{
P0=table1[j];
x=a[j];
P1=table2[x];
}
}
}本回答被网友采纳
第2个回答  2012-11-01
uchar disbuf[4] ; //数码管显示缓存
uchar workstatus = 0;//工作状态:初始化,计时,设置...
uchar giltcom=0;//闪烁位
void display(); //数码管扫描程序,
void scankey(); //按键扫描
void settime(uchar vkey){ //设置时间
switch(vkey){
case 1 : //切换闪烁位
giltcom = (giltcom + 1) % 4;
break;
case 2 ://修改数值
switch(giltcom){
case 0 : break;
case 1 : break;
case 2 : break;
case 3 : break;
}
break;
case 0 ://进入设置初始化
giltcom = 0;
break;
}
}
void getKey(uchar vkey){ //接收按键值
switch(vkey){
case 0 :workstatus = (workstatus + 1)% 2;break;//切换工作状态
case 1 :if(workstatus == 1)settime(1);break;//
case 2 :if(workstatus == 1)settime(2);break;
}
}
void scangilt(){ //扫描闪烁
static uchar n = 0;
uchar i;
if(workstatus == 1){
if(n++ > 50){
n=0;
for(i = 0; i < 4; i++){
if(i == giltcom){
disbuf[i] = 16;//灭
} else {
disbuf[i] = sce;
}
}
}
}
}追问

能qq聊吗?我的1030974250

第3个回答  2012-11-01
这个很简单啊,你就用一个专门的按键来实现闪烁和停止闪烁,另外一个按键来实现数据的加减不就得了?用一个按键来实现又闪烁又加减似乎有点不可能。追问

这我知道 就是怎么实现闪烁和左移不知道怎么编程

追答

.啊?这个很基础的呀。。你要哪个闪烁就单独控制他的对应的片选信号一时高一时低,不要控制的就一直给高不就得了?然后移位这个是C里的知识呀,左移就是<<...不知道你想问什么移位。。