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

        备战电赛,开始上手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();
}

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值