wenbo2005.online

学习记录 / 基础 TxT 篇

UART

基础 TxT 篇2025-06-11

MSPM0G3507有四个串口,本案例将使用PA10和PA11引脚上的UART0外设,搭配开发板板载的CH340这个USB转串口芯片,实现接收上位机(电脑)发送过来的串口数据,再通过串口发送功能将数据发送给上位机(电脑)的操作。

串口的时钟来源一共有三个(越高波特率越准,使用32MHz应该分频到8MHz左右,过高乱码!!):

BUSCLK:由内部高频振荡器提供的CPU时钟,通常芯片出厂时设置为了32MHz。

MFCLK:只能使用固定的4MHz时钟(参考用户手册132页)。开启的话需要配置时钟树的SYSOSC_4M分支,才能够正常开启。

LFCLK:由内部的低频振荡器提供时钟(32KHz)。在运行、睡眠、停止和待机模式下有效,使用该时钟可以实现更低的功耗。

一,图形化配置界面(关于串口的配置,其他自行配置):

1,在SYSCTL选项卡中,开启 Use Clock Tree

2,在UART选项卡中:

(一),基本配置

Name:USART_0

UART Profiles(配置模板):Custom (自定义)

Clock Source (时钟来源):BUSCLK (内部高速32M)

Cloack Divider(时钟分频):Divide by 1

TBR(波特率):9600(默认)

Claculated Baud Rate (实际波特率):9598.08

(二),高级配置

Oversampling(采样周期):16x

通常选择3和8即可,如果时钟偏差较大或者时钟速度太快导致波特率分频的系数计算异常,就选择16档

(三),中断配置

Enable Interrupts(是否开启接收中断):Receive(这里只开启接收中断)

Intrrupt Priority(中断优先级):Default(默认)

(四),PinMux 引脚设置

Rx pin :PA11/57

Tx Pin:PA10/56

建议将两个引脚上拉!!!

(二),代码编写:

#include "ti_msp_dl_config.h"
#include "stdio.h"
#include "string.h"

volatile uint32_t uwTick = 0;

//注意此处一定要加 volatile ,否则主函数无法正常使用这两个变量!!
volatile char rxdata[128];
volatile char rxindex=0;

void UART_Tx_Display(char* str,unsigned int length);

volatile uint32_t rx_time=0;
void Rx_Proc()
{
    if(uwTick - rx_time<200) return;
    rx_time=uwTick;

    if(rxindex > 0)
    {
        UART_Tx_Display(rxdata, rxindex);
        rxindex = 0;
        memset(rxdata, '\0',128);
    }
}

int main(void)
{
    SYSCFG_DL_init();
    //清除串口中断标志(开启之前要先清除中断标志位,否则开启中断后将会自动进入中断一次)
    NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN);
    //使能串口中断
    NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
    while (1)
    {
        Rx_Proc();
    }
}

//串口轮询发送字符串
void UART_Tx_Display(char* str,unsigned int length)
{
    for(uint32_t i=0; i<length; i++)
    {
    //检测串口发送寄存器是否处于忙碌状态
        while(DL_UART_isBusy(UART_0_INST)){}
            DL_UART_Main_transmitData(UART_0_INST, str[i]);
    }
}

//串口的中断服务函数
void UART_0_INST_IRQHandler(void)
{
    //如果产生了串口中断
    switch(DL_UART_getPendingInterrupt(UART_0_INST))
    {
    //如果是接收中断
        case DL_UART_IIDX_RX:
            rx_time = uwTick;
            rxdata[rxindex++] = DL_UART_Main_receiveData(UART_0_INST);
        break;
        default:
        break;
    }
}

void SysTick_Handler(void)
{
    uwTick++;
}

注意:可以重定向printf函数,但使用浮点类型可能会卡死(需要配置工程的优化等级,将默认的O2级优化降为O0,即不优化即可)

//重定向fputc函数
int fputc(int ch, FILE *stream)
{
    while( DL_UART_isBusy(UART_0_INST)){}
    DL_UART_Main_transmitData(UART_0_INST, ch);
    return ch;
}