#include "stm32f10x.h" // Device header
#include "DL10.h"
#include "OLED.h"
#include "Timer.h"
#include "Global.h"
#include "Delay.h"
typedef enum{
STATE_IDLE,
STATE_SEND_REQUEST,
STATE_WAIT_RESPONSE,
STATE_PROCRSS_RESPONSE,
STATE_RETRY_DELAY,
//STATE_ERROR,
}CommState_t;
CommState_t State=STATE_IDLE;
float Dl10_Temp;
uint8_t Retry_Count;
uint32_t backoff_ms;
int main(void)
{
OLED_Init();
DL10_Init();
Timer_Init();
last_action_time=GetTick();
Delay_ms(2000);
while(1)
{
switch(State)
{
/*¿ÕÏÐ״̬*/
case STATE_IDLE:
if((GetTick()-last_action_time) >= 1000)
{
Reset_States();
State=STATE_SEND_REQUEST;
}
break;
/*·¢ËÍÇëÇó*/
case STATE_SEND_REQUEST:
SendData_DL10();
WaitForResponse=1;
last_action_time = GetTick();//¼Ç¼·¢ËÍʱ¼ä
State=STATE_WAIT_RESPONSE;
break;
/*µÈ´ýÏìÓ¦*/
case STATE_WAIT_RESPONSE:
if(RxComplete)
{
State=STATE_PROCRSS_RESPONSE;
}
else if(CharTimeOutFlag || OverallTimeOutFlag)
{
State=STATE_RETRY_DELAY;
}
else if((GetTick()-last_action_time) >= 200)
{
State=STATE_RETRY_DELAY;
}
break;
case STATE_PROCRSS_RESPONSE:
if(Check_Crc())
{
Dl10_Temp=Process_Data();
OLED_ShowFloatNum(0,0,Dl10_Temp,2,2,OLED_8X16);
OLED_Update();
Retry_Count=0;
State=STATE_IDLE;
}
else
{
State=STATE_RETRY_DELAY;
}
break;
case STATE_RETRY_DELAY:
Retry_Count++;
if(Retry_Count >= 3)
{
Retry_Count=0;
State=STATE_IDLE;
}
else
{
backoff_ms = 100 * (1 << (Retry_Count – 1));
Delay_ms(backoff_ms);
State=STATE_SEND_REQUEST;
}
break;
}
}
}
状态机
1.空闲状态:等待一秒重置后切换到发送状态。
2.发送请求状态:发送modbus数据请求,启动计时,然后进入等待响应状态。
3.等待响应状态:如果收到数据帧了,开始处理响应。再如果字符间隔超时和整体超时,就进行重发。如果等待绝对时间超过200ms,重发。
4.处理响应:如果CRC校验成功,显示温度,并把重发次数清零。然后又回到空闲状态。否则CRC错误,重发。
5.重发:最大重发次数3次。否则计算退避时间,100ms,200ms,400ms。回到重新发送。
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
SystemTick++;
if(RxIndex > 0)
{
CharIntervalCount++;
if(CharIntervalCount > 4)
{
CharTimeOutFlag=1;
if(!RxComplete && RxIndex > 0)
{
RxComplete=1;
}
}
}
else
{
CharIntervalCount=0;
}
if(WaitForResponse)
{
OverallTimeOutCount++;
if(OverallTimeOutCount > 50)
{
OverallTimeOutFlag=1;
WaitForResponse=0;
if(!RxComplete && RxIndex > 0)
{
RxComplete=1;
}
}
}
else
{
OverallTimeOutCount=0;
}
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}
定时器
1.4ms的字符间隔计时。
2.50ms的整体计时。



