找回密码
 立即注册

QQ登录

只需一步,快速开始

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

关于单片机中断函数与while()程序执行的问题

[复制链接]
ID:482529 发表于 2019-3-1 18:08 | 显示全部楼层 |阅读模式
请教为何while(j<10)时,LED灯正常闪烁5次,但是将while(j<10)改成while(j<5),LED灯进入无限闪烁状态?我本以为灯会闪烁2次。
  1. /*************************************************
  2. *实验名:定时器实验
  3. *实验效果:第一个led灯以500ms一次的精确频率闪烁,共闪烁5次;

  4. *************************************************/
  5. #include<reg52.h>

  6. sbit led = P1^6;
  7. int i = 0;
  8. int j=0;

  9. void timer1_init()
  10. {
  11.         TMOD = 0x10; //定时器1选择工作方式1
  12.         TH1 = 0x4C;  //设置初始值,定时50ms
  13.         TL1 = 0x00;
  14.         EA = 1;      //打开总中断
  15.         ET1 = 1;     //打开定时器1中断
  16.         TR1 = 1;     //启动定时器1
  17. }

  18. void main()
  19. {
  20.         led = 0;
  21.         timer1_init();
  22.         while(j<10)
  23.         {
  24.                         if(i>=10)
  25.                         {i=0;
  26.                         led = ~led;
  27.                                                 j++;
  28.                                                 }
  29.                 }
  30.       
  31. }

  32. void timer1() interrupt 3
  33. {
  34.           TH1 = 0x4C;         //设置初始值,定时50ms
  35.         TL1 = 0x00;  
  36.         i++;
  37.                
  38.         
  39.                         }
复制代码



回复

使用道具 举报

ID:345680 发表于 2019-3-1 19:49 | 显示全部楼层
单片机编程不能这样子吧,要加上while(1),否则会出错,你这样子改一下行不行
void main()
{
        led = 0;
        timer1_init();
       while(1)
      {
        while(j<10)
        {
                        if(i>=10)
                        {i=0;
                        led = ~led;
                                                j++;
                                                }
                }
      
}
}
回复

使用道具 举报

ID:482529 发表于 2019-3-1 20:04 | 显示全部楼层
aux123456789 发表于 2019-3-1 19:49
单片机编程不能这样子吧,要加上while(1),否则会出错,你这样子改一下行不行
void main()
{

按照你说的试了一下,仍然是无限循环闪烁。不知其所以然。。。
回复

使用道具 举报

ID:482430 发表于 2019-3-1 22:40 | 显示全部楼层
个人感觉用不到j,同时,作为类似全局的计数器,用i,j来命名,也不合适。
试试这样写:

#include<reg52.h>

sbit led = P1^6;
int count = 0;

void timer1_init()
{
        TMOD = 0x10; //定时器1选择工作方式1
        TH1 = 0x4C;  //设置初始值,定时50ms
        TL1 = 0x00;
        EA = 1;      //打开总中断
        ET1 = 1;     //打开定时器1中断
        TR1 = 1;     //启动定时器1
}

void main()
{
        led = 0;
        count=0;
        timer1_init();

        while(1)
        {
                ;
        }
}

void timer1() interrupt 3
{
        TH1 = 0x4C;         //设置初始值,定时50ms
        TL1 = 0x00;  
        count++;
        if(count>=10)
        {
                count=0;
                led = ~led;
        }
}
回复

使用道具 举报

ID:482430 发表于 2019-3-1 23:03 | 显示全部楼层
不好意思,一开始没注意你的要求。
你的要求,是程序开始后,只闪烁固定的次数,代码应该这样写:

#include<reg52.h>

#define                FLASH_MAX_COUNT                5        //最大闪烁次数

sbit led = P1^6;
int count = 0;
int flashCount = 0;                //闪烁次数

void timer1_init()
{
        TMOD = 0x10; //定时器1选择工作方式1
        TH1 = 0x4C;  //设置初始值,定时50ms
        TL1 = 0x00;
        EA = 1;      //打开总中断
        ET1 = 1;     //打开定时器1中断
        TR1 = 1;     //启动定时器1
}

void main()
{
        led = 0;
        flashCount=0;
        timer1_init();

        while(1)
        {
                ;
        }
}

void timer1() interrupt 3
{
        TH1 = 0x4C;         //设置初始值,定时50ms
        TL1 = 0x00;  
        count++;
        if(count>=10)
        {
                count=0;
                if(flashCount<FLASH_MAX_COUNT)
                {
                        led = ~led;
                        flashCount++;
                }               
        }
}

这样,你可以通过调整FLASH_MAX_COUNT的值,控制你实际希望led灯以500ms的间隔,闪烁几次。
回复

使用道具 举报

ID:346616 发表于 2019-3-1 23:56 | 显示全部楼层
程序有问题,正常情况你这个程序会不停的来回执行main(),不管是j<10还是j<5都会无限闪烁。
还有请你明白j为什么用while循环10次,这个10指的是10次状态的改变,灭是一个状态,亮是一个状态,闪烁5次就等于亮灭5次,一共是10次状态改变。
所以你要闪两次,应该改成j<4。
下面那个i循环指的是一次50ms,循环10次500ms.
程序解决办法,可以按照你楼上的办法,也可以在下面加一句,使语句停留,避免无限执行main()

void main()
{
        led = 0;
        timer1_init();
        while(j<10)
        {
                        if(i>=10)
                        {i=0;
                        led = ~led;
                                                j++;
                                                }
                }
       while(1);
}

评分

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

查看全部评分

回复

使用道具 举报

ID:469932 发表于 2019-3-2 00:48 | 显示全部楼层
代码没问题,是你观察不仔细,while(j<5)是三次,如果想看清楚,你用一下下面的代码与仿真

001.rar (15.87 KB, 下载次数: 6)
回复

使用道具 举报

ID:482529 发表于 2019-3-2 16:57 | 显示全部楼层
boswell1983 发表于 2019-3-1 23:03
不好意思,一开始没注意你的要求。
你的要求,是程序开始后,只闪烁固定的次数,代码应该这样写:

谢谢回复。
我的问题是以下代码在调试后出现以下情况:
while(j<9)中的 j改成小于9以下的7,5则出现循环闪烁现象,而当 j取大于9的奇数,如11,13。。。2n+1都能正常按照预设闪烁 n次,且n>=5.
我使用的单片机是STC89C52,这会不会与单片机内部运行机制相关?
  1. /*************************************************
  2. *实验名:定时器实验
  3. *实验效果:第一个led灯以500ms一次的精确频率闪烁,共闪烁5次;

  4. *************************************************/
  5. #include <reg52.h>

  6. sbit led = P1 ^ 6;
  7. int i = 0;
  8. int j = 0;

  9. void timer1_init()
  10. {
  11.     TMOD = 0x10; //定时器1选择工作方式1
  12.     TH1 = 0x4C;  //设置初始值,定时50ms
  13.     TL1 = 0x00;
  14.     EA = 1;  //打开总中断
  15.     ET1 = 1; //打开定时器1中断
  16.     TR1 = 1; //启动定时器1
  17. }

  18. void main()
  19. {
  20.     led = 0;
  21.     timer1_init();
  22.     while (j < 9)
  23.     {
  24.         if (i >= 10)
  25.         {
  26.             i = 0;
  27.             led = ~led;
  28.             j++;
  29.         }
  30.     }
  31. }

  32. void timer1() interrupt 3
  33. {
  34.     TH1 = 0x4C; //设置初始值,定时50ms
  35.     TL1 = 0x00;
  36.     i++;
  37. }
复制代码
回复

使用道具 举报

ID:482430 发表于 2019-3-2 19:51 | 显示全部楼层
51童小白 发表于 2019-3-2 16:57
谢谢回复。
我的问题是以下代码在调试后出现以下情况:
while(j=5.

我觉得你现在出现这种无法解释的情况,应该是程序逻辑没理清楚。建议不要太钻牛角尖。
你可以自己把你原来的程序,主循环,写一个程序流程图;中断写一个程序流程图。然后自己分析问题出在哪里,这样收货会更大。

正常的单片机程序编写,主循环根本不用参与控制led灯这类事情。
一般控制led灯的闪烁,都是在定时器中断里完成的。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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