请教:芯片本身无串口通信功能(如F2001),P1.1用于发送和接收,每次8字节,该如何通信?
#define RXD 0x02 // RXD on P1.1
#define TXD 0x20 // TXD on P1.5
// Conditions for 2400 Baud SW UART, ACLK = 32768
#define Bitime_5 0x06 // ~ 0.5 bit length + small adjustment
#define Bitime 0x0E // 427us bit length ~ 2341 baud
unsigned int RXTXData;
unsigned char BitCnt;
void TX_Byte (void);
void RX_Ready (void);
// Built with IAR Embedded Workbench Version: 3.40A
//******************************************************************************
#include <msp430x20x3.h>
void main (void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
CCTL0 = OUT; // TXD Idle as Mark
TACTL = TASSEL_1 + MC_2; // ACLK, continuous mode
P1SEL = TXD + RXD; //
P1DIR = TXD; //
// Mainloop
for (;;)
{
RX_Ready(); // UART ready to RX one Byte
_BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/ interr until char RXed
TX_Byte(); // TX Back RXed Byte Received
}
}
// Function Transmits Character from RXTXData Buffer
void TX_Byte (void)
{
BitCnt = 0xA; // Load Bit counter, 8data + ST/SP
while (CCR0 != TAR) // Prevent async capture
CCR0 = TAR; // Current state of TA counter
CCR0 += Bitime; // Some time till first bit
RXTXData |= 0x100; // Add mark stop bit to RXTXData
RXTXData = RXTXData << 1; // Add space start bit
CCTL0 = CCIS0 + OUTMOD0 + CCIE; // TXD = mark = idle
while ( CCTL0 & CCIE ); // Wait for TX completion
}
// Function Readies UART to Receive Character into RXTXData Buffer
void RX_Ready (void)
{
BitCnt = 0x8; // Load Bit counter
CCTL0 = SCS + OUTMOD0 + CM1 + CAP + CCIE; // Sync, Neg Edge, Cap
}
// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
CCR0 += Bitime; // Add Offset to CCR0
// TX
if (CCTL0 & CCIS0) // TX on CCI0B?
{
if ( BitCnt == 0)
CCTL0 &= ~ CCIE; // All bits TXed, disa××e interrupt
else
{
CCTL0 |= OUTMOD2; // TX Space
if (RXTXData & 0x01)
CCTL0 &= ~ OUTMOD2; // TX Mark
RXTXData = RXTXData >> 1;
BitCnt --;
}
}
// RX
else
{
if( CCTL0 & CAP ) // Capture mode = start bit edge
{
CCTL0 &= ~ CAP; // Switch from capture to compare mode
CCR0 += Bitime_5;
}
else
{
RXTXData = RXTXData >> 1;
if (CCTL0 & SCCI) // Get bit waiting in receive latch
RXTXData |= 0x80;
BitCnt --; // All bits RXed?
if ( BitCnt == 0)
//>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
{
CCTL0 &= ~ CCIE; // All bits RXed, disa××e interrupt
_BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR)
}
//>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
}
}
请教斑竹,我现在是一个IO口既具有发送又具有接收功能,上述代码该如何修改?
无论如何要两个口线,否则你无法控制应答时序的。最简单办法可以用口线模拟IIC
我在软件中不断改变IO口的输入和输出方向不就可以了吗?见下!
#define RXD 0x02 // RXD on P1.1
#define TXD 0x02 // TXD on P1.1
...
TACTL = TASSEL_2 + MC_2; // MCLK, continuous mode
P1SEL = 0x02; //outside function
P1DIR = TXD;
......
void TX_Byte (void)
{
P1DIR |= BIT1;
BitCnt = 0x0A; // Load Bit counter, 8data + ST/SP
RXTXData=0x2a;
while (CCR0 != TAR) // Prevent async capture
CCR0 = TAR; // Current state of TA counter
CCR0 += Bitime; // Some time till first bit
RXTXData |= 0x100; // Add mark stop bit to RXTXData
RXTXData = RXTXData << 1; // Add space start bit
CCTL0 = OUTMOD0 + CCIE; // TXD = mark = idle
while ( CCTL0 & CCIE ); // Wait for TX completion
}
void RX_Ready (void)
{
P1DIR &=~BIT1; //input direct
for(int i = 0;i<8;i++)
{
BitCnt = 0x08; // Load Bit counter
CCTL0 = SCS + OUTMOD0 + CM1 + CAP + CCIE; // Sync,PWM output mode,Capture mode 1 , Neg Edge, Cap
while(CCTL0&CCIE);
}
}
// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
CCR0 += Bitime; // Add Offset to CCR0
// TX
//if (CCTL0 & CCIS_0) // TX on CCI0B?
if(!(P1DIR&0X02))
{
if(BitCnt == 0)
CCTL0 &= ~ CCIE; // All bits TXed, disa××e interrupt
else
{
CCTL0 |= OUTMOD2; // TX Space
if (RXTXData & 0x01)
CCTL0 &= ~ OUTMOD2; // TX Mark
RXTXData = RXTXData >> 1;
BitCnt --;
}
}
// RX
else
{
P1DIR &= ~TXD;
if( CCTL0 & CAP ) // Capture mode = start bit edge
{
CCTL0 &= ~ CAP; // Switch from capture to compare mode
CCR0 += Bitime_5;
}
else
{
RXTXData = RXTXData >> 1;
if (CCTL0 & SCCI) // Get bit waiting in receive latch
RXTXData |= 0x80;
BitCnt --; // All bits RXed?
if ( BitCnt == 0)
//>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
{
CCTL0 &= ~ CCIE; // All bits RXed, disa××e interrupt
cStr[0] = RXTXData;
_BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR)
}
//>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
}
}
可以是可以的,我以前也做过相关的东西,主要是机械结构上限制死了,没办法。只要在时序上做好分配就好了,一个送的时候另一个肯定已经在等好接收了。然后再反过来这样的双向传输就解决了应答问题。但这样的东西总是差一点的
谢谢.但是我的产品由于体积所限,只能用一个接口通信.假如我用两个IO口,接到同一个通信脚上,通过判断信号线的高低电平来判断是发送还是接收,不知道是否行得通?这样发送和接受是否会比较可靠些?我现在接收和发送的都不全对,还不知道是不是时序没分配好的原因.