当时为了调试,我在PCB板子上面画了一个DB9的插口,用以连接UCSI_A3的TXD和RXD的口,从而实现传输数据的功能。
DB9的二口是RXD口,DB9的三口是TXD口。
但是后来我发现UART所用的表示高低电平的电压和RS232的表示高低电平的电压不相同。RS232表示逻辑1的电平是-3~-15V,表示逻辑0的电平的+3~+15V 。所以我发现其实为了实现UART转变为RS232所用电平时,需要使用电平转换芯片。
但是要怎么利用UCSI_A3的UART模式,实现传输数据的功能呢?
1. 前言:
CPU与接口之间是通过并行方式传输的,接口与外设之间是通过串行方式传输的。所以,在串行接口中,必须要有“接收移位寄存器”(串转并)和发送移位寄存器(并转串)。MSP430F5438A上面的User's guide上面写的串行接口的结构是:
上图中黄色标注的部分即是串转并寄存器和并转串寄存器。
串行通信可以根据信息传送的方向分为单工,半双工,和全双工通讯。信息只能单向传输为单工通讯,信息能双向传输但不能同时双向传输被称为单双工通讯,信息可以同时双向传输被称为全双工通讯。
串行通讯又可以分为同步通讯和异步通讯两种,异步通讯(UART)的收发没有同一的时钟源,而同步通讯(SPI , I2C)有同一的时钟源。
USCI拥有一个硬件模块,支持多种串口模式。UART(通用异步收发器)是其中的一种,现就UART模式进行讲解。
2. UART的主要使用方法可以参照user's guide上面的一张图:
即:(1) 先置UCAxCTL1寄存器的UCSWRST的值为1。
(2) 根据自己的需要,配置相应的内容:包括时钟选择,分频比,调整参数UCBRS_x ,UCBRF_x。(具体怎么调整请参照User's guide,这里面就不一一列出了)
(3)清除UCSWRST位。
(4)允许中断标志位:UCRXIE或者UCTXIE。
调试一:
有下面的代码:
#include "msp430x54x.h"
unsigned char buffer[] = {"I'm youzi\n"};
void delay(unsigned int n)
{
unsigned int i,j;
for(i=0;i<n;i++)
for(j=0;j<1000;j++);
}
void Init_UART()
{
P10SEL = 0x30; // P10_4和P10_5第二功能打开,设置方向
P10DIR = 0x10;
UCA3CTL1 |= UCSWRST; // 首先使RST位置位,只有这样后面的设置才有效
UCA3CTL1 |= UCSSEL_2; // SMCLK,为系统时钟1048576Hz
UCA3BR0 = 9; // 1MHz 115200
UCA3BR1 = 0; // 1MHz 115200
UCA3MCTL |= UCBRS_1 + UCBRF_0; // 设置调整参数UCBRSx=1, UCBRFx=0
UCA3CTL1 &= ~UCSWRST; // RST复位
UCA3IE |= UCTXIE; // 使能发送中断允许
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // 关狗
Init_UART();
while(1)
{
while (!(UCA3IFG&UCTXIFG)); //等待BUF区准备好,当IFG=1时就表示准备好了
for(int i=0; i<sizeof(buffer); i++)
{
UCA3TXBUF = buffer[i]; //向串口发送数据
delay(20); //延时
__no_operation();
}
}
}
这段代码旨在实现每隔一段时间打印出" I'm youzi"
结果在串口调试助手显示出来为:
所以表示串口调试成功。
调试二:
有下面的代码:
#include "msp430x54x.h"
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P10SEL = 0x30; // P10.4,5 = USCI_A0 TXD/RXD
P10DIR = 0x10;
UCA3CTL1 |= UCSWRST; // **Put state machine in reset**
UCA3CTL1 |= UCSSEL_1; // CLK = ACLK
UCA3BR0 = 0x0D; // 2400 (see User's Guide)
UCA3BR1 = 0x00; //
UCA3MCTL |= UCBRS_6+UCBRF_0; // Modulation UCBRSx=6, UCBRFx=0
UCA3CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA3IE |= UCRXIE; // Enable USCI_A1 RX interrupt
__bis_SR_register(LPM3_bits + GIE); // Enter LPM3, interrupts enabled
__no_operation(); // For debugger
}
// Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCI_A3_VECTOR
__interrupt void USCI_A3_ISR(void)
{
switch(__even_in_range(UCA3IV,4))
{
case 0:break; // Vector 0 - no interrupt
case 2: // Vector 2 - RXIFG
while (!(UCA3IFG&UCTXIFG)); // USCI_A1 TX buffer ready?
UCA3TXBUF = UCA3RXBUF; // TX -> RXed character
break;
case 4:break; // Vector 4 - TXIFG
default: break;
}
}
这个代码的主要作用是为了实现传出的=传入的字符。
调试结果为:
即实现了接收了发送值的功能。
注:这个串口调试我花了好几天的时间才做完,后来发现是在P10.3 , P10.4口上面还接了个蓝牙HC06的1口和2口。导致串口调试助手一直收不到信号。
所以,当调试软件一直没有效果时,要好好检查一下硬件的原因。
串口UART的初步调试就到这里。回去睡觉了。