STM32解码EM4100的曼彻斯特编码(库函数版本)
前言:
前些日子老師布置一個(gè)任務(wù)叫我們焊接一個(gè)RFID讀卡器,其中剛好我們手上也有一個(gè)STM32F103RBT6開發(fā)板,老師于是布置任務(wù)叫我們用STM32完成對(duì)EM4100進(jìn)行讀卡操作
EM4100簡(jiǎn)介:
中 文 名:EM4100卡
存儲(chǔ)容量:64bit
工作頻率:125KHZ
讀寫距離:2-15cm
產(chǎn)品名稱:EM4100/EM4102卡
芯片類型:μEM瑞士微電 EM4100/EM4102
擦寫壽命:讀不限,只讀
外形尺寸:ISO標(biāo)準(zhǔn)卡/厚卡
封裝材料:PVC、ABS
典型應(yīng)用:身份識(shí)別、考勤系統(tǒng)、門禁系統(tǒng)、財(cái)物標(biāo)識(shí)等
詳細(xì)資料:
進(jìn)口瑞士微電子EM4100/4102無線射頻芯片,采用先進(jìn)的芯片封裝工藝,可作為非接觸卡片應(yīng)用的優(yōu)良解決方案。同時(shí)提供優(yōu)惠的印刷服務(wù)和適合應(yīng)用環(huán)境的異形卡。可廣泛用于身份識(shí)別,考勤系統(tǒng),門禁系統(tǒng),財(cái)物標(biāo)識(shí),過程控制,企業(yè)一卡通系統(tǒng),停車,物流,動(dòng)物識(shí)別,身份識(shí)別,識(shí)別貨品,工業(yè)自動(dòng)化,會(huì)議簽到,電子標(biāo)簽,超市,倉庫管理,人員管理,安防系統(tǒng),醫(yī)療機(jī)構(gòu)等。
EM4100卡命名的原因是該卡的核心芯片是由EM Microelectronic(瑞士微電)公司生產(chǎn)。
該段信息來源 https://blog.csdn.net/yichu5074/article/details/82621415
EM4100數(shù)據(jù)幀格式
要點(diǎn):
- 數(shù)據(jù)總共有64bit。
- 以連續(xù)的9個(gè)1開頭。
- 前4個(gè)bit為廠商位。
- 采用偶校驗(yàn)的方法。(保證1的個(gè)數(shù)為偶數(shù)個(gè))
- 最后一列為行校驗(yàn)。
- 最后一行為列檢驗(yàn)。
- 數(shù)據(jù)最后一位為0。
曼徹斯特編碼:
兩種格式剛好相反:
- 第一種:(EM4100采用這種編碼)
1:高電平到低電平(下降)
0:低電平到高電平(上升) - 第二種:
1:低電平到高電平(上升)
0:高電平到低電平(下降)
下圖為一次完整的EM4100幀數(shù)據(jù)
STM32F103RBT6解碼EM4100:
思路:
采用的外設(shè):TIM2 TIM3
- TIM2:捕獲中斷以及125khz載波生成。
- TIM3:計(jì)時(shí)器(32us更新中斷一次,每次RFID_CNT增加1)
行校驗(yàn)以及列檢驗(yàn)思路:
方案①:
每一行(除了連續(xù)的9個(gè)1以及最后一行)加起來%2為0。前四列加起來%2為0。(不推薦)
方案②:
采用異或邏輯^:每一行(除了連續(xù)的9個(gè)1以及最后一行)異或?yàn)?。前四列異或?yàn)?。
代碼片段:
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);//定時(shí)器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;//這個(gè)很重要!!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;//溢出次數(shù) u8 RFID_STA=0;//RFID狀態(tài) u16 TIME_CNT=0; const u16 Sample=384;//(256+512)/2 const u8 Sample_Per=32;//定時(shí)器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);//設(shè)置下降沿捕獲if(RFID_STA&0X20){//之前已經(jīng)捕捉到一個(gè)下降沿if((RFID_CNT>(Sample/Sample_Per))&&(RFID_CNT<2*(Sample/Sample_Per))){RFID_STA|=0X80;}//標(biāo)記同步else{RFID_STA|=0X40;if((RFID_CNT>2*(Sample/Sample_Per))||(RFID_CNT<(Sample/Sample_Per)/2)){RFID_STA=0;RFID_CNT=0;}}//標(biāo)記捕捉到上升沿RFID_STA&=0XDF;//取消之前捕捉的下降沿RFID_CNT=0;//清空溢出次數(shù)}else{RFID_STA|=0X40;//標(biāo)記捕捉到上升沿RFID_CNT=0;//清空溢出次數(shù)}}else{//代表下降沿TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Rising);//設(shè)置上升沿捕獲if(RFID_STA&0X40){//之前已經(jīng)捕捉到一個(gè)上升沿if((RFID_CNT>(Sample/Sample_Per))&&(RFID_CNT<2*(Sample/Sample_Per))){RFID_STA|=0X80;}//標(biāo)記同步else{RFID_STA|=0X20;if((RFID_CNT>2*(Sample/Sample_Per))||(RFID_CNT<(Sample/Sample_Per)/2)){RFID_STA=0;RFID_CNT=0;}}//標(biāo)記捕捉到下降沿RFID_STA&=0XBF;//取消之前捕捉的上升沿RFID_CNT=0;//清空溢出次數(shù)}else{RFID_STA|=0X20;//標(biāo)記捕捉到下降沿RFID_CNT=0;//清空溢出次數(shù)}}}else{//已經(jīng)建立同步if((RFID_STA&0X10)==0){//沒有捕捉完成if(GPIO_ReadInputDataBit(RFID_OUT, RFID_PIN_OUT)==Bit_SET){//代表上升沿TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Falling);//設(shè)置下降沿捕獲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);//設(shè)置上升沿捕獲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個(gè)連續(xù)的1開頭,以0結(jié)尾標(biāo)記捕捉完成}else{//捕捉完成后還有數(shù)據(jù)就每次反轉(zhuǎn)一次捕獲狀態(tài),易于下次重新開始捕獲if(GPIO_ReadInputDataBit(RFID_OUT, RFID_PIN_OUT)==Bit_SET){//代表上升沿TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Falling);//設(shè)置下降沿捕獲RFID_CNT=0;}else{//代表下降沿TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Rising);//設(shè)置上升沿捕獲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;}//溢出次數(shù)滿了if(TIME_CNT==0XFFFF){TIME_CNT=0;}//溢出次數(shù)滿了RFID_CNT+=1;TIME_CNT+=1;//時(shí)間計(jì)時(shí)單位}//更新中斷TIM_ClearITPendingBit(TIM3, TIM_IT_Update); }數(shù)據(jù)切片
采用unsigned char類型的數(shù)組ID[11],通過移位操作進(jìn)行獲取:
u8 i=0; u8 ID[11]={0};//包括最后一行的數(shù)據(jù) 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);} }行校驗(yàn)以及列檢驗(yàn)
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;//行校驗(yàn)}if(sum!=0)return 0;//行校驗(yàn)失敗}for(i=0;i<11;i++){sum^=ID[i];//列校驗(yàn)}if(sum>>1!=0)return 0;//列檢驗(yàn)失敗return 1;//校驗(yàn)成功 }附加功能:(把每一位換算成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;//轉(zhuǎn)換成ASCII碼的空格}} }總結(jié)
以上是生活随笔為你收集整理的STM32解码EM4100的曼彻斯特编码(库函数版本)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式-Adapter模式(适配器模式
- 下一篇: 在进入上交之后对未来的展望(第一篇博客)