IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> C语言常用的工具函数(PIE编码发送函数) -> 正文阅读

[嵌入式]C语言常用的工具函数(PIE编码发送函数)

在国标GB29768源代码移植修改的符合ISO18000 - 6C协议的PIE发送编码

例:导引头为:
在这里插入图片描述

0-1编码为:

在这里插入图片描述

其它详见协议规定。

代码如下:

#define PW 16600 //Tari / 2 = 83us

#define MAX_RESPONSE_BYTES      64
typedef struct
{
    uint32_t    numBytes;       // Nb of full bytes
    uint32_t    numBits;        // Nb of remaining bits
    uint8_t     data[MAX_RESPONSE_BYTES];
} leadinno_RxTxData_t;

extern leadinno_RxTxData_t leadinnoRxTxData;

#define LEADINNO_CMD_QUERY		0x08 // 占低4位
#define LEADINNO_CMD_READ		0xC2 // 占8位
#define LEADINNO_CMD_WRITE		0xC3 // 占8位

#define SET_PULSE_LOW() GPIOC->BRR = (uint32_t)GPIO_PIN_0
#define SET_PULSE_HIGH() GPIOC->BSRR = (uint32_t)GPIO_PIN_0

static void highLowPulse(uint8_t nbTC);
static void separatorPulse(void);

// 全局定义射频发送和接收的数据缓冲区
leadinno_RxTxData_t leadinnoRxTxData;

uint16_t value_crc16;

/**
	* @brief	初始化射频发送和接收的数据缓冲区
	*
    * @param *RxTxData 存放发送数据的缓冲区
	*
	* @retval 
	* @author GB29768
	* @date   20220401
	* @note 
	*/
static void leadinnoInitializeCmd(leadinno_RxTxData_t *RxTxData)
{
    RxTxData->data[0] = 0x00;
    RxTxData->numBytes = 0;
    RxTxData->numBits = 0;
}

/**
  * @brief  将待发送数据按二进制位添加到射频发送和接收的数据缓冲区.
  * @note
  * @param *RxTxData 存放发送数据的缓冲区
  * @param data 添加的数据字节
  * @param bits 添加的数据位数,LSB对齐
  *
  * @retval 
  * @author GB29768
  * @date   20220401
  * @note   不能添加超过一个字节(8位)的数据,不足一个字节的数据,LSB对齐
  */
void leadinnoAddByteToBitStream(leadinno_RxTxData_t *RxTxData, const uint8_t data, const uint8_t bits)
{
    if(bits > 0)
    {
        if(RxTxData->numBits == 8)
        {
            RxTxData->numBytes++;
            RxTxData->data[ RxTxData->numBytes ] = 0x00;
            RxTxData->numBits = 0;
        }

        uint32_t cumulatedBits = RxTxData->numBits + bits;
        if (cumulatedBits >= 8)
        {
            // 111x xxxx | xxxx xxxx   gGb29768RxTxData.numBits = 3, bits = 6
            // 1110 0000 | xxxx xxxx
            RxTxData->data[ RxTxData->numBytes ] |= (uint8_t)(data >> (cumulatedBits-8));
            RxTxData->numBytes++;
            
            // 1110 0000 | 0xxx xxxx
            RxTxData->data[ RxTxData->numBytes ] = (uint8_t)(data << (16-cumulatedBits));
            RxTxData->numBits = cumulatedBits - 8;
        }
        else
        {
            RxTxData->data[ RxTxData->numBytes ] |= (uint8_t)(data << (8-cumulatedBits));
            RxTxData->numBits = cumulatedBits;
        }
    }
}

/**
	* @brief	将待发送数据按二进制位添加到射频发送和接收的数据缓冲区
	*
    * @param data 添加的数据半字
    * @param bits 添加的数据位数
	*
	* @retval 
	* @author GB29768
	* @date   20220401
	* @note   不能添加超过两个字节(16位)的数据,超过1个字节的数据,高字节对齐;剩下的不足一个字节的数据,LSB对齐
	*/
static void leadinnoAddWordToBitStream(leadinno_RxTxData_t *RxTxData, const uint16_t data, const uint8_t bits)
{
    if(bits>8) {
        leadinnoAddByteToBitStream(RxTxData, (uint8_t)(data>>8), 8);
        leadinnoAddByteToBitStream(RxTxData, (uint8_t)(data), bits-8);
    }
    else {
        leadinnoAddByteToBitStream(RxTxData, (uint8_t)(data>>8), bits);
    }
}


/**
	* @brief	将待CRC16添加到射频发送和接收的数据缓冲区
	*
    * @param *RxTxData 存放发送数据的缓冲区
	*
	* @retval 
	* @author GB29768
	* @date   20220401
	* @note   如果总的数据位数不是偶数,则在最后添加一个二进制0,然后计算CRC16
	*/
static void leadinnoAddCrc(leadinno_RxTxData_t *RxTxData)
{
    uint16_t crc;
    
    uint16_t num = RxTxData->numBytes*8 + RxTxData->numBits;
    if (num%2 != 0)
    {
        leadinnoAddByteToBitStream(RxTxData, 0x00,1);
        num++;
    }
    crc = crc16Bitwise(RxTxData->data, num);
    leadinnoAddWordToBitStream(RxTxData, crc,16);
}


/**
	* @brief	发送射频发送数据缓冲区的数据到刺激器
	*
    * @param *RxTxData 存放发送数据的缓冲区
	*
	* @retval 
	* @author GB29768
	* @date   20220401
	* @note   包含导引头或帧同步和待发送数据的发送
	*/
static void leadinnoFinalizeCmdAndSend(leadinno_RxTxData_t *RxTxData)
{
    INIT_DWT();
    // Ensure pulse state is HIGH
    SET_PULSE_HIGH();
    
    // Lead Code
    separatorPulse();   // 12.5us
    highLowPulse(1);    // 1 High + 1 Low=2 TC (25us  @ tc=12.5)
    highLowPulse(5);    // 5 High + 1 Low=6 TC (75us @ tc=12.5)
    //highLowPulse(11);    // 11 High + 1 Low=2 TC (150us  @ tc=12.5)

    // Send all bytes
    int16_t i, j;
    uint8_t data;
    for(i=0 ; i<RxTxData->numBytes ; ++i)
    {
        data = RxTxData->data[i];
		
		for(j = 7 ; j >= 0; j--)
		{
			if(((data >> j) & 0x01) == 0)
				highLowPulse(1);	// 发送字符0 (25us  @ tc=12.5)
			else
				highLowPulse(3);	// 发送字符1 (50us  @ tc=12.5)
		}
    }

    // Send remaining bits
    if (RxTxData->numBits) {
        data = RxTxData->data[i];  // Get last byte partial content

		for(j = 7 ; j >= (8 - RxTxData->numBits); --j)
		{
			if(((data >> j) & 0x01) == 0)
				highLowPulse(1);	// 发送字符0 (25us  @ tc=12.5)
			else
				highLowPulse(3);	// 发送字符1 (50us  @ tc=12.5)
		}
    }

    // Reinit Rx/Tx data structure before Receive state
    leadinnoInitializeCmd(RxTxData);
}

/**
	* @brief	能控器发送query指令给刺激器,等待获取UID16
	*
    * @param *RxTxData 存放发送数据的缓冲区
    * @param rn16
    * @otherParam 后续去掉,临时用作标定pie时序的形参
	*
	* @retval uint8_t 命令结果
	* @author GB29768
	* @date   20220401
	* @note 本函数内部需实现PIE编码、CRC计算等功能
	*/
uint8_t leadinnoSendCmdQuery(leadinno_RxTxData_t *RxTxData, uint16_t rn16, uint32_t tsp, uint32_t t0, uint32_t trt, uint32_t ttr)
{
    leadinnoInitializeCmd(RxTxData);

    uint8_t gLastCommand = LEADINNO_CMD_QUERY;
    leadinnoAddByteToBitStream(RxTxData, gLastCommand, 4);
	
    leadinnoAddByteToBitStream(RxTxData, (uint8_t)(rn16 >> 8), 8);
    leadinnoAddByteToBitStream(RxTxData, (uint8_t)rn16, 8);
    leadinnoAddCrc(RxTxData);

    INIT_DWT();
    // Ensure pulse state is HIGH
    SET_PULSE_HIGH();
	
    // Lead Code
    SET_PULSE_LOW();
    nsdelay(tsp);

    SET_PULSE_HIGH();
    nsdelay(t0);

    SET_PULSE_LOW();
    nsdelay(t0);

    SET_PULSE_HIGH();
    nsdelay(trt);

    SET_PULSE_LOW();
    nsdelay(t0);

    SET_PULSE_HIGH();
    nsdelay(ttr);

    SET_PULSE_LOW();
    nsdelay(t0);

    SET_PULSE_HIGH();

    // Send all bytes
    int16_t i, j;
    uint8_t data;
    for(i=0 ; i<RxTxData->numBytes ; ++i)
    {
        data = RxTxData->data[i];
		
				for(j = 7 ; j >= 0; j--)
				{
					if(((data >> j) & 0x01) == 0)
						highLowPulse(1);	// 发送字符0 (25us  @ tc=12.5)
					else
						highLowPulse(3);	// 发送字符1 (50us  @ tc=12.5)
				}
    }

    // Send remaining bits
    if (RxTxData->numBits) {
        data = RxTxData->data[i];  // Get last byte partial content

			for(j = 7 ; j >= (8 - RxTxData->numBits); --j)
			{
				  if(((data >> j) & 0x01) == 0)
						highLowPulse(1);	// 发送字符0 (25us  @ tc=12.5)
					else
						highLowPulse(3);	// 发送字符1 (50us  @ tc=12.5)
			}
    }
		
    // Reinit Rx/Tx data structure before Receive state
    leadinnoInitializeCmd(RxTxData);

//    uint8_t resp = leadinnoWaitForResponse(RxTxData, CRC16_CHECK_ON);

//	  return resp;
		return 0;
}


/**
	* @brief	能控器发送read指令给刺激器,返回读取的结果
	*
    * @param *RxTxData 存放发送数据的缓冲区
	* @param reg 寄存器地址
	* @param *data 接收到的数据
	* @param rn16
    *
	* @retval uint8_t 超时时间内收到数据,返回0;失败返回非0
	* @author yangFei
	* @date   20220401
	* @note 本函数内部需实现PIE编码、CRC计算等功能   读取的长度是1 单位是word 16位
	*/
uint8_t leadinnoSendCmdRead(leadinno_RxTxData_t *RxTxData, uint8_t reg, uint8_t *data, uint16_t rn16)
{
#define  MEM_BANK 0
#define  WORD_COUNT 1
	
	leadinnoInitializeCmd(RxTxData);

    uint8_t gLastCommand = LEADINNO_CMD_READ;
    leadinnoAddByteToBitStream(RxTxData, gLastCommand, 8);
    leadinnoAddByteToBitStream(RxTxData, MEM_BANK, 2);
    leadinnoAddByteToBitStream(RxTxData, reg, 8);
    leadinnoAddByteToBitStream(RxTxData, WORD_COUNT, 8);
	
    leadinnoAddByteToBitStream(RxTxData, (uint8_t)(rn16 >> 8), 8);
    leadinnoAddByteToBitStream(RxTxData, (uint8_t)rn16, 8);
	
    leadinnoAddCrc(RxTxData);
    
    leadinnoFinalizeCmdAndSend(RxTxData);
	

		// uint8_t resp = leadinnoWaitForResponse(RxTxData, CRC16_CHECK_ON);
		// return resp;
	return 0;
}


/**
	* @brief	能控器发送read指令给刺激器,返回读取的结果
	*
    * @param *RxTxData 存放发送数据的缓冲区
	* @param reg 寄存器地址
 	* @param *data 要发送的数据
	* @param rn16
    *
	* @retval uint8_t 超时时间内收到数据,返回0;失败返回非0
	* @author yangFei
	* @date   20220401
	* @note 本函数内部需实现PIE编码、CRC计算等功能   读取的长度是1 单位是word 16位
	*/
uint8_t leadinnoSendCmdWrite(leadinno_RxTxData_t *RxTxData, uint8_t reg, uint8_t *data, uint16_t rn16)
{
#define  MEM_BANK 0
	
	  leadinnoInitializeCmd(RxTxData);

    uint8_t gLastCommand = LEADINNO_CMD_WRITE;
    leadinnoAddByteToBitStream(RxTxData, gLastCommand, 8);
    leadinnoAddByteToBitStream(RxTxData, MEM_BANK, 2);
    leadinnoAddByteToBitStream(RxTxData, reg, 8);
	
    leadinnoAddByteToBitStream(RxTxData, data[0], 8);
    leadinnoAddByteToBitStream(RxTxData, data[1], 8);
	
    leadinnoAddByteToBitStream(RxTxData, (uint8_t)(rn16 >> 8), 8);
    leadinnoAddByteToBitStream(RxTxData, (uint8_t)rn16, 8);
	
    leadinnoAddCrc(RxTxData);
    
    leadinnoFinalizeCmdAndSend(RxTxData);

    //uint8_t resp = leadinnoWaitForResponse(RxTxData, CRC16_CHECK_ON);
	 // return resp;
	return 0;
}


static void highLowPulse(uint8_t nbTC)
{
    // High pulse
    SET_PULSE_HIGH();
    nsdelay(nbTC * PW);

    // Low Pulse
    SET_PULSE_LOW();
    nsdelay(PW);      // 1 TC

    SET_PULSE_HIGH();
}



static void separatorPulse(void)
{
    SET_PULSE_LOW();
    nsdelay(4 * PW); 

    SET_PULSE_HIGH();
}
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 18:52:42  更:2022-04-22 18:56:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:48:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码