[方案相关] 基于 华大 HC32F460 芯片的 串口封装

[复制链接]
1280|7
 楼主| 斧王FUWANG 发表于 2023-12-20 15:16 | 显示全部楼层 |阅读模式

接触嵌入式短短1年,也不知道封装的合理性如何,实际性能如何,就是自己写的爽,我就这么干了~~~

直接上代码~

  1. #define Print(type,fmt,...){m_PrintfDevice = usart[type].usart_ch;printf(fmt,##__VA_ARGS__);};

  2. typedef enum usart_type
  3. {
  4.     uart1  = 0u, uart2, uart3, uart4
  5. } usart_t;

  6. typedef struct Usart_Struct{
  7.         M4_USART_TypeDef *          usart_ch;                        // 串口通道
  8.         en_port_t                                 Rx_Port;                        // Rx串口Port
  9.         en_pin_t                                 Rx_Pin;                                // Tx串口Pin
  10.         en_port_t                                 Tx_Port;                       
  11.         en_pin_t                                 Tx_Pin;
  12.         uint32_t                         BAUDRATE;
  13.         en_port_func_t                    USART_RX_FUNC;
  14.         en_port_func_t                    USART_TX_FUNC;  
  15.         en_int_src_t                           INT_USART_RI;        
  16.         en_int_src_t                           INT_USART_EI;
  17.         en_int_src_t                           INT_USART_TI;
  18.         en_int_src_t                           INT_USART_TCI;
  19.         enum IRQn                        Rx_IRQn;
  20.         enum IRQn                       Tx_IRQn;
  21.         en_usart_parity_t       usart_type;
  22.         en_usart_clk_div_t                 clk;
  23.         uint16_t                                 u16UsedSize;  
  24.     uint16_t                                  au8Buf[200];
  25. }Usart;

  26. void usart_common_call(void);
  27. void usart_common_err_call(void);
  28. static void RingBufWriteNew(Usart *usart, uint8_t u8Data,usart_t type);
  29. void all_usart_init(void);
  30. void new_usart_init(Usart *u);
  31. void resetBuf(Usart *u);


 楼主| 斧王FUWANG 发表于 2023-12-20 15:17 | 显示全部楼层
配置4路串口
  1. Usart usart[4]   = {
  2.         {
  3.                 M4_USART3, // group 2
  4.                 PortE,Pin13,PortE,Pin14,
  5.                 115200ul,
  6.                 Func_Usart3_Rx,Func_Usart3_Tx,
  7.                 INT_USART3_RI,INT_USART3_EI,INT_USART3_TI,INT_USART3_TCI,
  8.                 Int001_IRQn,Int003_IRQn,
  9.                 UsartParityNone,
  10.                 UsartClkDiv_1,0
  11.         },
  12.         
  13.     //...
  14. }
 楼主| 斧王FUWANG 发表于 2023-12-20 15:17 | 显示全部楼层
初始化各路串口

  1. void all_usart_init () {
  2.         PORT_DebugPortSetting(TDI,Disable);
  3.         int len = sizeof(usart) / sizeof(usart[0]);
  4.         for ( int i = 0 ; i < len ; i++) {
  5.                 new_usart_init(&usart[i]);
  6.         }
  7. }

  8. void new_usart_init(Usart *u){
  9.        
  10.     stc_irq_regi_conf_t stcIrqRegiCfg;
  11.     const stc_usart_uart_init_t stcInitCfg = {
  12.         UsartIntClkCkNoOutput,
  13.         u->clk,
  14.         UsartDataBits8,
  15.         UsartDataLsbFirst,
  16.         UsartOneStopBit,
  17.         u->usart_type,
  18.         UsartSampleBit8,
  19.         UsartStartBitFallEdge,
  20.         UsartRtsEnable,
  21.     };
  22.   
  23.         PORT_SetFunc(u->Rx_Port, u->Rx_Pin, u->USART_RX_FUNC, Disable);
  24.         PORT_SetFunc(u->Tx_Port, u->Tx_Pin, u->USART_TX_FUNC, Disable);
  25.        
  26.     USART_UART_Init(u->usart_ch, &stcInitCfg);

  27.     USART_SetBaudrate(u->usart_ch, u->BAUDRATE);
  28.   
  29.     stcIrqRegiCfg.enIRQn = u->Rx_IRQn;
  30.     stcIrqRegiCfg.pfnCallback = usart_common_call;
  31.     stcIrqRegiCfg.enIntSrc = u->INT_USART_RI ;
  32.     enIrqRegistration(&stcIrqRegiCfg);
  33.     NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
  34.     NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
  35.     NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

  36.     stcIrqRegiCfg.enIRQn =u->Tx_IRQn;
  37.     stcIrqRegiCfg.pfnCallback = usart_common_err_call;
  38.     stcIrqRegiCfg.enIntSrc = u->INT_USART_EI;
  39.     enIrqRegistration(&stcIrqRegiCfg);
  40.     NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
  41.     NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
  42.     NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

  43.         USART_FuncCmd(u->usart_ch, UsartRx, Enable);
  44.     USART_FuncCmd(u->usart_ch, UsartRxInt, Enable);
  45.     USART_FuncCmd(u->usart_ch, UsartTx, Enable);
  46. }
 楼主| 斧王FUWANG 发表于 2023-12-20 15:17 | 显示全部楼层
处理4路串口的接收中断,异常处理中断
  1. void usart_common_call(void){
  2.         for ( usart_t i = u_4g ; i <= u_dw ; i++) {
  3.                 if (Set == USART_GetStatus(usart[i].usart_ch,UsartRxNoEmpty)){
  4.                         uint8_t u8Data = USART_RecData(usart[i].usart_ch);
  5.                         (void)RingBufWriteNew(&usart[i], u8Data,i);
  6.                 }
  7.         }       
  8. };

  9. void usart_common_err_call(void){
  10.         en_usart_status_t errFlag[3] = {UsartFrameErr,UsartParityErr,UsartOverrunErr};
  11.         for (int i = 0 ; i < 3 ; i++) {
  12.                 for ( usart_t j = u_4g ; j <= u_dw ; j++ ) {
  13.                         if (Set == USART_GetStatus(usart[j].usart_ch, errFlag[i]))
  14.                         {
  15.                                 USART_ClearStatus(usart[j].usart_ch, errFlag[i]);
  16.                         }
  17.                 }
  18.         }
  19. };

  20. static void RingBufWriteNew(Usart *usart, uint8_t u8Data,usart_t type)
  21. {
  22.        
  23.         if (usart->u16UsedSize > 150) { // 这里的长度没有配置
  24.                 resetBuf(usart);
  25.         }
  26.         usart->au8Buf[usart->u16UsedSize++] = u8Data;
  27.        
  28.         if ( type == uart1 ) {
  29.                 //自行判断是否完整接收 校验 ...
  30.         }
  31.        
  32.         if ( type == uart2 ) {
  33.                
  34.                
  35.         }
  36.        
  37.         if ( type == uart3 ) {
  38.                
  39.         }
  40.        
  41.         if ( type == uart4 ) {
  42.                
  43.         }
  44. }
 楼主| 斧王FUWANG 发表于 2023-12-20 15:18 | 显示全部楼层
最后~各路串口的打印调试

Print(uart1,"%s\r\n" , "Hello World!");
xdvca 发表于 2024-7-31 22:47 | 显示全部楼层
建议:确保m_PrintfDevice被正确使用并初始化。宏定义本身是简洁的,但如果printf在实际使用中不稳定或无法打印所有类型的格式化输出,可以考虑使用更安全的日志记录方法。
gouguoccc 发表于 2024-8-1 07:53 来自手机 | 显示全部楼层
说实话,有点臃肿。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

39

主题

277

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部