找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5119|回复: 13
收起左侧

0-9999计数器出错

[复制链接]
ID:71991 发表于 2015-1-10 22:00 | 显示全部楼层 |阅读模式
以下程序计数到0002时显示出错显8002,请问各位大虾错在哪里呢?

#include<AT89X51.H>
unsigned char code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
                          0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
unsigned char int_time;
unsigned char second;
unsigned char minute;
void delay(void)
{
unsigned char i;
for(i=0;i<200;i++)
;
}

void DisplaySecond(unsigned char k)
{
P2=0x01; //P2.0 引脚输出低电平, DS6 点亮
P0=table[k/1000]; //显示千位
delay();
P2=0x02; //P2.1 引脚输出低电平, DS7 点亮
P0=table[k%1000/100]; //显示百位
delay();
P2=0x04; //P2.2 引脚输出低电平, DS6 点亮
P0=table[k%100/10]; //显示十位
delay();
P2=0x08; //P2.3 引脚输出低电平, DS7 点亮
P0=table[k%10]; //显示个位
delay();
P2=0x00; //关闭所有数码管
}
void main(void) //主函数
{
TMOD=0x01; //使用定时器T0
TH0=(65536-46083)/256; //将定时器计时时间设定为46083×1.085 微//=50000 微秒=50 毫秒
TL0=(65536-46083)%256;
EA=1; //开启总中断
ET0=1; //定时器T0 中断允许
TR0=1; //启动定时器T0 开始运行
int_time=0; //中断次数初始化
second=0; //秒初始化
while(1)
{
DisplaySecond(second); //调用秒的显示子程序
}
}
     



void interserve(void ) interrupt 1 using 1
{
    TR0=0; //关闭定时器T0
    int_time ++; //每来一次中断,中断次数int_time 自加1
if(int_time==1) //够20 次中断,即1 秒钟进行一次检测结果采样
{
second++; //秒加1
int_time=0; //中断次数清0
}
if(second==9999)
{
second =0; //秒等于9999 就返回0
         
}
TH0=(65536-46083)/256; //重新给计数器T0 赋初值
TL0=(65536-46083)%256;
TR0=1; //启动定时器T0
}

回复

使用道具 举报

ID:67796 发表于 2015-1-10 22:18 | 显示全部楼层
if(int_time==1) //够20 次中断,即1 秒钟进行一次检测结果采样

改为

if(int_time==20 //够20 次中断,即1 秒钟进行一次检测结果采样

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:71991 发表于 2015-1-10 22:40 | 显示全部楼层
exv 发表于 2015-1-10 22:18
if(int_time==1) //够20 次中断,即1 秒钟进行一次检测结果采样

改为

这个地方原来就是20的,我是想让数跑得快一点才改成1的,第一位数经常会显0与8两个数,计数跑到两多又百位就会重新清零。
AZYNUEI{7D{PZPW)4VU[GX6.png
回复

使用道具 举报

ID:67796 发表于 2015-1-10 22:43 | 显示全部楼层
hsanper 发表于 2015-1-10 22:40
这个地方原来就是20的,我是想让数跑得快一点才改成1的,第一位数经常会显0与8两个数,计数跑到两多又百 ...

unsigned char second,最大只能到255
if(second==9999)永远是false
回复

使用道具 举报

ID:71991 发表于 2015-1-11 11:23 | 显示全部楼层
exv 发表于 2015-1-10 22:43
unsigned char second,最大只能到255
if(second==9999)永远是false

修改成unsigned int second之后也是不行,而且错的更加多了。
回复

使用道具 举报

ID:67796 发表于 2015-1-11 11:43 | 显示全部楼层
hsanper 发表于 2015-1-11 11:23
修改成unsigned int second之后也是不行,而且错的更加多了。

unsigned char k,k最大到255

k/1000
k%1000/100

会出问题的

评分

参与人数 1黑币 +5 收起 理由
hsanper + 5 很给力!

查看全部评分

回复

使用道具 举报

ID:71991 发表于 2015-1-11 12:12 | 显示全部楼层
exv 发表于 2015-1-11 11:43
unsigned char k,k最大到255

k/1000

这个地方也修改过,改这后只有个位数是0-9跳,其它的都不正常,这个应该正常应该是跳0002,它就到成8082了



#include<AT89X51.H>

unsigned char code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
                          0x80,0x90};
unsigned char int_time;
unsigned int second;


void delay(void)
{
unsigned char i;
for(i=0;i<200;i++)
;
}

void DisplaySecond(unsigned int k)
{

P2=0x01; //P2.6 引脚输出低电平, DS6 点亮
P0=table[k/1000]; //显示千位
delay();
P2=0x02; //P2.7 引脚输出低电平, DS7 点亮
P0=table[k%1000/100]; //显示百位
delay();
P2=0x04; //P2.6 引脚输出低电平, DS6 点亮
P0=table[k%100/10]; //显示十位
delay();
P2=0x08; //P2.7 引脚输出低电平, DS7 点亮
P0=table[k%10]; //显示个位
delay();
P2=0x00; //关闭所有数码管
}

void main(void) //主函数
{
TMOD=0x01; //使用定时器T0
TH0=(65536-46083)/256; //将定时器计时时间设定为46083×1.085 微//=50000 微秒=50 毫秒
TL0=(65536-46083)%256;
EA=1; //开启总中断
ET0=1; //定时器T0 中断允许
TR0=1; //启动定时器T0 开始运行
int_time=0; //中断次数初始化
second=0; //秒初始化
while(1)
{
DisplaySecond(second); //调用秒的显示子程序

}
}
     
void interserve(void ) interrupt 1 using 1
{
    TR0=0; //关闭定时器T0
    int_time ++; //每来一次中断,中断次数int_time 自加1
if(int_time==20) //够20 次中断,即1 秒钟进行一次检测结果采样
{
int_time=0; //中断次数清0
second++; //秒加1

}
if(second==9999)
{
second =0; //秒等于9999 就返回0

QQ图片20150111121112.png

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:71991 发表于 2015-1-11 12:17 | 显示全部楼层
hsanper 发表于 2015-1-11 12:12
这个地方也修改过,改这后只有个位数是0-9跳,其它的都不正常,这个应该正常应该是跳0002,它就到成8082了 ...

求大神们找下一哪里出错了。谢谢

0-9999原文件与仿真电路.rar

6.65 KB, 下载次数: 49

回复

使用道具 举报

ID:61876 发表于 2015-1-11 15:22 | 显示全部楼层
我个人认为:是楼主的延时时间太短,字符产生鬼影造成的。只要加大延时时间,程序就完全可以正常运行。

评分

参与人数 2黑币 +50 收起 理由
admin + 45 回帖助人的奖励!
hsanper + 5 很给力!

查看全部评分

回复

使用道具 举报

ID:71991 发表于 2015-1-11 15:54 | 显示全部楼层
gaozhaohong 发表于 2015-1-11 15:22
我个人认为:是楼主的延时时间太短,字符产生鬼影造成的。只要加大延时时间,程序就完全可以正常运行。

按兄弟的意见加长延时所有的问题都解决,延时时间太短产生鬼影造成的。
void delay(void)
        {
        unsigned int i;
        for(i=0;i<1500;i++);
        }


谢谢
  gaozhaohong、 exv 两位大哥耐心的指点,谢谢
回复

使用道具 举报

ID:67796 发表于 2015-1-11 17:40 | 显示全部楼层
hsanper 发表于 2015-1-11 15:54
按兄弟的意见加长延时所有的问题都解决,延时时间太短产生鬼影造成的。
void delay(void)
        {

本想让你加几个0xff试试,问题既已解决了,甚好。

这是宋老师写的,你也参考下:


  1. /*
  2. *******************************************************************************
  3. *                     《手把手教你学51单片机(C语言版)》
  4. *                    配套 KST-51 单片机开发板 示例源代码
  5. *
  6. *         (c) 版权所有 2014 金沙滩工作室/清华大学出版社 保留所有权利
  7. *                 获取更多资料请访问金沙滩工作室
  8. *
  9. * 文件名:main.c
  10. * 描  述:第6章 基于中断带消隐的数码管动态显示示例
  11. * 版本号:v1.0.0
  12. * 备  注:详情见第6章6.5节
  13. *******************************************************************************
  14. */

  15. #include <reg52.h>
  16. sbit ADDR0 = P1^0;
  17. sbit ADDR1 = P1^1;
  18. sbit ADDR2 = P1^2;
  19. sbit ADDR3 = P1^3;
  20. sbit ENLED = P1^4;
  21. unsigned char code LedChar[] = {  //数码管显示字符转换表
  22.     0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  23.     0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  24. };
  25. unsigned char LedBuff[6] = {  //数码管显示缓冲区,初值0xFF确保启动时都不亮
  26.     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  27. };
  28. unsigned char i = 0;   //动态扫描的索引
  29. unsigned int cnt = 0;  //记录T0中断次数

  30. void main()
  31. {
  32.     unsigned long sec = 0;  //记录经过的秒数
  33.     EA = 1;       //使能总中断
  34.     ENLED = 0;    //使能U3,选择控制数码管
  35.     ADDR3 = 1;    //因为需要动态改变ADDR0-2的值,所以不需要再初始化了
  36.     TMOD = 0x01;  //设置T0为模式1
  37.     TH0  = 0xFC;  //为T0赋初值0xFC67,定时1ms
  38.     TL0  = 0x67;
  39.     ET0  = 1;     //使能T0中断
  40.     TR0  = 1;     //启动T0
  41.    
  42.     while (1)
  43.     {
  44.         if (cnt >= 1000)  //判断T0溢出是否达到1000次
  45.         {
  46.             cnt = 0;      //达到1000次后计数值清零
  47.             sec++;        //秒计数自加1
  48.             //以下代码将sec按十进制位从低到高依次提取并转为数码管显示字符
  49.             LedBuff[0] = LedChar[sec%10];
  50.             LedBuff[1] = LedChar[sec/10%10];
  51.             LedBuff[2] = LedChar[sec/100%10];
  52.             LedBuff[3] = LedChar[sec/1000%10];
  53.             LedBuff[4] = LedChar[sec/10000%10];
  54.             LedBuff[5] = LedChar[sec/100000%10];
  55.         }
  56.     }
  57. }
  58. /* 定时器0中断服务函数 */
  59. void InterruptTimer0() interrupt 1
  60. {
  61.     TH0 = 0xFC;  //重新加载初值
  62.     TL0 = 0x67;
  63.     cnt++;       //中断次数计数值加1
  64.     //以下代码完成数码管动态扫描刷新
  65.     P0 = 0xFF;   //显示消隐
  66.     switch (i)
  67.     {
  68.         case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;
  69.         case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;
  70.         case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;
  71.         case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;
  72.         case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;
  73.         case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;
  74.         default: break;
  75.     }
  76. }
复制代码


评分

参与人数 1黑币 +3 收起 理由
hsanper + 3 赞一个!

查看全部评分

回复

使用道具 举报

ID:18297 发表于 2015-1-11 20:38 | 显示全部楼层
各位:其实这个重影产生的原因根本不是延时程序的问题。
原来的程序:
P2=0x01; //P2.6 引脚输出低电平, DS6 点亮
P0=table[k/1000]; //显示千位
delay();
应该改为:
P2=0x00;              //关闭所有的位选
P0=table[k/1000]; //显示数据输出
P2=0x01;             //开启新的位选
delay();
一个道理:在动态数码管显示的程序中,必须:
先关闭所有位选,再输出数据,最后开启新的位选。
这样才能不会出现重影,只是更改延时程序,仿真时由于软件显示原因,没有看到重影,但是实际电路又会出现重影的。

请看附件更新后的程序,不会出现重影,延时不变。

0-9999仿真-去显示重影.rar

16.47 KB, 下载次数: 56

评分

参与人数 2黑币 +55 收起 理由
hsanper + 5 赞一个!
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:61876 发表于 2015-1-12 14:55 | 显示全部楼层
zjjhtony 发表于 2015-1-11 20:38
各位:其实这个重影产生的原因根本不是延时程序的问题。
原来的程序:
P2=0x01; //P2.6 引脚输出低电平, ...

高论!!!佩服!!!!
回复

使用道具 举报

ID:71991 发表于 2015-1-13 22:35 | 显示全部楼层
zjjhtony 发表于 2015-1-11 20:38
各位:其实这个重影产生的原因根本不是延时程序的问题。
原来的程序:
P2=0x01; //P2.6 引脚输出低电平, ...

多谢指点,又发现个新的误区值得学习。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表