[技术问答]

初次使用HC32F460,问问内部HRC时钟使用问题

[复制链接]
4896|12
手机看帖
扫描二维码
随时随地手机跟帖
yxl12345678|  楼主 | 2021-6-6 19:59 | 显示全部楼层 |阅读模式
使用外部晶振例子太多了。如果使用内部HRC作为PLL的输入时钟源,然后倍频分频的配置如下,看看还有什么需要纠正地方吗?

/******************************************************************************/
/** \file system_hc32f46x.c
**
** A detailed description is available at
** @link Hc32f46xSystemGroup Hc32f46xSystem description @endlink
**
**   - 2018-10-15  1.0  Zhangxl First version
**
******************************************************************************/

/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_common.h"
#include "hc32_ddl.h"


/**
*******************************************************************************
** \addtogroup Hc32f46xSystemGroup
******************************************************************************/

/*******************************************************************************
* Global pre-processor symbols/macros ('define')
******************************************************************************/

//@{

/**
******************************************************************************
** System Clock Frequency (Core Clock) Variable according CMSIS
******************************************************************************/
uint32_t HRC_VALUE = HRC_16MHz_VALUE;
//uint32_t SystemCoreClock = MRC_VALUE;
uint32_t SystemCoreClock = HRC_16MHz_VALUE;
/**
******************************************************************************
** \brief  Setup the microcontroller system. Initialize the System and update
** the SystemCoreClock variable.
**
** \param  None
** \return None
******************************************************************************/
void SystemInit(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 20) | (3UL << 22)); /* set CP10 and CP11 Full Access */
#endif
   
   
   
    /////////////////////////////////////////////
    stc_clk_mpll_cfg_t   stcMpllCfg;
    en_clk_sys_source_t  enSysClkSrc;
    stc_clk_sysclk_cfg_t stcSysClkCfg;

    MEM_ZERO_STRUCT(enSysClkSrc);//清零初始化
    MEM_ZERO_STRUCT(stcSysClkCfg);//清零初始化
    MEM_ZERO_STRUCT(stcMpllCfg);//清零初始化

    ///设置总线时钟 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;  
    CLK_SysClkConfig(&stcSysClkCfg);
   
    ///切换系统时钟源送入到MPLL  Switch system clock source to MPLL.
    CLK_HrcCmd(Enable);//使能HRC振荡器
    //CLK_MrcCmd(Enable);//使能MRC振荡器
    while(Set != CLK_GetFlagStatus(ClkFlagHRCRdy)) //等待HRC定
     {
       ;
     }
   
    stcMpllCfg.pllmDiv = 2u; // 输入分频
    stcMpllCfg.plln    = 24u;   // 锁相倍频
    stcMpllCfg.PllpDiv = 4u; // 输出分频P
    stcMpllCfg.PllqDiv = 4u; // 输出分频Q
    stcMpllCfg.PllrDiv = 4u; // 输出分频R
   
    CLK_SetPllSource(ClkPllSrcHRC);//选择HRC为PLL时钟源
    CLK_MpllConfig(&stcMpllCfg);//配置MPLL
   /*  */
    /* flash read wait cycle setting */
    EFM_Unlock();
    EFM_SetLatency(EFM_LATENCY_4);
    EFM_Lock();
   
    CLK_MpllCmd(Enable);//使能MPLL
    while(Set != CLK_GetFlagStatus(ClkFlagMPLLRdy)) //等待PLL稳定
     {
       ;
     }
   
    /* Switch system clock source to MPLL. */
    CLK_SetSysClkSource(CLKSysSrcMPLL);
   //CLK_SetSysClkSource(ClkSysSrcMRC);
     //CLK_SetSysClkSource(ClkSysSrcHRC);
    ////////////////////////////////////////////////////////
   
    SystemCoreClockUpdate();
   
}

void SystemCoreClockUpdate(void)  // Update SystemCoreClock variable
{
    uint8_t tmp = 0u;
    uint32_t plln = 19u, pllp = 1u, pllm = 0u, pllsource = 0u;

    /* Select proper HRC_VALUE according to ICG1.HRCFREQSEL bit */
    /* ICG1.HRCFREQSEL = '0' represent HRC_VALUE = 20000000UL   */
    /* ICG1.HRCFREQSEL = '1' represent HRC_VALUE = 16000000UL   */
    if (1UL == (HRC_FREQ_MON() & 1UL))
    {
        HRC_VALUE = HRC_16MHz_VALUE;
    }
    else
    {
        HRC_VALUE = HRC_20MHz_VALUE;
    }

    tmp = M4_SYSREG->CMU_CKSWR_f.CKSW;
    switch (tmp)
    {
        case 0x00:  /* use internal high speed RC */
            SystemCoreClock = HRC_VALUE;
            break;
        case 0x01:  /* use internal middle speed RC */
            SystemCoreClock = MRC_VALUE;
            break;
        case 0x02:  /* use internal low speed RC */
            SystemCoreClock = LRC_VALUE;
            break;
        case 0x03:  /* use external high speed OSC */
            SystemCoreClock = XTAL_VALUE;
            break;
        case 0x04:  /* use external low speed OSC */
            SystemCoreClock = XTAL32_VALUE;
            break;
        case 0x05:  /* use MPLL */
            /* PLLCLK = ((pllsrc / pllm) * plln) / pllp */
            pllsource = M4_SYSREG->CMU_PLLCFGR_f.PLLSRC;
            plln = M4_SYSREG->CMU_PLLCFGR_f.MPLLN;
            pllp = M4_SYSREG->CMU_PLLCFGR_f.MPLLP;
            pllm = M4_SYSREG->CMU_PLLCFGR_f.MPLLM;
            /* use exteranl high speed OSC as PLL source */
            if (0ul == pllsource)
           {
               SystemCoreClock = (XTAL_VALUE) / (pllm + 1ul) * (plln + 1ul) / (pllp + 1ul);
            }
            /* use interanl high RC as PLL source */
            else if (1ul == pllsource)
            {
                SystemCoreClock = (HRC_VALUE) / (pllm + 1ul) * (plln + 1ul) / (pllp + 1ul);
            }
            else
            {
                /* Reserved */
            }
            break;
    }
}

//@} // UsartGroup

/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

使用特权

评论回复
yxl12345678|  楼主 | 2021-6-6 20:00 | 显示全部楼层
288460bcb8cd29d1d.png

可能我是哪里没有配置对,使用串口通信的时候,有点问题,收发不是很正常。






使用特权

评论回复
yxl12345678|  楼主 | 2021-6-6 20:01 | 显示全部楼层
以下是和串口相关的,使用了串口超时中断接收数据帧。这个应该没有问题的。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
//////////////////////
  ////////////////外设时钟设置//////////////////////////

   /// Enable peripheral clock
   PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_USART1, Enable);  
   PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_USART2, Enable);
   PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_USART3, Enable);
   
       /* Timer0 peripheral enable */
    PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIM01, Enable);
    PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIM02, Enable);



void TimeInit(void)  //定时器初始化
{
    stc_clk_freq_t stcClkTmp;
    stc_tim0_base_init_t stcTimerCfg;
    stc_tim0_trigger_init_t StcTimer0TrigInit;

    MEM_ZERO_STRUCT(stcClkTmp);
    MEM_ZERO_STRUCT(stcTimerCfg);
    MEM_ZERO_STRUCT(StcTimer0TrigInit);

    /* Timer0 peripheral enable */
    PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIM01, Enable);
    PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIM02, Enable);

    /* Clear CNTAR register for channel A */
    TIMER0_WriteCntReg(M4_TMR01, Tim0_ChannelA, 0u);
    TIMER0_WriteCntReg(M4_TMR01, Tim0_ChannelB, 0u);
    TIMER0_WriteCntReg(M4_TMR02, Tim0_ChannelA, 0u);

    /* Config register for channel A */
    stcTimerCfg.Tim0_CounterMode = Tim0_Async;
    stcTimerCfg.Tim0_AsyncClockSource = Tim0_LRC;
    stcTimerCfg.Tim0_ClockDivision = Tim0_ClkDiv8;
    stcTimerCfg.Tim0_CmpValue = 800u;
    TIMER0_BaseInit(M4_TMR01, Tim0_ChannelA, &stcTimerCfg);
   
    stcTimerCfg.Tim0_CounterMode = Tim0_Async;
    stcTimerCfg.Tim0_AsyncClockSource = Tim0_LRC;
    stcTimerCfg.Tim0_ClockDivision = Tim0_ClkDiv8;
    stcTimerCfg.Tim0_CmpValue = 800u;
    TIMER0_BaseInit(M4_TMR01, Tim0_ChannelB, &stcTimerCfg);
   
    stcTimerCfg.Tim0_CounterMode = Tim0_Async;
    stcTimerCfg.Tim0_AsyncClockSource = Tim0_LRC;
    stcTimerCfg.Tim0_ClockDivision = Tim0_ClkDiv8;
    stcTimerCfg.Tim0_CmpValue = 800u;
    TIMER0_BaseInit(M4_TMR02, Tim0_ChannelA, &stcTimerCfg);
   
   
    /* Clear compare flag */
    TIMER0_ClearFlag(M4_TMR01, Tim0_ChannelA);
    TIMER0_ClearFlag(M4_TMR01, Tim0_ChannelB);
    TIMER0_ClearFlag(M4_TMR02, Tim0_ChannelA);

    /* Config timer0 hardware trigger */
    StcTimer0TrigInit.Tim0_InTrigEnable = false;
    StcTimer0TrigInit.Tim0_InTrigClear = true;
    StcTimer0TrigInit.Tim0_InTrigStart = true;
    StcTimer0TrigInit.Tim0_InTrigStop = false;
    TIMER0_HardTriggerInit(M4_TMR01, Tim0_ChannelA, &StcTimer0TrigInit);

    StcTimer0TrigInit.Tim0_InTrigEnable = false;
    StcTimer0TrigInit.Tim0_InTrigClear = true;
    StcTimer0TrigInit.Tim0_InTrigStart = true;
    StcTimer0TrigInit.Tim0_InTrigStop = false;
    TIMER0_HardTriggerInit(M4_TMR01, Tim0_ChannelB, &StcTimer0TrigInit);
  
    StcTimer0TrigInit.Tim0_InTrigEnable = false;
    StcTimer0TrigInit.Tim0_InTrigClear = true;
    StcTimer0TrigInit.Tim0_InTrigStart = true;
    StcTimer0TrigInit.Tim0_InTrigStop = false;
    TIMER0_HardTriggerInit(M4_TMR02, Tim0_ChannelA, &StcTimer0TrigInit);   
   
}


/*******************************************************************************
* 函 数 名: UART_Init
* 函数功能: 串口初始化
* 输    入: 无
* 输    出: 无
*******************************************************************************/   
void UART_Init(void)
{
   //USART_DeInit(M4_USART1);
   //USART_DeInit(M4_USART2);
   // USART_DeInit(M4_USART3);
  
    en_result_t enRet = Ok;
    stc_irq_regi_conf_t stcIrqRegiCfg;

    const stc_usart_uart_init_t stcInitCfg = {
        UsartIntClkCkNoOutput,
        UsartClkDiv_1,
        UsartDataBits8,
        UsartDataLsbFirst,
        UsartOneStopBit,
        UsartParityNone,
        UsartSamleBit8,
        UsartStartBitFallEdge,
        UsartRtsEnable,
    };
   
    const stc_usart_uart_init_t stcInitCfg1 = {
        UsartIntClkCkNoOutput,
        UsartClkDiv_1,
        UsartDataBits9,
        UsartDataLsbFirst,
        UsartOneStopBit,
        UsartParityEven,
        UsartSamleBit8,
        UsartStartBitFallEdge,
        UsartRtsEnable,
    };   

    /////////配置串口参数/////////////////////////

     enRet = USART_UART_Init(M4_USART1, &stcInitCfg1);
    if (enRet != Ok)
    {
        while (1)
        {
        }
    }
    enRet = USART_UART_Init(M4_USART2, &stcInitCfg1);
    if (enRet != Ok)
    {
        while (1)
        {
        }
    }   
   enRet = USART_UART_Init(M4_USART3, &stcInitCfg);
    if (enRet != Ok)
    {
        while (1)
        {
        }
    }     
   
   
   
    ///////////配置波特率///////////////////
    enRet = USART_SetBaudrate(M4_USART3, 9600u);
    if (enRet != Ok)
    {
        while (1)
        {
        }
    }   
    enRet = USART_SetBaudrate(M4_USART1, 9600u);
    if (enRet != Ok)
    {
        while (1)
        {
        }
    }
    enRet = USART_SetBaudrate(M4_USART2, 9600u);
    if (enRet != Ok)
    {
        while (1)
        {
        }
    }   
   
   
        ///Set USART RX IRQ
    stcIrqRegiCfg.enIRQn = Int000_IRQn;
    stcIrqRegiCfg.pfnCallback = &Usart1RxIrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_USART1_RI;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    // Set USART RX error IRQ
    stcIrqRegiCfg.enIRQn = Int001_IRQn;
    stcIrqRegiCfg.pfnCallback = &Usart1ErrIrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_USART1_RI;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
   
        ///Set USART RX IRQ
    stcIrqRegiCfg.enIRQn = Int002_IRQn;
    stcIrqRegiCfg.pfnCallback = &Usart2RxIrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_USART2_RI;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    // Set USART RX error IRQ
    stcIrqRegiCfg.enIRQn = Int003_IRQn;
    stcIrqRegiCfg.pfnCallback = &Usart2ErrIrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_USART2_RI;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
   
    ///Set USART RX IRQ
    stcIrqRegiCfg.enIRQn = Int004_IRQn;
    stcIrqRegiCfg.pfnCallback = &Usart3RxIrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_USART3_RI;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    // Set USART RX error IRQ
    stcIrqRegiCfg.enIRQn = Int005_IRQn;
    stcIrqRegiCfg.pfnCallback = &Usart3ErrIrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_USART3_RI;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
   
   
   
    ///Set USART1 RX timeout error IRQ
    stcIrqRegiCfg.enIRQn = Int006_IRQn;
    stcIrqRegiCfg.pfnCallback = &Usart1TimeoutIrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_USART1_RTO;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
   
    /// Set USART1 RX timeout error IRQ
    stcIrqRegiCfg.enIRQn = Int007_IRQn;
    stcIrqRegiCfg.pfnCallback = &Usart2TimeoutIrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_USART2_RTO;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
   
    /// Set USART1 RX timeout error IRQ
    stcIrqRegiCfg.enIRQn = Int008_IRQn;
    stcIrqRegiCfg.pfnCallback = &Usart3TimeoutIrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_USART3_RTO;
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
   
   
    ///Enable RX && TX function
    USART_FuncCmd(M4_USART1, UsartRx, Enable);
    USART_FuncCmd(M4_USART1, UsartTx, Enable);
   
    USART_FuncCmd(M4_USART2, UsartRx, Enable);
    USART_FuncCmd(M4_USART2, UsartTx, Enable);   
   
    USART_FuncCmd(M4_USART3, UsartRx, Enable);
    USART_FuncCmd(M4_USART3, UsartTx, Enable);  
   
    //Enable RX && RX interupt function*/
    USART_FuncCmd(M4_USART1, UsartRxInt, Enable);
    USART_FuncCmd(M4_USART2, UsartRxInt, Enable);
    USART_FuncCmd(M4_USART3, UsartRxInt, Enable);
   
    USART_FuncCmd(M4_USART1, UsartTimeOut, Enable);
    USART_FuncCmd(M4_USART1, UsartTimeOutInt, Enable);
    USART_FuncCmd(M4_USART2, UsartTimeOut, Enable);
    USART_FuncCmd(M4_USART2, UsartTimeOutInt, Enable);
    USART_FuncCmd(M4_USART3, UsartTimeOut, Enable);
    USART_FuncCmd(M4_USART3, UsartTimeOutInt, Enable);
}



///////////////////////////接收中断//////////////////////////////////////
////////////////////////////////////////////////////////////////
void Usart1RxIrqCallback(void)
{
  m_u16RxData=USART_RecData(M4_USART1);
  USART_FuncCmd(M4_USART1, UsartTxAndTxEmptyInt, Enable);
}

void Usart2RxIrqCallback(void)
{
  m_u16RxData=USART_RecData(M4_USART1);
  USART_FuncCmd(M4_USART1, UsartTxAndTxEmptyInt, Enable);
}

void Usart3RxIrqCallback(void)
{
  m_u16RxData=USART_RecData(M4_USART1);
  USART_FuncCmd(M4_USART1, UsartTxAndTxEmptyInt, Enable);
}

////////////////////////////接收超时中断/////////////////////////////////////
////////////////////////////////////////////////////////////////
void Usart1TimeoutIrqCallback(void)
{
   TIMER0_Cmd(M4_TMR01, Tim0_ChannelA,Disable);
   USART_ClearStatus(M4_USART1, UsartRxTimeOut);
}

void Usart2TimeoutIrqCallback(void)
{
   TIMER0_Cmd(M4_TMR01, Tim0_ChannelB,Disable);
   USART_ClearStatus(M4_USART2, UsartRxTimeOut);
}

void Usart3TimeoutIrqCallback(void)
{
   cmcc=1;
   TIMER0_Cmd(M4_TMR02, Tim0_ChannelA,Disable);
   USART_ClearStatus(M4_USART3, UsartRxTimeOut);
}

////////////////////错误中断////////////////////////////////
//////////////////////////////////////////////////////
void Usart1ErrIrqCallback(void)
{
  if (Set == USART_GetStatus(M4_USART1, UsartFrameErr))
    {
      USART_ClearStatus(M4_USART1, UsartFrameErr);
    }
  else
    {
      
    }
  if (Set == USART_GetStatus(M4_USART1, UsartParityErr))
    {
      USART_ClearStatus(M4_USART1, UsartParityErr);
    }
  else
    {
      
    }

  if (Set == USART_GetStatus(M4_USART1, UsartOverrunErr))
    {
      USART_ClearStatus(M4_USART1, UsartOverrunErr);
    }
  else
    {
      
    }
}

void Usart2ErrIrqCallback(void)
{
  if (Set == USART_GetStatus(M4_USART2, UsartFrameErr))
    {
      USART_ClearStatus(M4_USART2, UsartFrameErr);
    }
  else
    {
      
    }

  if (Set == USART_GetStatus(M4_USART2, UsartParityErr))
    {
      USART_ClearStatus(M4_USART2, UsartParityErr);
    }
  else
    {
      
    }

  if (Set == USART_GetStatus(M4_USART2, UsartOverrunErr))
    {
      USART_ClearStatus(M4_USART2, UsartOverrunErr);
    }
  else
    {
      
    }
}

void Usart3ErrIrqCallback(void)
{
  if (Set == USART_GetStatus(M4_USART3, UsartFrameErr))
    {
      USART_ClearStatus(M4_USART3, UsartFrameErr);
    }
  else
    {
      
    }

  if (Set == USART_GetStatus(M4_USART3, UsartParityErr))
    {
      USART_ClearStatus(M4_USART3, UsartParityErr);
    }
  else
    {
      
    }

  if (Set == USART_GetStatus(M4_USART3, UsartOverrunErr))
    {
      USART_ClearStatus(M4_USART3, UsartOverrunErr);
    }
  else
    {
      
    }
}

使用特权

评论回复
yxl12345678|  楼主 | 2021-6-6 20:01 | 显示全部楼层
主要还是 HRC使用内部时钟PLL的可能哪里没有配置好。希望哪位能帮看看下。

使用特权

评论回复
martinhu| | 2021-6-7 10:29 | 显示全部楼层
本帖最后由 martinhu 于 2021-6-7 11:03 编辑

楼主系统时钟用的是48MHz,UART使用的PCLK1设置为24M,但是MPLL的输出,应该是先倍频240MHz~480MHz,然后分频下来,楼主只倍频到196MHz,这个是有问题的。

UART内部的时钟分频设置的是DIV1,波特率9600,过采样设置的是OVER8 = 1,
这样代入公式,可以算出DIV_Integer大于255,超出了BRR寄存器的DIV_Integer(0~255)的上限值……,
事实上波特率设置函数会校验出错误并应该返回失败值
所以波特率设置不准,楼主需要设置UART内部的时钟分配器为DIV4或者过采样使用OVER16,
5654660bd8386506a1.png

使用特权

评论回复
yxl12345678|  楼主 | 2021-6-7 14:29 | 显示全部楼层
本帖最后由 yxl12345678 于 2021-6-7 16:15 编辑

stcMpllCfg.pllmDiv = 1u; // 输入分频
    stcMpllCfg.plln    = 25u; //锁相倍频
    stcMpllCfg.PllpDiv = 4u; // 输出分频P
    stcMpllCfg.PllqDiv = 4u; // 输出分频Q
    stcMpllCfg.PllrDiv = 4u; // 输出分频R


HRC 选择16MHZ,输入不分频,倍频25,达到400MHZ
PLLP分频输出作为系统时钟,设置是4分频,也就是系统时钟为100MHZ

USART的时钟来自PCLK1

  ///设置总线时钟 Set bus clk div
    stcSysClkCfg.enHclkDiv  = ClkSysclkDiv1;  
    stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;  
    stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;  
    stcSysClkCfg.enPclk1Div = ClkSysclkDiv2; (2分频)  
    stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;  
    stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;  
    stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;  
    CLK_SysClkConfig(&stcSysClkCfg);
    所以,PLCK1=SYSCLK/2=100MHZ/2=50MHZ。


const stc_usart_uart_init_t stcInitCfg = {
        UsartIntClkCkNoOutput,
        UsartClkDiv_4,(串口配置四分频  C=PCLK1/4)
        UsartDataBits8,
        UsartDataLsbFirst,
        UsartOneStopBit,
        UsartParityNone,
        UsartSamleBit8,
        UsartStartBitFallEdge,
        UsartRtsEnable,
    };
enRet = USART_UART_Init(M4_USART1, &stcInitCfg);
    if (enRet != Ok)
    {
        while (1)
        {
        }
    }
==========================
C=PLCK1/4=12.5MHZ。经过串口时钟分配后的实际波特率发生时钟,串口使用时钟。
波特率B = C / (8 * (2 - OVER8) * (DIV_Integer + 1))             (DIV_Integer  0~0xFF)


使用特权

评论回复
martinhu| | 2021-6-7 15:06 | 显示全部楼层
本帖最后由 martinhu 于 2021-6-7 15:07 编辑
yxl12345678 发表于 2021-6-7 14:29
stcMpllCfg.pllmDiv = 1u; // 输入分频
    stcMpllCfg.plln    = 25u; //锁相倍频
    stcMpllCfg.PllpDi ...

这么配置是对的,不过与你之前发的不一样
8521360bdc547ec3ed.png

如果PCLK1设置50M的话,那么楼主串口的问题,主要是BRR波特率寄存器溢出了,UART里面的时钟设置分频一下应该就好了,不要使用DIV1

使用特权

评论回复
yxl12345678|  楼主 | 2021-6-7 15:55 | 显示全部楼层
martinhu 发表于 2021-6-7 15:06
这么配置是对的,不过与你之前发的不一样

是的,那个我之前疏忽了。

使用特权

评论回复
yxl12345678|  楼主 | 2021-6-7 16:12 | 显示全部楼层
******************************************************************************
** System Clock Frequency (Core Clock) Variable according CMSIS
******************************************************************************/
uint32_t HRC_VALUE = HRC_16MHz_VALUE;
//uint32_t SystemCoreClock = MRC_VALUE;
uint32_t SystemCoreClock = HRC_16MHz_VALUE;

====================
这里写错了应该是:
uint32_t HRC_VALUE = HRC_16MHz_VALUE;
uint32_t SystemCoreClock = 100 000000;

使用特权

评论回复
tail066| | 2021-7-15 14:10 | 显示全部楼层
一堆代码,真心佩服你们能耐着性子看下来

使用特权

评论回复
Luckk0517| | 2024-4-16 17:00 | 显示全部楼层
博主我现在用内部HRC作为时钟源,配置timer0 定时中断,按照你的教程pclk1频率输出符合预期,但是定时器一直无法中断,有遇到过这个问题吗?另外我看其他博主HRC需要设置icg文件,这个有关系吗?

使用特权

评论回复
610u| | 2024-4-30 09:44 | 显示全部楼层
使用内部HRC作为PLL的输入时钟源的话从哪里查资料?

使用特权

评论回复
lvuu| | 2024-4-30 16:27 | 显示全部楼层
寄存器溢出的问题哦。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

83

帖子

0

粉丝