bbgjtotg 发表于 2025-2-7 09:41:02

请问使用stdio头文件后,串口用printf打印数据是否拥有最高中断优先级?

<p>使用printf好像会打断定时器中断,我在中断服务函数中的自增变量,在主函数的while循环中使用printf连续打印,变量的数值没有增加。</p>
<p>请问这是正常的吗?</p>

_奶咖君_ 发表于 2025-2-7 09:53:08

<p>0.0 中断优先级和中断优先级寄存器有关,,和C库无关</p>

bbgjtotg 发表于 2025-2-7 10:25:31

_奶咖君_ 发表于 2025-2-7 09:53
0.0 中断优先级和中断优先级寄存器有关,,和C库无关

2个自变量用定时器中断10ms自增1次但是打印出来是这样的
low_rpm_time:568
rp:568
low_rpm_time:568
rp:568
low_rpm_time:568
rp:568
low_rpm_time:568
rp:568
low_rpm_time:568
rp:568
low_rpm_time:568
rp:568
low_rpm_time:568
rp:568
low_rpm_time:568
rp:568
low_rpm_time:568
rp:569
low_rpm_time:569
rp:569
low_rpm_time:569
rp:569
low_rpm_time:569
rp:569
low_rpm_time:569
rp:569
low_rpm_time:569
rp:569
low_rpm_time:569
rp:569
low_rpm_time:569
rp:569
low_rpm_time:569
rp:569
low_rpm_time:569
rp:570
low_rpm_time:570
rp:570

DebugLab 发表于 2025-2-7 11:26:07

能设置优先级的只有串口中断
printf不是硬件中断不能设置优先级,因为printf耗时很长,不要在中断函数内使用
串口中断应该是每字节分别处理,处理1个字节后快速退出中断,在中断函数内只能读数据和设置指针,不要做浪费时间的操作(更不能有软件延时函数)
printf完整发送一个字符串(数组或数据包)是很浪费时间的,要先printf到缓冲区,然后由串口中断逐个字节发送
串口收发框架和printf参考程序:
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=4598

Lkck8210 发表于 2025-2-7 11:34:41

没截图没代码
那我只能帮你算一卦

Ayb_ice 发表于 2025-2-7 13:06:06

printf默认使用串口输出字符,与定时器没有关系,函数本身比较大,耗时

bbgjtotg 发表于 2025-2-7 13:26:04

Lkck8210 发表于 2025-2-7 11:34
没截图没代码
那我只能帮你算一卦

代码如下
#include"STC8Hxxx.h"
//#include "stc8h.h"
#include "intrins.h"
#include "stdio.h"


#define FOSC       33177600UL
#define BRT         (65536 - FOSC / 115200 / 4)


#define u8unsigned char
#define u16 unsigned int
#define u32 unsigned long
       
sbit AH=P1^1;
sbit BH=P3^5;
sbit hall= P3^2;        //霍尔检测,准双向引脚
sbit fgout = P3^3;        //FG信号输出,推挽引脚



//#define        ADC_SPEED        15                /* 0~15, ADC转换时间(CPU时钟数) = (n+1)*32ADCCFG */
//#define        RES_FMT                (1<<5)        /* ADC结果格式 0: 左对齐, ADC_RES: D11 D10 D9 D8 D7 D6 D5 D4, ADC_RESL: D3 D2 D1 D0 0 0 0 0 */
//                                                        /* ADCCFG   1: 右对齐, ADC_RES: 0 0 0 0 D11 D10 D9 D8, ADC_RESL: D7 D6 D5 D4 D3 D2 D1 D0 */

//保护通道
#define OverVot_Class1 0x06         //一级过压引脚p1.6
#define OverVot_Class2 0x07                //二级过压引脚p1,7
#define Overcurrent 0x03                        //过流保护引脚p1.3
//转速通道
#define SpeedADC 0x0c                        //转速读取p3.4,1100 ADC12
       
void _nop_(void);

u16        i = 1;

/***************************************************************************************************************************************/
//变量
u16 rp=0;                        //用于定时周期性读取ADC设定转速
u16 rpad=0;                        //用于是设置开环转速
u16 trpm=0;                        //用于统计圈数
u16 imax=0;                        //用于检测运行过程中的过流
u16 setpwm=0;                //设置开环pwm
u16 setrpm=0;                //设置闭环转速
u16 setrpm_adc=0;        //设置转速       
u16 motor_stop=0;        //判断是否处于停机状态

u16 rp_add = 0;                //用于多次统计

u16 low_rpm_time=0;



u16 pwm=0;                //pwm设定占空比
u8stop=0;                //停止计时

u8 abq=0;                //相位检测,用于检测转速,全局变量编译器自动置为0;

//声明转速相关临时变量,实时速度,定时器时间,实际转速与设定转速的比例
u8 fpwm=0,kpwm=0;

//用于循环判断变量,多次判断后才能进行变量增减
u32 rpm=0;
int rd=0;


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


void TM0_Isr() interrupt 1   //33.1776MHz300微秒
{
        rp++;                                //定时读取转速设定
        low_rpm_time++;                //堵转低转保护延时和转速计算

}

////串口部分
////定时器1做波特率,串口初始化
void UartInit()
{       
        P_SW1|=0x40;      //开启串口1的功能引脚选择,使用p3.6和p3.7
    SCON = 0x50;
    TMOD = 0x00;
    TL1 = BRT;
    TH1 = BRT >> 8;
    TR1 = 1;
    AUXR = 0x40;
       
        TI=1;
}


//软件延时部分check
void Delay300ms(void)        //@24.000MHz
{
        unsigned char data i, j, k;

        _nop_();
        _nop_();
        i = 37;
        j = 135;
        k = 138;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

void Delay20ms(void)        //@33.1776MHz
{
        unsigned char data i, j, k;

        i = 4;
        j = 94;
        k = 188;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}


/*******************************************************************************************************************/
void main()
{
        //ADC将p1.3;p1.5;p1.6;p1.7设置为高阻输入;pwm引脚模式配置p1.0,p1.1和p1.4为推挽模式
        P1M0 = 0x13;//0001,0011
        P1M1 = 0xE8;//1110,1000
        //p3.5;p3.3;推挽,p3.7;p3.6;p3.2;p3.1;p3.0准双向,p3.4高阻
        P3M0 = 0x28;//0010,1000
        P3M1 = 0x10;//0001,0000
       
        BH=0;                        //PMOS关
        AH=0;                        //PMOS关
       
        //上电需要等待总延时600毫秒
        Delay300ms();
        Delay300ms();
       
       
        rp=0;
        low_rpm_time=0;                                //定时器数据初始化
        Timer0_Init();


        UartInit();
        //hall外部中断,输出FG信号
        IT0 = 0;                                    //使能INT0上升沿和下降沿中断
    EX0 = 1;                                    //使能INT0中断
        //启动中断开关
        EA=1;
       
        while (1)
        {
//                        Delay20ms();
                        printf("rp:%d\n",rp);
//                        Delay20ms();
                        printf("low_rpm_time:%d\n",low_rpm_time);

        }       
}

bbgjtotg 发表于 2025-2-7 13:27:53

DebugLab 发表于 2025-2-7 11:26
能设置优先级的只有串口中断
printf不是硬件中断不能设置优先级,因为printf耗时很长,不要在中断函数内使 ...

printf是放在主循环里面,串口只负责发送;
谢谢大佬,我试试收发框架的方法

bbgjtotg 发表于 2025-2-7 13:29:26

Ayb_ice 发表于 2025-2-7 13:06
printf默认使用串口输出字符,与定时器没有关系,函数本身比较大,耗时

但是从vofa的输出上来看,printf会影响定时器中断中变量的自增

Ayb_ice 发表于 2025-2-7 14:33:12

bbgjtotg 发表于 2025-2-7 13:29
但是从vofa的输出上来看,printf会影响定时器中断中变量的自增

那说明你代码有问题,
页: [1] 2 3
查看完整版本: 请问使用stdio头文件后,串口用printf打印数据是否拥有最高中断优先级?