这里需要介绍一下串口的时钟来源,串口的时钟来源一共有三个,分别是:
BUSCLK
:由内部高频振荡器提供的CPU时钟,通常芯片出厂时设置为了32MHz。
MFCLK
:只能使用固定的4MHz时钟(参考用户手册132页)。开启的话需要配置时钟树的SYSOSC_4M
分支,才能够正常开启。
LFCLK
:由内部的低频振荡器提供时钟(32KHz)。在运行、睡眠、停止和待机模式下有效,使用该时钟可以实现更低的功耗。
在时钟树中打开MFCLK的开关。
本案例使用的是MFCLK
作为串口的时钟来源,开启MFCLK
需要在sysconfig中配置时钟树。在sysconfig左侧的选项卡中找到SYSCTL
选项,在选项页中找到 Use Clock Tree
进行打勾,以开启时钟树的配置。
在sysconfig中,左侧可以选择MCU的外设,我们找到并点击UART选项卡,在UART中点击ADD,就可以添加串口外设。
配置串口的参数。
串口的基本配置。这里使用的是波特率为9600、数据位8位、停止位1位、校验位无、不使用硬件流控制的配置。
串口的高级配置。这里我们使用默认选项。需要注意的是采样周期Oversampling
,采样周期的选择有3、8、16等三个档,通常选择3和8即可,如果时钟偏差较大或者时钟速度太快导致波特率分频的系数计算异常,就选择16档。只要不要让sysconfig报错即可。这里我们的串口时钟频率是4MHz,所以我们选择16档。
串口中断的配置。本案例使用中断方式的串口接收,每当接收到一个字节将会进入到接收中断中。
设置串口的引脚。
代码
#include "ti_msp_dl_config.h"
volatile unsigned int delay_times = 0;
volatile unsigned char uart_data = 0;
void delay_ms(unsigned int ms);
void uart0_send_char(char ch);
void uart0_send_string(char* str);
int main(void)
{
SYSCFG_DL_init();
//清除串口中断标志
NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN);
//使能串口中断
NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
while (1)
{
//LED引脚输出高电平
DL_GPIO_setPins(LED1_PORT, LED1_PIN_14_PIN);
delay_ms(500);
//LED引脚输出低电平
DL_GPIO_clearPins(LED1_PORT, LED1_PIN_14_PIN);
delay_ms(500);
}
}
//搭配滴答定时器实现的精确ms延时
void delay_ms(unsigned int ms)
{
delay_times = ms;
while( delay_times != 0 );
}
//串口发送单个字符
void uart0_send_char(char ch)
{
//当串口0忙的时候等待,不忙的时候再发送传进来的字符
while( DL_UART_isBusy(UART_0_INST) == true );
//发送单个字符
DL_UART_Main_transmitData(UART_0_INST, ch);
}
//串口发送字符串
void uart0_send_string(char* str)
{
//当前字符串地址不在结尾 并且 字符串首地址不为空
while(*str!=0&&str!=0)
{
//发送字符串首地址中的字符,并且在发送完成之后首地址自增
uart0_send_char(*str++);
}
}
//滴答定时器的中断服务函数
void SysTick_Handler(void)
{
if( delay_times != 0 )
{
delay_times--;
}
}
//串口的中断服务函数
void UART_0_INST_IRQHandler(void)
{
//如果产生了串口中断
switch( DL_UART_getPendingInterrupt(UART_0_INST) )
{
case DL_UART_IIDX_RX://如果是接收中断
//接发送过来的数据保存在变量中
uart_data = DL_UART_Main_receiveData(UART_0_INST);
//将保存的数据再发送出去
uart0_send_char(uart_data);
break;
default://其他的串口中断
break;
}
}
-
串口中断必须手动开启。通过函数
NVIC_EnableIRQ
指定开启某一个中断。开启之前要先清除中断标志位,否则开启中断后将会自动进入中断。 -
串口发送数据。可以通过函数
DL_UART_Main_transmitData
将字符数据发出。但为了确保不会阻塞发送通道的数据,需要增加忙判断。例如,你在发送ABCD时,刚刚准备发A,A还没有发送出去,芯片就要发送B了,这样就导致了数据丢失。 -
串口接收数据。接收数据本案例是通过串口中断接收的方式,一有数据过来就马上中断接收,非特殊情况不会有阻塞。