找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机2个定时器开启,串口中断进不了是哪里占用了?

[复制链接]
跳转到指定楼层
楼主
ID:302293 发表于 2023-7-13 10:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/********************************************************************
* 文件名  : 独立按键.c
* 描述    :  该程序实现独立按键去控制 LED灯 的亮灭,并讲诉了对按键的处理方法。
                         独立按键相应的IO口平时为高电平,一旦按键按下,单片机便检测到低电平。
                         按下P3.2,P0.0口对应的LED亮灭交替变化。
                         按下P3.3,P0.1口对应的LED亮灭交替变化。
                         按下P3.4,P0.2口对应的LED亮灭交替变化。
* 创建人  : 东流,2009年8月27日
* 版本号  : 1.0
***********************************************************************/
#include<reg52.h>
#include"lop.h"
#define uchar unsigned char
#define uint  unsigned int
#define u8 unsigned char
#define u16 unsigned int
typedef u8 a;
sbit KEY1 = P1^2;   
sbit KEY2 = P1^3;
sbit KEY3 = P1^4;
sbit LED1 = P0^0;
sbit LED2 = P0^1;
sbit LED3 = P0^2;
sbit LED5 = P1^0;
sfr P4 =0Xe8;
sbit P4_0 = P4^0;
static u16        count;  
char cost;        
bit lixc=1;
sfr WDT_CONTR=0xe1;         //1110 0001
//extern enu;
u8 cmd;
void KEY();

typedef struct
{

u8 i;
u8 *p;


}enu;

enu number;


/********************************************************************
* 名称 : Delay()
* 功能 : 延时,延时时间为 10ms * del
* 输入 : del
* 输出 : 无
***********************************************************************/
void Delay(uint del)
{
        uint i,j;
        for(i=0; i<del; i++)
        for(j=0; j<1827; j++);   

}

/********************************************************************
* 名称 : Delay()
* 功能 : 实现按键功能,当按键按下时,相应的LED亮灭交替
* 输入 : 无
* 输出 : 无
***********************************************************************/
void KEY()
{
         
          a i;
         number.i=0;
//        Delay(2);         
        if(KEY1==0 || KEY2==0 || KEY3==0)        
        {
                Delay(5);                            //20毫秒软件防抖
                if(KEY1 == 0)
                {
                Delay(5);
               
//        while(!KEY1);        
//                 P4_0  = 0 ;                //LED显示取反
                         Delay(1);           
                 ++cost;             SBUF= cost;        
        while(!TI);TI=0;
        
                }
        if(KEY2 == 0)
                {                        
//                P4_0 = 1;
                --cost;
                         SBUF= cost;
                           while(!TI);TI=0;
                }
                else
                {                        
                        LED3 = !LED3;
                }
                Delay(50);                        //延时0.5秒再进行下次按键的检测
           if(cost>=3)
                {
                   lixc=0;        P4_0=1;
                }
           else
                 lixc=1;
        
        }        
}

/*------------------------------------------------
                    串口初始化
------------------------------------------------*/
void InitUART  (void)
{

    SCON  = 0x50;                        // SCON: 模式 1, 8-bit UART, 使能接收  
//              // TMOD: timer 1, mode 2, 8-bit 重装
    TMOD |= 0x21;
        TH1   = 0xFD;               // TH1:  重装值 9600 波特率 晶振 11.0592MHz  
    TL1 = 0xFD;      //波特率
        TR1   = 1;                  // TR1:  timer 1 打开                        
    IE |= 0x92;      //开启中断
        EA    = 1;                  //打开总中断
    ES    = 1;                  //打开串口中断
//  SM0=0;
//        SM1=1;      //串口方式1         
//    REN=1;      //允许接收   
//    PCON=0x00;  //关倍频





}                           
void Init_Timer1(void)
{
// TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
// TH0=0x0c;              //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
// TL0=0x0c;
// ET0=1;           //定时器中断打开
// TR0=1;           //定时器开关打开
// EA=1;            //总中断打开

    TMOD &= 0xf0;                        //定时器0
    TMOD |= 0x01;
    TH0  = (65536-2000)/256; //2ms溢出
    TL0  = (65536-2000)%256;
}
void Init_Timer2(void)
{
// TMOD=0x21;  //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH1=(65536-50000)/256; //给TH1和初初值,由15536开始计数,到65535溢出
TL1=(65536-50000)%256; //外部晶振为12MHz,对应的延时时间为50ms
ET1=1;           //定时器中断打开
TR1=1;           //定时器开关打开
EA=1;            //总中断打开

}
void timer0(void) interrupt 1
  {

//     TH0=0x00;                  //重新赋值
//     TL0=0x00;                  
         TH0 = 0xDC; //10MS
          TL0 = 0x00;
     if(count>100&&lixc==1)
         {
         
            count=0;
                  P4_0 =!P4_0 ;
         }
count++;

//  if(count>=15)
//    {
//           count=0;
//           WDT_CONTR|=0x10;                  //         00010000  || 1110 0001
//        }
}
void timer1(void) interrupt 3 using 1
{
//        TH1=(65536-50000)/256; //给TH1和初初值,由15536开始计数,到65535溢出
//    TL1=(65536-50000)%256; //外部晶振为12MHz,对应的延时时间为50ms
        TH1 = 0xDC; //10MS
        TL1 = 0x00;
     if(cmd>150)
         {
         
            cmd=0;
                   LED5  =!LED5 ;
         }
cmd++;



}

void ET0_init()//定时器0初始化            
{   
    EA=1;         //打开总中断
        TR0=1;         //打开定时器0中断
        ET0=1;         //启动定时器0中断
        TH0=(65536-50000)/256;//无脑赋值 相当于50毫秒进入一次中断函数,20次就是1秒
        TL0=(65536-50000)%256; //无脑赋值
        TMOD= 0x01;//设置定时器t0的工作方式
}
void UartInit()        //串口定时器1初始化
{
     EA=1; //打开总中断

    TMOD|=0x21;  //设置定时器1工作方式为方式2   
          TR1=1;      //启动定时器1  
    TH1=0xfd;            //波特率9600
    TL1=0xfd;  
    SCON=0X50;      //允许接收   
//         ES=0;
}               




void USART_IRQ(void) interrupt 4
{
          unsigned char Temp;          //定义临时变量

   if(RI)                        //判断是接收中断产生
     {
          RI=0;                      //标志位清零
          Temp=SBUF;                 //读入缓冲区的值
//          P1=Temp;                   //把值输出到P1口,用于观察
      SBUF=Temp;                 //把接收到的值再发回电脑端
         }
   if(TI)                        //如果是发送标志位,清零
     TI=0;
        
}
/********************************************************************
* 名称 : Main()
* 功TMOD=0x11,转为二进制就是00010001,即T0和T1的最低两位均为01,工作方式为方式1--16位定时器或计数器。第三位为0,
设定T0,T1为定时器,对内部脉冲进行计数,用来折算时间。第四位也是0,说明不参考INTx引脚电平,
由内部寄存器来控制定时器的启停。能 : 实现按键控制LED的亮灭
* 输入 : 无
* 输出 : 无

***********************************************************************/
void Main(void)
{
//        Init_Timer1();        
//        Init_Timer2();
//        InitUART();
   ET0_init();        
   UartInit();                                       
   WDT_CONTR = 0x24;
while(1)
        {
                 KEY();           
//                 WDT_CONTR = 0x24;        

        WDT_CONTR|=0x10;
        }
}

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

使用道具 举报

沙发
ID:57657 发表于 2023-7-13 22:13 | 只看该作者
ES    = 1;                  //打开串口中断
PS =1;     //串口中断高优先级
//  SM0=0;
回复

使用道具 举报

板凳
ID:1085441 发表于 2023-7-14 00:20 | 只看该作者
尽量避免同时开几个中断,否则会出一些莫名其妙的问题。建议中庸一个定时器中断,其他用查询。
回复

使用道具 举报

地板
ID:213173 发表于 2023-7-14 06:13 | 只看该作者
定时器1用做串口波特率发生器后不可以同时再用作定时器1中断!
回复

使用道具 举报

5#
ID:636210 发表于 2023-7-14 07:58 | 只看该作者
串口与定时1在时间上重叠上,都用定时器1。这个定时中断没处理好,再好好研究串口与定时1同时用可能造成的时序问题。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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