zoukankan      html  css  js  c++  java
  • rfid 125khz

    环境是STVD V4.1.6,
    编译器是COSMIC STM8 C Compiler 16K ,Version: 4.3.1
    调用的库有:GPIO,TIM2

    相关宏定义:

    //RF数据引脚
    #define DATA_PORT   GPIOC
    #define DATA_PIN    GPIO_PIN_3

    //定义每一位的宽度,t/4us
    #define BIT_TIME        128//一位数据时间
    #define HAFE_TIME       64//半位数据时间
    #define ERROR_BAND      10//允许是时间误差
    #define BIT_HAFE_TIME   192//1.5位数据时间

    //端口C外部中断,捕捉RFID卡数据输出的所有电平跳变
    @far @interrupt void IntSrvPortC(void)
    {
        unsigned char ucTemp;
        unsigned char ucCurrBitTime;
        _Bool bData;
       
        static _Bool s_bLastData;
       
        //先读取定时器计数器,即与上次中断的时间间隔,这是当前位的位宽
        //定时器每个值为4us,单独开启一个定时器计数
        if(TIM2->CNTRH == 0)
        {
            ucCurrBitTime = TIM2->CNTRL;
        }
        else//如果定时时间超过255,则以255计算
        {
            ucCurrBitTime = 255;
        }
        TIM2_SetCounter(0);//复位计数器,从0开始重新计时
       
        //接收到数据,接收超时计数器清零
        g_ucNoDataCnt = 0;
       
        //开始接收
        if(s_ucBitCounter < 18)//同步头,一共9个1,所以有18个跳变
        {
            if(s_ucBitCounter == 0)
            {
                //先找上升沿,数据0
                if(RESET != GPIO_ReadInputPin(DATA_PORT,DATA_PIN))
                {
                    //找到上升沿,进入下一步
                    s_ucBitCounter = 1;
                }
            }
            else if(s_ucBitCounter == 1)
            {
                //再找下降沿,如果上次的上升沿与本下降沿时间间隔为1个数据周期,则为连续的"01"
                //高电平时间持续1个数据周期,必定是"01"
                if(RESET == GPIO_ReadInputPin(DATA_PORT,DATA_PIN)//本次为下降沿
                && ucCurrBitTime > BIT_TIME - ERROR_BAND)//一个周期以上的高电平
                {
                    //找到"01",进入下一步
                    s_ucBitCounter = 2;
                }
                else//不是"01",重新找"01"
                {
                    s_ucBitCounter = 0;
                }
            }
            else
            {
                //已经找到"01"了,接下来要再找到连续的8个1
                //若两个电平跳变间隔1个数据周期,则必定出现0,重新找"01"
                if(ucCurrBitTime > BIT_TIME - ERROR_BAND)
                {
                    if(RESET == GPIO_ReadInputPin(DATA_PORT,DATA_PIN))//下降沿
                    {
                        //本次下降沿,重新找上升沿
                        s_ucBitCounter = 0;
                    }
                    else//本次上升沿,接着找下降沿
                    {
                        s_ucBitCounter = 1;
                    }
                }
                else
                {
                    s_ucBitCounter++;
                    bData = 1;//为下面接收到数据作准备
                }
            }
        }
        else//获取同步头成功
        {
            //根据本次电平跳变情况,与上次跳变间隔,及上次数据位,
            //可判断出本次跳变是空跳还是有效数据
            //本次是下降沿
            if(RESET == GPIO_ReadInputPin(DATA_PORT,DATA_PIN))
            {
                //与上次跳变间隔1个数据周期,说明高电平持续了1个数据周期,必然是1
                if(ucCurrBitTime > BIT_TIME - ERROR_BAND)
                {
                    bData = 1;
                }
                //与上次跳变间隔半个周期,若上次数据为1,本次数据也为1
                //即连续的两个1
                else if(s_bLastData == 1)
                {
                    bData = 1;
                }
                //间隔不足1个数据周期,且上次数据为0,则本次是空跳
                else
                {
                    return;
                }
            }
            //本次上升沿
            else
            {
                //与上次跳变间隔1个数据周期,说明低电平持续了1个数据周期,必然是0
                if(ucCurrBitTime > BIT_TIME - ERROR_BAND)
                {
                    bData = 0;
                }
                //与上次跳变间隔半个周期,若上次数据为0,本次数据也为0
                //即连续的两个0
                else if(s_bLastData == 0)
                {
                    bData = 0;
                }
                //间隔不跳1个数据周期,且上次数据为1,则本次是空跳
                else
                {
                    return;
                }
            }
            
            if(s_ucBitCounter >= 73)//同步头18个跳变,加上55个数据位
            {
                //接收到完成数据,重新开始接收数据
                s_ucBitCounter = 0;
                //把数据移出缓冲区,且清空缓冲区
                for(ucTemp=0;ucTemp<11;ucTemp++)
                {
                    g_ucData[ucTemp] = g_ucDataBuff[ucTemp] & 0x1f;
                }
                g_bitResevData = TRUE;//接收完成,处理数据
            }
            else
            {
                //把数据放入缓冲区
                ucTemp = s_ucBitCounter - 18;//减去同步头的18个跳变
                ucTemp /= 5;//得到当前接收到的数据属于第几个字节
                g_ucDataBuff[ucTemp] <<= 1;//从高位开始接收
                g_ucDataBuff[ucTemp] += bData;
                s_ucBitCounter++;//继续接收下一位
            }
        }
       
        s_bLastData = bData;//更新历史数据
        return;
    }

     

    收藏

  • 相关阅读:
    idea设置全局ignore
    win 2012 安装mysql 5.7.20 及报错 This application requires Visual Studio 2013 Redistributable. Please ins
    win 2012 安装mysql 5.7.20 及报错 This application requires Visual Studio 2013 Redistr
    kafka 删除 topic
    java编译中出现了Exception in thread “main" java.lang.UnsupportedClassVersionError
    Centos中使用yum安装java时,没有jps的问题的解决
    Spring 整合Junit
    Spring纯注解配置
    Spring 基于注解的 IOC 配置
    打印java系统的信息
  • 原文地址:https://www.cnblogs.com/zym0805/p/6554602.html
Copyright © 2011-2022 走看看