问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

msp430f5529库函数配置串口初始化(波特率计算公式)

创作时间:
作者:
@小白创作中心

msp430f5529库函数配置串口初始化(波特率计算公式)

引用
CSDN
1.
https://m.blog.csdn.net/m0_73801887/article/details/140726980

本文详细介绍了如何使用msp430f5529微控制器的库函数配置串口,包括端口初始化、波特率计算、结构体配置以及中断使能等关键步骤。对于正在学习或使用msp430的工程师具有直接的参考价值。

备战电赛,开始上手msp430,在串口这块浪费了一下午。很多帖子的串口代码分享是直接配置寄存器的,使用库函数的不多而且讲的不细,这篇帖子较为细致的说一下msp430f5529库函数配置串口。

msp430f5529火箭板一共有2个串口,usart0和usart1。usart0的TX口为P3.3,RX口为P3.4。usart1的TX口为P4.4,RX口为P4.5。

这里只讲usart0的配置,usart1同理,不再详细讲解。

首先,初始化端口,串口是片上外设,应该把用到的端口配置为外设的模拟输入:

  GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3,GPIO_PIN3 + GPIO_PIN4);

之后就是利用库函数的初始化结构体配置串口的基础功能,这里如果是之前经常使用stm32标准库的朋友,应该不会陌生。先定义结构体,结构体变量的名字是自己取的,这里取“param”(有点懒了,最好取能体现串口的名字)

  USCI_A_UART_initParam param = {0};//初始化为0

配置结构体中的各个量。首先选择时钟,这里我选的是SMCLK,如果没有对系统时钟初始化,那SMCLK默认1048576Hz,ACLK默认32768Hz 。我的板子的主频被我设置成了25MHz,所以SMCLK这里是25MHz。不过影响不大,我会给出波特率的计算方法,可以按照自己的实际情况更改

  param.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;//25MHz

接下来是重中之重。msp430f5529库函数设置串口波特率的方法有点复杂,它涉及三个变量(初始化结构体中的),分别是clockPrescalar、firstModReg、secondModReg。clockPrescalar是预分频值,可以把频率降低;firstModReg和secondModReg都是波特率计算的相关变量。假设选取的时钟频率是25MHz,如果设置串口波特率为9600,配置这三个量就行了。

第一步,将时钟频率除以目标波特率,得到总分频值,如下

第二步,计算预分频值。采用16倍过采样,故取N的整数部分再除以16,就是clockPrescalar的值。2604/16 = 162.75,可以取162

第三步,计算补偿值。firstModReg和secondModReg就是分频系数的补偿值,因为只取整数部分显然会导致较大的误差。firstModReg 的值为 取N的小数部分乘16后的整数:0.1667*16 = 2.6672,取整为3。secondModReg一般直接取0即可。

   param.clockPrescalar = 162;
   param.firstModReg = 3;
   param.secondModReg = 0;

之后的部分就是很套路的了,直接看代码:

  param.parity = USCI_A_UART_NO_PARITY;//无奇偶校验位
  param.msborLsbFirst = USCI_A_UART_LSB_FIRST;//LSB优先
  param.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;//一位停止位
  param.uartMode = USCI_A_UART_MODE;//串口模式
  param.overSampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;//启用过采样

使用配置函数将结构体中的设置配置给串口

  USCI_A_UART_init(USCI_A0_BASE, &param);

使能串口

  USCI_A_UART_enable(USCI_A0_BASE);

使能串口中断

  USCI_A_UART_clearInterrupt(USCI_A0_BASE,USCI_A_UART_RECEIVE_INTERRUPT);
  USCI_A_UART_enableInterrupt(USCI_A0_BASE,USCI_A_UART_RECEIVE_INTERRUPT);

这是完整初始化代码和中断代码:

    void USART0_Config(void)
    {

      GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3,GPIO_PIN3 + GPIO_PIN4);
 
      USCI_A_UART_initParam param = {0};
      param.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;//25MHz
      param.clockPrescalar = 162;
      param.firstModReg = 3;
      param.secondModReg = 0;
      param.parity = USCI_A_UART_NO_PARITY;
      param.msborLsbFirst = USCI_A_UART_LSB_FIRST;
      param.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;
      param.uartMode = USCI_A_UART_MODE;
      param.overSampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;
     
      USCI_A_UART_init(USCI_A0_BASE, &param);
 
      USCI_A_UART_enable(USCI_A0_BASE);
     
      USCI_A_UART_clearInterrupt(USCI_A0_BASE,USCI_A_UART_RECEIVE_INTERRUPT);
      USCI_A_UART_enableInterrupt(USCI_A0_BASE,USCI_A_UART_RECEIVE_INTERRUPT);
    
    }

    #pragma vector=USCI_A0_VECTOR
    __interrupt void USCI_A0_ISR (void)
    {
        switch (__even_in_range(UCA0IV, 4))
        {
            case 0: break;            // 无中断
            case 2: x = UCA0RXBUF;    // 接收中断
                    break;                
            case 4: break;            // 发送中断
            default: break;
        }

    }

补充一下时钟初始化函数,能让主频由1048576Hz变成25MHz

void System_Clock_Init(void)
{
    // Stop Watch Dog Timer
    WDT_A_hold(WDT_A_BASE);
    
    // XT1 Pin used as peripheral function for 32768 Hz
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4 + GPIO_PIN5);
    
    // XT2 Pin used as peripheral function for 4 MHz
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN2 + GPIO_PIN3);
    
    //__bis_SR_register(GIE);
    
    // System Power Improve step by step
    PMM_setVCore(PMM_CORE_LEVEL_1);
    PMM_setVCore(PMM_CORE_LEVEL_2);
    PMM_setVCore(PMM_CORE_LEVEL_3);
    
    UCS_setExternalClockSource(32768, 4000000);
    
    // Turn on external crystal
    UCS_turnOnLFXT1(UCS_XT1_DRIVE_3, UCS_XCAP_3);
    UCS_turnOnXT2(UCS_XT2_DRIVE_4MHZ_8MHZ);
    
    // UCS_XT2CLK_SELECT: 4 MHz    UCS_VLOCLK_SELECT: 10 kHz    UCS_REFOCLK_SELECT: 32768 Hz
    // 4 000 000 / 8 = 500 000 = 500 kHz
    // Set PLL Clock source and prescale
    UCS_initClockSignal(UCS_FLLREF, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_8);
    
    // Target PLL Frequency(kHz) and ratio
    // 25 000 000 / 500 000 = 50
    UCS_initFLLSettle(25000, 50);
    
    UCS_initClockSignal(UCS_ACLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);
    /*
        If the frequency is greater than 16 MHz,
        the function sets the MCLK and SMCLK source to the undivided DCO frequency.
        Otherwise, the function sets the MCLK and SMCLK source to the DCOCLKDIV frequency.
    */
    UCS_initClockSignal(UCS_MCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);
    UCS_initClockSignal(UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);
    
    UCS_turnOnSMCLK();
    
    Clk_ACLK = UCS_getACLK();
    Clk_SMCLK = UCS_getSMCLK();
    Clk_MCLK = UCS_getMCLK();
}
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号