在线时间587 小时
UID3253488
注册时间2016-3-21
NXP金币0

TA的每日心情 | 怒 2017-1-4 08:05 |
---|
签到天数: 11 天 连续签到: 1 天 [LV.3]偶尔看看II
版主
  
- 积分
- 2569

- 最后登录
- 2019-3-28
|
/******************************************************************************************
发现很多网友不会用单片机接收RS485数据帧(无规律的不定长数据帧),其实这个问题并不难,如
果用K6X这类芯片,串口自带IDLE中断的,关于什么是IDLE中断,请找度娘。但对于KL系列的芯片是没有
这个功能的。那就是我今天分享的方法,用一个定时器做辅助,即使你100个串口也是占用一个定时器资
源,说下思路:
众所周知,串口无论接收多少数据,都是一个字节一个字节读进去的。我们通过判断接收字节之间的
时间即可判断出是否接收完成。具体的看代码吧。需要资源提供一个1-2ms的中断即可。啰嗦几句对于定时
器这类宝贵的资源,要合理的使用。代码没编译,只是写了一下逻辑流程。
******************************************************************************************/
#define REVMAXSIZE 128
#define MAX_COUNT_VALUE 0xFFFFFFFF
volatile uint32_t SysTimeCount = 0;
typedef struct{
uint8_t RevBuff[REVMAXSIZE];
uint8_t RevFlag;
uint16_t RevSize;
uint32_t RevTime;
}USART_RevInfo;
USART_RevInfo RevInfo;
void HardtimerInterruptCallBack(void)
{
SysTimeCount ++;
}
uint32_t GetSysTimeCount(void)
{
return SysTimeCount;
}
int DiffentSysTimeCount(uint32_t Start,uint32_t End)
{
uint32_t dwValue;
if (End >= Start)
{
dwValue = End - Start;
}
else
{
dwValue = MAX_COUNT_VALUE + End - Start;
}
return dwValue;
}
void USARTInterruptCallBack(uint8_t inData)
{
if(RevInfo.RevSize < REVMAXSIZE)
{
RevInfo.RevBuff[RevInfo.RevSize++] = inData;
RevInfo.RevTime = GetSysTimeCount();
RevInfo.RevFlag = 0xff;
}
}
int USARTRevLoop(uint32_t TimeOut,uint8_t *outData,uint16_t *Size)//main_loop
{
if(RevInfo.RevFlag = 0xff)
{
if(DiffentSysTimeCount(RevInfo.RevTime,GetSysTimeCount()) >= TimeOut)
{
memcpy(outData,RevInfo.RevBuff,RevInfo.RevSize);
*Size = RevInfo.RevSize;
memset(RevInfo,0,sizeof(USART_RevInfo));
return 1;
}
}
else
return 0;
}
|
|