找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1224|回复: 9
打印 上一主题 下一主题
收起左侧

单片机计数器的问题,累计达到1000后,led显示加一 有程序看不懂,详细在文章里面

[复制链接]
跳转到指定楼层
楼主
ID:974245 发表于 2022-1-4 09:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
案例:基于CD4511的两位数显示脉冲计数器
计数器T0,工作方式0,对外部脉冲进行计数,当外部脉冲数量达到1000后,LED显示加一。
我就不太懂那个程序“外部脉冲数量达到1000后,LED显示加一”,是怎么加到1000的。
是这段程序吗?
void Counter0(void){
if(TF0==1){
TF0=0;
/*计数器初值设置*/
TH0=0xe0;
TL0=0x18;
counter++;
if(counter>=99){
counter=0;
}
}
}


还有这个也看不懂,返回函数是什么?
//显示函数
void disply(unsigned char BCD){
unsigned char x,y;//定义x,y两个变量
x=BCD%10;//取i的个位字符BCD编码放于x中
y=BCD/10;//取i的十位字符BCD编码放于y中

y<<=4;//x左移4位
data_buf=y|x;//返回各位与十位的组合BCD编码并送至P2口显示

}


总程序如下:(心态崩了看不懂,求大佬指点)
  1. #include <reg51.h>
  2. void Counter0(void);
  3. void Counter_Init(void);
  4. void disply(unsigned char BCD);
  5. sfr data_buf=0xA0;//显示数据端口
  6. unsigned char counter;//全局变量,用于保存计数值
  7. void main()
  8. {
  9.         counter=0;
  10.         Counter_Init();
  11.         while(1){
  12.                 Counter0();
  13.                 disply(counter);
  14.         }
  15.         
  16. }

  17. void Counter_Init(void){
  18.         TMOD=0x04;//工作方式的设置
  19.         /*计数器初值设置*/
  20.         TH0=0xe0;//初始值设置,7192转为13位后的高8位
  21.         TL0=0x18;//初始值设置,7192转为13位后的低8位
  22.         /*关闭计数器中断*/
  23.         EA=0;
  24.         ET0=0;
  25.         /*启动计数器*/
  26.         TR0=1;//启动T0

  27. }

  28. void Counter0(void){
  29.         if(TF0==1){
  30.                 TF0=0;
  31.                 /*计数器初值设置*/
  32.                 TH0=0xe0;
  33.                 TL0=0x18;
  34.                 counter++;
  35.                 if(counter>=99){
  36.                         counter=0;
  37.                 }
  38.         }
  39. }

  40. //显示函数
  41. void disply(unsigned char BCD){
  42.         unsigned char x,y;//定义x,y两个变量
  43.         x=BCD%10;//取i的个位字符BCD编码放于x中
  44.         y=BCD/10;//取i的十位字符BCD编码放于y中
  45.         
  46.         y<<=4;//x左移4位
  47.         data_buf=y|x;//返回各位与十位的组合BCD编码并送至P2口显示
  48.         
  49. }
复制代码





分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:8222 发表于 2022-1-4 13:50 | 只看该作者
void Counter_Init(void){
        TMOD=0x04;//工作方式的设置
        /*计数器初值设置*/
        TH0=0x1c;//初始值设置,7192转为13位后的高8位
        TL0=0x18;//初始值设置,7192转为13位后的低8位
        /*关闭计数器中断*/
        EA=0;
        ET0=0;
        /*启动计数器*/
        TR0=1;//启动T0

}

这红色地方错了。原理是计数到1000,TF0=1,counter就加1。13位的计数器计数范围为8192,计数1000,需要预置7192,十六进为0x1C18。
回复

使用道具 举报

板凳
ID:887371 发表于 2022-1-4 14:08 | 只看该作者
楼主是对定时器的工作模式0不理解,百度搜索下。
我简单说下:
T0的值(TH0*32+TL0%32),当定时器用时,每经过一个时钟,该值加1.当计数器用时,每收到一个脉冲,该值加1.当值等于8192时,产生中断,TF0自动置1.

楼主程序中
  1. TH0=0xe0;//TH0=7192/32;
  2. TL0=0x18;//TL0=7192%32;
复制代码

7192+1000=8192,所以是脉冲数量到1000,产生中断。
假如定时器初值为(8192-100),那么是脉冲数量到100,产生中断。
假如定时器初值为0,那么是脉冲数量到8192,产生中断。
回复

使用道具 举报

地板
ID:887371 发表于 2022-1-4 14:15 | 只看该作者
温xyz 发表于 2022-1-4 13:50
void Counter_Init(void){
        TMOD=0x04;//工作方式的设置
        /*计数器初值设置*/

红色地方没错,13位和16位计算方法不同。
请参考3楼帖子。
回复

使用道具 举报

5#
ID:974245 发表于 2022-1-4 15:42 | 只看该作者
datouyuan 发表于 2022-1-4 14:08
楼主是对定时器的工作模式0不理解,百度搜索下。
我简单说下:
T0的值(TH0*32+TL0%32),当定时器用时,每 ...

好的谢谢您,我再理解理解
回复

使用道具 举报

6#
ID:844772 发表于 2022-1-4 17:24 | 只看该作者
真是不懂13位的时候,为啥这么设计呢:TH的高8位,TL的低5位的计数值
回复

使用道具 举报

7#
ID:624769 发表于 2022-1-4 20:04 | 只看该作者
glinfei 发表于 2022-1-4 17:24
真是不懂13位的时候,为啥这么设计呢:TH的高8位,TL的低5位的计数值

好处是, 32个周期之后, TH就会加1,对于不开中断,判断时间间隔来讲,只要读取TH,就能得到一个比较好的时间间隔宽度,在单片机速度比较慢,比较追求效率的时代,13位定时器有着得天独厚的优势。
回复

使用道具 举报

8#
ID:844772 发表于 2022-1-5 08:41 | 只看该作者
188610329 发表于 2022-1-4 20:04
好处是, 32个周期之后, TH就会加1,对于不开中断,判断时间间隔来讲,只要读取TH,就能得到一个比较好 ...

原来是这样,还想着是原始芯片某种设计限制造成的。
回复

使用道具 举报

9#
ID:887371 发表于 2022-1-6 10:13 | 只看该作者
glinfei 发表于 2022-1-4 17:24
真是不懂13位的时候,为啥这么设计呢:TH的高8位,TL的低5位的计数值

单片机的AD也是类似设计。
高8位AD占用一个字节,10位AD的低2位,12位AD的低4位占用一个字节。
如需要8位精度只需读高8位,提高了效率。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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