找回密码
 立即注册
查看: 50|回复: 4

32G12K128定时器应用问题 | 从我们经典的程序框架出发

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:9
  • 最近打卡:2025-08-22 18:13:02
已绑定手机

5

主题

5

回帖

63

积分

注册会员

积分
63
发表于 4 天前 | 显示全部楼层 |阅读模式
做一个定时器定期扫描信号,
用一个输入信号控制两个输出信号切换。
输出信号需独立。不能有互相干扰。代码如下:

abccb982-38c9-4554-8e56-7d240e1ade7b.png
这个代码有问题,在输入信号常有时会有问题。希望大神给指点下。感谢。

回复

使用道具 举报 送花

3

主题

2031

回帖

910

积分

等待验证会员

积分
910
发表于 4 天前 | 显示全部楼层
针对您提出的STC32G12K128定时器应用问题,以下为专业分析与建议:

首先,您描述的场景是通过一个输入信号控制两个独立输出信号的切换,要求输出信号互不干扰。代码中使用了定时器进行定期扫描,但在输入信号常有时出现异常,这可能涉及定时器配置、中断处理或信号逻辑设计等方面的问题。

一、问题分析

1. 定时器配置不当  
   定时器用于周期性扫描输入信号状态,若定时器频率设置不合理(如过快或过慢),可能导致扫描间隔不准确,影响控制逻辑的稳定性。此外,若未正确设置定时器中断优先级,可能造成中断响应延迟或丢失。

2. 中断处理逻辑缺陷  
   在输入信号持续为高电平时,若中断服务程序(ISR)未能及时处理或存在死循环,可能导致系统卡顿或输出信号无法正常切换。此外,若在ISR中执行耗时操作(如延时或复杂计算),将影响其他任务的执行。

3. 输出信号互干扰  
   若两个输出信号使用同一组GPIO端口或共享相同资源(如PWM通道),可能导致信号冲突。需确保每个输出信号独立配置,避免因共用引脚或寄存器导致的相互影响。

4. 输入信号检测逻辑不完善  
   输入信号的检测方式(如轮询或中断)若未充分考虑噪声或抖动,可能导致误触发或漏检。建议采用软件去抖或硬件滤波提高信号可靠性。

5. 代码结构问题  
   您提供的代码可能存在逻辑漏洞,例如未正确初始化定时器、未启用中断、或未合理分配资源。需检查代码中的关键部分,如定时器模式选择、中断使能、GPIO配置等。

二、优化建议

1. 合理配置定时器  
根据需求设定合适的定时器频率,确保扫描周期稳定。例如,若需要每10ms扫描一次,可配置定时器为10ms中断。
使用定时器的捕获/比较功能(如PWM或计数器模式)以提高精度。

2. 优化中断处理逻辑  
确保中断服务程序简短高效,避免在ISR中执行耗时操作。
若需在中断中执行复杂逻辑,可设置标志位,由主循环处理。

3. 独立配置输出信号  
为两个输出信号分配不同的GPIO引脚,并确保其驱动能力满足负载需求。
若使用PWM功能,需确认是否为独立通道,避免资源冲突。

4. 增强输入信号稳定性  
在输入信号引脚添加上拉/下拉电阻,减少噪声干扰。
在代码中加入软件去抖逻辑(如延时检测或状态机判断)。

5. 代码结构优化  
检查定时器初始化代码,确保正确配置模式、预分频值和中断使能。
验证GPIO配置是否正确,包括方向、复用功能和电平设置。
添加必要的注释和日志输出,便于调试和排查问题。

三、示例代码框架(仅供参考)
  1. c
  2. include "stc32g12k128.h"
  3. // 定义输入输出引脚
  4. define INPUTPIN    P10
  5. define OUTPUT1PIN  P11
  6. define OUTPUT2PIN  P12
  7. // 定时器配置参数
  8. define TIMERFREQ   1000000UL // 1MHz
  9. define SCANNINGTIME 10000     // 10ms
  10. void TimerInit(void) {
  11.     // 配置定时器为10ms中断
  12.     T0CON = 0x00;                // 设置为16位自动重载模式
  13.     TMOD = 0x01;                 // 定时器0模式1
  14.     TH0 = (65536 - SCANNINGTIME  (TIMERFREQ / 1000000UL)) >> 8;
  15.     TL0 = (65536 - SCANNINGTIME  (TIMERFREQ / 1000000UL)) & 0xFF;
  16.     ET0 = 1;                     // 使能定时器0中断
  17.     EA = 1;                      // 全局中断使能
  18.     TR0 = 1;                     // 启动定时器0
  19. }
  20. void TimerISR(void) interrupt 1 {
  21.     static uint8t state = 0;
  22.     // 清除中断标志
  23.     TF0 = 0;
  24.     // 扫描输入信号
  25.     if (INPUTPIN == 1) {
  26.         state = !state;          // 切换状态
  27.     }
  28.     // 控制输出信号
  29.     if (state) {
  30.         OUTPUT1PIN = 1;
  31.         OUTPUT2PIN = 0;
  32.     } else {
  33.         OUTPUT1PIN = 0;
  34.         OUTPUT2PIN = 1;
  35.     }
  36. }
  37. void main(void) {
  38.     // 初始化IO
  39.     P1M1 = 0x00;
  40.     P1M2 = 0x00;
  41.     P10 = 1;                    // 输入引脚设为输入
  42.     P11 = 0;                    // 输出1设为输出
  43.     P12 = 0;                    // 输出2设为输出
  44.     // 初始化定时器
  45.     TimerInit();
  46.     while (1) {
  47.         // 主循环可执行其他任务
  48.     }
  49. }
复制代码

四、总结

您的代码问题可能源于定时器配置、中断处理或输出信号管理不当。建议从上述几个方面逐一排查,并结合实际应用场景优化逻辑。若仍存在问题,可提供更多代码细节或调试信息以便进一步分析。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:522
  • 最近打卡:2025-08-24 00:56:18
已绑定手机

40

主题

2410

回帖

3256

积分

荣誉版主

积分
3256
发表于 4 天前 | 显示全部楼层
看代码逻辑很混乱,建议画一个输入和输出关系的时序图,这样好帮你查问题。
睁开眼睛做场梦~~~
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:161
  • 最近打卡:2025-08-23 08:11:44

775

主题

1万

回帖

1万

积分

管理员

积分
18735
发表于 4 天前 | 显示全部楼层

从下面这个程序框架出发,改到你需要的:

截图202508202301006898.jpg



#include <STC32G.H>                        //包含STC32G的头文件

#include "intrins.h"                        //使用_nop_()函数所必须要包含的头文件,
                                                                //否则延时函数中调用的_nop_()函数没有被头文件引用过来,
                                                                //会导致编译器找不到这个而函数而报错。


unsigned char int0_flag = 0;        //定义1个位变量,INT0事件位变量标志,记录INT0已产生中断
// 供主循环查询INT0是否已产生中断,在主循环中处理INT0的中断事件任务,不堵塞其他中断
unsigned char int1_flag = 0;        //定义1个位变量,INT1事件位变量标志,记录INT1已产生中断
// 供主循环查询INT1是否已产生中断,在主循环中处理INT1的中断事件任务,不堵塞其他中断
unsigned char int2_flag = 0;        //定义1个位变量,INT2事件位变量标志,记录INT2已产生中断
// 供主循环查询INT2是否已产生中断,在主循环中处理INT2的中断事件任务,不堵塞其他中断
unsigned char int3_flag = 0;        //定义1个位变量,INT3事件位变量标志,记录INT3已产生中断
// 供主循环查询INT3是否已产生中断,在主循环中处理INT3的中断事件任务,不堵塞其他中断

unsigned char t0_flag = 0;                //定义1个位变量,T0事件位变量标志,记录定时器0已产生中断
// 供主循环查询定时器0是否已产生中断,在主循环中处理定时器0的中断事件任务,不堵塞其他中断
unsigned char t1_flag = 0;                //定义1个位变量,T1事件位变量标志,记录定时器1已产生中断
// 供主循环查询定时器1是否已产生中断,在主循环中处理定时器1的中断事件任务,不堵塞其他中断
unsigned char t3_flag = 0;                //定义1个位变量,T3事件位变量标志,记录定时器3已产生中断
// 供主循环查询定时器3是否已产生中断,在主循环中处理定时器3的中断事件任务,不堵塞其他中断
unsigned char t4_flag = 0;                //定义1个位变量,T4事件位变量标志,记录定时器4已产生中断
// 供主循环查询定时器4是否已产生中断,在主循环中处理定时器4的中断事件任务,不堵塞其他中断

unsigned char uart1_txflag = 0;        //定义1个位变量,UART1事件位变量标志,记录UART1已产生发送中断
// 供主循环查询UART1是否已产生发送中断,在主循环中处理UART1的中断事件任务,不堵塞其他中断
unsigned char uart1_rxflag = 0;        //定义1个位变量,UART1事件位变量标志,记录UART1已产生接收中断
// 供主循环查询UART1是否已产生接收中断,在主循环中处理UART1的中断事件任务,不堵塞其他中断
unsigned char uart2_txflag = 0;        //定义1个位变量,UART2事件位变量标志,记录UART2已产生发送中断
// 供主循环查询UART2是否已产生发送中断,在主循环中处理UART2的中断事件任务,不堵塞其他中断
unsigned char uart2_rxflag = 0;        //定义1个位变量,UART2事件位变量标志,记录UART2已产生接收中断
// 供主循环查询UART2是否已产生接收中断,在主循环中处理UART2的中断事件任务,不堵塞其他中断
unsigned char uart3_txflag = 0;        //定义1个位变量,UART3事件位变量标志,记录UART3已产生发送中断
// 供主循环查询UART3是否已产生发送中断,在主循环中处理UART3的中断事件任务,不堵塞其他中断
unsigned char uart3_rxflag = 0;        //定义1个位变量,UART3事件位变量标志,记录UART3已产生接收中断
// 供主循环查询UART3是否已产生接收中断,在主循环中处理UART3的中断事件任务,不堵塞其他中断
unsigned char uart4_txflag = 0;        //定义1个位变量,UART4事件位变量标志,记录UART4已产生发送中断
// 供主循环查询UART4是否已产生发送中断,在主循环中处理UART1的中断事件任务,不堵塞其他中断
unsigned char uart4_rxflag = 0;        //定义1个位变量,UART4事件位变量标志,记录UART4已产生接收中断
// 供主循环查询UART4是否已产生接收中断,在主循环中处理UART4的中断事件任务,不堵塞其他中断

void Timer0_Init(void)                        //定时器1初始化,2秒@24MHz
{                              
        TM0PS = 0x3D;                                //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        AUXR &= 0x7F;                                //定时器时钟12T模式
        TMOD &= 0xF0;                                //设置定时器模式
        TL0 = 0xFC;                                        //设置定时初始值
        TH0 = 0x03;                                        //设置定时初始值
        TF0 = 0;                                        //清除TF0标志
        TR0 = 1;                                        //定时器0开始计时
        ET0 = 1;                                        //使能定时器0中断
}

void Timer1_Init(void)                        //定时器1初始化,500毫秒@24MHz
{
        TM1PS = 0x0F;                                //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        AUXR &= 0xBF;                                //定时器时钟12T模式
        TMOD &= 0x0F;                                //设置定时器模式
        TL1 = 0xDC;                                        //设置定时初始值
        TH1 = 0x0B;                                        //设置定时初始值
        TF1 = 0;                                        //清除TF1标志
        TR1 = 1;                                        //定时器1开始计时
        ET1 = 1;                                        //使能定时器1中断
}

void Timer3_Init(void)                    //100毫秒@24MHz
{
        TM3PS = 0x24;                            //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        T4T3M |= 0x02;                            //定时器时钟1T模式
        T3L = 0x9F;                                    //设置定时初始值
        T3H = 0x02;                                    //设置定时初始值
        T4T3M |= 0x08;                            //定时器3开始计时
        IE2 |= 0x20;                            //使能定时器3中断
}

void Timer4_Init(void)                    //200毫秒@24MHz
{
        TM4PS = 0x49;                            //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        T4T3M |= 0x20;                            //定时器时钟1T模式
        T4L = 0x9F;                                    //设置定时初始值
        T4H = 0x02;                                    //设置定时初始值
        T4T3M |= 0x80;                            //定时器4开始计时
        IE2 |= 0x40;                            //使能定时器4中断
}

void Uart1_Init(void)                        //115200bps@24MHz
{
        SCON = 0x50;                                //8位数据,可变波特率
        AUXR |= 0x01;                                //串口1选择定时器2为波特率发生器
        AUXR |= 0x04;                                //定时器时钟1T模式
        T2L = 0xCC;                                        //设置定时初始值
        T2H = 0xFF;                                        //设置定时初始值
        AUXR |= 0x10;                                //定时器2开始计时
        ES = 1;                                                //使能串口1中断
}

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

void Uart3_Init(void)                        //115200bps@24MHz
{
        S3CON = 0x10;                                //8位数据,可变波特率
        S3CON &= 0xBF;                                //串口3选择定时器2为波特率发生器
        AUXR |= 0x04;                                //定时器时钟1T模式
        T2L = 0xCC;                                        //设置定时初始值
        T2H = 0xFF;                                        //设置定时初始值
        AUXR |= 0x10;                                //定时器2开始计时
        IE2 |= 0x08;                                //使能串口3中断
}

void Uart4_Init(void)                        //115200bps@24MHz
{
        S4CON = 0x10;                                //8位数据,可变波特率
        S4CON &= 0xBF;                                //串口4选择定时器2为波特率发生器
        AUXR |= 0x04;                                //定时器时钟1T模式
        T2L = 0xCC;                                        //设置定时初始值
        T2H = 0xFF;                                        //设置定时初始值
        AUXR |= 0x10;                                //定时器2开始计时
        IE2 |= 0x10;                                //使能串口4中断
}

void main (void)
{
        EAXFR = 1;                                        //允许访问扩展的特殊寄存器,XFR
        WTST = 0;                                        //设置取程序代码等待时间,赋值为0表示不等待,程序以最快速度运行
        CKCON = 0;                                        //设置访问片内的xdata速度,赋值为0表示用最快速度访问,不增加额外的等待时间

        P0M0 = 0x00; P0M1 = 0x00;         //设置 P0 口为准双向口模式
        P1M0 = 0x00; P1M1 = 0x00;         //设置 P1 口为准双向口模式
        P2M0 = 0x00; P2M1 = 0x00;         //设置 P2 口为准双向口模式
        P3M0 = 0x00; P3M1 = 0x00;        //设置 P3 口为准双向口模式
        P3M0 = 0x00; P3M1 = 0x0c;         //P32、P33设置为高阻输入(需要同步开启上拉电阻)
        P4M0 = 0x00; P4M1 = 0x00;         //设置 P4 口为准双向口模式
        P5M0 = 0x00; P5M1 = 0x00;         //设置 P5 口为准双向口模式
        P6M0 = 0x00; P6M1 = 0x00;         //设置 P6 口为准双向口模式
        P7M0 = 0x00; P7M1 = 0x00;         //设置 P7 口为准双向口模式
       
        P3PU = 0x0c;                                 //P32、P33打开上拉电阻

        int0_flag = 0;                            //初始化用户标志位
        int1_flag = 0;                            //初始化用户标志位
        int2_flag = 0;                            //初始化用户标志位
        int3_flag = 0;                            //初始化用户标志位
   
        t0_flag = 0;                            //初始化用户标志位
        t1_flag = 0;                            //初始化用户标志位
        t3_flag = 0;                            //初始化用户标志位
        t4_flag = 0;                            //初始化用户标志位
   
        uart1_txflag = 0;                        //初始化用户标志位
        uart1_rxflag = 0;                        //初始化用户标志位
        uart2_txflag = 0;                        //初始化用户标志位
        uart2_rxflag = 0;                        //初始化用户标志位
        uart3_txflag = 0;                        //初始化用户标志位
        uart3_rxflag = 0;                        //初始化用户标志位
        uart4_txflag = 0;                        //初始化用户标志位
        uart4_rxflag = 0;                        //初始化用户标志位

        IT0 = 0;                                         //使能 INT0 上升沿和下降沿中断
        //        IT0 = 1;                                 //使能 INT0 下降沿中断
        EX0 = 1;                                         //使能 INT0 中断
        IE0 = 0;                                        //清INT0中断标志

        //        IT1 = 0;                                 //使能 INT1 上升沿和下降沿中断
        IT1 = 1;                                         //使能 INT1 下降沿中断
        EX1 = 1;                                         //使能 INT1 中断
        IE1 = 0;                                        //清INT1中断标志

        INTCLKO |= 0x10;                        //使能INT2中断

        INTCLKO |= 0x20;                        //使能INT3中断
       
        Timer0_Init();                                //调用定时器0初始化函数
        Timer1_Init();                                //调用定时器1初始化函数
        Timer3_Init();                                //调用定时器0初始化函数
        Timer4_Init();                                //调用定时器1初始化函数

        Uart1_Init();                                //调用UART1初始化函数
        Uart2_Init();                                //调用UART2初始化函数
        Uart3_Init();                                //调用UART3初始化函数
        Uart4_Init();                                //调用UART4初始化函数

        EA = 1;                                                //总中断允许位打开
        P40 = 0;                                         //打开LED灯供电
        while(1)                                         //主循环中查询需要处理的各种事件
        {
                /*  本演示程序中,主循环查询各中断有无需要继续处理的事件的次序,
                依次是 INTx/TIMERx/UARTx, 用户可以自己根据实际情况,
                调整查询各中断有无需要继续处理的事件的优先次序  */

                //查询外部中断0事件
                if(int0_flag)                        //主循环中查询,INT0是否已产生中断,是否有需要处理的INT 0事件
                {
                        int0_flag = 0;                //清0,INT0事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询外部中断1事件
                if(int1_flag)                        //主循环中查询,INT1是否已产生中断,是否有需要处理的INT1事件
                {
                        int1_flag = 0;                //清0,INT1事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询外部中断2事件
                if(int2_flag)                        //主循环中查询,INT2是否已产生中断,是否有需要处理的INT2事件
                {
                        int2_flag = 0;                //清0,INT2事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询外部中断3事件
                if(int3_flag)                        //主循环中查询,INT3是否已产生中断,是否有需要处理的INT3事件
                {
                        int3_flag = 0;                //清0,INT3事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询定时器0中断事件
                if(t0_flag)                                //主循环中查询,定时器0是否已产生中断,是否有需要处理的定时器0事件
                {
                        t0_flag = 0;                //清0,T0事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询定时器1中断事件
                if(t1_flag)                                //主循环中查询,定时器1是否已产生中断,是否有需要处理的定时器1事件
                {
                        t1_flag = 0;                //清0,T1事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询定时器3中断事件
                if(t3_flag)                                //主循环中查询,定时器3是否已产生中断,是否有需要处理的定时器3事件
                {
                        t3_flag = 0;                //清0,T3事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询定时器4中断事件
                if(t4_flag)                                //主循环中查询,定时器4是否已产生中断,是否有需要处理的定时器4事件
                {
                        t4_flag = 0;                //清0,T4事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询串口1中断事件
                if(uart1_txflag)                //主循环中查询,UART1是否已产生发送中断,是否有需要处理的UART1发送事件
                {
                        uart1_txflag = 0;        //清0,UART1发送事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                if(uart1_rxflag)                //主循环中查询,UART1是否已产生接收中断,是否有需要处理的UART1接收事件
                {
                        uart1_rxflag = 0;        //清0,UART1接收事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询串口2中断事件
                if(uart2_txflag)                //主循环中查询,UART2是否已产生发送中断,是否有需要处理的UART2发送事件
                {
                        uart2_txflag = 0;        //清0,UART2发送事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                if(uart2_rxflag)                //主循环中查询,UART2是否已产生接收中断,是否有需要处理的UART2接收事件
                {
                        uart2_rxflag = 0;        //清0,UART2接收事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询串口3中断事件
                if(uart3_txflag)                //主循环中查询,UART3是否已产生发送中断,是否有需要处理的UART3发送事件
                {
                        uart3_txflag = 0;        //清0,UART3发送事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                if(uart3_rxflag)                //主循环中查询,UART3是否已产生接收中断,是否有需要处理的UART3接收事件
                {
                        uart3_rxflag = 0;        //清0,UART3接收事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询串口4中断事件
                if(uart4_txflag)                //主循环中查询,UART4是否已产生发送中断,是否有需要处理的UART4发送事件
                {
                        uart4_txflag = 0;        //清0,UART4发送事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                if(uart4_rxflag)                //主循环中查询,UART4是否已产生接收中断,是否有需要处理的UART4接收事件
                {
                        uart4_rxflag = 0;        //清0,UART4接收事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }
        }
}


void int0_isr(void) interrupt INT0_VECTOR
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        int0_flag = 1;                                // int0_flag置1是通知主循环处理部分INT0中断事件不需要特急处理的任务
                                                                //置1,记录INT0已产生中断,供主循环查询判断有无需处理的INT0任务

        if(INT0)                                         //边沿中断,进入后再次判断电平从而判断是什么样的电平
        {
                _nop_();                                //判断为高电平,则当前为上升沿
                _nop_();                                //可以在这里插入断点进行观察现象
        }
        else
        {
                _nop_();                                //判断为低电平,则当前为下降沿
                _nop_();                                //可以在这里插入断点进行观察现象
        }
}
//INT0中断服务程序,INT0_VECTOR在STC32G.H头文件中已宏定义为0

void int1_isr(void) interrupt INT1_VECTOR
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        int1_flag = 1;                                // int1_flag置1是通知主循环处理部分INT1中断事件不需要特急处理的任务
}
//INT1中断服务程序,INT1_VECTOR在STC32G.H头文件中已宏定义为2

void int2_isr(void) interrupt INT2_VECTOR
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        int2_flag = 1;                                // int2_flag置1是通知主循环处理部分INT2中断事件不需要特急处理的任务
}
//INT2中断服务程序,INT2_VECTOR在STC32G.H头文件中已宏定义为10

void int3_isr(void) interrupt INT3_VECTOR
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        int3_flag = 1;                                // int3_flag置1是通知主循环处理部分INT3中断事件不需要特急处理的任务
}
//INT3中断服务程序,INT3_VECTOR在STC32G.H头文件中已宏定义为11

void Timer0_Isr(void) interrupt TMR0_VECTOR                //定时器0中断服务程序
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        t0_flag = 1;                                // t0_flag置1是通知主循环处理部分T0中断事件不需要特急处理的任务
                                                                //置1,记录定时器0已产生中断,供主循环查询判断有无需处理的定时器0任务
}
//定时器0中断服务程序,TMR0_VECTOR在STC32G.H头文件中已宏定义为1

void Timer1_Isr(void) interrupt TMR1_VECTOR  
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        t1_flag = 1;                                // t1_flag置1是通知主循环处理部分T1中断事件不需要特急处理的任务
                                                                //置1,记录定时器1已产生中断,供主循环查询判断有无需处理的定时器1任务
}
//定时器1中断服务程序,TMR1_VECTOR在STC32G.H头文件中已宏定义为3


void Timer3_Isr(void) interrupt TMR3_VECTOR
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        t3_flag = 1;                                // t3_flag置1是通知主循环处理部分T3中断事件不需要特急处理的任务
                                                                //置1,记录定时器3已产生中断,供主循环查询判断有无需处理的定时器1任务
}
//定时器3中断服务程序,TMR3_VECTOR在STC32G.H头文件中已宏定义为19

void Timer4_Isr(void) interrupt TMR4_VECTOR
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        t4_flag = 1;                                // t1_flag置4是通知主循环处理部分T4中断事件不需要特急处理的任务
                                                                //置1,记录定时器4已产生中断,供主循环查询判断有无需处理的定时器1任务
}
//定时器4中断服务程序,TMR4_VECTOR在STC32G.H头文件中已宏定义为20

void Uart1_Isr(void) interrupt UART1_VECTOR
{
        if (TI)                                                //检测串口1发送中断
        {
                TI = 0;                                        //清除串口1发送中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart1_txflag = 1;                // uart1_txflag置1是通知主循环处理部分串口1发送中断事件不需要特急处理的任务
                                                                //置1,记录UART1已产生发送中断,供主循环查询判断有无需处理的UART1发送任务
        }
        if (RI)                                                //检测串口1接收中断
        {
                RI = 0;                                        //清除串口1接收中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart1_rxflag = 1;                // uart1_rxflag置1是通知主循环处理部分串口1接收中断事件不需要特急处理的任务
                                                                //置1,记录UART1已产生接收中断,供主循环查询判断有无需处理的UART1接收任务
        }
}
//UART1中断服务程序,UART1_VECTOR在STC32G.H头文件中已宏定义为4

void Uart2_Isr(void) interrupt UART2_VECTOR
{
        if (S2CON & 0x02)                        //检测串口2发送中断
        {
                S2CON &= ~0x02;                        //清除串口2发送中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart2_txflag = 1;                // uart2_txflag置1是通知主循环处理部分串口2发送中断事件不需要特急处理的任务
                                                                //置1,记录UART2已产生发送中断,供主循环查询判断有无需处理的UART2发送任务
        }
        if (S2CON & 0x01)                        //检测串口2接收中断
        {
                S2CON &= ~0x01;                        //清除串口2接收中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart2_rxflag = 1;                // uart2_rxflag置1是通知主循环处理部分串口2接收中断事件不需要特急处理的任务
                                                                //置1,记录UART2已产生接收中断,供主循环查询判断有无需处理的UART2接收任务
        }
}
//UART2中断服务程序,UART2_VECTOR在STC32G.H头文件中已宏定义为8

void Uart3_Isr(void) interrupt UART3_VECTOR
{
        if (S3CON & 0x02)                        //检测串口3发送中断
        {
                S3CON &= ~0x02;                        //清除串口3发送中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart3_txflag = 1;                // uart3_txflag置1是通知主循环处理部分串口3发送中断事件不需要特急处理的任务
                                                                //置1,记录UART3已产生发送中断,供主循环查询判断有无需处理的UART3发送任务
        }
        if (S3CON & 0x01)                        //检测串口3接收中断
        {
                S3CON &= ~0x01;                        //清除串口3接收中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart3_rxflag = 1;                // uart3_rxflag置1是通知主循环处理部分串口3接收中断事件不需要特急处理的任务
                                                                //置1,记录UART3已产生接收中断,供主循环查询判断有无需处理的UART3接收任务
        }
}
//UART3中断服务程序,UART3_VECTOR在STC32G.H头文件中已宏定义为17

void Uart4_Isr(void) interrupt UART4_VECTOR
{
        if (S4CON & 0x02)                        //检测串口4发送中断
        {
                S4CON &= ~0x02;                        //清除串口4发送中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart4_txflag = 1;                // uart4_txflag置1是通知主循环处理部分串口4发送中断事件不需要特急处理的任务
                                                                //置1,记录UART4已产生发送中断,供主循环查询判断有无需处理的UART4发送任务
        }
        if (S4CON & 0x01)                        //检测串口4接收中断
        {
                S4CON &= ~0x01;                        //清除串口4接收中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart4_rxflag = 1;                // uart4_rxflag置1是通知主循环处理部分串口4接收中断事件不需要特急处理的任务
                                                                //置1,记录UART4已产生接收中断,供主循环查询判断有无需处理的UART4接收任务
        }
}
//UART4中断服务程序,UART4_VECTOR在STC32G.H头文件中已宏定义为18


回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:9
  • 最近打卡:2025-08-22 18:13:02
已绑定手机

5

主题

5

回帖

63

积分

注册会员

积分
63
发表于 前天 18:13 | 显示全部楼层
神*** 发表于 2025-8-20 23:02
从下面这个程序框架出发,改到你需要的:

这个全面专业   非常感谢
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-8-24 04:00 , Processed in 0.123527 second(s), 76 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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