国民技术 N32G430 电路板设计错误, 硬件引起的软件故障

        准备使用串口的中断功能实现串口调试与控制,结果初始化完中断之后发现从串口接收信息(从电脑往单片机发送消息)不会触发中断,不触发中断的话无法有效对数据采集和处理,串口收信息的功能就算是彻底废了,经过长时间的排查,结果发现是硬件的问题…… 

        自己设计的电路板有时候就是这么不靠谱

问题复现 

        主控使用了国民技术(Nation)的N32g430,是一款国产MCU,资料比较少,大部分都是参照官方给出的例程。

        首先是初始化串口以及开启中断,参照官方代码

void log_init(void)
{
    GPIO_InitType GPIO_InitStructure;
    USART_InitType USART_InitStructure;
    //时钟使能
    RCC_AHB_Peripheral_Clock_Enable(LOG_PERIPH_GPIO);
    RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO | LOG_PERIPH);
    //GPIO口初始化
    GPIO_Structure_Initialize(&GPIO_InitStructure);
    GPIO_InitStructure.Pin            = LOG_TX_PIN | LOG_RX_PIN;
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF5_USART1;
    GPIO_Peripheral_Initialize(LOG_GPIO, &GPIO_InitStructure);
    //串口功能初始化
    USART_InitStructure.BaudRate            = 115200;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_TX | USART_MODE_RX;
    /* init uart */
    USART_Initializes(LOG_USARTx, &USART_InitStructure);
    //中断功能初始化
    NVIC_InitType NVIC_InitStructure;
    /* Enable the USARTy Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel                   = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Initializes(&NVIC_InitStructure);
    //开启串口
    /* enable uart */
    USART_Enable(LOG_USARTx);
    //开启中断
    USART_Interrput_Enable(USART1,USART_INT_RXDNE);

}

        和STM32很像 ,初始化完串口再开启中断功能,这样一旦串口接收到数据就会触发对应的中断,可以及时对接收到的数据做处理,有点类似于JavaScript中的回调函数,处理函数的名称在startup_xx.s中,但是没有具体的实现逻辑,需要在n32g430_it.c中重写这个函数

/**
 *\name    USART1_IRQHandler.
 *\fun     串口1中断函数,所有有关串口1的中断时间都会调用整个函数\n
 *         需要在函数内部在逐个对于中断类型做判断,判断是哪个事件引起的中断
 *@return  void
**/
void USART1_IRQHandler(void)
{
    //串口接收数据触发中断事件
    if (USART_Interrupt_Status_Get(USART1, USART_INT_RXDNE) != RESET)
    {
        USART_Interrupt_Status_Clear(USART1,USART_INT_RXDNE);//清除中断状态位
        LED_Toggle(LED1_PORT,LED1_PIN);//LED灯闪烁,测试功能
        log_info("%c",USART_Data_Receive(USART1));//将接收到的数据再从串口发出去
    }
    //串口发送数据触发中断事件
    if (USART_Interrupt_Status_Get(USART1, USART_INT_TXDE) != RESET){
        USART_Interrupt_Status_Clear(USART1,USART_INT_TXDE);
    }
    //串口数据溢出中断事件
    if (USART_Interrupt_Status_Get(USART1, USART_INT_OREF) != RESET){
        USART_Interrupt_Status_Clear(USART1,USART_INT_OREF);
    }
}

        这样,理论上串口接收到数据就会触发中断,但实际上完全没有效果,以为是软件设置的问题,参考了好多份例程,发现设置都差不多,后来又以为是移植freeRTOS系统的问题,而且一旦开启TXDE中断,程序将会卡死,用JLink调试,发现程序在中断函数中死循环,而且每一次进入的都是TXDE事件分支,即使在该分支中使用USART_Interrupt_Status_Clear(USART1,USART_INT_TXDE);函数清除了TXDE的标志位,下一次循环还是会进这里。

        无奈只能先关了TX中断,单独调试RX中断,但这时候又无论如何都到达不了中断函数了,无法触发。后面又想到了使用开发板的按键做调试,我之前将几个空闲的IO口设计成了按键和LED灯,辅助调试

//按键3状态判断
sw3_state = check_key_state_change(&flag_sw3,SW3_PORT,SW3_PIN);
//按键3被按下
if (sw3_state == NO_PRESS_CHANGE){
    //开启RX中断
    USART_Interrput_Enable(USART1,USART_INT_RXDNE);
}
//按键4状态判断
sw4_state = check_key_state_change(&flag_sw4,SW4_PORT,SW4_PIN);
//按键4被按下
if (sw4_state == NO_PRESS_CHANGE){
    //关闭RX中断
    USART_Interrput_Disable(USART1,USART_INT_RXDNE);
}

        这里实际修改了很多次,各种情况都试过了,RX,TX的,都没有办法调出问题所在

        甚至去查了官方的用户手册中有关于串口通信的内容 

         最终也没什么结果

        幸好,我尝试用另一个USB转TTL工具连接,这个 烧录器是有灯的,一旦有RX或者TX的数据流过,对应的灯会轻微闪烁,结果观察发现,单片机发送数据时,RX的灯会闪,但是电脑发送数据时,RX的灯完全不会变,说明信号根本就没有进入到单片机芯片里面。

        而我上一版电路板是可以正常连接的,这个地方没有改过,理论上不应该出现问题,拿出上一版电路板,再次测试,发现确实可以通信,于是仔细对照两版的区别。

        唯一的区别在于上一版电路板由于把TYPE-C引脚焊盘弄坏了,就连CH340C芯片也拆下来了,新版的TYPE-C和CH340C都焊接得没问题,但测试的时候电脑无法识别,由于之前预留了排针引出口,就直接使用外接得USB转TTL工具了,CH340没有拆下来。

解决方法

        尝试性地划断了CH340与排针之间的走线,结果发现所有功能都正常了!!!!!

 

问题分析 

         回看原理图,发现CH340C还处于工作状态,对于外接TTL产生了干扰,而且参考典型电路,RX和TX引脚上没有串联电阻或者二极管,导致可能会电平倒灌

        现在可以确定问题出在这里,但是CH340为什么不能工作以及它是如何干扰外接TTL工具还有待验证。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值