日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32解码EM4100的曼彻斯特编码(库函数版本)

發布時間:2024/8/1 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32解码EM4100的曼彻斯特编码(库函数版本) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:

前些日子老師布置一個任務叫我們焊接一個RFID讀卡器,其中剛好我們手上也有一個STM32F103RBT6開發板,老師于是布置任務叫我們用STM32完成對EM4100進行讀卡操作

EM4100簡介:

中 文 名:EM4100卡
存儲容量:64bit
工作頻率:125KHZ
讀寫距離:2-15cm
產品名稱:EM4100/EM4102卡
芯片類型:μEM瑞士微電 EM4100/EM4102
擦寫壽命:讀不限,只讀
外形尺寸:ISO標準卡/厚卡
封裝材料:PVC、ABS
典型應用:身份識別、考勤系統、門禁系統、財物標識等
詳細資料:
進口瑞士微電子EM4100/4102無線射頻芯片,采用先進的芯片封裝工藝,可作為非接觸卡片應用的優良解決方案。同時提供優惠的印刷服務和適合應用環境的異形卡。可廣泛用于身份識別,考勤系統,門禁系統,財物標識,過程控制,企業一卡通系統,停車,物流,動物識別,身份識別,識別貨品,工業自動化,會議簽到,電子標簽,超市,倉庫管理,人員管理,安防系統,醫療機構等。

EM4100卡命名的原因是該卡的核心芯片是由EM Microelectronic(瑞士微電)公司生產。

該段信息來源 https://blog.csdn.net/yichu5074/article/details/82621415

EM4100數據幀格式

要點:

  • 數據總共有64bit。
  • 以連續的9個1開頭。
  • 前4個bit為廠商位。
  • 采用偶校驗的方法。(保證1的個數為偶數個)
  • 最后一列為行校驗。
  • 最后一行為列檢驗。
  • 數據最后一位為0。

曼徹斯特編碼:

兩種格式剛好相反:

  • 第一種:(EM4100采用這種編碼)
    1:高電平到低電平(下降)
    0:低電平到高電平(上升)
  • 第二種:
    1:低電平到高電平(上升)
    0:高電平到低電平(下降)

下圖為一次完整的EM4100幀數據

STM32F103RBT6解碼EM4100:

思路:

  • 首先找到高電平時間或者低電平時間在512us附近。
  • 找到后標記已經同步,并且此時為一次有效捕獲中斷。
  • 下一次上升沿或者下降沿必須距離上一次有效捕獲中斷512us附近。
  • 選用uint64_t的RFID_DATA來存放每一次有效數據。
  • 采集完一次有效捕獲中斷后檢查RFID_DATA是否以連續的9個1開頭并且最后一位為0。
  • 如果滿足條件則標記采集完成。否則繼續采集。
  • 采用的外設:TIM2 TIM3

    • TIM2:捕獲中斷以及125khz載波生成。
    • TIM3:計時器(32us更新中斷一次,每次RFID_CNT增加1)

    行校驗以及列檢驗思路:

    方案①:
    每一行(除了連續的9個1以及最后一行)加起來%2為0。前四列加起來%2為0。(不推薦)
    方案②:
    采用異或邏輯^:每一行(除了連續的9個1以及最后一行)異或為0。前四列異或為0。

    代碼片段:

    RFID_init(void)

    void RFID_init(void){TIM_TimeBaseInitTypeDef TIM2_struct;TIM_OCInitTypeDef TIM2_oc;GPIO_InitTypeDef GPIO1_InitStruct;GPIO_InitTypeDef GPIO2_InitStruct;TIM_ICInitTypeDef TIM2_ICInitStruct;NVIC_InitTypeDef NVIC_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIMER_init(3,71,31);//定時器3初始化GPIO1_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;GPIO1_InitStruct.GPIO_Pin=RFID_PIN_IN;GPIO1_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;GPIO2_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO2_InitStruct.GPIO_Pin=RFID_PIN_OUT;GPIO2_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(RFID_IN, &GPIO1_InitStruct);GPIO_Init(RFID_OUT, &GPIO2_InitStruct);TIM2_struct.TIM_ClockDivision=TIM_CKD_DIV1;TIM2_struct.TIM_Prescaler=71;TIM2_struct.TIM_CounterMode=TIM_CounterMode_Up;TIM2_struct.TIM_Period=7;TIM_ARRPreloadConfig(TIM2, ENABLE);TIM_TimeBaseInit(TIM2, &TIM2_struct);TIM2_oc.TIM_OCMode=TIM_OCMode_PWM1;TIM2_oc.TIM_OCPolarity=TIM_OCPolarity_High;TIM2_oc.TIM_OutputState=TIM_OutputState_Enable;TIM2_oc.TIM_Pulse=4;TIM_OC1Init(TIM2,&TIM2_oc);TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;NVIC_Init(&NVIC_InitStruct);TIM2_ICInitStruct.TIM_Channel=TIM_Channel_2;TIM2_ICInitStruct.TIM_ICFilter=0xf;//這個很重要!!TIM2_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Falling;TIM2_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;TIM2_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;TIM_ICInit(TIM2, &TIM2_ICInitStruct);TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);TIM_Cmd(TIM2, ENABLE); }

    void TIM2_IRQHandler(void)

    uint64_t RFID_DATA=0; u8 RFID_CNT=0;//溢出次數 u8 RFID_STA=0;//RFID狀態 u16 TIME_CNT=0; const u16 Sample=384;//(256+512)/2 const u8 Sample_Per=32;//定時器3溢出一次 32us /* RFID_STA 沒有用到后4位 bit7是否同步 bit6是否捕捉上升沿 bit5是否捕捉下降沿 bit4解析成功 */ void TIM2_IRQHandler(void){if(TIM_GetITStatus(TIM2,TIM_IT_CC2)!=RESET){if((RFID_STA&0X80)==0){//沒有建立同步if(GPIO_ReadInputDataBit(RFID_OUT, RFID_PIN_OUT)==Bit_SET){//代表上升沿TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Falling);//設置下降沿捕獲if(RFID_STA&0X20){//之前已經捕捉到一個下降沿if((RFID_CNT>(Sample/Sample_Per))&&(RFID_CNT<2*(Sample/Sample_Per))){RFID_STA|=0X80;}//標記同步else{RFID_STA|=0X40;if((RFID_CNT>2*(Sample/Sample_Per))||(RFID_CNT<(Sample/Sample_Per)/2)){RFID_STA=0;RFID_CNT=0;}}//標記捕捉到上升沿RFID_STA&=0XDF;//取消之前捕捉的下降沿RFID_CNT=0;//清空溢出次數}else{RFID_STA|=0X40;//標記捕捉到上升沿RFID_CNT=0;//清空溢出次數}}else{//代表下降沿TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Rising);//設置上升沿捕獲if(RFID_STA&0X40){//之前已經捕捉到一個上升沿if((RFID_CNT>(Sample/Sample_Per))&&(RFID_CNT<2*(Sample/Sample_Per))){RFID_STA|=0X80;}//標記同步else{RFID_STA|=0X20;if((RFID_CNT>2*(Sample/Sample_Per))||(RFID_CNT<(Sample/Sample_Per)/2)){RFID_STA=0;RFID_CNT=0;}}//標記捕捉到下降沿RFID_STA&=0XBF;//取消之前捕捉的上升沿RFID_CNT=0;//清空溢出次數}else{RFID_STA|=0X20;//標記捕捉到下降沿RFID_CNT=0;//清空溢出次數}}}else{//已經建立同步if((RFID_STA&0X10)==0){//沒有捕捉完成if(GPIO_ReadInputDataBit(RFID_OUT, RFID_PIN_OUT)==Bit_SET){//代表上升沿TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Falling);//設置下降沿捕獲if((RFID_CNT>2*(Sample/Sample_Per))||(RFID_CNT<(Sample/Sample_Per)/2)){RFID_STA=0;RFID_CNT=0;}if((RFID_CNT>(Sample/Sample_Per))&&(RFID_CNT<2*(Sample/Sample_Per))){RFID_DATA=RFID_DATA<<1;RFID_CNT=0;}//上升沿代表0}else{//代表下降沿TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Rising);//設置上升沿捕獲if((RFID_CNT>2*(Sample/Sample_Per))||(RFID_CNT<(Sample/Sample_Per)/2)){RFID_STA=0;RFID_CNT=0;}if((RFID_CNT>(Sample/Sample_Per))&&(RFID_CNT<2*(Sample/Sample_Per))){RFID_DATA=RFID_DATA<<1;RFID_DATA|=0x01;RFID_CNT=0;}//下降沿代表1}if(((RFID_DATA&0XFF80000000000001)==0XFF80000000000000)){RFID_STA|=0X10;}//RFID_DATA以9個連續的1開頭,以0結尾標記捕捉完成}else{//捕捉完成后還有數據就每次反轉一次捕獲狀態,易于下次重新開始捕獲if(GPIO_ReadInputDataBit(RFID_OUT, RFID_PIN_OUT)==Bit_SET){//代表上升沿TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Falling);//設置下降沿捕獲RFID_CNT=0;}else{//代表下降沿TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Rising);//設置上升沿捕獲RFID_CNT=0;} }}}//捕獲中斷TIM_ClearITPendingBit(TIM2, TIM_IT_CC2); }

    void TIM3_IRQHandler(void)

    void TIM3_IRQHandler(void){if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET){if(RFID_CNT==0XFF){RFID_CNT=0;}//溢出次數滿了if(TIME_CNT==0XFFFF){TIME_CNT=0;}//溢出次數滿了RFID_CNT+=1;TIME_CNT+=1;//時間計時單位}//更新中斷TIM_ClearITPendingBit(TIM3, TIM_IT_Update); }

    數據切片

    采用unsigned char類型的數組ID[11],通過移位操作進行獲取:

    u8 i=0; u8 ID[11]={0};//包括最后一行的數據 u8 RFID_ID[10]={0};//換算成ASCII碼的RFID_ID值 if(RFID_STA&0X10){for(i=0;i<11;i++){ID[i]=((RFID_DATA>>(50-5*i))&0x1f);} }

    行校驗以及列檢驗

    u8 RFID_check(void){u8 i=0,j=0;u8 sum=0;for(i=0;i<10;i++){for(j=0;j<5;j++){sum^=(ID[i]>>(4-j))&0x01;//行校驗}if(sum!=0)return 0;//行校驗失敗}for(i=0;i<11;i++){sum^=ID[i];//列校驗}if(sum>>1!=0)return 0;//列檢驗失敗return 1;//校驗成功 }

    附加功能:(把每一位換算成ASCII碼值)

    void RFID_process(void) {u8 i;for(i=0;i<10;i++){switch(ID[i]>>1){case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8: case 9:RFID_ID[i]=(ID[i]>>1)+48;break;//換算成ASCII碼的1 2 3 4 5 6 7 8 9case 10:case 11:case 12:case 13:case 14:case 15:RFID_ID[i]=(ID[i]>>1)-10+65;break;//換算成ASCII碼的A B C D E Fdefault:RFID_ID[i]=32;//轉換成ASCII碼的空格}} }

    總結

    以上是生活随笔為你收集整理的STM32解码EM4100的曼彻斯特编码(库函数版本)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。