额,不好意思,复制错代码了,我贴一下中断的代码,这段代码说是解决了之前第一段代码的抖动问题,但是我觉得利用中断也就是下面这段代码会有我上面说的疑问:当cnt=1000时也就是到了1s时,执行循环中的if语句,当中断触发时进入中断也就是1s+1ms时,执行switch动态刷新数码管程序,但是跳出去时,LedBuff[5]这个数组没有计算完,我调试了代码发现这段32位整型数的除法运算程序运行时长长达6.8ms,也就是当到1s时sec++,然后开始计算那6行32位运算,需要6.8ms,但是6.8ms还没到还没算完时在1s+1ms时触发中断,进入switch给P0赋值,那么进入中断时P0的值没有更新到那6行32位运算完的值岂不是会有数码管秒数显示错误?但是,我把代码下载到单片机里面,却没有显示错误,显示是正确的,只不过我发现单片机的1s要更快,大概单片机上过了60s时,电脑上过了61s.所以疑问:按理来说第二段代码解决了抖动但应该会有数码管显示错误,但是下载到单片机上显示没有任何问题,只是时间上有点不准,不知道为什么显示会没有问题,应该是第7个ms那6行运算全部计算完之后P0的赋值才应该是sec++后的正确秒数啊?难道原因是7个ms也就是刷新完一轮数码管的时间太短暂了,把错误的秒数显示出来肉眼看不到吗,麻烦各位大佬再帮我看一下,小弟初学乍道,劳烦各位了
- #include <reg52.h>
- //数码管显示字符转换表
- unsigned char code LedChar[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; //0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71
- unsigned char LedBuff[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //数码管显示缓冲区,初值 0xFF 确保启动时都不亮
- unsigned char code wei[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; //数码管各位的码表
- unsigned char i = 0; //动态扫描的索引
- unsigned int cnt = 0; //记录 T0 中断次数
- //sbit dula=P2^6; //段选信号的锁存器控制
- sbit wela=P2^7; //位选信号的锁存器控制
- void main()
- {
- unsigned long sec = 0; //记录经过的秒数
- EA = 1; //使能总中断
- ET0 = 1; //使能 T0 中断
- TMOD = 0x01; //设置 T0 为模式 1
- TH0 = 0xFC; //为 T0 赋初值 0xFC67,定时 1ms
- TL0 = 0x67;
- TR0 = 1; //启动 T0
- while (1)
- {
- if (cnt == 1000) //判断 T0 溢出是否达到 1000 次
- {
- sec++; //秒计数自加 1
- //以下代码将 sec 按十进制位从低到高依次提取并转为数码管显示字符
- LedBuff[0] = LedChar[sec%10];
- LedBuff[1] = LedChar[sec/10%10];
- LedBuff[2] = LedChar[sec/100%10];
- LedBuff[3] = LedChar[sec/1000%10];
- LedBuff[4] = LedChar[sec/10000%10];
- LedBuff[5] = LedChar[sec/100000%10];
- cnt = 0; //达到 1000 次后计数值清零
- } //以下代码完成数码管动态扫描刷新
- }
- }
- /* 定时器 0 中断服务函数 */
- void InterruptTimer0() interrupt 1
- {
- TH0 = 0xFC; //重新加载初值
- TL0 = 0x67;
- cnt++; //中断次数计数值加 1
- //以下代码完成数码管动态扫描刷新
- P0 = 0x00; //显示消隐
- switch (i)
- {
- case 0: wela=0;P0=wei[5];wela=1;wela=0;i++;P0=LedBuff[0]; break;
- case 1: wela=0;P0=wei[4];wela=1;wela=0;i++;P0=LedBuff[1]; break;
- case 2: wela=0;P0=wei[3];wela=1;wela=0;i++;P0=LedBuff[2]; break;
- case 3: wela=0;P0=wei[2];wela=1;wela=0;i++;P0=LedBuff[3]; break;
- case 4: wela=0;P0=wei[1];wela=1;wela=0;i++;P0=LedBuff[4]; break;
- case 5: wela=0;P0=wei[0];wela=1;wela=0;i=0;P0=LedBuff[5]; break;
- default: break;
- }
- }
复制代码 |