请问使用stdio头文件后,串口用printf打印数据是否拥有最高中断优先级?
<p>使用printf好像会打断定时器中断,我在中断服务函数中的自增变量,在主函数的while循环中使用printf连续打印,变量的数值没有增加。</p><p>请问这是正常的吗?</p>
<p>0.0 中断优先级和中断优先级寄存器有关,,和C库无关</p>
_奶咖君_ 发表于 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 能设置优先级的只有串口中断
printf不是硬件中断不能设置优先级,因为printf耗时很长,不要在中断函数内使用
串口中断应该是每字节分别处理,处理1个字节后快速退出中断,在中断函数内只能读数据和设置指针,不要做浪费时间的操作(更不能有软件延时函数)
printf完整发送一个字符串(数组或数据包)是很浪费时间的,要先printf到缓冲区,然后由串口中断逐个字节发送
串口收发框架和printf参考程序:
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=4598
没截图没代码
那我只能帮你算一卦 printf默认使用串口输出字符,与定时器没有关系,函数本身比较大,耗时 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);
}
} DebugLab 发表于 2025-2-7 11:26
能设置优先级的只有串口中断
printf不是硬件中断不能设置优先级,因为printf耗时很长,不要在中断函数内使 ...
printf是放在主循环里面,串口只负责发送;
谢谢大佬,我试试收发框架的方法 Ayb_ice 发表于 2025-2-7 13:06
printf默认使用串口输出字符,与定时器没有关系,函数本身比较大,耗时
但是从vofa的输出上来看,printf会影响定时器中断中变量的自增 bbgjtotg 发表于 2025-2-7 13:29
但是从vofa的输出上来看,printf会影响定时器中断中变量的自增
那说明你代码有问题,