请选择 进入手机版 | 继续访问电脑版

 找回密码
 立即注册
搜索
查看: 535|回复: 16

刚开始学51关于定时器中断的一些问题有些不清楚求教

[复制链接]

1

主题

8

帖子

31

积分

新手上路

Rank: 1

积分
31
发表于 2021-7-10 14:58:56 | 显示全部楼层 |阅读模式
#include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;          //对数据类型进行声明定义
typedef unsigned char u8;
void yanshi(long i);
sbit led=P2^0;         //定义P20口是led
sbit k1=P3^1;
sbit led2=P2^4;

void Timer0Init()
{
        TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。

        TH0=0XFC;        //给定时器赋初值,定时1ms
        TL0=0X18;       
        ET0=1;//打开定时器0中断允许
        EA=1;//打开总中断
        TR0=1;//打开定时器                       
}


void main()
{       
while(1){led2=~led2;yanshi(5000); Timer0Init();}       
                               
}


void Timer0() interrupt 1
{
        static u16 i;
        TH0=0XFC;        //给定时器赋初值,定时1ms
        TL0=0X18;
        i++;
        if(i==1000)
        {
                i=0;
                led=~led;
                       
        }       
}
void yanshi(long i)
{while(i--);}

在写入这个程序后led与led2能够同时闪烁,定时器中断后不应该在运行void timer0这个函数吗,看效果好像又没起到中断效果。
但是我在led=~led后面加了一个yanshi(1);能达到中断效果,但是回不到主程序,led2就刚开始闪几次就没反应了这是为什么呢。

回复

使用道具 举报

3

主题

19

帖子

125

积分

注册会员

Rank: 2

积分
125
发表于 2021-7-11 16:48:23 | 显示全部楼层
定时器初始化应该放在while外面

点评

海!外直播 cutt.us/v44 禁闻视频 v.ht/ddzz 一个社会如果只能靠删除不同看法去维护统一思想的宣传,那就证明这个思想宣传已经到了弱不经风的程度了。看这个就知道..  发表于 2021-7-11 17:16
回复 支持 反对

使用道具 举报

1

主题

8

帖子

31

积分

新手上路

Rank: 1

积分
31
 楼主| 发表于 2021-7-12 09:10:53 | 显示全部楼层
hoodieboi 发表于 2021-7-11 16:48
定时器初始化应该放在while外面

#include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;          //对数据类型进行声明定义
typedef unsigned char u8;
void yanshi(long i);
sbit led=P2^0;         //定义P20口是led
sbit k1=P3^1;
sbit led2=P2^4;
sbit led3=P2^1;
sbit led4=P2^2;
sbit led5=P2^3;
static u16 i;

void Timer0Init()
{
        TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。

        TH0=0XFC;        //给定时器赋初值,定时1ms
        TL0=0X18;       
        ET0=1;//打开定时器0中断允许
        EA=1;//打开总中断
        TR0=1;//打开定时器                       
}


void main()
{Timer0Init();       
while(1){led2=~led2;yanshi(5000); }       
                               
}


void Timer0() interrupt 1
{
        static u16 i;
        TH0=0XFC;        //给定时器赋初值,定时1ms
        TL0=0X18;
        i++;
        if(i==1000)
        {
               
                led=~led;
        }       
        if(i==2000)
        {i=0;
        led=~led;
        led3=~led3;
        yanshi(1);}
}
void yanshi(long i)
{while(i--);}


这样还是没用,依旧时间到了还是只运行定时器里的指令,主程序没反应了
回复 支持 反对

使用道具 举报

3

主题

19

帖子

125

积分

注册会员

Rank: 2

积分
125
发表于 2021-7-12 13:22:07 | 显示全部楼层
逍遥 发表于 2021-7-12 09:10
#include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;          // ...

延时里long改成u16
回复 支持 反对

使用道具 举报

1

主题

8

帖子

31

积分

新手上路

Rank: 1

积分
31
 楼主| 发表于 2021-7-12 18:01:51 | 显示全部楼层

可以了诶,请教大神这是为什么啊,long跟u16不是只是一个取数范围吗,1应该都在范围里,为啥u16可以long就不行啊
回复 支持 反对

使用道具 举报

3

主题

19

帖子

125

积分

注册会员

Rank: 2

积分
125
发表于 2021-7-12 19:55:56 | 显示全部楼层
逍遥 发表于 2021-7-12 18:01
可以了诶,请教大神这是为什么啊,long跟u16不是只是一个取数范围吗,1应该都在范围里,为啥u16 ...

它们进行一次自减时间不同 你原来用long那个 并不是没执行主函数而是一直在延时
回复 支持 反对

使用道具 举报

1

主题

8

帖子

31

积分

新手上路

Rank: 1

积分
31
 楼主| 发表于 2021-7-14 08:18:29 | 显示全部楼层
hoodieboi 发表于 2021-7-12 19:55
它们进行一次自减时间不同 你原来用long那个 并不是没执行主函数而是一直在延时

自减时间不同不懂是什么意思啊,就例如u16的取值范围是0-10,long是-10到10,我只要yanshi()里到0不应该都跳出循环吗,我yanshi()里数值没改,指示取值范围大了为啥效果就不一样呢
回复 支持 反对

使用道具 举报

3

主题

19

帖子

125

积分

注册会员

Rank: 2

积分
125
发表于 2021-7-14 12:44:20 | 显示全部楼层
逍遥 发表于 2021-7-14 08:18
自减时间不同不懂是什么意思啊,就例如u16的取值范围是0-10,long是-10到10,我只要yanshi()里到0不应 ...

while延时是靠每次减一的时间叠加达到的延时 long型和uint型每次减一的时间不同,我刚才试了下uint型晶振12m时减5000下需要45ms,long型需要200ms 这么说的话用long型也不会一直在延时中。你的代码用long的时候有个警告可能与那个警告有关
回复 支持 反对

使用道具 举报

1

主题

8

帖子

31

积分

新手上路

Rank: 1

积分
31
 楼主| 发表于 2021-7-14 13:06:37 | 显示全部楼层
本帖最后由 逍遥 于 2021-7-14 13:10 编辑
hoodieboi 发表于 2021-7-14 12:44
while延时是靠每次减一的时间叠加达到的延时 long型和uint型每次减一的时间不同,我刚才试了下uint型晶振 ...

谢大神指教,我查了一下那个警告,翻译的意思是    MAIN.C(59): warning C235: parameter 1: different types linking...   (  C235:参数1:不同类型的链接… )   但是实在看不出这个是啥意思,目前引用的就一个延时函数和一个取值范围,我试了一下16位数的取值范围好像就可以,long的取值范围为32位好像就不行了。好像只能用整型无符号的两个16位的,unsigned int  16位   unsigned short int 16位这两个能用 ,用unsigned long int 32位的就会产生警告,这是和单片机本身型号有关吗
回复 支持 反对

使用道具 举报

3

主题

19

帖子

125

积分

注册会员

Rank: 2

积分
125
发表于 2021-7-14 13:12:39 | 显示全部楼层
逍遥 发表于 2021-7-14 13:06
谢大神指教,我查了一下那个警告,翻译的意思是    MAIN.C(59): warning C235: parameter 1: different t ...

为什么我这边看到的是重入警告*** WARNING L15: MULTIPLE CALL TO SEGMENT
回复 支持 反对

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

Archiver|手机版|小黑屋|普中开源电子分享网 粤ICP备16123577号-2

GMT+8, 2021-7-24 18:23 , Processed in 0.095697 second(s), 24 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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