Chinaunix首页 | 论坛 | 博客
  • 博客访问: 164687
  • 博文数量: 73
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 235
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-27 09:43
个人简介

为兴趣挑灯夜战

文章分类
文章存档

2018年(4)

2017年(7)

2016年(9)

2015年(4)

2014年(49)

分类: C/C++

2017-07-23 19:24:51

在上一篇中讲了磁卡软解码技术的信号处理部分,刷卡时,磁条信号经过处理后得到宽宽窄窄的曼码信号,单片机需要准确的记录下刷卡时三个轨道每一个信号电平的宽度,保存下来,然后再进行解码。
在设计中我使用的单片机是STM32F103单片机,要准确的同时记录三个轨道的数据信息,必须是用中断,就是单片机识别到信号管脚电平变化时就产生中断,然后通过定时器记录下信号高电平或电平的时间。在stm32单片机中,可以使用定时起的PWM输入模式或捕获模式,其中PWM输入模式可以同时记录下一个脉冲信号的周期及脉冲宽度,通过周期减去脉宽,就得到一个脉冲信号中的低电平的时间,而捕获模式一次捕获只能记录下一个高电平或一个低电平的时间。对于PWM输入模式,一个定时起智能实现一路信号的捕获,所三个轨道信号同时采样得使用三个定时器,为了减少硬件资源的占用,我抛弃了PWM输入模式。而定时器输入捕获模式却不能同时实现任意边沿触发,解决办法是先设置触发模式为某一种边沿触发,在捕获中断产生时,在中断中读取当前的捕获边沿的模式,然后重新设置为相反的触发模式,比如说,若当前为上升沿捕获模式,则修改捕获触发为下降 触发。
磁条刷卡的速度要求在100-1200mm/s,为了精确的技术曼码信号的数据,定时技术速度设置为1us,在最慢的刷卡速度时,一个曼码0信号的脉宽可达到4000多微秒,所以用来计数的数组得使用shot int 型。存取数据时要注意一个问题,即要防止内存泄漏,所以必须判断存储的数据是否超高存储数组的长度,如果超过就要停止记录,结束采样,另外也要判断一次刷卡速度是否结束,结束后就立即开始解码。
由于要不造成泄密问题,我只能大概的说一下实现方法,而不能粘贴所有源码,敬请谅解。
下面是对数据采集时捕获中断里对轨道1数据的采集过程:

点击(此处)折叠或打开

  1. /////////////////////////////Track1///////////////////////////////////////////    
  2.     if(TIM_GetITStatus(CptTimer, Track_1_ITCC) == SET && TrackData.track1_cnt < Track1_buf_len)
  3.     {
  4.         TIM_ClearITPendingBit(CptTimer, Track_1_ITCC);
  5.         
  6.         if(TrackData.track1_cnt == 0)
  7.         {        
  8.              TrackData.track1_CptCnt_Now= Track_1_GetCapture(CptTimer);
  9.              TrackData.track1_Cpt_Data[TrackData.track1_cnt]=0xFF;
  10.              TrackData.track1_cnt= 1;
  11.              TrackData.SwpStatus=SwipingCard;
  12.         }
  13.         else if(TrackData.track1_cnt>0)
  14.         {
  15.             TrackData.track1_CptCnt_Last=TrackData.track1_CptCnt_Now;
  16.             TrackData.track1_CptCnt_Now= Track_1_GetCapture(CptTimer);
  17.             
  18.             if (TrackData.track1_CptCnt_Now > TrackData.track1_CptCnt_Last)
  19.             {
  20.              TrackData.track1_Cpt_Data[TrackData.track1_cnt]=TrackData.track1_CptCnt_Now-TrackData.track1_CptCnt_Last;
  21.             }
  22.             else
  23.             {
  24.              TrackData.track1_Cpt_Data[TrackData.track1_cnt]=0xFFFF-TrackData.track1_CptCnt_Last+TrackData.track1_CptCnt_Now;
  25.             }
  26.             
  27.          TrackData.track1_cnt++;
  28.      }
  29.         
  30.      temp=CptTimer->CCER;
  31.      if(temp&(0x0001<<13)){
  32.             TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  33.             TIM_ICInitStructure.TIM_Channel = Track_1_CptChannel;
  34.             TIM_ICInit(CptTimer, &TIM_ICInitStructure);
  35.      }else{
  36.              TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
  37.             TIM_ICInitStructure.TIM_Channel = Track_1_CptChannel;
  38.             TIM_ICInit(CptTimer, &TIM_ICInitStructure);
  39.      }
  40.    }

.........................................................................................................
解码过程在下一篇中讲解
........................................................................................................





阅读(753) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~