華大HC32F460初使用及串口測試


前言

因工作需求,上手了一塊HC32F460,網上資料不是很多,因此記錄下調試記錄供后人參考。

使用環境

  • IDE: Keil v5.23.0
  • DDL: hc32f46x_ddl_Rev1.3.1
  • PROJECT: uart_irq_rx_tx

時鍾配置

簡單介紹

HC32提供了六個時鍾源,例程采用的是8M外部時鍾,因此這里也使用外部時鍾。內部時鍾配置暫時未搞明白,等后期更新。

外部晶振定義在system_hc32f46x.h第103行

#if !defined (XTAL_VALUE)
#define XTAL_VALUE ((uint32_t)8000000)  /*!< External high speed OSC freq. */
#endif

需要根據實際晶振大小配置。晶振錯誤時系統仍能運行,但是串口等需要時鍾的設備數據會出現錯誤。

我手上的開發板晶振是12Mhz,因此修改定義為12000000。

設置分頻

例程在main.cstatic void ClkInit(void)對系統時鍾進行了配置,采用的是Xtal to MPLL的方法。這里只關心分頻倍數。

   /* Set bus clk div. */
   stcSysClkCfg.enHclkDiv  = ClkSysclkDiv1;
   stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;
   stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;
   stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;
   stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;
   stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;
   stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;

這里對工作時鍾進行分頻。通過系統框圖可以看到,這時輸入時鍾MPLL倍頻出來的MPLLP。

image

分頻時注意不要超過工作時鍾的上限即可。

通過下列結構體進行倍頻

    /* MPLL config. */
    stcMpllCfg.pllmDiv = 1u; /* XTAL 8M / 1 */
    stcMpllCfg.plln = 50u;   /* 8M*50 = 400M */
    stcMpllCfg.PllpDiv = 4u; /* MLLP = 100M */
    stcMpllCfg.PllqDiv = 4u; /* MLLQ = 100M */
    stcMpllCfg.PllrDiv = 4u; /* MLLR = 100M */

MLLP為100M,可以計算出

    /* Set bus clk div. */
    stcSysClkCfg.enHclkDiv  = ClkSysclkDiv1;//100M
    stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;//50M
    stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;//100M
    stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;//50M
    stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;//25M
    stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;//25M
    stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;//50M

由於我需要測試串口最大速率,所以需要修改系統頻率最高(200M)。

12M分 /倍頻

分頻和例程相同,倍頻如下

    stcMpllCfg.pllmDiv = 12u; /* XTAL 12M / 3=4M */
    stcMpllCfg.plln = 400u;   /* 4M*100 = 400M */
    stcMpllCfg.PllpDiv = 2u; /* MLLP = 200M */
    stcMpllCfg.PllqDiv = 2u; /* MLLQ = 200M */
    stcMpllCfg.PllrDiv = 2u; /* MLLR = 200M */

查看配置時鍾

SDK中提供了獲取時鍾頻率的APICLK_GetClockFreq

要使用它,需要先初始化時鍾頻率結構體。

stc_clk_freq_t          stcClkFreq;//系統頻率

然后通過 CLK_GetClockFreq(&stcClkFreq);獲取頻率值。

image

可以看到,頻率和設置相同。

配置串口

例程默認采用的USART3

/* USART channel definition */
#define USART_CH                        (M4_USART3)

/* USART baudrate definition */
#define USART_BAUDRATE                  (115200ul)

/* USART RX Port/Pin definition */
#define USART_RX_PORT                   (PortE)
#define USART_RX_PIN                    (Pin04)
#define USART_RX_FUNC                   (Func_Usart3_Rx)

/* USART TX Port/Pin definition */
#define USART_TX_PORT                   (PortE)
#define USART_TX_PIN                    (Pin05)
#define USART_TX_FUNC                   (Func_Usart3_Tx)

由於修改串口配置牽涉到的地方較多,這里直接采用USART3進行測試。

燒錄工程到板子上后,串口發送數據后會回顯到屏幕上,如果時鍾不對,會出現回顯數據和發送數據不一致的情況。

收發邏輯

在接收到數據后,系統跳轉到UsartRxIrqCallback函數,讀取接收值,並且打開串口發送和TxEmpty中斷。

static void UsartRxIrqCallback(void)
{
    m_u16RxData = USART_RecData(USART_CH);
    USART_FuncCmd(USART_CH, UsartTxAndTxEmptyInt, Enable);
}

此時由於TxBuff為空,會進入UsartTxIrqCallback,發送讀取的值出去,關閉TxEmpty中斷,打開UsartTxCmplt中斷。

static void UsartTxIrqCallback(void)
{
    USART_SendData(USART_CH, m_u16RxData);
    USART_FuncCmd(USART_CH, UsartTxEmptyInt, Disable);
    USART_FuncCmd(USART_CH, UsartTxCmpltInt, Enable);
}

發送數據成功后,進入UsartTxCmpltIrqCallback,關閉中斷和串口發送功能。

static void UsartTxCmpltIrqCallback(void)
{
    USART_FuncCmd(USART_CH, UsartTxCmpltInt, Disable);
    USART_FuncCmd(USART_CH, UsartTx, Disable);
}

這些中斷回調函數通過中斷號綁定到具體中斷上

    /* Set USART RX IRQ */
    stcIrqRegiCfg.enIRQn = Int000_IRQn;
    stcIrqRegiCfg.pfnCallback = &UsartRxIrqCallback;

需要注意的是,由於關閉了UsartTx功能,后續無法發送任何數據出去,除非再次打開該功能。

DEBUG功能

SDK默認重定義printf函數到串口3上,不需要自己修改文件即可使用Printf。

相關的代碼實現在hc32f46x_utility.c中,也同樣包括毫秒延時和微妙延時函數(秒延時未提供,但無傷大雅)。

把串口發送中斷關掉,只保留串口接收中斷

static void UsartRxIrqCallback(void)
{
    m_u16RxData = USART_RecData(USART_CH);
//    USART_FuncCmd(USART_CH, UsartTxAndTxEmptyInt, Enable);
}

然后打開串口發送功能(在while(1)上面)

    /*Enable RX && RX interupt function*/
    USART_FuncCmd(USART_CH, UsartRx, Enable);
    USART_FuncCmd(USART_CH, UsartRxInt, Enable);
    USART_FuncCmd(USART_CH, UsartTx, Enable);

然后就可以使用printf或者USART_SendData發送數據了。

    while (1)
    {
//      printf("testing,[%d]\r\n",i);
      USART_SendData(USART_CH,0xA5);
      sysVar.txCount++;
      Ddl_Delay1ms(1000);
    }

波特率測試

理論上串口最高波特率為PCLK/32,PCLK為400MHz時,波特率為12.5Mhz

通過示波器抓數據得,2Bit為6.25MHz,符合理論值。

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM