huanghao_min 发表于 2023-12-9 19:57:09

STC8A8K64D 定时器3中断和串口2中断同时开启,定时器3不工作

本帖最后由 huanghao_min 于 2023-12-9 20:18 编辑

源程序:
#include <stc8a8k64d4.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
static bit uart1SendBusy=0;
static unsigned char timerFlag=0;

void uart1Init(void)                //9600bps@22.1184MHz
{
      SCON = 0x50;                //8位数据,可变波特率
      AUXR |= 0x40;                //定时器时钟1T模式
      AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
      TMOD &= 0x0F;                //设置定时器模式
      TL1 = 0xC0;                        //设置定时初始值
      TH1 = 0xFD;                        //设置定时初始值
      ET1 = 0;                        //禁止定时器中断
      TR1 = 1;                        //定时器1开始计时
      ES = 1   ;          //使能串口中断
}

void uart1SendChar(char dat)
{
      while(uart1SendBusy);
      uart1SendBusy=1;
      SBUF=dat;
}

void uart1SendString(char *p)
{
      while(*p!='\0')
      {
                uart1SendChar(*p++);
      }
}

void uart1_isr() interrupt 4
{
    if (TI)
    {
                TI = 0;   
                uart1SendBusy=0;               
    }
    if (RI)
    {
      RI = 0;                              
    }
}


void Timer3_Init(void)                //1秒@22.1184MHz
{
      unsigned char psw2Value;
      unsigned char value;
      psw2Value =P_SW2;
      P_SW2=psw2Value|0x80;      //使能访问XFR
      TM3PS = 0x1C;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
      P_SW2=psw2Value;
      T4T3M &= 0xFD;                        //定时器时钟12T模式
      T3L = 0xB9;                              //设置定时初始值
      T3H = 0x07;                              //设置定时初始值
      T4T3M |= 0x08;                        //定时器3开始计时
      IE2 |=0x20;                        //使能定时器3中断
}

void Timer3_Isr(void) interrupt 19
{
      timerFlag=0xaa;
}


void uart2Init(void)                //9600bps@22.1184MHz
{
      S2CON = 0x50;                //8位数据,可变波特率
      AUXR |= 0x04;                //定时器时钟1T模式
      T2L = 0xC0;                        //设置定时初始值
      T2H = 0xFD;                        //设置定时初始值
      AUXR |= 0x10;                //定时器2开始计时
      IE2|= 0x01;                //使能串口2中断
}


void main(void)
{
      uart1Init();
      EA = 1;
      uart1SendString("program init\r\n");
      uart2Init();
      Timer3_Init();
               
      while(1)
      {
                if(timerFlag==0xaa)
                {
                        timerFlag=0;
                        uart1SendString("this is a test\r\n");
                }
      }
}
//=================================================================//
1、当uart2Init函数中的IE2|= 0x01;      //使能串口2中断   开启后,定时器3中断就不会产生,串口1不会提示字符串"this is a test";
2、当屏蔽uart2Init函数中的IE2|= 0x01;      //使能串口2中断   后,定时器3中断产生,串口1会连续打印提示字符串"this is a test";
3、当IE2直接赋值IE2= 0x21时,定时器3也不会产生中断,串口1不会提示字符串"this is a test";

神农鼎 发表于 2023-12-9 20:00:18

还是建议用 STC-USB Link1D 来仿真



神农鼎 发表于 2023-12-9 20:01:25



【新提醒】仿真 STC8 系列 MCU,用 STC-USB Link1D ! 有视频讲解 - 仿真/ISP下载/做自己的ISP/编译器/头文件 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)

神农鼎 发表于 2023-12-9 20:01:50


_奶咖君_ 发表于 2023-12-11 09:21:52

话说为啥没看到你串口2的中断服务函数....加上去试一试?

huanghao_min 发表于 2023-12-11 09:25:35

本帖最后由 huanghao_min 于 2023-12-11 09:27 编辑

加入串口2的中断,还是一样的效果
void uart2_isr() interrupt 8
{

}

_奶咖君_ 发表于 2023-12-11 10:23:56

加上这部分 你在尝试一下

_奶咖君_ 发表于 2023-12-11 10:28:31

这个是串口输出的结果

huanghao_min 发表于 2023-12-11 10:41:08

本帖最后由 huanghao_min 于 2023-12-11 10:43 编辑

谢谢老师,确实现在可以,这个程序必须加上
void uart2_isr() interrupt 8
{
      if(S2CON&0x02)
      {
                S2CON &=~0x02;
      }
      if(S2CON&0x01)
      {
                S2CON &=~0x01;
      }
}
接收中断和发送中断都必须处理;

如果只处理发送中断,
void uart2_isr() interrupt 8
{
    if (S2CON & 0x02)
    {
                S2CON &= ~0x02;   
                uart2SendBusy=0;               
    }
}
也不能正常运行

_奶咖君_ 发表于 2023-12-11 10:45:56

huanghao_min 发表于 2023-12-11 10:41
谢谢老师,确实现在可以,这个程序必须加上
void uart2_isr() interrupt 8
{


照理说应该不会,,,我自己的工程里面用用轮询的方式 处理TI 也是可以的,,可能关键的地方在接收中断标志这里。。
页: [1] 2
查看完整版本: STC8A8K64D 定时器3中断和串口2中断同时开启,定时器3不工作