找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3757|回复: 8
收起左侧

利用单片机T1产生定时时钟,控制8个LED循环点亮,闪动频率为10次/s

[复制链接]
ID:630579 发表于 2019-10-28 19:44 | 显示全部楼层 |阅读模式
30黑币
我不是很理解T1中断服务函数处的代码,整个代码是这样的:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
sbit LSA=P1^5;                  //LED位选译码地址引脚A
sbit LSB=P1^6;
sbit LSC=P1^7;

uchar tmp;           //临时变量
uchar sec;
void main(void)
{
LSA=0;               
LSB=0;
LSC=0;
TMOD=0x01;          //设置定时器T0工作于方式1
EA=1;                 //全局中断允许
ET1=1;
TR1=1;
TH1=-18432/256;  //定时器初值
TL1=-18432%256;
P0=0xfe;
tmp=P0;
while(1);                 //循环
}
void Timer1(void) interrupt 3
{   
TH1=-18432/256;
TL1=-18432%256;
sec++;               
if(sec==2)
{
  sec=0;
  tmp=_crol_(tmp,1);  //循环左移一位
  P0=tmp;
}
}

整个代码是这样,但是if(sec==2)不理解,是怎么实现10次/s的。求大佬解答!

最佳答案

查看完整内容

代码有问题,sec就没有赋初值。如果if(sec==2)是正确的,那么代表定时器T1是一个50ms的定时器,刚好2次进入中断处理函数void Timer1(void)后,耗时是100ms,也就是10次/s。 但是假设是11.0592MHz的晶振,一个机器周期=1/11.0592/12=1.08507us 20*1000/1.08507=18432,也就是定时器T1是20毫秒的。所以应该是 if(sec==5) 另外这条语句也要改下: uchar sec; uchar sec = 0;
回复

使用道具 举报

ID:631729 发表于 2019-10-28 19:44 | 显示全部楼层
代码有问题,sec就没有赋初值。如果if(sec==2)是正确的,那么代表定时器T1是一个50ms的定时器,刚好2次进入中断处理函数void Timer1(void)后,耗时是100ms,也就是10次/s。

但是假设是11.0592MHz的晶振,一个机器周期=1/11.0592/12=1.08507us
20*1000/1.08507=18432,也就是定时器T1是20毫秒的。所以应该是

if(sec==5)

另外这条语句也要改下:
uchar sec;
uchar sec = 0;
回复

使用道具 举报

ID:631355 发表于 2019-10-28 22:11 | 显示全部楼层
每10ms中断一次TL1=(65536-10000)%256;//每10ms中断一次ET1=1;EA=1;TR1=1;}2.中断程序:voidTimer1()interrupt3{TH1=(65536-10000)/256;TL1=(65536-10000)%256;if(++count>10)//每次中断count计数一次,当计数到10,说明100ms到{count=0;P1=_corl_(num,1);}}
回复

使用道具 举报

ID:631355 发表于 2019-10-28 22:14 | 显示全部楼层
if(sec==2)%为求余运算符,例如i%j用来求i除以j的余数。特别地,当使用i%j==0时,用来判断i是否能被j整除(余数为0表示被除数能被除数整除)。对于你的问题,结合条件语句if,则表示“如果i能被2整除”。

评分

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

查看全部评分

回复

使用道具 举报

ID:411550 发表于 2019-10-28 23:11 | 显示全部楼层
sec==2就是你定时器设定时间再乘上二

评分

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

查看全部评分

回复

使用道具 举报

ID:235200 发表于 2019-10-28 23:32 | 显示全部楼层
要达到每秒10次,即每100ms切换1位LED,用TH1=-18432/256;TL1=-18432%256;定时50ms(不能直接定时100ms),所以计数2次达100ms
回复

使用道具 举报

ID:213173 发表于 2019-10-29 08:09 | 显示全部楼层
void Timer1(void) interrupt 3
{   
        TH1=-18432/256;//等同(65536-18432)/256; 11.0592MHz,定时20ms
        TL1=-18432%256;
        sec++;               
        if(sec==2)//测试等于符号==,与赋值符号=性质不同,测试sec是否为2
        {
          sec=0;
          tmp=_crol_(tmp,1);  //40ms循环左移一位
          P0=tmp;
        }
}

评分

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

查看全部评分

回复

使用道具 举报

ID:332444 发表于 2019-10-29 08:49 | 显示全部楼层
每秒频闪10次=1000/10=100毫秒,计算中断赋值,用累计的算式,如果累计到2,那么这个中断赋值应该是50毫秒,如果不是50毫秒调整到50毫秒即可.

评分

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

查看全部评分

回复

使用道具 举报

ID:630579 发表于 2019-11-3 20:01 | 显示全部楼层
csmyldl 发表于 2019-10-28 23:32
要达到每秒10次,即每100ms切换1位LED,用TH1=-18432/256;TL1=-18432%256;定时50ms(不能直接定时100ms),所以 ...

-18432设置的好像是20ms的
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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