📄 softuart.c
字号:
/****************************************************************************\
文件名:softuart.c
描述:软件模拟异步串口通讯模块。
利用定时器A的比较/捕获功能软件模拟异步串口通讯,RXD:P2.2,TXD:P1.1。
数据格式:1个起始位,8个数据位,1个停止位。接收/发送时低位在前
波特率:2400bit/s 半双工。
可以通过查询方式确定是否有数据被收到或者发送完毕。
原始资料来自TI公司。
版本:1.0 2005-2-20
\****************************************************************************/
#include <MSP430x14x.h>
#include "softuart.h"
#define TXDSEL P1SEL
#define TXDDIR P1DIR
#define RXDSEL P2SEL
#define SF_TXD BIT1
#define SF_RXD BIT2
#define NEXT_TIME 14 //一位数据的时间,427us,约 2341bit/s
#define NEXT_TIME_H 6 //大约半位数据的时间,在此时间读RXD的数据
#define DATA_WEI_RX 8
#define DATA_WEI_TX 10
unsigned char CntWei; //接收或者发送的位数计数器
unsigned char RxBuf; //接收缓冲器
unsigned int TxBuf; //发送缓冲器
unsigned char bRTx=0; //1:发送完或收到一个字节 0:没有收到或没发送完
/*****************************************************************************
初始化
*****************************************************************************/
void InitSfUart()
{
TACTL |= TASSEL_1+ MC_2+TACLR;//定时器A,时钟源:ACLK,连续计数模式
CCTL0 |= OUTMOD_1; //TXD空闲时输出1
TXDSEL |= SF_TXD; //选择P1.1使用第二功能
TXDDIR |= SF_TXD; //选择P1.1为输出模式
RXDSEL |= SF_RXD; //选择P2.2使用第二功能
}
/****************************************************************************
进入接收状态
****************************************************************************/
void InitRxd()
{
CntWei=DATA_WEI_RX;
CCTL0 = CCIS_1+OUTMOD_1+CM_2+CAP+CCIE; //选择下降沿捕获,CCIB(P2.2)
//为信号源,捕获中断允许
}
/****************************************************************************
发送数据
tx0:要发送的数据
****************************************************************************/
void SendUart(unsigned char tx0)
{
TxBuf=(tx0<<1)|0x200;
CntWei=DATA_WEI_TX;
CCR0=TAR+NEXT_TIME;
CCTL0 = OUTMOD_1+CCIE; //输出高电平
}
/*****************************************************************************
定时器A中断函数
中断源:CC0
******************************************************************************/
#pragma vector=TIMERA0_VECTOR
__interrupt void TimerA0()
{
CCR0 += NEXT_TIME; //下一位到来的时间
if((CCTL0&CCIS_1)==CCIS_1)
{
//处于接收状态
if((CCTL0&CAP)==CAP)
{
CCTL0 &= ~CAP; //处于捕获模式,转比较方式
CCR0 += NEXT_TIME_H; //1.5位后读取数据
}
else
{
//接收数据
if(CntWei!=0)
{
RxBuf = RxBuf>>1;
if((CCTL0&SCCI)==SCCI)
RxBuf |= 0x80;
CntWei--;
}
else
{
//接收完毕
CCTL0 &= ~CCIE; //关闭接收中断,退出接收状态
bRTx=1; //接收到一个字节标志置位
LPM3_EXIT; //退出低功耗状态
}
}
}
else
{
//处于发送状态
if(CntWei!=0)
{
//未发送完
CCTL0 &= ~OUTMOD2; //输出模式1,置位
if((TxBuf&0x1)==0)
{
//发送0
CCTL0 |= OUTMOD2; //输出模式5,复位
}
TxBuf >>=1;
CntWei--;
}
else
{
//全部发送完
CCTL0 &= ~CCIE; //关闭中断
bRTx=1;
}
}
}
/*****************************************************************************
读收到的数据,清除有数据收到标志
返回值:收到的数据
******************************************************************************/
unsigned char ReadBuf()
{
bRTx=0;
return RxBuf;
}
/****************************************************************************
查询是否收到或者发送完数据
返回值:是否收到或者发送完数据的标志 1:完成;0:没有完成
****************************************************************************/
unsigned char GetRTx()
{
return bRTx;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -