找回密码
 立即注册

QQ登录

只需一步,快速开始

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

关于stc8g单片机里面定时器中断和串口中断输出的问题

[复制链接]
跳转到指定楼层
楼主
ID:1147156 发表于 2025-4-13 10:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
代码如下  我是想1us 定时器0中断一次  计数20000次时 定时器中断函数里  串口1输出数据  但是监控串口 没有输出   我也加了优先级 串口优先2  定时器0优先1
只有主循环里才能输出  具体看不出时序对不对  

请大佬看看哪里有问题
难道是中断里面不支持再次中断
  1. #include <STC8G.h>
  2. #include <intrins.h>
  3. #include <stdio.h>

  4. typedef     unsigned char   u8;
  5. typedef     unsigned int    u16;
  6. typedef     unsigned long   u32;

  7. #define     Baudrate1           115200L
  8. #define     UART1_BUF_LENGTH    32


  9. u8  TX1_Cnt;    //发送计数
  10. u8  RX1_Cnt;    //接收计数
  11. bit B_TX1_Busy; //发送忙标志

  12. u8  idata RX1_Buffer[UART1_BUF_LENGTH]; //接收缓冲


  13. void    PrintString1(u8 *puts);
  14. void    PrintChar(u8 dat);




  15. #define                SYSCLK                        24000000
  16. #define                BAUD                                115200                                //22.1184M下,99.2-115.2均可驱动舵机。
  17. #define         BRT (65536 - SYSCLK / BAUD / 4)                 

  18. //端口定义
  19. sbit        CH1in        = P3^2;
  20. sbit        CH2in        = P3^3;
  21. sbit        CH3in        = P5^4;
  22. sbit        CH4in        = P5^5;

  23. //常量定义

  24. unsigned char S_data1[] = {0x00,0xFF,0xFA,0x05,0x03,0x1A,0x00,0x02,0xD9};

  25. unsigned char S_data2[] = {0x01,0xFF,0xFB,0x05,0x03,0x04,0x00,0x00,0xDB};

  26.         

  27. u16 Scount=0;
  28. u8 k;

  29. void TM0_Isr() interrupt 1    //定时器0中断函数
  30. {
  31.         
  32.         Scount++;
  33.         
  34.         if(Scount==20000){                //20ms  串口输出一次
  35.                
  36.                 PrintString1(S_data1);
  37.                 Scount=0;
  38.         }
  39.         
  40. }



  41. void Timer0Init(void)                //10微秒@24.000MHz
  42. {
  43.         AUXR |= 0x80;                //定时器时钟1T模式
  44.         TMOD &= 0xF0;                //设置定时器模式
  45.         
  46.         //TL0 = 0x10;                //设置定时初值        10微妙
  47.         //TL0 = 0xD0;                //设置定时初值        2微妙
  48.         //TL0 = 0xE8;                //设置定时初值        1微妙
  49.         TL0 = 0xE8;
  50.         
  51.         TH0 = 0xFF;                //设置定时初值
  52.         TF0 = 0;                //清除TF0标志
  53.         
  54.         TR0 = 1;                //定时器0开始计时
  55.         
  56.         ET0 = 1;                //使能定时器0中断
  57.         EA = 1;                        //打开总中断
  58.         
  59.         PT0  = 1;    //高优先级中断
  60.         
  61. }




  62. void Delay1000ms()                //@24.000MHz  //软件延时1000ms
  63. {
  64.         unsigned char i, j, k;

  65.         _nop_();
  66.         _nop_();
  67.         i = 92;
  68.         j = 50;
  69.         k = 238;
  70.         do
  71.         {
  72.                 do
  73.                 {
  74.                         while (--k);
  75.                 } while (--j);
  76.         } while (--i);
  77. }

  78. void Delay20ms()                //@24.000MHz
  79. {
  80.         unsigned char i, j, k;

  81.         _nop_();
  82.         _nop_();
  83.         i = 2;
  84.         j = 211;
  85.         k = 231;
  86.         do
  87.         {
  88.                 do
  89.                 {
  90.                         while (--k);
  91.                 } while (--j);
  92.         } while (--i);
  93. }


  94. void UartInit(void)                //115200bps@24.000MHz
  95. {
  96.         SCON = 0x50;                //8位数据,可变波特率
  97.         AUXR |= 0x40;                //定时器1时钟为Fosc,即1T
  98.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  99.         TMOD &= 0x0F;                //设定定时器1为16位自动重装方式
  100.         
  101.         TL1 = 0xCC;                //设定定时初值        115200
  102.         TH1 = 0xFF;                //设定定时初值
  103.         
  104.         //TL1 = 0x8F;                //设定定时初值        9600
  105.         //TH1 = 0xFD;                //设定定时初值
  106.         
  107.         ET1 = 0;                //禁止定时器1中断
  108.         TR1 = 1;                //启动定时器1
  109.         
  110.         ES = 1;                        //是能串口1中断
  111.         EA = 1;                 //使能总中断
  112.         
  113.         PS  = 2;    //高优先级中断
  114.         
  115.                 B_TX1_Busy = 0;
  116.                     TX1_Cnt = 0;
  117.                     RX1_Cnt = 0;
  118. }




  119. void UART1_int (void) interrupt 4
  120. {
  121.     if(RI)
  122.     {
  123.         RI = 0;
  124.         RX1_Buffer[RX1_Cnt] = SBUF;
  125.         if(++RX1_Cnt >= UART1_BUF_LENGTH)   RX1_Cnt = 0;    //防溢出
  126.     }

  127.     if(TI)
  128.     {
  129.         TI = 0;
  130.         B_TX1_Busy = 0;
  131.     }
  132. }





  133. void    PrintChar(u8 dat)   //发送字符
  134. {
  135.     SBUF = dat;
  136.     B_TX1_Busy = 1;
  137.     while(B_TX1_Busy);
  138. }



  139. void PrintString1(u8 *puts) //发送一个字符串
  140. {
  141.         unsigned char i;
  142.     for (i=0;i<9;i++)  
  143.     {
  144.         SBUF = puts[i];
  145.         B_TX1_Busy = 1;
  146.         while(B_TX1_Busy);
  147.     }
  148. }








  149. void main(void)
  150. {
  151.         
  152.                 P5M1 = 0;   
  153.                 P5M0 = 0;        //P5 标准输出口
  154.         
  155.                 P3M1 = 0;   
  156.                 P3M0 = 0;        //P3 标准输出口
  157.         
  158.                                 UartInit();        //初始化串口
  159.         
  160.         Timer0Init();//初始化定时器

  161. //        EX1init(); //初始化外部中断
  162.         


  163.         
  164.         while(1)//主循环
  165.         {   
  166.                                        
  167.         //                PrintString1(S_data1);
  168.                                        
  169.         //                Delay20ms();
  170.                                        

  171.         }
  172.                                 
  173. }

复制代码

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

使用道具 举报

沙发
ID:1109793 发表于 2025-4-13 14:29 | 只看该作者
PS = 2是个啥意思?PS不是一个BIT吗?
就是PS = 1一样了,PT0也=1,就是T0还是高于串口了,那么在T0中断里面调用发送函数过程中,串口是无法产生中断的。你这又是等待又是中断的,还要加个B_TX1_Busy ,感觉挺麻烦的,发送函数为何不直接用TI判定发送完成?
回复

使用道具 举报

板凳
ID:1133081 发表于 2025-4-13 17:09 | 只看该作者
虽然单片机累不死但是会忙不赢。你为了20ms发送一次串口信号让定时器中断20000次合适吗?你确定 PrintString1(S_data1);在10us时间内能完成吗?中断程序执行时间大于中断周期是忌讳。
回复

使用道具 举报

地板
ID:1147156 发表于 2025-4-13 19:56 | 只看该作者
xiaobendan001 发表于 2025-4-13 14:29
PS = 2是个啥意思?PS不是一个BIT吗?
就是PS = 1一样了,PT0也=1,就是T0还是高于串口了,那么在T0中断里 ...

刚刚开始编这个单片机的程序 都是照的例子改写的  那简单一点的应该是怎么样 ?
改成这样还是不行
    PS  = 0;    //中断优先级 2
    PSH = 1;
回复

使用道具 举报

5#
ID:1147156 发表于 2025-4-13 19:58 | 只看该作者
WL0123 发表于 2025-4-13 17:09
虽然单片机累不死但是会忙不赢。你为了20ms发送一次串口信号让定时器中断20000次合适吗?你确定 PrintStrin ...

因为我程序需要1us就要判断电平高低来计数  其他判断程序还没写  先确定发送指令的方面
回复

使用道具 举报

6#
ID:1109793 发表于 2025-4-14 07:41 | 只看该作者
rootony 发表于 2025-4-13 19:56
刚刚开始编这个单片机的程序 都是照的例子改写的  那简单一点的应该是怎么样 ?
改成这样还是不行
     ...

PSH是啥?我也没找到。
我记得要提高优先级,就是PS = 1;同时PT0不能设置,就是保持=0;
这样串口才会比定时器优先。
回复

使用道具 举报

7#
ID:1147156 发表于 2025-4-14 22:25 | 只看该作者
xiaobendan001 发表于 2025-4-14 07:41
PSH是啥?我也没找到。
我记得要提高优先级,就是PS = 1;同时PT0不能设置,就是保持=0;
这样串口才会 ...

PSH就是PS的高位啊  优先级一共四级 00 01 10 11
妳说的那个简单的发送函数是什么样的  能贴一段代码吗
就是有T0中断 还有完整的串口发送数据的
回复

使用道具 举报

8#
ID:1109793 发表于 2025-4-15 07:12 | 只看该作者
rootony 发表于 2025-4-14 22:25
PSH就是PS的高位啊  优先级一共四级 00 01 10 11
妳说的那个简单的发送函数是什么样的  能贴一段代码吗
...

哪个头文件里面的定义啊
我也没找到STC8G.H里面,只有一个IP
回复

使用道具 举报

9#
ID:1109793 发表于 2025-4-15 07:18 | 只看该作者
rootony 发表于 2025-4-14 22:25
PSH就是PS的高位啊  优先级一共四级 00 01 10 11
妳说的那个简单的发送函数是什么样的  能贴一段代码吗
...

刚刚查看了PDF,有四个优先级寄存器,IP,IPH,IP2,IP2H。其中只有IP是可以位访问的。
回复

使用道具 举报

10#
ID:624769 发表于 2025-4-15 22:42 | 只看该作者
你先 解决 20ms 串口发送一次问题, 再去考虑 每us判断电平的问题。
就你写出 PS = 2;  以及写出 PSH = 1; 这个情况来看,不要折腾太多能力范围外的东西。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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