【TI MSP430】如何实现模拟串口通信

发布者:chaohuangmeitao最新更新时间:2018-05-05 来源: eefocus关键字: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

//------------------------------------------------------------------------------
// 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;
    }
}
//------------------------------------------------------------------------------


关键字:TI  MSP430  模拟串口通信 引用地址:【TI MSP430】如何实现模拟串口通信

上一篇: Sim900+单片机开发,实现打电话发短信
下一篇:MSP430 SPI驱动 代码设计流程

推荐阅读最新更新时间:2024-03-16 16:01

MSP430直流电机控制以及测速+仿真
本设计测试部分采用测周期发,12864液晶显示,如有不足,欢迎指教 SP430直流电机控制仿真原理图 下面是部分单片机程序源码预览: /* * LCD_12864.c * * Created on: 2016年6月15日 * Author: Jack zhao */ #include MSP430F249.h #include LCD_12864.h #define uchar unsigned char #define uint unsigned int uchar DIR_S ={ /*-- 文字: 顺 --*/ /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x1
[单片机]
<font color='red'>MSP430</font>直流电机控制以及测速+仿真
高压电机控制系统的设计考量
  在现代机器人设计中,头部、颈部、四肢的任何活动都需要各种各样电机的支持,如传统的旋转电机、步进电机、直线电机和其它特殊电机,但这些电机的驱动和控制要求各有不同,如何实现各种电机的精确控制解决方案?如何以最低的功耗实现对它们的控制?常常对设计师来说是一大挑战。本文将详细地讨论高压电机控制系统的各核心子系统在具体实现时应注意哪些问题。   高压交流(HVAC)电机、工业逆变器或高压永磁无刷电机是高电压系统的几个例子,它们典型地按他们的马力进行分类。虽然仍是最常见的,但其他类型电机也已经出现,如直线电机和内嵌各种激励器实现的齿轮头电机。数字电机控制解决方案允许精确地控制这些机械驱动机构的位置、速度和转矩。在这类大型机械驱动机构中的MO
[单片机]
高压电机控制系统的设计考量
基于MSP430F169的光伏并网发电模拟装置
引言 目前,煤炭、石油等能源正走向枯竭,且环境污染问题也日益严重,新能源和可再生能源的利用已经成为世界各国的燃眉之急。作为一种无污染的可再生能源,太阳能越来越受到人们的青睐。太阳能光伏并网发电产业迅速发展对人们提出的可持续发展有重大的意义。本设计利用锁相环倍频、比较器过零触发和MSP430F169单片机DA产生与输入信号同频同相且幅值可控的正弦波,作为DA-AC电路的输入参考信号,其中DA-AC电路采用D类功放中自激反馈模型,利用负反馈的自激振荡产生正弦波脉宽调制(SPWM)波,通过硬件之间的配合,实现了逆变电压输出及最大功率、同频同相的跟踪。 装置方案的选用 DC-AC逆变方案:采用D类功放中自振荡式模型的逆变拓扑,利用负
[单片机]
基于<font color='red'>MSP430</font>F169的光伏并网发电<font color='red'>模拟</font>装置
msp430g2553单片机学习心得
四年前学习的TI的Msp430g2553这款单片机,最近在整理学习记录的时候把当时的学习心得重新写下来。学习单片机最早是学习的51系列的,看的也是广为推崇的郭天祥郭老师的《十天学习单片机》,个人觉得单片机学习还是最先攻克51的。学习好51之后,对单片机操作有了基本的认识,再学习其他款单片机自然是能融会贯通。 TI的430系列主打是低功耗,它的技术文档和Dome程序都非常详细,尤其是技术文档真让人有种膜拜的感觉,在每个模块的时候还有个框图,对理解模块内设置非常有帮助,我当时还特意打印了。当时它的User's Guide还没有中文版,如果实在看不懂,可以借鉴F149系列的(这款有人翻译了中文版本)。 个人觉得在学习g25
[单片机]
MSP430第十六章:看门狗
1. 介绍 看门狗定时器模块WDT_A的作用是在软件发生死机或跑飞后控制程序重启。当超过设定的时间而没有喂狗时,就会产生复位中断。如果不需要看门狗功能,可配置为普通定时器或者关闭。 8个可选定时时间 看门狗工作模式 定时器模式 带密码保护的控制寄存器 可选时钟源 允许关闭降低功耗 时钟故障保护 2. 看门狗操作 看门狗定时器模块可以配置为看门狗或普通定时器。WDTCTL是一个16位密码保护的读写寄存器。任何读或写访问都必须使用word指令,并且写访问必须使用密码05Ah。任何对WDTCTL的写操作,只要高字节的值不是05Ah,就会违反密码,并触发PUC系统重置。对WDTCTL的任何读取都是在高字节读取069h。字节读取WD
[单片机]
<font color='red'>MSP430</font>第十六章:看门狗
MSP430 时钟设置(五)
4、CPU运行在DCO时钟下: 最慢的频率,我们可以运行DCO约在1MHz(这也是默认速度)。因此,我们将开始切换MCLK到DCO下。在大多数系统中,你会希望在VLO或者是晶振下运行ACLK。由于ACLK在我们目前的代码是在VLO上运行,我们会打开DCO运行。 #include msp430g2231.h void main(void) { WDTCTL = WDTPW + WDTHOLD; 关闭看门狗定时器 if (CALBC1_1MHZ == 0xFF || CALDCO_1MHZ == 0xFF) { while(1); 挂起 } BCSCT
[单片机]
突破功耗与速度限制,TI最新高速DAC亮相!
  “无线基站制造商面临的挑战是需不断推出既可确保低功耗,又能突破带宽与性能限制的系统,”TI 高性能模拟业务部高级副总裁 Steve Anderson 指出。   为此,TI近日宣布推出业界最低功耗的 4 通道 16 位 DAC (数模转换器)DAC3484。该款产品 在 1.25 GSPS 速率下比速度最接近的 4 通道 DAC 快 25%,而每通道功耗仅为 250 mW, 比性能最接近的同类竞争产品低 65%。此外,DAC3484 还比其它 4 通道 DAC 解决方案小 40%,并支持高达 250 MHz 的宽带功率放大器线性化。具有更高输入总线的 DAC34H84 或双通道 DAC3482 可支持高达 500 MHz 的
[模拟电子]
德州仪器高性能模拟产品系列介绍集锦(一)
ADS1230 —— 用于桥接传感器的 20 位 Δ-Σ ADC ADS1230 是一种高精度 20 位模数转换器 (ADC)。ADS1230 集成了板载低噪声可编程增益放大器 (PGA)、板载振荡器以及高精度 20 位 Δ-Σ ADC,可提供完整的前端解决方案,以满足多种桥接传感器应用要求,其中包括秤重、应变仪以及压力传感器。 BQ29413 —— 用于锂离子电池的电压保护 bq2941x 是一种用于 2、3 或 4 节锂离子电池组的二次过压保护 IC,其集成了高精度过压检测电路以及针对过压检测时间的可编程延迟电路。 SN65MLVD2 — SN65MLVD3 —— 单通道 M
[新品]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved