鲜衣怒马 发表于 2015-2-12 09:50:43

求助:KE系列官方库中UART波特率设置问题(已解决)

本帖最后由 鲜衣怒马 于 2015-2-12 16:41 编辑

昨天学习KE04,自己搭板子用官方库总算把LED点亮了,调试串口时发现全是乱码,追踪串口初始化时发现官方的波特率设置似乎和参考手册上的公式不一致
void UART_Init(UART_Type *pUART, UART_ConfigType *pConfig)
{
    uint16_t u16Sbr;
    uint8_t u8Temp;
    uint32_t u32SysClk = pConfig->u32SysClkHz;
    uint32_t u32Baud = pConfig->u32Baudrate;

    /* Sanity check */
    ASSERT((pUART == UART0) || (pUART == UART1) || (pUART == UART2));

        /* Enable the clock to the selected UART */   
    if (pUART == UART0)
        {
                SIM->SCGC |= SIM_SCGC_UART0_MASK; //使能UART0总线时钟
        }
#if defined(CPU_KE02)| defined(CPU_KE06)
        else if (pUART == UART1)
        {
      SIM->SCGC |= SIM_SCGC_UART1_MASK;
        }
    else
        {
      SIM->SCGC |= SIM_SCGC_UART2_MASK;
        }
#endif   
    /* Make sure that the transmitter and receiver are disabled while we
   * change settings.
   */
    pUART->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK ); //更改设置前关闭发送和接受
   
    /* Configure the UART for 8-bit mode, no parity */
    pUART->C1 = 0;
   
    /* Calculate baud settings */
    u16Sbr = (((u32SysClk)>>4) + (u32Baud>>1))/u32Baud;
   
    /* Save off the current value of the UARTx_BDH except for the SBR field */
    u8Temp = pUART->BDH & ~(UART_BDH_SBR_MASK);
   
    pUART->BDH = u8Temp |UART_BDH_SBR(u16Sbr >> 8);
    pUART->BDL = (uint8_t)(u16Sbr & UART_BDL_SBR_MASK);

    /* Enable receiver and transmitter */
    pUART->C2 |= (UART_C2_TE_MASK | UART_C2_RE_MASK );
}


非官方库中的初始化代码跟参考手册一样
void UART_Init(UART_InitTypeDef* UART_InitStruct)
{
    uint16_t sbr;
    static bool is_fitst_init = true;
    /* enable clock gate */
    *((uint32_t*) SIM_UARTClockGateTable.addr) |= SIM_UARTClockGateTable.mask;
   
    UART_Type * UARTx = (UART_Type*)UART_InstanceTable;
   
    /* disable Tx Rx first */
    UARTx->C2 &= ~((UART_C2_TE_MASK)|(UART_C2_RE_MASK));
       
    /* disable Tx Rx */
    UARTx->C2 &= ~((UART_C2_TE_MASK)|(UART_C2_RE_MASK));
   
    /* config baudrate */
    sbr = UART_InitStruct->srcClock/((UART_InitStruct->baudrate)*16);
    UARTx->BDH &= ~(UART_BDH_SBR_MASK);
    UARTx->BDH |= (sbr>>8) & UART_BDH_SBR_MASK;
    UARTx->BDL = (sbr & UART_BDL_SBR_MASK);
   
    /* enable Tx Rx */
    UARTx->C2 |= ((UART_C2_TE_MASK)|(UART_C2_RE_MASK));
   
    /* link debug instance */
    /* if it's first initalized ,link getc and putc to it */
    if(is_fitst_init)
    {
      UART_DebugInstance = UART_InitStruct->instance;
    }
    is_fitst_init = false;
}

何解?

鲜衣怒马 发表于 2015-2-12 09:53:20

请看
第一段的35行
第二段的17行

PS:给代码加点颜色没加上。。。

javabean 发表于 2015-2-12 09:56:17

找个逻辑分析仪看看实际的数据情况

子鱼 发表于 2015-2-12 10:25:09

鲜衣怒马 发表于 2015-2-12 09:53
请看
第一段的35行
第二段的17行


官方的代码中
还需要看第40、41行的代码
   
    pUART->BDH = u8Temp |UART_BDH_SBR(u16Sbr >> 8);
    pUART->BDL = (uint8_t)(u16Sbr & UART_BDL_SBR_MASK);

和非官方库中的也是不一样的

鲜衣怒马 发表于 2015-2-12 10:49:04

子鱼 发表于 2015-2-12 10:25
官方的代码中
还需要看第40、41行的代码
   


基本一样

鲜衣怒马 发表于 2015-2-12 10:52:35

两者的SBR计算下来相差0.5??

FSL_TICS_ZJJ 发表于 2015-2-12 10:57:28

鲜衣怒马 发表于 2015-2-12 10:52
两者的SBR计算下来相差0.5??

你好!
其实是官方的代码在计算波特率的时候,考虑了四舍五入的过程。
    u16Sbr = (((u32SysClk)>>4) + (u32Baud>>1))/u32Baud;
这样计算是没有错误的,相当于+0.5,如果UART Module clock / (baud*16) 的小数大于0.5,则进位,如果小于0.5则不进位。
不知道你自己的板子外围晶振是否是8M,官方是8M,bus时钟配置为20M,所以建议你检查下你的busclock以及你的波特率,看看你实际的值和理论值是否偏差较大。

FSL_TICS_ZJJ 发表于 2015-2-12 11:02:30

本帖最后由 FSL_TICS_ZJJ 于 2015-2-12 11:06 编辑

鲜衣怒马 发表于 2015-2-12 10:52
两者的SBR计算下来相差0.5??

你时钟模式是配的FEE吗?
先配置BUSOUT,SIM_SOPT0, 把bus时钟输出到PTH2,看看是不是20M?
然后再用示波器看看你的波特率是否偏差了1.5%。

鲜衣怒马 发表于 2015-2-12 11:09:04

FSL_TICS_ZJJ 发表于 2015-2-12 10:57
你好!
其实是官方的代码在计算波特率的时候,考虑了四舍五入的过程。
    u16Sbr = (((u32SysClk)>>4) + ...

谢谢,明白了

FSL_TICS_ZJJ 发表于 2015-2-12 11:13:23

鲜衣怒马 发表于 2015-2-12 11:09
谢谢,明白了

不客气,后续有问题,欢迎继续交流。

鲜衣怒马 发表于 2015-2-12 11:13:41

FSL_TICS_ZJJ 发表于 2015-2-12 11:02
你时钟模式是配的FEE吗?
先配置BUSOUT,SIM_SOPT0, 把bus时钟输出到PTH2,看看是不是20M?
然后 ...

时钟配置是FEI ,可能是时钟配置有点问题吧,我再看看

FSL_TICS_ZJJ 发表于 2015-2-12 11:34:08

鲜衣怒马 发表于 2015-2-12 11:13
时钟配置是FEI ,可能是时钟配置有点问题吧,我再看看

FEI,那么你要按照出厂值来,切记在你不知道trim准确值的时候乱trim,否则容易时钟偏掉。
你按照出厂值37.5Khz配置。

鲜衣怒马 发表于 2015-2-12 11:59:20

FSL_TICS_ZJJ 发表于 2015-2-12 11:34
FEI,那么你要按照出厂值来,切记在你不知道trim准确值的时候乱trim,否则容易时钟偏掉。
你按照出厂值37 ...

那个例程确实调用了ICS_Trim()进行了调整,那么Trim准确值具体怎么得到?内部参考时钟默认是37.5K,是不是初始化时不用调整?谢谢

FSL_TICS_ZJJ 发表于 2015-2-12 14:03:12

鲜衣怒马 发表于 2015-2-12 11:59
那个例程确实调用了ICS_Trim()进行了调整,那么Trim准确值具体怎么得到?内部参考时钟默认是37.5K,是不 ...

关于trim,你可以看看这个帖子:
【经验分享】使用CodeWarrior10.5软件的PE工具trim芯片

可以使用这个方法得到ICS_C3,ICS_C4的值,然后以后你把值填到你的ICS_C3以及ICS_C4寄存器中trim就可以了。
另外,你也可以不trim,直接就用出厂值就行了。

jinyi7016 发表于 2015-2-12 17:16:37

时钟应该是主要原因吧

ayaqby 发表于 2015-2-12 21:13:56

jinyi7016 发表于 2015-2-12 17:16
时钟应该是主要原因吧

ZJJ的态度老好了,最佳FAE提名哦{:hug:}

mcucow 发表于 2015-2-15 11:27:23

波特率 要准的话
我记得第一天就是晶振不要用整数的 8M,12M
页: [1]
查看完整版本: 求助:KE系列官方库中UART波特率设置问题(已解决)