找回密码
 立即注册
查看: 124|回复: 8

AI8051U printf打印概率性死机

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:53
  • 最近打卡:2026-07-04 09:39:43
已绑定手机

5

主题

5

回帖

141

积分

注册会员

积分
141
发表于 2026-6-21 11:06:25 | 显示全部楼层 |阅读模式
再没有任何修改的情况, 有时候使用printf就会卡住, 不会往下执行。 有没有遇到过的。UART1_SendBuffer发送不会有问题, printf就会没办法输出。 运行40M, 波特率115200  调整到1000000直接printf无法使用。

////////////////////////////////////////
// 重写printf字符发送重定向函数
// 入口参数: dat (printf函数待打印的字符)
// 函数返回: 需要返回入口参数的数据
////////////////////////////////////////
char putchar (char dat)                 //将串口1和printf函数绑定
{
    while (!UART1_CheckTxFlag());       //等待之前的数据发送完成
    UART1_ClearTxFlag();                //清除完成标志
    UART1_SendData(dat);                //发送当前字节

    return dat;
}


////////////////////////////////////////
// 串口1发送数据函数
// 入口参数: dat (待发送的字节数据)
// 函数返回: 无
////////////////////////////////////////
void UART1_SendByte(uint8_t dat)
{
    putchar((char)dat);
}

////////////////////////////////////////
// 串口1发送多字节数据函数
// 入口参数: dat  (发送数据缓冲区)
//           size (数据大小)
// 函数返回: 无
////////////////////////////////////////
void UART1_SendBuffer(uint8_t *dat, uint8_t size)
{
    while (size--)                      //判断数据是否结束
        UART1_SendByte(*dat++);         //发送当前字节
}

=  



回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:142
  • 最近打卡:2026-07-04 10:53:37
已绑定手机

5

主题

331

回帖

6374

积分

论坛元老

积分
6374
发表于 2026-6-21 12:05:39 | 显示全部楼层
要看putchar是怎么调用的。
比如一个在主循环里用,一个在中断里用,其中一个清除了flag,那么另一个就得不到flag所以卡死。
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:53
  • 最近打卡:2026-07-04 09:39:43
已绑定手机

5

主题

5

回帖

141

积分

注册会员

积分
141
发表于 2026-6-21 12:24:05 | 显示全部楼层
lcws*** 发表于 2026-6-21 12:05
要看putchar是怎么调用的。
比如一个在主循环里用,一个在中断里用,其中一个清除了flag,那么另一个就得不 ...

没有用中断, 就是纯等待
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:453
  • 最近打卡:2026-07-03 08:57:36

830

主题

1万

回帖

2万

积分

管理员

积分
23929
发表于 2026-6-21 12:26:30 | 显示全部楼层
截图202606211224185147.jpg

截图202606211225397139.jpg
截图202606211226126967.jpg

截图202606211227283460.jpg




回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:142
  • 最近打卡:2026-07-04 10:53:37
已绑定手机

5

主题

331

回帖

6374

积分

论坛元老

积分
6374
发表于 2026-6-21 12:45:20 | 显示全部楼层
自在*** 发表于 2026-6-21 12:24
没有用中断, 就是纯等待

建议把工程传上来
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:53
  • 最近打卡:2026-07-04 09:39:43
已绑定手机

5

主题

5

回帖

141

积分

注册会员

积分
141
发表于 2026-6-21 15:43:15 | 显示全部楼层
lcws*** 发表于 2026-6-21 12:45
建议把工程传上来

自己重新处理了下, 就是一开始不对导致的,
现在专门加了一个buff,然后来进行处理。
就算串口出问题了,也不会导致整成死机,
增加了中断, 同时检查串口的状态,可以进行恢复。



// 200字节
#define  PRINTF_BUFF_SIZE 200
uint8_t xdata debug_ErrorFlag=0;
uint8_t xdata printfbuff[PRINTF_BUFF_SIZE];
uint8_t xdata *printf_buf_in;
uint8_t xdata *printf_buf_out;
uint8_t xdata printf_Status=0;

void printfBuff_input(unsigned char value)// 接收数据input处理
{
    if((printf_buf_in < printf_buf_out) && (1 == printf_buf_out - printf_buf_in)) {
        debug_ErrorFlag = 1;
        return; // 上报出错....
    }else if((printf_buf_in > printf_buf_out) && ((printf_buf_in - printf_buf_out) >= PRINTF_BUFF_SIZE)) {
        debug_ErrorFlag =1;
        return; // 上报出错...
    }else {
        if(printf_buf_in >= (unsigned char *)(printfbuff + PRINTF_BUFF_SIZE)) {
            printf_buf_in = (unsigned char *)(printfbuff);
        }
        
    *printf_buf_in++ = value;
    }
}

uint8_t with_data_printfbuff(void)
{
  if(printf_buf_out != printf_buf_in){
        return 1;
    }else{
        return 0;
    }
}
uint8_t printfBuff_output(void)
{
    unsigned char value = 0;
    //有数据
    if(printf_buf_out != printf_buf_in) {
        if(printf_buf_out >= (unsigned char *)(printfbuff + PRINTF_BUFF_SIZE)) {
            printf_buf_out = (unsigned char *)(printfbuff); //数据已经到末尾
        }
        
        value = *(printf_buf_out);
        printf_buf_out++;
    }
    return value;
}


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

    printf_Status = 0;
    printf_buf_out = printfbuff;
    printf_buf_in = printfbuff;
    debug_ErrorFlag=0;
}

void Uart1_Isr(void) interrupt 4
{
    if (TI)             //检测串口1发送中断
    {
        TI = 0;         //清除串口1发送中断请求位
        if(with_data_printfbuff()){
            SBUF = printfBuff_output();
        }else {
            printf_Status = 0;
        }
    }
    if (RI)             //检测串口1接收中断
    {
        RI = 0;         //清除串口1接收中断请求位
    }
}

#endif

void Debug_handle(void)
{
    if(debug_ErrorFlag){
        Uart1_Init(); // reset debug...
        printf("debug uart reset...\r\n");
    }

    // 如果有数据需要打印,且串口没有再发送数据, 则发送下一个字节
    if(printf_Status==0 && with_data_printfbuff()){
        printf_Status = 1;
        SBUF = printfBuff_output();
    }
    if(printf_Status){
        TOUCH_LED1 = 1;
    }else {
        TOUCH_LED1 = 0;
    }
}

////////////////////////////////////////
// 重写printf字符发送重定向函数
// 入口参数: dat (printf函数待打印的字符)
// 函数返回: 需要返回入口参数的数据
////////////////////////////////////////
char putchar (char dat)                 //将串口1和printf函数绑定
{
    #if 0
    while (!UART1_CheckTxFlag());       //等待之前的数据发送完成
    UART1_ClearTxFlag();                //清除完成标志
    UART1_SendData(dat);                //发送当前字节
    #else
    #endif
    printfBuff_input(dat);
    return dat;
}



回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:299
  • 最近打卡:2026-07-04 00:01:55
已绑定手机

66

主题

808

回帖

3037

积分

论坛元老

DIY玩家

积分
3037
发表于 2026-6-21 21:43:34 | 显示全部楼层
可能使用printf耗时更长
永怀这学徒心
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:393
  • 最近打卡:2026-07-04 17:13:30

83

主题

7888

回帖

1万

积分

超级版主

积分
16827
发表于 2026-6-21 22:23:56 | 显示全部楼层
程序不完整,应该是等待标志时,没处理好,死锁了。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:727
  • 最近打卡:2026-06-26 17:48:25
已绑定手机

95

主题

7373

回帖

1万

积分

超级版主

积分
13944
发表于 2026-6-24 14:44:55 | 显示全部楼层
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-7-5 07:47 , Processed in 0.076759 second(s), 84 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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