12480|30

2002

帖子

24

TA的资源

五彩晶圆(高级)

楼主
 

launchPad另一种uart的实现 [复制链接]

首先声明,所谓的另一种是,是相对于官方温度传感例程里面的方法来说的。官方程序里面大致是这样的,设为连续计数模式,TXD,RXD作为TA的捕获/比较功能引脚,当捕获到起始位或要发送数据的时候,在当前计数值的基础上加上一位的宽度来设定下一个中断时间,然后根据要发送的值来确定TXD功能引脚的输出。这种方法充分利用了硬件资源,但是相对应的要设置的寄存器和中断要处理的稍多点,使用起来稍显复杂。

 

其实uart通讯很简单,起始位加8bit数据加上停止位(不是特别的应用或高速率传输时一般可以省掉校验位)就好了,在起始位(高电平向低电平转换时刻即下降沿)开始按数据置高或拉低一个数据位宽度(由波特率决定)即可。

 

所以这里就简单的利用crr0的up mode中断,产生一个数据位的时长,我们只需要把要发送的数据,前后分别加上起始位和停止位按低位在前,高位在后的顺序发出去就好了。

 

//发送一个字节
void send_char(uchar tchar)
{
  TACTL = TACLR + TASSEL_2 + ID_3;              //选择SMCLK时钟;清TAR
  CCR0 = BITTIME_1b;                    //crr0定时间隔为1bit时间宽度
  CCTL0 |= CCIE;                        //打开CCR0中断
  bitcnt = 10;                           //待发送的位数
  uart_buf = 0x0100;                     //8+N+1
  uart_buf |= tchar;                  //stop bit and start bit;
  uart_buf <<=1;
  Send_flag = 0;
  TACTL |= MC_1;                        //Start TA, UP mode.
  _BIS_SR(GIE);
  while(!Send_flag);                   //wait until send complete
  Send_flag = 1;
}

//发送一个字符串
void send_String(uchar *tstr)
{
  while(*tstr)
    send_char(*tstr++);
}


void send_IRQ(void)
{
  if(bitcnt>0)
  {
    if(uart_buf & 0x01)
      POUT |= TXD;
    else
      POUT &= ~TXD;
    uart_buf >>= 1;
    bitcnt--;
  }
  else
  {
    TACTL &= ~MC_3;                    //Close the TA when a Byte send over.   ??
    CCTL0 &= ~CCIE;                    //关闭CCR0中断
    Send_flag = 1;
  }
 
}
效果如下图

 

 

最后附上项目供参考。

通讯格式.jpg (17.8 KB, 下载次数: 30)

通讯格式.jpg

uart.jpg (45.36 KB, 下载次数: 24)

uart.jpg

2231 uart mode1.rar

128.47 KB, 下载次数: 893

最新回复

C:\Users\Administrator\Desktop\QQ图片20160408163912.jpg  详情 回复 发表于 2016-4-8 16:43

赞赏

1

查看全部赞赏

 
点赞 关注

回复
举报

2002

帖子

24

TA的资源

五彩晶圆(高级)

推荐
 

另外附上一个小巧但功能强大的串口调试工具给大家

直接解压运行putty,载入设置好的msp430就可以了。

 

[ 本帖最后由 shower.xu 于 2011-11-5 15:58 编辑 ]

无标题.jpg (77.69 KB, 下载次数: 6)

无标题.jpg

puttyfile_0.61cn.rar

233.55 KB, 下载次数: 327

点评

怎么会显示这个呢?  详情 回复 发表于 2016-4-8 16:42

赞赏

1

查看全部赞赏

 
 

回复

7228

帖子

192

TA的资源

五彩晶圆(高级)

板凳
 
挺详细的
 
 
 

回复

85

帖子

0

TA的资源

一粒金砂(高级)

4
 
之前我用过delay来着;不开中断时也挺好的。
 
 
 

回复

1万

帖子

16

TA的资源

版主

5
 

楼主这个是软件实现的

还有一种是硬件,写得不错顶哈
 
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 
 

回复

10

帖子

0

TA的资源

一粒金砂(初级)

6
 
不错,正学之中
 
 
 

回复

12

帖子

0

TA的资源

一粒金砂(中级)

7
 
不错   真不错
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(中级)

8
 

回复 楼主 shower.xu 的帖子

请问楼主,我想做G2231和51间的数据传输,请问用这个UART能实现么?或者是用I2C?硬件该怎么实现呢?
 
 
 

回复

2002

帖子

24

TA的资源

五彩晶圆(高级)

9
 
只是单向的是可以的,双向的传输的话需要添加接收部分
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(中级)

10
 

回复 9楼 shower.xu 的帖子

我想用51给2231发数据,就用这个UART就行么,查了user guide,还是没懂啊,能不能说的详细点?
 
 
 

回复

2002

帖子

24

TA的资源

五彩晶圆(高级)

11
 
原帖由 michaelxi007 于 2012-4-11 12:32 发表 我想用51给2231发数据,就用这个UART就行么,查了user guide,还是没懂啊,能不能说的详细点?

1、51端调好,可收发。
2、430这边设置好波特率,改为接收模式,本帖只是做单一的发送的。
就可以了
官方例程有个9600,双向的,很简洁,给你参考
//******************************************************************************
//  MSP430G2xx1 Demo - Timer_A, Ultra-Low Pwr UART 9600 Echo, 32kHz ACLK
//
//  Description: Use Timer_A CCR0 hardware output modes and SCCI data latch
//  to implement UART function @ 9600 baud. Software does not directly read and
//  write to RX and TX pins, instead proper use of output modes and SCCI data
//  latch are demonstrated. Use of these hardware features eliminates ISR
//  latency effects as hardware insures that output and input bit latching and
//  timing are perfectly synchronised with Timer_A regardless of other
//  software activity. In the Mainloop the UART function readies the UART to
//  receive one character and waits in LPM3 with all activity interrupt driven.
//  After a character has been received, the UART receive function forces exit
//  from LPM3 in the Mainloop which configures the port pins (P1 & P2) based
//  on the value of the received byte (i.e., if BIT0 is set, turn on P1.0).

//  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|<--------
//
//  D. Dang
//  Texas Instruments Inc.
//  October 2010
//  Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************

#include "msp430g2231.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()
//------------------------------------------------------------------------------
void main(void)
{
    WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer

    DCOCTL = 0x00;                          // Set DCOCLK to 1MHz
    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;
    }
}
//------------------------------------------------------------------------------

[ 本帖最后由 shower.xu 于 2012-4-11 13:24 编辑 ]

uart.rar

2.52 KB, 下载次数: 53

点评

// 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;  详情 回复 发表于 2012-7-12 16:43

赞赏

1

查看全部赞赏

 
 
 

回复

2002

帖子

24

TA的资源

五彩晶圆(高级)

12
 
编辑器抽筋,不能修改内容
这里简单说明。
1、用P1.1/P1.2和TIMERA0、A1模拟uart
2、发送完成休眠,接收完成唤醒并回传,然后休眠
3、你只需要在for循环中        // Wait for incoming character
        __bis_SR_register(LPM0_bits);
语句后面处理收到的rxBuffer即可。可以直接用
 
 
 

回复

424

帖子

0

TA的资源

纯净的硅(高级)

13
 
LaunchPad的历程中就是这么实现的。
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(中级)

14
 

回复 12楼 shower.xu 的帖子

太谢谢你了,真的,太感谢了,不过……再弱弱地问一问
//------------------------------------------------------------------------------
// Prints a string over using the Timer_A UART
//------------------------------------------------------------------------------
void TimerA_UART_print(char *string)
{
    while (*string) {
        TimerA_UART_tx(*string++);
    }
}
这一个函数具体是干什么用的?把这一个字符串传输出去是起什么作用的啊?
 
 
 

回复

2002

帖子

24

TA的资源

五彩晶圆(高级)

15
 
TimerA_UART_tx(unsigned char byte)一次发送一个字节,void TimerA_UART_print(char *string)函数通过循环调用TimerA_UART_tx()来发送一个字符串,直到字符串结束。
你是用的时候就只用TimerA_UART_print("uart test!");就可以把字符串uart test!通过串口发送出去了。
不要对函数名的print词误解。
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(中级)

16
 

回复 15楼 shower.xu 的帖子

明白了,今晚测试了一下,效果非常好,跟51通信的效果非常好 真是谢谢了,不知道什么时候我也能独立写出这样的程序啊……
 
 
 

回复

2002

帖子

24

TA的资源

五彩晶圆(高级)

17
 
知识是汗水的沉淀,聚沙成漠,汇水成河。共勉
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

18
 
这样的波特率是2400吗? 如何变成9600?
 
 
 

回复

38

帖子

0

TA的资源

一粒金砂(中级)

19
 

回复 4楼 shower.xu 的帖子

// 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
我是菜鸟这段怎么理解啊

点评

其实意思是根据收到的数据将对应的位的灯打开或熄灭  详情 回复 发表于 2012-7-12 21:44
 
 
 

回复

2002

帖子

24

TA的资源

五彩晶圆(高级)

20
 
原帖由 tanfeng193 于 2012-7-12 16:43 发表 // 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; ...

其实意思是根据收到的数据将对应的位的灯打开或熄灭
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

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