• 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;
    }

     

    收藏

  • 相关阅读:
    a和b互换的2种方式
    spring cloud 方法调用 feign
    spring boot redis 五种类型使用实例
    springboot引入properties文件 yml文件
    Spark-Streaming结合Redis
    Spark-Streaming结合Mysql案例
    Springboot与scala编写第一个web程序
    Springboot工程Mybatis二级缓存配置
    小奇画画
    saf
  • 原文地址:https://www.cnblogs.com/zym0805/p/6554602.html
Copyright © 2020-2023  润新知