查看: 5598|回复: 6

[分享] MKL46 MCU UART0的初始化。

[复制链接]

该用户从未签到

12

主题

103

帖子

0

新手上路

Rank: 1

积分
173
最后登录
1970-1-1
发表于 2013-11-27 18:25:52 | 显示全部楼层 |阅读模式
看datasheet,说UART0使用的是内核时钟, UART1和UART2使用的是总线时钟。
我采用例程上的UART0初始化函数,
uart0_init(UART0_BASE_PTR, (g_ulCoreClkKHz / 2), 19200);
我发现初始化后UART0实际的波特率是9600,
而当:uart0_init(UART0_BASE_PTR, (g_ulCoreClkKHz / 4), 19200);
初始化后UART0实际的波特率是19200。所以感觉到很奇怪。
我的系统采用的是外部晶振,16MHz,内核时钟频率为48MHz。
UART初始化部分代码如下:
    PORTA_PCR1 = PORT_PCR_MUX(0x2); //UART0 Rx
    PORTA_PCR2 = PORT_PCR_MUX(0x2); //UART0 Tx

    SIM_SOPT2 |= SIM_SOPT2_UART0SRC(1); // select the PLLFLLCLK as UART0 clock source

    uart0_init(UART0_BASE_PTR, (g_ulCoreClkKHz / 4 ), 19200);
uart0初始化函数如下:
void uart0_init (UART0_MemMapPtr uartch, int sysclk, int baud)
{
    uint8 i;
    uint32 calculated_baud = 0;
    uint32 baud_diff = 0;
    uint32 osr_val = 0;
    uint32 sbr_val, uart0clk;
    uint32 baud_rate;
    uint32 reg_temp = 0;
    uint32 temp = 0;
    
    SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;
    
    // Disable UART0 before changing registers
    UART0_C2 &= ~(UART0_C2_TE_MASK | UART0_C2_RE_MASK);
  
    // Verify that a valid clock value has been passed to the function 
    if ((sysclk > 50000) || (sysclk < 32))
    {
        sysclk = 0;
        reg_temp = SIM_SOPT2;
        reg_temp &= ~SIM_SOPT2_UART0SRC_MASK;
        reg_temp |= SIM_SOPT2_UART0SRC(0);
        SIM_SOPT2 = reg_temp;
                       
                          // Enter inifinite loop because the 
                          // the desired system clock value is 
                          // invalid!!
                          while(1)
                                {}
    }
    
    // Verify that a valid value has been passed to TERM_PORT_NUM and update
    // uart0_clk_hz accordingly.  Write 0 to TERM_PORT_NUM if an invalid 
    // value has been passed.  
    if (TERM_PORT_NUM != 0)
    {
        reg_temp = SIM_SOPT2;
        reg_temp &= ~SIM_SOPT2_UART0SRC_MASK;
        reg_temp |= SIM_SOPT2_UART0SRC(0);
        SIM_SOPT2 = reg_temp;
                       
                          // Enter inifinite loop because the 
                          // the desired terminal port number 
                          // invalid!!
                          while(1)
                                {}
    }
    
    
    
    // Initialize baud rate
    baud_rate = baud;
    
    // Change units to Hz
    uart0clk = sysclk * 1000;
    // Calculate the first baud rate using the lowest OSR value possible.  
    i = 4;
    sbr_val = (uint32)(uart0clk/(baud_rate * i));
    calculated_baud = (uart0clk / (i * sbr_val));
        
    if (calculated_baud > baud_rate)
        baud_diff = calculated_baud - baud_rate;
    else
        baud_diff = baud_rate - calculated_baud;
    
    osr_val = i;
        
    // Select the best OSR value
    for (i = 5; i  baud_rate)
            temp = calculated_baud - baud_rate;
        else
            temp = baud_rate - calculated_baud;
        
        if (temp 3) && (osr_val < 9))
            UART0_C5|= UART0_C5_BOTHEDGE_MASK;
        
        // Setup OSR value 
        reg_temp = UART0_C4;
        reg_temp &= ~UART0_C4_OSR_MASK;
        reg_temp |= UART0_C4_OSR(osr_val-1);
    
        // Write reg_temp to C4 register
        UART0_C4 = reg_temp;
        
        reg_temp = (reg_temp & UART0_C4_OSR_MASK) + 1;
        sbr_val = (uint32)((uart0clk)/(baud_rate * (reg_temp)));
        
         /* Save off the current value of the uartx_BDH except for the SBR field */
        reg_temp = UART0_BDH & ~(UART0_BDH_SBR(0x1F));
   
        UART0_BDH = reg_temp |  UART0_BDH_SBR(((sbr_val & 0x1F00) >> 8));
        UART0_BDL = (uint8)(sbr_val & UART0_BDL_SBR_MASK);
        
        /* Enable receiver and transmitter */
        UART0_C2 |= (UART0_C2_TE_MASK
                    | UART0_C2_RE_MASK );
    }
    else
                {
        // Unacceptable baud rate difference
        // More than 3% difference!!
        // Enter infinite loop!
        while(1)
                                {}
                }                                       
    
}
回复

使用道具 举报

  • TA的每日心情
    开心
    2018-7-2 06:04
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    59

    主题

    2888

    帖子

    10

    金牌会员

    Rank: 6Rank: 6

    积分
    6030
    最后登录
    2025-8-21
    发表于 2013-11-28 11:24:16 | 显示全部楼层

    RE:MKL46 MCU UART0的初始化。

    你使用官网的那个FRDMKL46_Demo例程测试下,uart0初始化正常码?
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-2 06:04
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    59

    主题

    2888

    帖子

    10

    金牌会员

    Rank: 6Rank: 6

    积分
    6030
    最后登录
    2025-8-21
    发表于 2013-11-28 11:35:16 | 显示全部楼层

    RE:MKL46 MCU UART0的初始化。

    你选择时钟源的时候选择了PLL/2的频率作为UART0时钟源。
    计算波特率的时候就不能用g_ulCoreClkKHz去初始化了。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    12

    主题

    103

    帖子

    0

    新手上路

    Rank: 1

    积分
    173
    最后登录
    1970-1-1
     楼主| 发表于 2013-11-28 13:05:05 | 显示全部楼层

    回复:MKL46 MCU UART0的初始化。

    回复第 3 楼 于2013-11-28 11:35:16发表:
    你选择时钟源的时候选择了PLL/2的频率作为UART0时钟源。
    计算波特率的时候就不能用g_ulCoreClkKHz去初始化了。
     
     谢谢!
    那初始化的时候UART0的时钟应该怎么确定呢?
    我发现只有将g_ulCoreClkKHz/4传进去,才能得到想要的波特率

     
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    12

    主题

    103

    帖子

    0

    新手上路

    Rank: 1

    积分
    173
    最后登录
    1970-1-1
     楼主| 发表于 2013-11-28 14:36:36 | 显示全部楼层

    RE:MKL46 MCU UART0的初始化。

    找到问题所在了,是晶振错了,8M的晶振,当成16M的用了。所以出错。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-2 06:04
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    59

    主题

    2888

    帖子

    10

    金牌会员

    Rank: 6Rank: 6

    积分
    6030
    最后登录
    2025-8-21
    发表于 2013-11-28 15:45:48 | 显示全部楼层

    回复:MKL46 MCU UART0的初始化。

    回复第 4 楼 于2013-11-28 13:05:05发表:
    回复第 3 楼 于2013-11-28 11:35:16发表:
    你选择时钟源的时候选择了PLL/2的频率作为UART0时钟源。
    计算波特率的时候就不能用g_ulCoreClkKHz去初始化了。
     
     谢谢!
    那初始化的时候UART0的时钟应该怎么确定呢?
    我发现只有将g_ulCoreClkKHz/4传进去,才能得到想要的波特率

     

     

    我看那程序中有这么一段
    UART0 PLL bordrate.jpg
    以及另处调用uart0_init()时用到了uart0_clk_khz
    UART0 PLL bordrate2.jpg
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    18

    帖子

    0

    新手上路

    Rank: 1

    积分
    9
    最后登录
    1970-1-1
    发表于 2013-12-21 10:55:33 | 显示全部楼层

    回复:MKL46 MCU UART0的初始化。

    各种芯片datasheet上搜IC数据手册看中文版吧,不仅datasheet是中文的,还可以用中文关键字搜索datasheet内容
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-9-5 06:14 , Processed in 0.100657 second(s), 26 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表