【MSP430】MSP430深入研究 之 通用收发器USART(上)

    通用同步/异步收发器采用一个硬件,支持两种通用串行总线接口模式(msp430f16x支持三种,另外一种是I2C),UART接口(异步模式),SPI接口(同步模式)。我们可以根据寄存器UxTCL的SYNC来选择USART的工作模式。在MSP430F149中有两个相同的串行总线接口,可以分别或者同事配置成两种模式。

——摘自《MSP430基础与实践》

这次先介绍通用异步串行接口UART;

【MSP430】MSP430深入研究 之 通用收发器USART(上)_第1张图片

figure1. USART(in UART modem)

那大致可以看出他就分为以下几个部分:

>串口控制器:UxCTL

>接受控制器:UxRCTL

>发送控制器:UxTCTL

>波特率控制器:UxBR0 UxBR1 UxMCTL

>收发使能控制器:UxME

>收发中断控制器:UxIE

>标志寄存器:UxIFG


figure 2. Flow Chart of USART Initializing 

USART Control Register:


figure 3. USART Control Register

可见SWRST默认是为1:意思是USART默认为Reset状态,所以我们在设置完,只有把SWRST置为0才能使能UART或SPI或I2C;

感觉说这些都是多余浪费时间的,既然是深入研究,那么我们就做点别人很少研究的东西!

关于波特率的设置:

【MSP430】MSP430深入研究 之 通用收发器USART(上)_第2张图片

figure 4. Baud Rate

波特率的设置,datasheet上已经给出了解释!可能大家对UxBR0、UxBR1的认识已经没有什么问题了!重要是UxMCTL,我们先来看看UxMCTL的寄存器:


figure 5. Register of UxMCTL

mi : Data of each corresponding modulation bit (1 or 0);

所以不管你把那个置为1,只要他们的和与8相除,商为接近你想要得到的小数的值即可!

举个例子:MCLK = 8000 000Hz, Baud Rate =  9600;

UxBR + (m0+m1+ ... + m7)/8 = 8000 0000/9600 = 833  + 0.33333

UxBR 设为 833 不用说了,8 X 0.3333 = 2.666 ≈ 3;那么m0~m7里面只要有3个1就可以了,所以为了方便期间我们用移位的方法:

unsigned char temp = 0;

for(i=0; i<3; i++)

{

    temp = temp <<1;

    temp |= 1;

}

由于串口通信比较简单,就没什么好多说的了!

实例代码:

#include <msp430x14x.h>
#include "msp430_lib.h"

#define BUFF_SIZE 128
typedef struct {
    int recv_len;
    unsigned char recv_buff[BUFF_SIZE];
}UART_RECV;
UART_RECV u_recv;
void uart0_init(int baud_rate)
{
    unsigned char i,temp;
    // 设为复位模式,方便多次初始化
    U0CTL |= SWRST;
    // 8个bit
    U0CTL |= CHAR;
    // 这里波特率设置
    U0BR1 = (unsigned int)0xff&((NOW_SYSCLK/baud_rate)>>16);
    U0BR0 = (unsigned int)(NOW_SYSCLK/baud_rate)&0xff;
    i = (NOW_SYSCLK - baud_rate*(unsigned int)(NOW_SYSCLK/baud_rate))*8/baud_rate;
    while(i){
        i--;
        temp = temp << 1;
        temp |= 1;
    }
    U0MCTL = temp;
    // 进入标准模式
    U0CTL &= ~SWRST;
    // 使能发送和接收
    U0ME |= UTXE0 + URXE0;
    // 使能接收中断
    U0IE |= URXIE0;
    // 配置PIN为特殊功能模式
    P3SEL |= BIT7 + BIT6;
    // 使能全局中断
    _EINT();
    u_recv.recv_len = 0;
}
/*
 * 数据发送函数
 */
void uart_senddata(unsigned char byte)
{
    while(!(U0IFG & UTXIFG0));
    U0TXBUF = byte;
}
//  中断处理函数
#pragma vector=UART0RX_VECTOR
__interrupt void uart_rxirq()
{
    u_recv.recv_buff[u_recv.recv_len++] = U0RXBUF;
}
中断数据接收的地方,我创建了一个缓冲区,用了一个全局变量!方便一下子接收很多数据!


请多多指教!

你可能感兴趣的:(串口通信)