This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F67791A: -IPZR, 用P2.0 ,P2.1 IO口做虚拟UART , 9600bps,每次上电,发送出去的前6个字节,不对。用的TImer0 比较模式

Part Number: MSP430F67791A

因工程需要, 用P2.0和P2.1 做虚拟UART,   P2.0是TXD。 9600bps ,每次初始化后第一次发送出去的前6个字节不对,  后面的就正常了。换成2400bps也不行。用的SMCLK    1.045Mhz (内部)。

接收端(PC机)的现象,每次重新上电,第一次都不正常,循环起来后都正常了:

[18:10:44.389]收←◆01 17 4C B0 60 82 05 06 07 08 09   ----------上电第一次发送,不正常
[18:11:03.305]收←◆00 01 02 03 04 05 06 07 08 09          ----------上电第二次发送,正常            
[18:11:12.703]收←◆00 01 02 03 04 05 06 07 08 09          -----------。。。。正常
[18:11:16.419]收←◆00 01 02 03 04 05 06 07 08 09 

但测试中发现:如果初始化的程序:  TA0CCTL0|=OUT;    这个语句不要, 则第一次发送也能正常。    但这样的话不符合例程中的TXD Idle as Mark   刚开始空闲状态输出高电平规定。

程序如下:

     //SMCLK 1048576/9600=109

#include <msp430.h>

#define RXD 0x02 // RXD on P2.1 (TIMER0_A1_VECTOR CCR1 - CCI1A, 捕获输入
#define TXD 0x01 // TXD on P2.0 (TIMER0_A0_VECTOR CCR0--- 比较输出


#define Bitime_5 55 // 0.5 bit
#define Bitime 109 // 1位时间 109/1048576=103.95uS

unsigned int TXData; //为了处理过程中方便增加起始位和停止位,直接发送10位
unsigned char RXData; //接收单字节
unsigned char rxBitCnt=8; //接收位计数
unsigned char txBitCnt=10; //发送位计数

void TX_Byte (void);

void main (void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer(关闭看门狗模块)

//初始化

P2SEL0 = TXD + RXD; // PP2.0/1 TA0 for TXD/RXD function(TA0引脚功能)
P2DIR = TXD; // TXD output on P1(输出引脚)
TA0CCTL0|=OUT;     // TXD Idle as Mark(捕获/比较寄存器0:输出高电平)   ??????????????该语句决定了第一次发送是否正常。不知为何? 
TA0CTL = TASSEL_2+MC1; // SMCLK, continous mode(定时器A:SMCLK时钟,连续计数模式)
//
_EINT();

for (;;)
{

delay_ms(2000);                 //延时2秒测试
for(int i=0;i<10;i++)              //发送0~10的数据
{

TXData=i;

TX_Byte(); // 
}

}

//发送一个字节

void TX_Byte (void)
{
txBitCnt = 0xA; // Load Bit counter, 8data + ST/SP(发送10位数据)
TA0CCR0=TA0R; // Current state of TA counter(定时器计数器当前值放比较寄存器中)
TA0CCR0 += Bitime; // Some time till first bit(后推一位的时间)
TXData |= 0x100; // Add mark stop bit to RXTXData(填充停止位)
TXData = TXData << 1; // Add space start bit(填充起始位)
TA0CCTL0 = OUTMOD0+CCIE; // TXD = mark = idle(置位输出模式,允许中断)
while ( TA0CCTL0 & CCIE ); // Wait for TX completion(等待发送完成)

}

//发送中断

#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void)
{
TA0CCR0 += Bitime; // Add Offset to CCR0(下一定时时间为1位时间)


if ( txBitCnt == 0) //所有位发送完成 
{
TA0CCTL0 &= ~ CCIE; // All bits TXed, disable interrupt(禁止中断)

}
else
{

TA0CCTL0 |= OUTMOD2; // TX Space(输出模式OUTMOD2+OUTMOD0:复位) 
if (TXData & 0x01) //6mclk
TA0CCTL0 &= ~ OUTMOD2; // TX Mark(输出模式OUTMOD0:置位) 

TXData = TXData >> 1; //低位先发
txBitCnt --; //位计数




}

}