340|1

3612

帖子

0

资源

纯净的硅(初级)

TI MSP430 如何实现模拟串口通信 [复制链接]

1、背景:

很多时候由于硬件资源有限,但又需要使用串口通信,此时可以考虑使用模拟串口;

2、前提:

要实现特定bps的串口速率,需要相应频率的定时器,保证误码率在可以接受的范围内;

例如:

1MHz的时钟最高可模拟9600bps的通信速率:1M/9600 = 104  误码率<1%

3、参考代码:

//******************************************************************************

//  ACLK = TACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO

//  //* An external watch crystal is required on XIN XOUT for ACLK *//  

//

//               MSP430G2xx1

//            -----------------

//        /|\|              XIN|-

//         | |                 | 32kHz

//         --|RST          XOUT|-

//           |                 |

//           |   CCI0B/TXD/P1.1|-------->

//           |                 | 9600 8N1

//           |   CCI0A/RXD/P1.2|<--------

//

//******************************************************************************

#include <msp430.h>

//------------------------------------------------------------------------------

// Hardware-related definitions

//------------------------------------------------------------------------------

#define UART_TXD   0x02                     // TXD on P1.1 (Timer0_A.OUT0)

#define UART_RXD   0x04                     // RXD on P1.2 (Timer0_A.CCI1A)

//------------------------------------------------------------------------------

// Conditions for 9600 Baud SW UART, SMCLK = 1MHz

//------------------------------------------------------------------------------

#define UART_TBIT_DIV_2     (1000000 / (9600 * 2))

#define UART_TBIT           (1000000 / 9600)

//------------------------------------------------------------------------------

// Global variables used for full-duplex UART communication

//------------------------------------------------------------------------------

unsigned int txData;                        // UART internal variable for TX

unsigned char rxBuffer;                     // Received UART character

//------------------------------------------------------------------------------

// Function prototypes

//------------------------------------------------------------------------------

void TimerA_UART_init(void);

void TimerA_UART_tx(unsigned char byte);

void TimerA_UART_print(char *string);

//------------------------------------------------------------------------------

// main()

//------------------------------------------------------------------------------

int main(void)

{

    WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer

    if (CALBC1_1MHZ==0xFF)                                        // If calibration constants erased

    {                                                                                       

      while(1);                             // do not load, trap CPU!!       

    }

    DCOCTL = 0;                             // Select lowest DCOx and MODx settings

    BCSCTL1 = CALBC1_1MHZ;

    DCOCTL = CALDCO_1MHZ;

    P1OUT = 0x00;                           // Initialize all GPIO

    P1SEL = UART_TXD + UART_RXD;            // Timer function for TXD/RXD pins

    P1DIR = 0xFF & ~UART_RXD;               // Set all pins but RXD to output

    P2OUT = 0x00;

    P2SEL = 0x00;

    P2DIR = 0xFF;

    __enable_interrupt();

    TimerA_UART_init();                     // Start Timer_A UART

    TimerA_UART_print("G2xx1 TimerA UART\r\n");

    TimerA_UART_print("READY.\r\n");

    for (;;)

    {

        // Wait for incoming character

        __bis_SR_register(LPM0_bits);

        // Update board outputs according to received byte

        if (rxBuffer & 0x01) P1OUT |= 0x01; else P1OUT &= ~0x01;    // P1.0

        if (rxBuffer & 0x02) P1OUT |= 0x08; else P1OUT &= ~0x08;    // P1.3

        if (rxBuffer & 0x04) P1OUT |= 0x10; else P1OUT &= ~0x10;    // P1.4

        if (rxBuffer & 0x08) P1OUT |= 0x20; else P1OUT &= ~0x20;    // P1.5

        if (rxBuffer & 0x10) P1OUT |= 0x40; else P1OUT &= ~0x40;    // P1.6

        if (rxBuffer & 0x20) P1OUT |= 0x80; else P1OUT &= ~0x80;    // P1.7

        if (rxBuffer & 0x40) P2OUT |= 0x40; else P2OUT &= ~0x40;    // P2.6

        if (rxBuffer & 0x80) P2OUT |= 0x80; else P2OUT &= ~0x80;    // P2.7

        // Echo received character

        TimerA_UART_tx(rxBuffer);

    }

}

//------------------------------------------------------------------------------

// Function configures Timer_A for full-duplex UART operation

//------------------------------------------------------------------------------

void TimerA_UART_init(void)

{

    TACCTL0 = OUT;                          // Set TXD Idle as Mark = '1'

    TACCTL1 = SCS + CM1 + CAP + CCIE;       // Sync, Neg Edge, Capture, Int

    TACTL = TASSEL_2 + MC_2;                // SMCLK, start in continuous mode

}

//------------------------------------------------------------------------------

// Outputs one byte using the Timer_A UART

//------------------------------------------------------------------------------

void TimerA_UART_tx(unsigned char byte)

{

    while (TACCTL0 & CCIE);                 // Ensure last char got TX'd

    TACCR0 = TAR;                           // Current state of TA counter

    TACCR0 += UART_TBIT;                    // One bit time till first bit

    TACCTL0 = OUTMOD0 + CCIE;               // Set TXD on EQU0, Int

    txData = byte;                          // Load global variable

    txData |= 0x100;                        // Add mark stop bit to TXData

    txData <<= 1;                           // Add space start bit

}

//------------------------------------------------------------------------------

// Prints a string over using the Timer_A UART

//------------------------------------------------------------------------------

void TimerA_UART_print(char *string)

{

    while (*string) {

        TimerA_UART_tx(*string++);

    }

}

//------------------------------------------------------------------------------

// Timer_A UART - Transmit Interrupt Handler

//------------------------------------------------------------------------------

#pragma vector = TIMERA0_VECTOR

__interrupt void Timer_A0_ISR(void)

{

    static unsigned char txBitCnt = 10;

    TACCR0 += UART_TBIT;                    // Add Offset to CCRx

    if (txBitCnt == 0) {                    // All bits TXed?

        TACCTL0 &= ~CCIE;                   // All bits TXed, disable interrupt

        txBitCnt = 10;                      // Re-load bit counter

    }

    else {

        if (txData & 0x01) {

          TACCTL0 &= ~OUTMOD2;              // TX Mark '1'

        }

        else {

          TACCTL0 |= OUTMOD2;               // TX Space '0'

        }

        txData >>= 1;

        txBitCnt--;

    }

}      

//------------------------------------------------------------------------------

// Timer_A UART - Receive Interrupt Handler

//------------------------------------------------------------------------------

#pragma vector = TIMERA1_VECTOR

__interrupt void Timer_A1_ISR(void)

{

    static unsigned char rxBitCnt = 8;

    static unsigned char rxData = 0;

    switch (__even_in_range(TAIV, TAIV_TAIFG)) { // Use calculated branching

        case TAIV_TACCR1:                        // TACCR1 CCIFG - UART RX

            TACCR1 += UART_TBIT;                 // Add Offset to CCRx

            if (TACCTL1 & CAP) {                 // Capture mode = start bit edge

                TACCTL1 &= ~CAP;                 // Switch capture to compare mode

                TACCR1 += UART_TBIT_DIV_2;       // Point CCRx to middle of D0

            }

            else {

                rxData >>= 1;

                if (TACCTL1 & SCCI) {            // Get bit waiting in receive latch

                    rxData |= 0x80;

                }

                rxBitCnt--;

                if (rxBitCnt == 0) {             // All bits RXed?

                    rxBuffer = rxData;           // Store in global variable

                    rxBitCnt = 8;                // Re-load bit counter

                    TACCTL1 |= CAP;              // Switch compare to capture mode

                    __bic_SR_register_on_exit(LPM0_bits);  // Clear LPM0 bits from 0(SR)

                }

            }

            break;

    }

}

//------------------------------------------------------------------------------


回复

2803

帖子

0

资源

纯净的硅(中级)

不错的分享,谢谢


回复
您需要登录后才可以回帖 登录 | 注册

最新文章 更多>>
    关闭
    站长推荐上一条 1/4 下一条

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

    电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表