MSP430g2553硬件UART(基于官方例程的修改)


一开始官方例程的UART_Keyboard在电脑上老是运行不了,于是就自己上网学习了一下UART实现的具体过程,修改了一下官方的例程代码,在这里记录一下

其实官方例程有时候运行不起在于:
1.波特率设置
2.官方的Rx中断处理函数并不适用于所有串口调试程序
3.注意跳线帽!!!RX接TX,TX接RX!!

官方例程的UART程序流程

这里我用onenote大致画了一下
对于Tx和Rx中断:
当单片机内部的Rx_buf寄存器(一般来说8bits)收到了无符号字符型数据时,就会产生Rx中断,系统调用Rx中断处理函数,也就是说当收到一个字符串型数据时系统会产生多次Rx中断。
当单片机内部的Tx_buf寄存器(也是8bits)将数据发送完毕时,会产生Tx中断,同理,当发送一个字符串型数据时系统会产生多次Tx中断。
对于FIFO:
也就是申明的存储字符型数据的字符数组
RxFIFO用来读取Rx_buf传来的字符型数据,并供给CPU进行读取
TxFIFO用来存放CPU准备发送的数据,并让Tx_buf进行读取
所以每个FIFO要用三个变量来表示:读指针位置,写指针位置,已有的容量大小
在这里插入图片描述

代码分析

main.c

可以看出来主函数只起到了关闭看门狗的作用,精华都在初始化UART函数中


int main(void)
{
 WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
 USCI_A0_init();
}

USCI_A0_init()

void USCI_A0_init(void){
    //配置时钟
      DCOCTL = 0;                               // Select lowest DCOx and MODx settings
      BCSCTL1 = CALBC1_1MHZ;                    // Set DCO 实际时钟频率1048576Hz
      DCOCTL = CALDCO_1MHZ;
      //配置GPIO寄存器
      P1SEL = BIT1 + BIT2 ;                     // P1.1 = RXD, P1.2=TXD
      P1SEL2 = BIT1 + BIT2 ;                    // P1.1 = RXD, P1.2=TXD
    //配置串口寄存器
      UCA0CTL1 |= UCSSEL_2;                     // SMCLK
      UCA0BR0 = 104;                            // 1MHz 9600
      UCA0BR1 = 0;                              // 1MHz 9600
      UCA0MCTL =UCBRS_0;//UCBRS0;                        // Modulation UCBRSx = 1
      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
     //开中断
      IE2 |= UCA0RXIE+UCA0TXIE;			//使能TX,RX中断
      _enable_interrupts();
     //设置单片机工作模式
      _bis_SR_register(LPM0_bits);		//单片机工作在LPM0功耗模式
 }

在这里有几个比较重要的寄存器需要说明:
UCA0CTL1:
时钟源选择和软件复位使能
UCSSEL_2:时钟源一般可以选择ACLK和SMCLK(官网例程选择了ACLK,这里选择SMCLK)
至于软件复位的那位UCSWRST:0被禁用。USCI复位被释放用于运行。1被启用。USCI逻辑保持在复位状态。意思就是说在单片机复位之后 如果 此位是0 那么串口可以正常工作 为1 即保持 复位状态 复位状态后 此位为1 就是说 复位后如果不清零 那么串口是不会工作的

UCA0BR0,UCA0BR1
波特率配置寄存器

给定一个BRCLK时钟源,波特率用来决定需要分频的因子N:
N = fBRCLK/Baudrate
分频因子N通常是非整数值,因此至少一个分频器和一个调制阶段用来尽可能的接近N。
所以:
UCA0BRX用来存放N的整数部分,其中BR0存放低位,BR1存放高位(这里的SMCLK时钟源频率大概为32khz)

UCA0MCTL
波特率调整控制器

有整数部分时不够的,还要有小数部分!
UCBRSx = round( ( N – INT(N) ) × 8 )
注意这个寄存器的最后一位时用来选择模式的!!我们这里用0模式!
给出一个计算列题:
例2:32768Hz频率下驱动以2400波特率异步通ACLK = REFO = ~32768Hz, MCLK = SMCLK = DCO ~1.045MHz
N = fBRCLK/Baudrate = 32768/2400 = ~13.65
UCBRx = INT(N) = INT(13.65) = 13
UCBRSx = round( ( N – INT(N) )×8 ) = round( ( 13.65 – 13) × 8 )=round(5.2)=5
UCA0CTL1 |= UCSSEL_1; // 选ACLK为时钟
UCAxBR0 = 13;
UCAxBR1 = 0 ;
UCAxMCTL = 0x0A;//7-4:
UCBRFx,3-1:UCBRSx,0:UCOS16
UCBRSx为寄存器UCAxMCTL的1-3位,所以写入0x0A(00001010)

定义中断处理函数

//====================================中断处理函数============================================
//TX中断处理函数
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void)
{
//    while(!(IFG2 & UCA0TXIFG));  //待发送为空
    IFG2&=~UCA0TXIFG;     // 手动清除标志位,标志位置零
    UART_OnTx();          // 调用Tx事件处理函数
}
//RX中断处理函数
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
//  while (!(IFG2&UCA0TXIFG));                // 等待发送完成
   IFG2&=~UCA0RXIFG;                // USCI_A0 TX buffer ready?
   UART_OnRx();                      //!!!!!!!EVENT.H函数!
//  UCA0TXBUF = UCA0RXBUF;                    // TX -> RXed character
}

这里改写了一下中断处理函数,想要试一试配置成功与否的话可以直接在Rx中断里面写:UCA0TXBUF = UCA0RXBUF;收到啥发啥

/******************************************************************************************************
 * 名       称:UART_OnRx()
 * 功       能:UART的Rx事件处理函数
 * 入口参数:无
 * 出口参数:无
 * 说       明:对接收到的数据,区别对待进行处理
 * 范       例:无
 ******************************************************************************************************/
void UART_OnRx()
{
    unsigned char Temp=0;           //定义读取的RX_buf中的8bits数
    Temp=UCA0RXBUF;                 //读取RX_buf中的数据
    //判断RXBUF中的收到的数据 1:回车,匹配数据 0:不是回车,放入FIFO中
    if(Temp==0x0d)                  //如果是回车
    {
        if(Rx_FIFO_DataNum>0)       //如果已经收到数据
        {
            Command_match();        //判断指令
//            Rx_FIFO_Clear();        //读取完一次指令,清零
        }
        else{
            UART_SendString(String1);       //没收到任何数据
        }
    }
    else                            //收到的不是回车,则读取数据
    {
        Rx_FIFO_WriteChar(Temp);    //写入数据到FIFO中
    }
}

/******************************************************************************************************
 * 名       称:UART_OnTx()
 * 功       能:UART的Tx事件处理函数
 * 入口参数:无
 * 出口参数:无
 * 说       明:Tx_FIFO里有数据就将数据移到Tx Buffer寄存器中去
 * 范       例:无
 ******************************************************************************************************/
void UART_OnTx(void)
{
 unsigned char Temp;
 if(Tx_FIFO_DataNum>0)           //数据量==0为结束条件
 {
  Tx_FIFO_ReadChar(&Temp); //调用FIFO库函数,返回8bit数据
  UCA0TXBUF= Temp;            //
 }
}

全部的项目就上传到CSDN上好了,不一一打下来了

  • 8
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
官方例程,包含uart,iic,ad10等具体例子。msp430g2x13_ca_01.c Comp_A, Output Reference Voltages on P1.1 msp430g2x13_ca_02.c Comp_A, Detect Threshold, Set P1.0 if P1.1 > 0.25*Vcc msp430g2x13_ca_03.c Comp_A, Simple 2.2V Low Battery Detect msp430g2x33_adc10_01.c ADC10, Sample A0, Set P1.0 if A0 > 0.5*AVcc msp430g2x33_adc10_02.c ADC10, Sample A1, 1.5V Ref, Set P1.0 if A1 > 0.2V msp430g2x33_adc10_03.c ADC10, ADC10, Sample A10 Temp, Set P1.0 if Temp ++ ~2C msp430g2x33_adc10_04.c ADC10, ADC10, Sample A1, Signed, Set P1.0 if A1 > 0.5*AVcc msp430g2x33_adc10_05.c ADC10, ADC10, Sample A11, Lo_Batt, Set P1.0 if AVcc 0.5V msp430g2x33_adc10_12.c ADC10, Sample A7, 1.5V, TA1 Trig, Ultra-Low Pwr msp430g2x33_adc10_13.c ADC10, DTC Sample A1 32x, AVcc, TA0 Trig, DCO msp430g2x33_adc10_14.c ADC10, DTC Sample A1-0 16x, AVcc, Repeat Seq, DCO msp430g2x33_adc10_16.c ADC10, ADC10, DTC Sample A0 -> TA1, AVcc, DCO msp430g2x33_adc10_temp.c ADC10, Sample A10 Temp and Convert to oC and oF msp430g2xx3_1.c Software Toggle P1.0 msp430g2xx3_1_vlo.c Software Toggle P1.0, MCLK = VLO/8 msp430g2xx3_clks.c Basic Clock, Output Buffered SMCLK, ACLK and MCLK/10 msp430g2xx3_dco_calib.c Basic Clock with preloaded DCO calibration constants msp430g2xx3_dco_flashcal.c DCO Calibration Constants Programmer msp430g2xx3_flashwrite_01.c Flash In-System Programming, Copy SegC to SegD msp430g2xx3_LFxtal_nmi.c LFXT1 Oscillator Fault Detection msp430g2xx3_lpm3.c Basic Clock, LPM3 Using WDT ISR, 32kHz ACLK msp430g2xx3_lpm3_vlo.c Basic Clock, LPM3 Using WDT ISR, VLO ACLK msp430g2xx3_nmi.c Basic Clock, Configure RST/NMI as NMI msp430g2xx3_P1_01.c Software Poll P1.4, Set P1.0 if P1.4 = 1 msp430g2xx3_P1_02.c Software Port Interrupt Service on P1.4 from LPM4 msp430g2xx3_P1_03.c Poll P1 With Software with Internal Pull-up msp430g2xx3_P1_04.c P1 Interrupt from LPM4 with Internal Pull-up msp430g2xx3_pinosc_01.c Capacitive Touch, Pin Oscillator Method, 1 button msp430g2xx3_pinosc_02.c Capacitive Touch, Pin Oscillator Method, 4-buttons msp430g2xx3_pinosc_03.c Capacitive Touch, Pin Oscillator Method, 4-buttons, ACLK for CCR msp430g2xx3_pinosc_04.c Capacitive Touch, Pin Oscillator Method, 8 buttons, UART msp430g2xx3_ta_01.c Timer_A, Toggle P1.0, CCR0 Cont. Mode ISR, DCO SMCLK msp430g2xx3_ta_02.c Timer_A, Toggle P1.0, CCR0 Up Mode ISR, DCO SMCLK msp430g2xx3_ta_03.c Timer_A, Toggle P1.0, Overflow ISR, DCO SMCLK msp430g2xx3_ta_04.c Timer_A, Toggle P1.0, Overflow ISR, 32kHz ACLK msp430g2xx3_ta_05.c Timer_A, Toggle P1.0, CCR0 Up Mode ISR, 32kHz ACLK msp430g2xx3_ta_06.c Timer_A, Toggle P1.0, CCR1 Cont. Mode ISR, DCO SMCLK msp430g2xx3_ta_07.c Timer_A, Toggle P1.0-2, Cont. Mode ISR, DCO SMCLK msp430g2xx3_ta_08.c Timer_A, Toggle P1.0-2, Cont. Mode ISR, 32kHz ACLK msp430g2xx3_ta_10.c Timer_A, Toggle P1.1/TA0, Up Mode, DCO SMCLK msp430g2xx3_ta_11.c Timer_A, Toggle P1.1/TA0, Up Mode, 32kHz ACLK msp430g2xx3_ta_13.c Timer_A, Toggle P1.1/TA0, Up/Down Mode, DCO SMCLK msp430g2xx3_ta_14.c Timer_A, Toggle P1.1/TA0, Up/Down Mode, 32kHz ACLK msp430g2xx3_ta_16.c Timer_A, PWM TA1-2, Up Mode, DCO SMCLK msp430g2xx3_ta_17.c

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值