找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1839|回复: 7
收起左侧

单片机外部中断和定时器都使用时,定时器没有实现功能。帮帮忙

[复制链接]
ID:676703 发表于 2020-5-24 17:18 | 显示全部楼层 |阅读模式
设计要求是:生产线计数器,光电计数,过一次光电计数器,记一个数,用数码管显示,当计数到10时,LED灯闪烁2秒。(仿真时,计数器用按键模拟)
下面是单片机程序,定时器不能实现所需要求。

#include<AT89x51.H>
#define uchar unsigned char
#define uint unsigned int
typedef unsigned int u16;          //对数据类型进行声明定义
typedef unsigned char u8;
uchar duan[10]={0xc0,0Xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //所需的段的位码
uchar wei[2]={0XBf,0X7f}; //位的控制端
uint c,v,date; //定义数据类型
uint dispcount=0;

sbit led=P1^4;         //定义P1.4口是led
/*****延时函数*****/
void delay(uchar t)
{
uchar i,j;
for(i=0;i<t;i++)
{
    for(j=13;j>0;j--);
        {;
        }
        }
        }
/*****数码管动态扫描*****/
void xianshi()
{
/***数据转换***/
c=date%100/10;  //求十位
v=date%10;      //求个位
P2=wei[0];
P0=duan[c];
delay(50);
P2=wei[1];
P0=duan[v];
delay(50);
}
/*****中断函数*****/
void ExtInt0() interrupt 0   //中断服务程序
{
dispcount++;        //外部中断一次,计数加一
if(dispcount==51)   //计数范围0~50
{dispcount=0;}
}

/*******************************************************************************
* 函 数 名         : Timer0Init
* 函数功能                   : 定时器0初始化
*******************************************************************************/
void Timer0Init()
{
        TMOD|=0X01; //选择为定时器0模式,工作方式1,仅用TR0打开启动。

        TH0=0XFC;          //给定时器高八位赋初值,定时1ms
        TL0=0X18;        
        ET0=1;      //打开定时器0中断允许
        EA=1;       //打开中断总开关
        TR0=1;      //打开定时器0                        
}
/*****主函数*****/
void main()
{
    static u16 i;
        TCON=0x01;     //中断设置 TCON寄存器          (外部中断触发方式设)
        IE=0x81;       //IE外部中断0请求标志位   (总中断开关)
        Timer0Init();  //定时器0初始化
        while(1)
         {
         date=dispcount;
         xianshi();           //调用数码管显示
         if(dispcount%2==0&&dispcount!=0)          //1s时
        {
            led=0;           //打开LED
                i++;
                if(i>1000)        //时间大于1s
                {
                led=1;           //关闭LED
                i=0;        //清零
                }
        }
                else {led=1;}        
         }
}
/*******************************************************************************
* 函 数 名         : void Timer0() interrupt 1
* 函数功能                   : 定时器1中断函数
*******************************************************************************/
void Timer0() interrupt 1
{
        static u16 i;
        TH0=0XFC;        //给定时器赋初值,定时1ms
        TL0=0X18;
        i++;

}

回复

使用道具 举报

ID:213173 发表于 2020-5-24 22:39 | 显示全部楼层
无标题.jpg
  1. #include<AT89x51.H>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. typedef unsigned int u16;          //对数据类型进行声明定义
  5. typedef unsigned char u8;
  6. uchar duan[10]={0xc0,0Xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //所需的段的位码
  7. uchar wei[2]={0X01,0X02}; //位的控制端
  8. uint c,v,date; //定义数据类型
  9. uint dispcount=0;

  10. sbit led=P1^4;         //定义P1.4口是led
  11. /*****延时函数*****/
  12. void delay(uchar t)
  13. {
  14.         uchar i,j;
  15.         for(i=0;i<t;i++)
  16.                 for(j=13;j>0;j--);
  17. }
  18. /*****数码管动态扫描*****/
  19. void xianshi()
  20. {
  21. /***数据转换***/
  22.         c=date/10;  //求十位
  23.         v=date%10;      //求个位
  24.         P2=wei[0];
  25.         P0=duan[c];
  26.         delay(50);
  27.         P2=wei[1];
  28.         P0=duan[v];
  29.         delay(50);
  30. }
  31. /*****中断函数*****/
  32. void ExtInt0() interrupt 0   //中断服务程序
  33. {
  34.         dispcount++;        //外部中断一次,计数加一
  35.         if(dispcount>50)   //计数范围0~50
  36.                 dispcount=1;
  37. }

  38. /*******************************************************************************
  39. * 函 数 名         : Timer0Init
  40. * 函数功能                   : 定时器0初始化
  41. *******************************************************************************/
  42. void Timer0Init()
  43. {
  44.         TMOD|=0X01; //选择为定时器0模式,工作方式1,仅用TR0打开启动。
  45.         TH0=0XFC;   //给定时器高八位赋初值,定时1ms
  46.         TL0=0X18;        
  47.         ET0=1;      //打开定时器0中断允许
  48.         EA=1;       //打开中断总开关
  49.         TR0=1;      //打开定时器0                        
  50. }
  51. /*****主函数*****/
  52. void main()
  53. {
  54. //        static u16 i;
  55.         TCON=0x01;     //中断设置 TCON寄存器(外部中断触发方式设)
  56.         IE|=0x81;       //IE外部中断0请求标志位   (总中断开关)
  57.         Timer0Init();  //定时器0初始化
  58.         while(1)
  59.         {
  60.                 date=dispcount;
  61.                 xianshi();           //调用数码管显示   
  62.         }
  63. }
  64. /*******************************************************************************
  65. * 函 数 名         : void Timer0() interrupt 1
  66. * 函数功能                   : 定时器1中断函数
  67. *******************************************************************************/
  68. void Timer0() interrupt 1
  69. {
  70.         static u16 i;
  71.         TH0=0XFC;        //给定时器赋初值,定时1ms
  72.         TL0=0X18;
  73.         if(dispcount%10==0&&dispcount!=0)          //1s时
  74.         {
  75.                 i++;
  76.                 if(i%100==0)       //100ms
  77.                         led=~led;
  78.                 if(i>=2000)       //时间大于2s
  79.                 {
  80.                         i=2000;
  81.                         led=1;
  82.                 }
  83.         }
  84.         else
  85.         {
  86.                 led=1;   
  87.                 i=0;
  88.         }
  89. }
复制代码



回复

使用道具 举报

ID:195446 发表于 2020-5-24 23:41 | 显示全部楼层
你这两个中断打架,定时器中断级别低打不过外部中断,外部中断要是快的话,定时器中断没机会,好像不工作,实际上它很着急。。。。。。。
回复

使用道具 举报

ID:676703 发表于 2020-5-25 18:59 | 显示全部楼层
本帖最后由 carrot1111 于 2020-5-25 19:18 编辑
mffhxa 发表于 2020-5-24 23:41
你这两个中断打架,定时器中断级别低打不过外部中断,外部中断要是快的话,定时器中断没机会,好像不工作, ...

上一层已经解决了,也谢谢你!
回复

使用道具 举报

ID:676703 发表于 2020-5-25 19:17 | 显示全部楼层

可以!!很成功,谢谢你~
回复

使用道具 举报

ID:676703 发表于 2020-5-25 19:39 | 显示全部楼层

设计很巧妙,愚昧的问一下,第78行  if(i%100==0)   这个判断的用途是什么?
回复

使用道具 举报

ID:213173 发表于 2020-5-25 20:58 | 显示全部楼层
carrot1111 发表于 2020-5-25 19:39
设计很巧妙,愚昧的问一下,第78行  if(i%100==0)   这个判断的用途是什么?

if(i%100==0)   当 i 等于100的整数倍时条件满足,执行led=~led;闪烁。闪烁时间限制为2s,if(i>=2000) {i=2000;led=1;},i 不再增加。下一次中断i++,i实际值2001,如此反复,不符合闪烁条件。
回复

使用道具 举报

ID:676703 发表于 2020-5-25 21:48 | 显示全部楼层
wulin 发表于 2020-5-25 20:58
if(i%100==0)   当 i 等于100的整数倍时条件满足,执行led=~led;闪烁。闪烁时间限制为2s,if(i>=2000) {i ...

我明白了,它可以实现闪烁功能。非常感谢!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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