历史上的今天
返回首页

历史上的今天

今天是: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

推荐阅读

史海拾趣

DCD [Digital Core Design]公司的发展小趣事

DCD公司自创立之初,就专注于数字核心设计领域的研发。创始人们凭借对电子技术的深刻理解和市场需求的敏锐洞察,带领团队攻克了一个又一个技术难关。在产品研发初期,公司面临着资金短缺和技术难题的双重压力,但团队凭借着坚韧不拔的精神,成功研发出了首款具有竞争力的数字核心设计产品,为公司的发展奠定了坚实的基础。

GTM公司的发展小趣事

DCD公司自创立之初,就专注于数字核心设计领域的研发。创始人们凭借对电子技术的深刻理解和市场需求的敏锐洞察,带领团队攻克了一个又一个技术难关。在产品研发初期,公司面临着资金短缺和技术难题的双重压力,但团队凭借着坚韧不拔的精神,成功研发出了首款具有竞争力的数字核心设计产品,为公司的发展奠定了坚实的基础。

大毅科技公司的发展小趣事

大毅科技一直注重技术创新和研发投入。公司拥有一支高素质的研发团队,不断推出具有市场竞争力的新产品。其中,高压电阻和可修整电阻等产品得到了客户的广泛认可。此外,大毅科技还积极投入于新型材料的研发,以提高产品的性能和降低成本。这些技术创新的成果不仅使大毅科技在市场中保持了领先地位,还为公司的持续发展奠定了坚实基础。

安森德(Ascend)公司的发展小趣事

安森德公司自创立之初,便以技术创新为核心竞争力。在半导体工艺领域,公司研发团队不断攻坚克难,成功研发出具有自主知识产权的超结MOSFET技术。这一技术的导通损耗和开关损耗均达到行业领先水平,为电源设备带来了更高的效率和更低的能源消耗。凭借这一技术突破,安森德的产品迅速在市场上获得认可,为公司的快速发展奠定了坚实基础。

Hirose Electric公司的发展小趣事

随着产品技术的成熟,安森德公司开始积极拓展市场。公司凭借优质的产品和服务,成功进入工业电源、电机驱动、消费电子等多个领域。同时,安森德积极寻求与全球顶尖企业的战略合作,通过与这些企业的技术交流和业务合作,不断提升自身的技术水平和市场竞争力。这些合作不仅为安森德带来了更多的商业机会,也进一步提升了公司在行业内的知名度和影响力。

Deutsch公司的发展小趣事

随着全球环保意识的不断提高,电子行业的环保要求也日益严格。Deutsch公司积极响应环保号召,将环保和可持续发展作为公司的重要战略之一。公司投入大量资源研发环保型产品和技术,减少生产过程中的能源消耗和污染排放。同时,公司还积极参与环保公益活动,推动整个行业的绿色发展。这些努力不仅提升了公司的社会形象,也为公司的可持续发展奠定了坚实基础。

问答坊 | AI 解惑

专业人员教授如何测试MP3音质

前言 随着市场的发展,现在的MP3播放器品种越来越多,价钱也越来越实惠。也越来越多的MP3进入了用户的口袋。可以说是MP3随身听丰富了个人的世界,能随时随地随心所欲地欣赏美妙音乐。作为随身听,MP3的最终目的是还原真实的音乐。作为音响爱好者, ...…

查看全部问答>

低频数字式相位测量仪

本帖最后由 paulhyde 于 2014-9-15 08:57 编辑 低频数字式相位测量仪  …

查看全部问答>

看到一个好玩的:屁强度探测器

探测的依据是    声音  温度  浓度 …

查看全部问答>

有人熟悉NTFS格式么?

最近做一个项目,需要支持移动硬盘,移动硬盘大部分都是NTFS的格式,但是目前维护的FAT文件系统不支持, 有没人熟悉NTFS的,可以请教下…

查看全部问答>

wince中分割窗体

用vs2005开发wince sdi程序,发现没有CSplitterWnd这个类,应该如何实现分割窗体呢?…

查看全部问答>

windows xp 与 windows ce 嵌入式系统的usb通信

现有一个条形码识别掌机, 掌机系统为 windows ce.net 6.0, 有usb接口。 将掌机usb接口直接与windows vista电脑相接,不需要任何操作就可以实现通信。 但将掌机与windows xp相接,用了很多方法都不行,比如安装一个activesync 4.5,在连接 ...…

查看全部问答>

USB接口主,从控制器有什么不同?

可用于主控制的接口有CH375,SL811,还有吗?用于从控制的就多了,如PDIUSBD12,还有MCU内置,如C8051F340就内置USB控制器. 这写USB从控制器能用作主控制器吗?谢谢!…

查看全部问答>

不知道为什么uart无法使用

库文件完全一样,示例代码能运行,但是即使把示例代码完全复制到自己的工程中都不能输出正确的结果。复制到自己的项目中后,完全相同的代码但是编译后的大小要比demo工程直接编译的大一点点。一直到不到哪里出了问题。有人遇到过吗?或者给点查错的 ...…

查看全部问答>

武林学习LM3S811(五)中断按键

参考周立功的实例,实现按键中断翻转LED的功能。为的下次触摸芯片驱动做准备。 工程:…

查看全部问答>

新一代FPGA设计学习工具:Robei

美国Robei公司开发了一套全新的FPGA设计仿真工具,现在在教育界和工业界引起巨大的反响。 下面是这个软件的简单介绍: Robei FPGA仿真软件是一款世界上最小的FPGA仿真工具。该软件具备先进的图形化设计工具,代码修改,Verilog编译仿真和波形分析 ...…

查看全部问答>