基于mcu单线通的通信实现和代码
1. 基于裸机mcu
2. 目前项目用于灯带,这个也可以用于电池通信
3. 需要两个定时中断 a. 1ms b.70us 这两个是项目需要,不要完全一致
4. 有通信协议(这两天补齐)
5. 可以直接移植,已经做了清晰的区分
源文件(.c)
#include "Typedef.h"
#include "TailLight.h"
#include "gpio.h"
#include "TimeOut.h"
#define SYNC_SIGNAL_TIME 29 // 同步信号时间29ms
#define SEND_SYNC_DATA 0x00
#define SEND_LIGHT_OFF 0x00
#define SEND_LIGHT_ON 0x01
#define SEND_LEFT_LIGHT_ON 0x02
#define SEND_RIGHT_LIGHT_ON 0x03
#define SEND_REVERSE_LIGHT_ON 0x04
#define RECV_ACK_DATA 0x80
typedef enum {
Send_State_idle,
Send_State_Sync,
Send_State_Bit_Low,
Send_State_Bit_High
} SEND_STATE_T;
typedef struct tail_light_send_t_ {
SEND_STATE_T eState; // 状态枚举
uint8 u8CurrByte; // 当前发送字节
uint8 u8CurrBit; // 当前发送的bit位
uint8 u8TimerCnt; // 定时器计数
uint8 u8BitVal; // 当前bit值
bool bIsSendComplete; // 发送完成标记
bool bIsReadIdComplete; // 读取ID完成标记
} TAIL_LIGHT_SEND_T;
typedef struct tail_light_recv_t_ {
bool bIsRecvComplete; // 接收完成标记
uint8 u8Recv3msCnt; //接收时的3ms定时检测
uint8 u8RecvByte; // 接收的字节
uint8 u8RecvBitIdx; // 当前接收的bit索引
uint32 u32TimeTicklow70us;//接收检测低电平时间
uint32 u32TimeTickhigh70us;//接收检测低电平时间
} TAIL_LIGHT_RECV_T;
TAIL_LIGHT_SEND_T strTailLightSend;
TAIL_LIGHT_RECV_T strTailLightRecv;
uint8 TailLight_Id = 0x00;
uint8 flagcmd = 0xFF;
uint8 Level = 0x02;
static void TailLightSendStructInit(void);
static void TailLightRecvStructInit(void);
static void TailLightSwitchToTransmit(void);
static void TailLightSwitchToReceive(void);
static void ResetSendRecv(void);
static void SendStateMachine(void);
static void TailLightSendSyncSignal(void);
static void ReadTailLightId(void);
void TailLightInit(void)
{
TailLightSendStructInit();
TailLightRecvStructInit();
TailLightSwitchToTransmit();
strTailLightSend.bIsReadIdComplete = false; // 读取ID未完成
}
static void TailLightSendStructInit(void)
{
strTailLightSend.eState = Send_State_Sync; // 初始状态设为同步
strTailLightSend.u8CurrByte = 0; // 待发送字节初始0
strTailLightSend.u8CurrBit = 0; // 当前bit初始0
strTailLightSend.u8TimerCnt = 0; // 定时器计数初始0
strTailLightSend.u8BitVal = 0; // 当前bit值初始0
strTailLightSend.bIsSendComplete = false; // 发送完成标记初始false
}
static void TailLightRecvStructInit(void)
{
strTailLightRecv.bIsRecvComplete = false; // 接收完成标记初始false
strTailLightRecv.u8Recv3msCnt = 0;
strTailLightRecv.u8RecvByte = 0; // 接收字节初始0
strTailLightRecv.u8RecvBitIdx = 0; // 接收bit索引初始0
strTailLightRecv.u32TimeTicklow70us =0;
strTailLightRecv.u32TimeTickhigh70us =0;
}
static void TailLightSwitchToTransmit(void)
{
GpioConfgigOutPP(TAIL_LIGHT_GPIO,TAIL_LIGHT_PIN);
}
static void TailLightSwitchToReceive(void)
{
GpioConfgigInputIPD(TAIL_LIGHT_GPIO,TAIL_LIGHT_PIN);
}
static void TailLightSendSyncSignal(void)
{
SendStateMachine();
}
static void TailLightSendByte(uint8 byte)
{
if (strTailLightSend.eState == Send_State_idle)
{
return; // 忙碌中,忽略新请求
}
strTailLightSend.u8CurrByte = byte;
TailLightSendSyncSignal();
}
static void ReadTailLightId(void)
{
TailLightSendByte(SEND_SYNC_DATA);
if(strTailLightRecv.bIsRecvComplete)
{
TailLight_Id = strTailLightRecv.u8RecvByte;
strTailLightSend.bIsReadIdComplete = true;
ResetSendRecv();
}
}
uint8 CombineIdAndCmd(uint8 id, uint8 cmd)
{
uint8 valid_id = id & 0x0F;
uint8 valid_cmd = cmd & 0x0F;
return (valid_id << 4) | valid_cmd;
}
static void TailLightControl(uint8 cmd)
{
uint8 u8SendCmd = 0;
u8SendCmd = CombineIdAndCmd(TailLight_Id,cmd);
TailLightSendByte(u8SendCmd);
return ;
}
static void SendStateMachine(void)
{
switch (strTailLightSend.eState)
{
case Send_State_Sync:
if (strTailLightSend.u8TimerCnt == 0)
{
GPIO_ResetBits(TAIL_LIGHT_GPIO, TAIL_LIGHT_PIN);
}
strTailLightSend.u8TimerCnt++;
if (strTailLightSend.u8TimerCnt == (SYNC_SIGNAL_TIME + 1 ))
{
GPIO_SetBits(TAIL_LIGHT_GPIO, TAIL_LIGHT_PIN);
strTailLightSend.u8TimerCnt = 0;
strTailLightSend.u8CurrBit = 0;
strTailLightSend.u8BitVal = (strTailLightSend.u8CurrByte >> (7 - strTailLightSend.u8CurrBit)) & 0x01;
strTailLightSend.eState = Send_State_Bit_Low;
}
break;
case Send_State_Bit_Low:
if (strTailLightSend.u8TimerCnt == 0)
{
GPIO_ResetBits(TAIL_LIGHT_GPIO, TAIL_LIGHT_PIN);
}
if ((strTailLightSend.u8BitVal == 0 && strTailLightSend.u8TimerCnt == 2) ||
(strTailLightSend.u8BitVal == 1 && strTailLightSend.u8TimerCnt == 1))
{
GPIO_SetBits(TAIL_LIGHT_GPIO, TAIL_LIGHT_PIN);
strTailLightSend.u8TimerCnt = 0;
strTailLightSend.eState = Send_State_Bit_High;
}
strTailLightSend.u8TimerCnt++;
break;
case Send_State_Bit_High:
if ((strTailLightSend.u8BitVal == 0 && strTailLightSend.u8TimerCnt == 1) ||
(strTailLightSend.u8BitVal == 1 && strTailLightSend.u8TimerCnt == 2))
{
strTailLightSend.u8CurrBit++;
strTailLightSend.u8TimerCnt = 0;
if (strTailLightSend.u8CurrBit < 8)
{
strTailLightSend.u8BitVal = (strTailLightSend.u8CurrByte >> (7 - strTailLightSend.u8CurrBit)) & 0x01;
GPIO_ResetBits(TAIL_LIGHT_GPIO, TAIL_LIGHT_PIN);
strTailLightSend.eState = Send_State_Bit_Low;
}
else
{
TailLightSwitchToReceive();
strTailLightSend.eState = Send_State_idle;
strTailLightSend.bIsSendComplete = true; //发送完成,准备开始接收
GPIO_ResetBits(TAIL_LIGHT_GPIO, TAIL_LIGHT_PIN);
}
}
strTailLightSend.u8TimerCnt++;
break;
case Send_State_idle:
break;
default:
break;
}
}
static void ProcessBit(uint8 bit_val)
{
if (strTailLightRecv.u8RecvBitIdx < 8)
{
strTailLightRecv.u8RecvByte |= (bit_val << (7 - strTailLightRecv.u8RecvBitIdx));
strTailLightRecv.u8RecvBitIdx++;
}
if (strTailLightRecv.u8RecvBitIdx >= 8)
{
strTailLightRecv.bIsRecvComplete = true;
if(strTailLightRecv.u8RecvByte == RECV_ACK_DATA)
{
flagcmd = 0x0FF;
ResetSendRecv();
}
}
}
void TailLightRecvCheckLevel(void)
{
if(strTailLightSend.bIsSendComplete && !strTailLightRecv.bIsRecvComplete)
{
Level = GPIO_ReadInputDataBit(TAIL_LIGHT_GPIO, TAIL_LIGHT_PIN);
if(Level == 0)
{
strTailLightRecv.u32TimeTicklow70us += 70;
}
else
{
strTailLightRecv.u32TimeTickhigh70us += 70;
}
}
}
static void ResetSendRecv(void)
{
TailLightSendStructInit();
TailLightRecvStructInit();
TailLightSwitchToTransmit();
}
void TailLightHandle(void)
{
if(strTailLightSend.bIsSendComplete && !strTailLightRecv.bIsRecvComplete)
{
strTailLightRecv.u8Recv3msCnt++;
if(strTailLightRecv.u8Recv3msCnt == 3)
{
if(strTailLightRecv.u32TimeTicklow70us > strTailLightRecv.u32TimeTickhigh70us )
{
ProcessBit(0);
}
else if(strTailLightRecv.u32TimeTickhigh70us > strTailLightRecv.u32TimeTicklow70us)
{
ProcessBit(1);
}
else
{
ResetSendRecv();
}
strTailLightRecv.u8Recv3msCnt = 0;
strTailLightRecv.u32TimeTicklow70us =0;
strTailLightRecv.u32TimeTickhigh70us =0;
}
return;
}
if(!strTailLightSend.bIsReadIdComplete)
{
ReadTailLightId();
return;
}
if(flagcmd == 0x00)
{
if(!strTailLightSend.bIsSendComplete)
{
TailLightControl(SEND_LIGHT_OFF);
return;
}
}
else if(flagcmd == 0x01)
{
if(!strTailLightSend.bIsSendComplete)
{
TailLightControl(SEND_LIGHT_ON);
return;
}
}
else if(flagcmd == 0x02)
{
if(!strTailLightSend.bIsSendComplete)
{
TailLightControl(SEND_LEFT_LIGHT_ON);
return;
}
}
else if(flagcmd == 0x03)
{
if(!strTailLightSend.bIsSendComplete)
{
TailLightControl(SEND_RIGHT_LIGHT_ON);
return;
}
}
else if(flagcmd == 0x04)
{
if(!strTailLightSend.bIsSendComplete)
{
TailLightControl(SEND_REVERSE_LIGHT_ON);
return;
}
}
}
头文件(.h)
#ifndef __TAILLIGHT_H__
#define __TAILLIGHT_H__
void TailLightInit(void);
void TailLightHandle(void);
void TailLightRecvCheckLevel(void);
#endif
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...





