#define SimUartRxMax 100 //最大65535
#define SimUartTxMax 100 //最大65535
enum{NoFinish = 0, Finish = 1};
enum{TxFinish = 0, TxStart = 1, TxData = 2, TxStop = 3, WaitStop = 4};
enum{RxFinish = 0, RxStart = 1, RxData = 2, RxStop = 3, WaitFinish = 4};
enum{LowEL = 0, HighEL = 1};
typedef enum{TXIDLEING, TXSENDING, RXIDLEING, RXRECEING} SimUartState;
typedef enum{NOERROR = 0, TXOVERLENGTH, TXBUSYING}SimUartError;
typedef struct
{
volatile unsigned char TxCache;
volatile unsigned char TxFlag;
volatile unsigned char TxMask;
volatile unsigned char RxCache;
volatile unsigned char RxFlag;
volatile unsigned char RxMask;
volatile SimUartState TxState;
volatile SimUartState RxState;
}SimUartManage;
typedef struct
{
volatile SimUartManage SelfSimUartManage;
volatile unsigned char RxBuffer[SimUartRxMax];
volatile unsigned char TxBuffer[SimUartTxMax];
volatile unsigned short RxCnt;
volatile unsigned char RxFFlag;
volatile unsigned short TxCnt;
volatile unsigned short TxLength;
}SimUartRxTxControl;
typedef volatile SimUartRxTxControl * SimUartRxTxControlPrtType;
#define TIMERTYPEMACRO TIM_HandleTypeDef
typedef unsigned char (* READGPIO)(unsigned short);
typedef void (* WRITEGPIO)(unsigned short, unsigned char);
typedef void (* UARTPROTOCOL)(SimUartRxTxControlPrtType);
typedef void (* SETTIMERCOUNT)(TIMERTYPEMACRO ,unsigned short);
// volatile SimUartRxTxControl MySimUartRxTxControl;
// SimUartRxTxControlPrtType MySimUartRxTxControlPrt
// unsigned char MyReadGPIO(unsigned short Pin);
// void MyWirtGPIO(unsigned short Pin, unsigned char Value);
// void MyUartRxProtocol(SimUartRxTxControlPrtType MySimUartRxTxControlPrt);
// void MySetTimerCounter(TIMERTYPEMACRO Timer,unsigned short Value);
SimUartState GetSimUartTxState(SimUartRxTxControlPrtType SimUartRxTxControlPrt)
{
return SimUartRxTxControlPrt->SelfSimUartManage.TxState;
}
SimUartState GetSimUartRxState(SimUartRxTxControlPrtType SimUartRxTxControlPrt)
{
return SimUartRxTxControlPrt->SelfSimUartManage.RxState;
}
void OneTimerBitRxTx(SimUartRxTxControlPrtType SimUartRxTxControlPrt,
READGPIO ReadGPIO,unsigned short RxPin,WRITEGPIO WriteGPIO, unsigned short TxPin,UARTPROTOCOL UartRxProtocol)
{
if(RxFinish != SimUartRxTxControlPrt->SelfSimUartManage.RxFlag)
{
SimUartRxTxControlPrt->SelfSimUartManage.RxState = RXRECEING;
switch(SimUartRxTxControlPrt->SelfSimUartManage.RxFlag)
{
case RxStart:
(LowEL == ReadGPIO(RxPin)) ? (SimUartRxTxControlPrt->SelfSimUartManage.RxFlag = RxData) : (SimUartRxTxControlPrt->SelfSimUartManage.RxFlag = RxFinish);
SimUartRxTxControlPrt->SelfSimUartManage.RxCache = 0;
SimUartRxTxControlPrt->SelfSimUartManage.RxMask = 0x01;
break;
case RxData:
if(LowEL != ReadGPIO(RxPin))
{
SimUartRxTxControlPrt->SelfSimUartManage.RxCache |= SimUartRxTxControlPrt->SelfSimUartManage.RxMask;
}
SimUartRxTxControlPrt->SelfSimUartManage.RxMask <<= 1;
if(0 == SimUartRxTxControlPrt->SelfSimUartManage.RxMask)
{
SimUartRxTxControlPrt->SelfSimUartManage.RxFlag = RxStop;
}
break;
case RxStop:
(LowEL == ReadGPIO(RxPin)) ? (SimUartRxTxControlPrt->SelfSimUartManage.RxFlag = RxFinish) : (SimUartRxTxControlPrt->SelfSimUartManage.RxFlag = WaitFinish);
if(WaitFinish == SimUartRxTxControlPrt->SelfSimUartManage.RxFlag)
{
SimUartRxTxControlPrt->SelfSimUartManage.RxFlag = RxFinish;
if(NoFinish == SimUartRxTxControlPrt->RxFFlag)
{
SimUartRxTxControlPrt->RxBuffer[SimUartRxTxControlPrt->RxCnt] = SimUartRxTxControlPrt->SelfSimUartManage.RxCache;
SimUartRxTxControlPrt->RxCnt ++;
UartRxProtocol(SimUartRxTxControlPrt);
if(SimUartRxTxControlPrt->RxCnt >= SimUartRxMax)
{
SimUartRxTxControlPrt->RxFFlag = Finish;
SimUartRxTxControlPrt->RxCnt = 0;
}
}
}
break;
}
}
if(RxFinish == SimUartRxTxControlPrt->SelfSimUartManage.RxFlag)
{
SimUartRxTxControlPrt->SelfSimUartManage.RxState = RXIDLEING;
}
if(TxFinish != SimUartRxTxControlPrt->SelfSimUartManage.TxFlag)
{
switch(SimUartRxTxControlPrt->SelfSimUartManage.TxFlag)
{
case TxStart:
WriteGPIO(TxPin, LowEL);
SimUartRxTxControlPrt->SelfSimUartManage.TxFlag = TxData;
SimUartRxTxControlPrt->SelfSimUartManage.TxMask = 0x01;
break;
case TxData:
if(SimUartRxTxControlPrt->SelfSimUartManage.TxCache & SimUartRxTxControlPrt->SelfSimUartManage.TxMask)
{
WriteGPIO(TxPin, HighEL);
}
else
{
WriteGPIO(TxPin, LowEL);
}
SimUartRxTxControlPrt->SelfSimUartManage.TxMask <<= 1;
if(0 == SimUartRxTxControlPrt->SelfSimUartManage.TxMask)
{
SimUartRxTxControlPrt->SelfSimUartManage.TxFlag = TxStop;
}
break;
case TxStop:
WriteGPIO(TxPin, HighEL);
SimUartRxTxControlPrt->SelfSimUartManage.TxFlag = WaitStop;
break;
case WaitStop:
if(SimUartRxTxControlPrt->TxCnt == SimUartRxTxControlPrt->TxLength)
{
SimUartRxTxControlPrt->SelfSimUartManage.TxFlag = TxFinish;
SimUartRxTxControlPrt->TxCnt = 0;
SimUartRxTxControlPrt->TxLength = 0;
SimUartRxTxControlPrt->SelfSimUartManage.TxState = TXIDLEING;
}
else
{
SimUartRxTxControlPrt->SelfSimUartManage.TxFlag = TxStart;
SimUartRxTxControlPrt->SelfSimUartManage.TxCache = SimUartRxTxControlPrt->TxBuffer[SimUartRxTxControlPrt->TxCnt];
SimUartRxTxControlPrt->TxCnt ++;
}
break;
}
}
}
SimUartError SimUartRxEXTIOHandler(SimUartRxTxControlPrtType SimUartRxTxControlPrt, SETTIMERCOUNT SetTimerCounter,TIMERTYPEMACRO Timer, unsigned short Value)
{
if(RxFinish == SimUartRxTxControlPrt->SelfSimUartManage.RxFlag)
{
SimUartRxTxControlPrt->SelfSimUartManage.RxFlag = RxStart;
SimUartRxTxControlPrt->SelfSimUartManage.RxState = RXRECEING;
//添加清除定时器中断的指令
SetTimerCounter(Timer, Value);
}
return NOERROR;
}
//1:成功 0:由于忙而失败 3:由于超过发送长度而失败(并不是发送最长)
SimUartError SimUart_TxByte(SimUartRxTxControlPrtType SimUartRxTxControlPrt, const unsigned char *SendBuffer, size_t SendSize)
{
if(TXIDLEING == GetSimUartTxState(SimUartRxTxControlPrt))
{
size_t counter;
if(SendSize >= SimUartTxMax)
return TXOVERLENGTH;
SimUartRxTxControlPrt->SelfSimUartManage.TxState = TXSENDING;
for(counter = 0; counter < SendSize; counter ++)
{
SimUartRxTxControlPrt->TxBuffer[counter] = *(SendBuffer + counter);
}
SimUartRxTxControlPrt->TxLength = SendSize;
SimUartRxTxControlPrt->SelfSimUartManage.TxFlag = TxStart;
SimUartRxTxControlPrt->TxCnt = 0;
SimUartRxTxControlPrt->SelfSimUartManage.TxCache = SimUartRxTxControlPrt->TxBuffer[SimUartRxTxControlPrt->TxCnt];
SimUartRxTxControlPrt->TxCnt ++;
return NOERROR;
}
else
{
return TXBUSYING;
}
}
1、此模拟串口的实现使用的时一个线中断做Rx,一个定时器实现收发时序;
2、代码中红 {MOD}的部分需要用户自己去实现或者修改;
3、用户可以根据结构体成员的属性去实现一些更丰富的接口函数,例如:设置收发状态,重设收发为空闲状态等;
4、可以使用严格的宏定义来实现多个模拟串口的建立和编译前差错等等;
5、当然接收部分写的比较简单,没有做一些报错和纠错的功能,感兴趣的同志可以发挥自己所能看能否写的如硬件串口一般坚硬。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>