基于mcu单线通的通信实现和代码

内容分享1天前发布
0 0 0

基于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


© 版权声明

相关文章

暂无评论

none
暂无评论...