单片机的通讯必然逃不过UART,串口通讯对于对于单片机的调试运行也有着非常重要的作用,通过UART可以实现多设备的通讯,实现更复杂功能的实现。UART的基本原理也不过多的赘述了,网上很多的文章描述的肯定也比我讲的清楚,本文只介绍一下功能的实现并且在板子上进行验证。例程也可以在Resource Explorer中找到。
这个例程实现的功能是MSP432通过UART与PC进行通讯。MSP432将通过的串口收到的字符发回给PC,并在串口调试工具中显示出来。UART帧格式被配置为一个起始位,一个停止位,无校验位。P1.2与P1.3分别为接收端口与发送端口。使用的波特率为9600.。
首先我们先要配置串口结构体,如下面代码所示。
const eUSCI_UART_ConfigV1 uartConfig =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK, // 时钟源
78, // BRDIV = 78
2, // UCxBRF = 2
0, // UCxBRS = 0
EUSCI_A_UART_NO_PARITY, // 无校验
EUSCI_A_UART_LSB_FIRST, // 默认低位优先
EUSCI_A_UART_ONE_STOP_BIT, // 一位停止位
EUSCI_A_UART_MODE, // UART模式
EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
EUSCI_A_UART_8_BIT_LEN // 8 bit data length
};
要配置的参数这么多我们应该怎么写呢。SDK的用户手册和数据手册非常的好用,波特率相关的设置,用户手册里都计算好了相关的参数,只需要查表就可以了,不用自己辛辛苦苦的按照波特率计算公式去计算。
后面关于数据传输的参数也都可以在用户手册里找到说明。
接下来是主函数的编写,代码如下。
int main(void)
{
/* 设置看门狗 */
MAP_WDT_A_holdTimer();
/* 选择P1.2 和P1.3 为UART功能 */
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
/* 设置时钟源为12MHz */
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);
/* 配置UART*/
MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);
/* 使能UART */
MAP_UART_enableModule(EUSCI_A0_BASE);
/* 使能中断 */
MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
MAP_Interrupt_enableInterrupt(INT_EUSCIA0);
MAP_Interrupt_enableSleepOnIsrExit();
MAP_Interrupt_enableMaster();
while(1)
{
MAP_PCM_gotoLPM0();
}
}
代码中将P1.2和P1.3设置为UART功能,之所以选择GPIO_PRIMARY_MODULE_FUNCTION是因为通过查询芯片手册我们可以得知这两个引脚的第一功能为串口功能。
最后呢是中断回调函数的编写。将收到的数据发回给电脑串口。
void EUSCIA0_IRQHandler(void)
{
uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE);
if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)
{
MAP_UART_transmitData(EUSCI_A0_BASE, MAP_UART_receiveData(EUSCI_A0_BASE));
}
}
将代码烧入板子,观察运行结果。通过电脑发送数据都可以通过开发板打回数据。
但是发现了与以往使用串口不同的是,这个串口并不需要外接任何的模块,直接通过电脑就可以了。这个是因为这两个引脚在开发板上已经被跳线帽和板子上的串口调试芯片相连了,所以不需要外加的任何东西。
下面用串口来实现控制LED的亮灭,发送1LED点亮,发送其他值,LED熄灭。
#include "msp.h"
#include
#include
#include
const eUSCI_UART_ConfigV1 uartConfig =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
78, // BRDIV = 78
2, // UCxBRF = 2
0, // UCxBRS = 0
EUSCI_A_UART_NO_PARITY, // No Parity
EUSCI_A_UART_LSB_FIRST, // LSB First
EUSCI_A_UART_ONE_STOP_BIT, // One stop bit
EUSCI_A_UART_MODE, // UART mode
EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
EUSCI_A_UART_8_BIT_LEN // 8 bit data length
};
int main(void)
{
/* Halting WDT */
MAP_WDT_A_holdTimer();
GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
/* Selecting P1.2 and P1.3 in UART mode */
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3,
GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
/* Setting DCO to 12MHz */
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);
//![Simple UART Example]
/* Configuring UART Module */
MAP_UART_initModule(EUSCI_A2_BASE, &uartConfig);
/* Enable UART module */
MAP_UART_enableModule(EUSCI_A2_BASE);
/* Enabling interrupts */
MAP_UART_enableInterrupt(EUSCI_A2_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
MAP_Interrupt_enableInterrupt(INT_EUSCIA2);
MAP_Interrupt_enableSleepOnIsrExit();
MAP_Interrupt_enableMaster();
//![Simple UART Example]
while(1)
{
MAP_PCM_gotoLPM0();
}
}
/* EUSCI A0 UART ISR - Echoes data back to PC host */
void EUSCIA2_IRQHandler(void)
{
uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A2_BASE);
uint8_t recieve;
if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)
{
recieve = MAP_UART_receiveData(EUSCI_A2_BASE);
if(recieve == 49)
GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);
else
GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
MAP_UART_transmitData(EUSCI_A2_BASE, recieve);
}
}
总的来说,MSP432的串口相关操作相较于平时常用的arduino来说复杂了许多,仍需要多加应用才能够熟练的掌握。