单片机写集成式单片机数码管动态显示扫描显示程序时出现了三个未定义的错误,谁知道怎没修改吗?

查看: 792|回复: 0
从写ADC0804程序中发现的一个关于数码管动态扫描的问题
以前我写过一个电子时钟程序,动态扫描里面使用了这样的代码序列:
P2 = 0& &&&// 先关闭所有数码管
P2 = dis_& &&&// | LEDMASK;& &
P0 = dis_buf[dis_index];& &// 从第0个数码管开始,即最左边开始
由于每个数码管都有数字要显示,没发现有什么问题.
但是今天写ADC0804程序时应用这个动态扫描函数却发现了一点问题,
那就是我不想显示的数码管一直都显示着一个模糊的数字,并且跟它往前相邻的数字一样.
猜测和调试了很久,最后才发现问题出在代码的执行顺序上.
正确的代码执行序列应该是关灯后立刻把内容准备好,再开灯,这样才能没有副作用.
所以对P0的赋值要夹在对P2的两次赋值之间.
电子时钟.c
/*逻辑已经修改清晰,使用时分秒三个变量独立处理,并配有相应函数*/
#include &reg51.h&
#include &intrins.h&
#define PUSH(Key)&&!Key& &//XL600都是按下为低电平的,高电平时作为输入
#define LEDMASK& &0x24& &//&&---&&1的地方不亮
#define MIDDLINE&&10
#define BALCK& &11
#define ISKEY(pos)&&(key & (1 && pos))& && &//检测是第几个按键,从0开始起
sbit KeyPP&&= P3 ^ 2;& && & //Key Play and Pause
sbit KeyHourAdd = P3 ^ 3;& && & //Key Hour Add
sbit KeyMinAdd = P3 ^ 4;& && & //Key Min Add
//sbit KEYSET&&= P3 ^ 5;
enum { KEYPP = 0, KEYHOURADD = 1, KEYMINADD = 2, KEYSET = 3};
unsigned char code Led7Tab[12] = { 0x28, 0x7E, 0xA2, 0x62, 0x74, //0 1 2 3 4
& && &&&0x61, 0x21, 0x7A, 0x20, 0x60,& && & //5 6 7 8 9
& && &&&0xF7,& & //中间短横线& & MIDDLINE
& && &&&0xFF};& & //不显示,全黑& &BALCK
unsigned char dis_buf[8], hour, min, sec,
void clr_time();
void timetick();&&
void& & UpdateTime();& && &
void delayms(unsigned char ms);
void proc_key(unsigned char key);& &
void PART2LED(unsigned char part, unsigned char pos);& &
void ToThenCarry(unsigned char *src, unsigned char top, unsigned char *dest);
unsigned char scan_key();
void main(void)
TMOD = 0x01;& && &&&
TH0 = 0xFC;
TL0 = 0x17;
IE = 0x82;&&
clr_time();& && && && && && && && && && &&&
&&if(scan_key() != 0)
& &delayms(10);
& &if((key = scan_key()) != 0)
& &{& && && && && && && && && &
& & while(scan_key() != 0)
& & proc_key(key);
&&else if(start)
& && &timetick();
}& && && && && && && && && && && && && && && && && && &
unsigned char scan_key()
unsigned char key = 0, keyP& && && &//由于按键类型是sbit,不可以成为&&运算符的左值,
& && && && && && && && && && && && && && && &&&//故将其装换为新的unsigned char变量,然后移位
key |= (keyPos= ~KeyPP) && 0;& && && &
key |= (keyPos= ~KeyHourAdd) && 1;& &
key |= (keyPos= ~KeyMinAdd) && 2;& && &
//这里就可以扩展以后的按键了
return (key);
}& && && && && && && && && && && && && &
void proc_key(unsigned char key)
if(ISKEY(KEYPP))
& &&&start = !
else if(ISKEY(KEYHOURADD))
& &&&if(hour == 24)
&&hour = 0;
& &&&UpdateTime();
& && &&&else if(ISKEY(KEYMINADD))
& &&&if(min == 60)
&&min = 0;
& &&&UpdateTime();
}& && && && && && && && && && && && && && && && && &
}& && && && && && && && && && && && && && && && &
void clr_time()& && && &//全部清零
& & hour = min = sec = 0;
& & dis_buf[2] = dis_buf[5] = Led7Tab[MIDDLINE];
& & UpdateTime();
void UpdateTime()
& & PART2LED(hour, 1);
& & PART2LED(min,&&4);
& & PART2LED(sec,&&7);
void PART2LED(unsigned char part, unsigned char pos)
& & dis_buf[pos] = Led7Tab[part % 10];
& & dis_buf[pos - 1] = Led7Tab[(part / 10)];
void ToThenCarry(unsigned char *src, unsigned char top, unsigned char *dest)
& & if(*src &= top)
++(*dest);
void timetick()& && &
& & delayms(255);
& & ToThenCarry(&sec, 60, &min);
& & ToThenCarry(&min, 60, &hour);
& & if(hour == 24)
clr_time();
& & UpdateTime();
& & dis_buf[2] = dis_buf[5] ^= 0x08;& && &//技巧:F7 -- FF 互变,用
void Display() interrupt 1& && & //动态扫描显示数码管,放在中断里就是最好的方案,搞得我想了半天其它方法
& && &&&static unsigned char data dis_digit = 0xFE;& &&&// P2的二进制掩码选通第几个数码管,从0位即最左边扫描起
static unsigned char dis_index& &&&= 0;&&//& &逻辑第几个数码管
TH0 = 0xFC;
TL0 = 0x17;
P2 = 0& &&&// 先关闭所有数码管
P0 = dis_buf[dis_index];& &// 从第0个数码管开始,即最左边开始
& && & //&&P0的赋值要夹在这中间,也就是紧跟在灯全灭之后,
& && & //&&否则,它会模糊地显示上一个数字,即它之前的那个数字,
& && & //&&这个bug直到今天写ADC0804程序才发现.
& && & //& &Apr. 4, 2009
P2 = dis_& &
dis_digit = _crol_(dis_digit, 1);&&// 循环左移
dis_index++;& &
dis_index &= 0x07;& & // 技巧:& & 掩码:0111,当1000时变成0&&
}& && && && && && && && && && && && && && && && && && && &
void delayms(unsigned char ms)
& & while(--ms)
for ( i = 0; i & 320; i++)
#include &..\mcu.h&
#define ADCDATA P1
sbit ADC0804_WR = P3 ^ 6;
sbit ADC0804_RD = P3 ^ 7;
unsigned char dis_buf[8];
void Number2Led(unsigned char number);
void ClearDisplay(void);
void main(void)
& & TMOD = 0x02;
& & TH0 = 0xF0;
& & TL0 = 0xF0;
& & IE = 0x82;&&
& & TR0 = 1;& && && &
& & ADCDATA = 0xFF;
& & ClearDisplay();
& & while(1)
ADC0804_WR = 0;
ADC0804_WR = 1;
ADC0804_RD = 1;
ADC0804_RD = 0;
value = ADCDATA;
Number2Led(value);
void Number2Led(unsigned char number)
& & unsigned char i,
& & i = 7;
& & while(1)
dis_buf = LED7TAB[number % 10];
if(number & 10)
& &&&number /= 10;
& & for(j = 1; j &= j++)
dis_buf[j] = 0xFF;
void Display() interrupt 1& && & //动态扫描显示数码管,放在中断里就是最好的方案,搞得我想了半天其它方法
& && &&&static unsigned char dis_digit& &&&= 0xFE;& &&&// P2的二进制掩码选通第几个数码管,从0位即最左边扫描起
static unsigned char dis_index& &&&= 0;&&//& &逻辑第几个数码管
P2 = 0& &&&// 先关闭所有数码管
P0 = dis_buf[dis_index];& &// 从第0个数码管开始,即最左边开始
P2 = dis_& &&&// | LEDMASK;& &
dis_digit = _crol_(dis_digit, 1);&&// 循环左移
dis_index++;& &
dis_index &= 0x07;& & // 技巧:& & 掩码:0111,当1000时变成0&&
}& && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && &&&
void ClearDisplay(void)
& & for(index = 0; index & 8; index++)
dis_buf[index] = 0xFF;
Powered by[实验二]数码管动态扫描显示及外部中断的使用_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
[实验二]数码管动态扫描显示及外部中断的使用
上传于||文档简介
&&华​东​师​大​A​V​R​实​验​报​告​整​理​版​,​自​己​编​写​,​有​误​欢​迎​纠​错​!
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
你可能喜欢单片机数码管显示问题_百度知道
单片机数码管显示问题
wela=1;}void T1_miaobiao() interrupt 3{ TH1=()/j--); for(i=}void main(){ TMOD=0x10,bai,即最后一位显示1%秒:#include&i--)
for(j=110; dula=1用动态扫描方法和定时器1在数码管的前三位显示出秒表,0x6f; bai=num&#47,精确到1%秒,请问各位高手; }void display(uint num){ ET1=1; num++; ge=num%100; P0=0xfb,0x7f,num1; EA=1; dula=0;0。程序如下; P0=0 P0=table[shi],0x39;sbit wela=P2^7;void delay(uint ms){ delay(1),0x4f; P0=0 dula=1;256; P0=0xfd,0x71},0x06; while(1) {display(num); TH1=()/ TR1=1; dula=0;reg52; P0=0100; shi=num&#47,0x66;0,0x7c,0x07,其余正常; P0=table[ge].h&gt, delay(1); wela=0,0x6d; P0=table[bai]; wela=0,0x79;#define uint unsigned int #define uchar unsigned char256,0x5e; wela=1; TL1=()%256;
dula=1;sbit dula=P2^6; }}编译之后运行结果为百分位显示断断续续; if(num==1000) num=0; wela=1,时钟频率为11; P0=0xff,0x5b; dula=0,这是怎么回事啊;i&gt,j; wela=0,0x7d;uchar code table[]={0x3f;j&gt,一直循环下去.; delay(1); TL1=()%256,0x77
提问者采纳
对num加一: ge=num%100;
&#47,应该是;//中断100次;/
}}&#47。计时的修改如下,中断一次.
if(num == 1000) num = 0,无法正常观看;这时再让num加一: ge=num%10;
/------------另外,才是1s
num1 = 0; 不对; TL1=()%256; if(num1==100) {
/ num1++;256:void T1_miaobiao() interrupt 3{ TH1=()/&#47原程序设置的是10ms,这个速度太快了;
num++,加到100
提问者评价
多谢啦,找了半天,原来是个位写错了,呵呵
其他类似问题
8人觉得有用
为您推荐:
您可能关注的推广
数码管显示的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁单片机数码管显示的程序有错误详情看问题补充_百度知道
单片机数码管显示的程序有错误详情看问题补充
P0=0 &reg52;P0=0shanshuo(1500);#define&nbsp.jpg" target="_blank" title="点击查看大图" class="ikqb_img_alink"><img class="ikqb_img" src="=&nbsp.P2_0&nbsp://b;table[]={0xc0;P2_0&=&nbsp,0x99;&nbsp,j,0x80. &uchar&code& &j&&uint&nbsp,0xb0;unsigned& &P2_/zhidao/wh%3D600%2C800/sign=c4e92ebf80cb39dbc251c/3b292df5e0fe535a85edf8db17156;shanshuo(1500); &nbsp.jpg" esrc="0;P2_0& &&nbsp://b.hiphotos,0x90},0x82;uchar& &nbsp.jpg" />这是原理图#include&1.baidu.h& &unsigned&nbsp,0xf9;main(){while(1){&shanshuo(uint&P0=table[1].com/zhidao/wh%3D450%2C600/sign=4b4bafe043e93300cacafb/3b292df5e0fe535a85edf8db17156;int#define&&&P2_/zhidao/pic/item/3b292df5e0fe535a85edf8db17156;char&for(i=}}我要的显示效果是显示第一个数码管&=&&nbsp<a href="}void&i&=&0;&nbsp. &uint&&i--)&=&1.5秒在0和1之间变换但是实际上四个都亮但是只有第一个是最大亮度&nbsp://b;&nbsp,0xa4;&&xms)& &for(j=110,0x92;P0=table[0];void&0;i;&j--);P2^0;{&nbsp.sbit&nbsp,0xf8;0;然后每1; &nbsp
uchar code table[]={0xc0;0;j--);j&i--)
for(j=110; delay(1500); delay(5);
P0=0xff,0xb0;
P2_0=1,0xf9#include & delay(5).h&i&gt,0xf8;
P2_2=1;}void main(){while(1){
P0=table[0];for(i= P0=0xff,0x92,0xa4;void delay(uint xms)
sbit P2_1 = P2^1; delay(5);
delay(5);#define uint unsigned int#define uchar unsigned char sbit P2_0 = P2^0,0x90},0x99;sbit P2_3 = P2^3; P0=table[1];reg52;0;
delay(5); delay(1500),j;sbit P2_2 = P2^2; P2_3=1,0x82,0x80
提问者采纳
shanshuo(5),0xb0#include & shanshuo(1500).h&0,0x80;while(1){
P2_0 = 0; P0=table[1];j&0;i&}void main(){P2=0xff,0x82,0x99,j;uchar code table[]={0xc0; shanshuo(5); shanshuo(1500);#define uint unsigned int#define uchar unsigned char sbit P2_0 = P2^0;void shanshuo(uint xms)
uint i,0x92,0xa4; P0=table[0];reg52,0xf9; P0=0for(i=xms,0x90},0xf8; P0=0j--);i--)
这样还是有鬼影
提问者评价
来自团队:
其他类似问题
8人觉得有用
为您推荐:
其他2条回答
要关掉其它数码管。最后提点建议,另其控制IO为1不就得了。void main(){P2=0xff、增强驱动三极管抗扰能力。解决方法。这很大程度上能避免鬼影产生; shanshuo(1500),会有鬼影产生除了程序问题外; shanshuo(1500):1。PNP可在基极与VCC之间接10K左右上拉电阻,不要使用太多飞线好奇怪、布线合理;}}此外,但编程无国界,电路也是很重要的,子程序或变量命名不要采用中文拼音的形式啦。像采用扫描方式驱动LED数码管的; P0=table[1],虽然我们是中国人,并且不要把飞线缠在一起。2。NPN型三极管可在基极与地之间接10K左右下拉电阻!看得好辛苦,布线也会有串扰现象,你显示第一个数码管一直让P2_0=0不就得了,还是与国际接轨好;P2_0=0;while(1){
P0=table[0]
这样还是有鬼影 不知道难道是单片机本身问题
如果按我的程序都还会有鬼影,应该就是线间串扰的结果。你是不是用万用板搭的电路?三极管上拉做好没?先不要闪烁显示,先稳定显示试试。
是不是for太短了,
您可能关注的推广
数码管显示的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁

我要回帖

更多关于 单片机数码管电路图 的文章

 

随机推荐