历史上的今天
今天是:2024年10月16日(星期三)
2019年10月16日 | TI MSP430 如何实现模拟串口通信
2019-10-16 来源:eefocus
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
史海拾趣
|
前言 随着市场的发展,现在的MP3播放器品种越来越多,价钱也越来越实惠。也越来越多的MP3进入了用户的口袋。可以说是MP3随身听丰富了个人的世界,能随时随地随心所欲地欣赏美妙音乐。作为随身听,MP3的最终目的是还原真实的音乐。作为音响爱好者, ...… 查看全部问答> |
|
windows xp 与 windows ce 嵌入式系统的usb通信 现有一个条形码识别掌机, 掌机系统为 windows ce.net 6.0, 有usb接口。 将掌机usb接口直接与windows vista电脑相接,不需要任何操作就可以实现通信。 但将掌机与windows xp相接,用了很多方法都不行,比如安装一个activesync 4.5,在连接 ...… 查看全部问答> |
|
可用于主控制的接口有CH375,SL811,还有吗?用于从控制的就多了,如PDIUSBD12,还有MCU内置,如C8051F340就内置USB控制器. 这写USB从控制器能用作主控制器吗?谢谢!… 查看全部问答> |
|
库文件完全一样,示例代码能运行,但是即使把示例代码完全复制到自己的工程中都不能输出正确的结果。复制到自己的项目中后,完全相同的代码但是编译后的大小要比demo工程直接编译的大一点点。一直到不到哪里出了问题。有人遇到过吗?或者给点查错的 ...… 查看全部问答> |
|
美国Robei公司开发了一套全新的FPGA设计仿真工具,现在在教育界和工业界引起巨大的反响。 下面是这个软件的简单介绍: Robei FPGA仿真软件是一款世界上最小的FPGA仿真工具。该软件具备先进的图形化设计工具,代码修改,Verilog编译仿真和波形分析 ...… 查看全部问答> |




