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 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> stm32曼彻斯特编码一种自研的解码方法实现 -> 正文阅读

[嵌入式]stm32曼彻斯特编码一种自研的解码方法实现

1.什么是曼彻斯特编码?

首先了解下什么是曼彻斯特编码,任何编码都是为了表示数据,在玩单片机都知道单片机数据最基础就是二进制数据1和0,曼彻斯特编码就是通过高低电平的变化来表示1和0,当电平由低变高时表示数据1,由高变低时为数据0,如下图:

2.数据会出错?引入时钟

? ?1和0确定好,那么就出现了一个问题,如果数据是101会怎样?如下图:

? ? ?按照我们刚说的 电平由低变高时表示数据1,由高变低时为数据0,上图的高低变化是怎么样的?低->高->低->高,数据是不是就会被误判为 11 ,为了解决这个问题,所以我们必须要限定高低电平持续的时间多久才能确切知道是 低->高->高->低->低->高 (101) ,还是 低->高->低->高(11),所以就引入一个时钟线来提供固定频率,以确定高低时间持续多少个时钟周期。

至此为什么曼彻斯特编码需要一根时钟线和一根数据线 ,大家应该彻底理解了。

3.实验发现问题,确定曼彻斯特编码头

? ? 那么在实验时又发现问题,因为曼彻斯特基本都用于RFID领域,线圈受到地磁场或空气中各种电磁场影响很多数据输出的端子都很不稳定,如果不定义一个数据头很容易误读很多数据,引起资源浪费,所以发明者给曼彻斯特编码设定了一个曼彻斯特编码头 9个 1 。

至此什么是曼彻斯特编码我们就完全理解了。

4.实现曼彻斯特解码

? ? 了解了原理那么读数据就变的简单了,各有各的想法,我这里主要提供一种思路,可以不借助时钟线照样读出曼彻斯特数据。采用一个中断一个定时器 通过平均时间对比法来确定数据线上的数据。思路就是记录每次高低电平持续时间与一个时钟周期的时间对比,确定数据的1和0。

具体实现:用中断来侦测数据线高低电平变化,每次高低变化时触发中断,此时开始定时器计时,等下次中断再来时记录下定时器时间,这样我们就可以获取一段数据过来时所有的高低电平持续时间,获取到这些时间后取平均值,就大致推算出了一个时钟周期大概的时间,拿每一个数据去跟这个时间对比,找到第一个连续18个时间都大致等于这个时间平均值的地方,说明是9个1到来了,此后的数据 每一位都与 这个时间平均值比较 如果是 大概等于这个时间 那就说明 这段高/低电平持续了一个时钟周期,如果 大概等于 2个 时间的平均值 , 那就说明 这段高/低电平持续了2个时钟周期,那么再依据IO中断是高低电平轮流触发,通过这段时间的位置奇偶数,就可确定数据线高低电平跟随时钟变化情况,用1和0表示高低电平,记录下来,再每2位判断是1->0 还是 0->1确定数据是0还是1,至此就获取到了我们要的数据。

代码如下:

//定时器配置

void RFIDTim_init(void)
{
?? ?TIM_TimeBaseInitTypeDef TIM_TimeBaseSt;

?? ?RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

?? ?TIM_DeInit(RFID_TIM);

?? ?TIM_TimeBaseSt.TIM_Prescaler = 72-1;?? ?//
?? ?TIM_TimeBaseSt.TIM_CounterMode = TIM_CounterMode_Up;
?? ?TIM_TimeBaseSt.TIM_Period = 1000;
?? ?TIM_TimeBaseSt.TIM_ClockDivision =TIM_CKD_DIV1;
?? ?TIM_TimeBaseInit(RFID_TIM, &TIM_TimeBaseSt);?
?? ?TIM_Cmd(RFID_TIM, ENABLE);
?? ?DEBUG("time init ok \n");
?? ?
}

//IO及中断配置

void RFID_Exti_Init(void){
?? ?EXTI_InitTypeDef ? EXTI_InitStructure;
?? ?GPIO_InitTypeDef ? GPIO_InitStructure;
?? ?NVIC_InitTypeDef ? NVIC_InitStructure;

?? ?/* Enable GPIOA clock */
?? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
?? ?/* Enable AFIO clock */
?? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);


?? ?/* Configure PA.00 pin as input floating */
?? ?GPIO_InitStructure.GPIO_Pin = OUT_PIN;
?? ?GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
?? ?GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
?? ?GPIO_Init(OUT_PORT, &GPIO_InitStructure);

?? ?GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource7);//将PA7挂在中断源上

?? ?/* Configure EXTI0 line */
?? ?EXTI_InitStructure.EXTI_Line = EXTI_Line7;
?? ?EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
?? ?EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
?? ?EXTI_InitStructure.EXTI_LineCmd = ENABLE;
?? ?EXTI_Init(&EXTI_InitStructure);
?? ?EXTI_ClearITPendingBit(EXTI_Line7);?? ??? ??? ?
?? ?
?? ?/* Enable and set EXTI0 Interrupt to the lowest priority */
?? ?NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
?? ?NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
?? ?NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
?? ?NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
?? ?NVIC_Init(&NVIC_InitStructure);

}


//RFID初始化

void RFIDInit(void)
{
?? ?DEBUG("Start Init EM4095 RFID Module\r\n");
?? ??? ??? ??? ?
?? ?RFIDTim_init();//定时器配置
?? ?
?? ?RFID_Exti_Init();//IO初始化及中断配置

?? ?DEBUG("finish init EM4095 RFID Module\r\n");

}

?中断处理函数

// Interrupt bei Flankenwechsel
void EXTI9_5_IRQHandler(void)
{
?? ?static u8 N = 0;?

?? ?if(EXTI_GetITStatus(EXTI_Line7) != RESET)
?? ?{
?? ? ? ?if(gFlag == 0x00)
?? ? ? ?{
?? ??? ??? ?TT_Buffer[N]= TIM_GetCounter(RFID_TIM); //数组记录计时器计时时间
?? ??? ??? ?TT_voltage[N]=GPIO_ReadInputDataBit(OUT_PORT,OUT_PIN);//数组保存此时IO电平
?? ??? ??? ?TIM_SetCounter(RFID_TIM, 0);//计时器清0
?? ??? ??? ?N++; ?? ??? ? ??
?? ??? ??? ?if(N== 1)//cym
?? ??? ??? ?{
?? ??? ??? ? ? gFlag = 0xFF;
?? ??? ??? ?}
?? ? ? ? }
?? ??? ?EXTI_ClearITPendingBit(EXTI_Line7);
?? ?}?
}

//数据解析

unsigned char Decode(void)
{
? ? u16 ?min,max,avg,i,n;

?? ?min = 0xFF;max = 0xFF;avg = 0xFF;i = 0xFF;n = 0xFF;

? ? //-------------------- STEP1: 找出 [平均值]
? ? for(i=1; i<256; i++) //---- 从1开始! 0字节是不可靠数据
? ? {
? ? ? ? if(TT_Buffer[i]<min)
? ? ? ? {
? ? ? ? ? ? min = TT_Buffer[i];
? ? ? ? }
?? ??? ?if(TT_Buffer[i]>max)
? ? ? ? {
? ? ? ? ? ? max = TT_Buffer[i];
? ? ? ? }
? ? }

?? ?//数据过滤
?? ?if(min<100||max>1000)
?? ?{
?? ??? ?//DEBUG("\r\n min: %d max: %d ; |舍弃 ! | \r\n",min,max);
?? ??? ?return 0;
?? ?}

?? ?avg=((min+max)/2);//-----平均值
? ? n = 0;

? ? //-------------------- STEP2: 提取原始数据
? ??? ?for(i=1; i<256; i++) //---- 必须从1开始! 0字节是不可靠数据
?? ?{
?? ??? ?if (TT_Buffer[i]<avg )//(abs((int)TT_Buffer[i] - 245)<=70)
?? ??? ?{
?? ??? ??? ?if (TT_voltage[i]==1)
?? ??? ??? ??? ?Bin_Buffer[n++]=0;
?? ??? ??? ?else
?? ??? ??? ??? ?Bin_Buffer[n++]=1;
?? ??? ?}
?? ??? ?else if (TT_Buffer[i]>avg )//(abs((int)TT_Buffer[i] - 485)<=70)
?? ??? ?{
?? ??? ??? ?if (TT_voltage[i]==1)
?? ??? ??? ?{
?? ??? ??? ??? ?Bin_Buffer[n++]=0;
?? ??? ??? ??? ?Bin_Buffer[n++]=0;
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?Bin_Buffer[n++]=1;
?? ??? ??? ??? ?Bin_Buffer[n++]=1;
?? ??? ??? ?}
?? ??? ?}
?? ?}

? ? //-------------------- STEP3: 查找RFID头标志(9个1)

? ? i = n-128; ?//------- 有效起始点!
? ? while(i--)
? ? {
? ? ? ? if(FindHeader(i))
? ? ? ? {
? ? ? ? ? ? if(FindID(i))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return 1;
? ? ? ? ? ? }
? ? ? ? }
? ? }

? ? return 0;
}

/*=================== 查找RFID 头标志 9个1
//--- 匹配返回:1
//--- 无效返回:0*/
u8 FindHeader(u16 index)
{
? ? u8 n;

? ? if((Bin_Buffer[index]==0)&&(Bin_Buffer[index+1]==1))//cym 1/0
? ? {
? ? ? ? index++;
? ? ? ? index++;
? ? }
? ? else
? ? {
? ? ? ? return (0);
? ? }

? ? for(n=0; n<9; n++)
? ? {
? ? ? ? if((Bin_Buffer[index]==1)&&(Bin_Buffer[index+1]==0))//cym 0/1
? ? ? ? {
? ? ? ? ? ? index = index+2;
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? return (0);
? ? ? ? }
? ? }

? ? return (1);
}

将头后的数据解析为实际的卡号数据。
u8 FindID(u16 i)
{
? ? u8 n;
? ? u8 k;
? ? u8 sum;

? ? //-------------------- STEP1: 提取RFID有效数据
? ? if(i)
? ? {
? ? ? ? for(n=0; n<11; n++)RFID[n] = 0x00; //------ Buffer清零

? ? ? ? i = i+20; ?//--- 有效数据流

? ? ? ? for(k=0; k<11; k++)
? ? ? ? {
? ? ? ? ? ? for(n=0; n<5; n++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? RFID[k] = RFID[k]<<1;

? ? ? ? ? ? ? ? if((Bin_Buffer[i]==1)&&(Bin_Buffer[i+1]==0))//cym 0/1
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? RFID[k] |= 0x01;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? i += 2;
? ? ? ? ? ? }
? ? ? ? }

? ? }

? ? //---------------------------- STEP2: 校对数据

? ? //---------------------- X 轴校验
? ? for(k=0; k<10; k++)
? ? {
? ? ? ? sum = 0;
? ? ? ? if(RFID[k]&0x01)sum++;
? ? ? ? if(RFID[k]&0x02)sum++;
? ? ? ? if(RFID[k]&0x04)sum++;
? ? ? ? if(RFID[k]&0x08)sum++;
? ? ? ? if(RFID[k]&0x10)sum++;

? ? ? ? if(sum%2) //--- 偶校验出错!
? ? ? ? {
? ? ? ? ? ? // MessageBox("X 轴校验出错!");
? ? ? ? ? ? return 0;
? ? ? ? }
? ? }

? ? //------------------- Y 轴校验
? ? sum = 0;
? ? for(k=0; k<11; k++)
? ? {
? ? ? ? sum ^= RFID[k];
? ? }

? ? if(sum&0x1E) //--- 偶校验出错!
? ? {
? ? ? ? //MessageBox("Y 轴校验出错!");
? ? ? ? return 0;
? ? }

? ? //------------------ STEP3: 获取RFID卡号(4个字节32位)
? ? for(k=0; k<10; k++)
? ? {
? ? ? ? RFID[k] = RFID[k]>>1; //---去掉校验值
? ? }

? ? Vendor ?= 0;
? ? CardIDH = 0;
? ? CardIDL = 0;

? ? k = RFID[0]<<4;
? ? Vendor = k|RFID[1]; //--- 卡版本或供应商信息

? ? k = RFID[2]<<4;
? ? k |= RFID[3];
? ? CardIDH |= k<<8;

? ? k = RFID[4]<<4;
? ? k |= RFID[5];
? ? CardIDH |= k;

? ? k = RFID[6]<<4;
? ? k |= RFID[7];
? ? CardIDL |= k<<8;

? ? k = RFID[8]<<4;
? ? k |= RFID[9];
? ? CardIDL |= k;

? ? //------------------ STEP4: 显示解码结果
? ? return 1;
}
?

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

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 1:18:04-

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