您的位置 首页 模拟

MSP430单片机完成模仿串口通讯的规划

MSP430单片机实现模拟串口通信的设计-1、背景:

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

2、前提:

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

例如:

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

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

//——————————————————————————

// 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 UARTrn”);

TimerA_UART_print(“READY.rn”);

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;

}

}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/moni/345060.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部