stm32韦根数据接收支持26和34自动识别,记录数据分析过程和源码

韦根26和韦根34数据格式结构拆分和校验计算。

下面是同一张卡片使用韦根26和韦根34读卡器输出的数据

void EXTIX_Init(void)
{
 
 	EXTI_InitTypeDef EXTI_InitStructure;
 	NVIC_InitTypeDef NVIC_InitStructure;

    WG_Init();

  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//使能复用功能时钟

    //GPIOB.0 中断线以及中断初始化配置   下降沿触发
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);
    EXTI_InitStructure.EXTI_Line=EXTI_Line0;	
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_Init(&EXTI_InitStructure);	 	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

   //GPIOB.1	  中断线以及中断初始化配置 下降沿触发
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);
  	EXTI_InitStructure.EXTI_Line=EXTI_Line1;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_Init(&EXTI_InitStructure);	  	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			//使能按键KEY2所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2, 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;					//子优先级2
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure);
    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;			//使能按键KEY1所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;					//子优先级1 
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
   NVIC_Init(&NVIC_InitStructure);  	  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器


}
 //外部中断3服务程序
void EXTI0_IRQHandler(void)
{

	if( EXTI_GetITStatus(EXTI_Line0) != RESET ) 
	{
		TIM_SetCounter(TIM3,0); 
        TIM_Cmd(TIM3, ENABLE);
		if(DATA_IN0 == 0)
        {

				WG_Data <<= 1;
				WG_Count++;
                num++;
			
		}			
		    EXTI_ClearITPendingBit(EXTI_Line0);  	/清除LINE2上的中断标志位  
	}
}

//外部中断4服务程序
void EXTI1_IRQHandler(void)
{

	if( EXTI_GetITStatus(EXTI_Line1) != RESET ) 
	{
	     TIM_SetCounter(TIM3,0); 
         TIM_Cmd(TIM3, ENABLE);
		if(DATA_IN1 == 0)
        {
					WG_Data = (WG_Data<<1) | 0x01;
					WG_Count++;
				num1++;
		}
		EXTI_ClearITPendingBit(EXTI_Line1);  ///清除LINE3上的中断标志位  
	}

}
TIM3_Int_Init(2499,7199);//10Khz的计数频率,计数到2500为250ms 初始化
//通用定时器3中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
	
	//定时器TIM3初始化
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
    TIM_ClearFlag(TIM3, TIM_FLAG_Update);							    /* 清除溢出中断标志 */
    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

	//中断优先级NVIC设置
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
}
//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
	{
			TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志
            WG_State = 1;
			TIM_Cmd(TIM3, DISABLE);
	}
}
int WG_Recv26(unsigned char *str)
{
			if(WG_State)
            {
                printf("num==%d  num1=%d\r\n",num,num1);
                printf("WG_Count=%d\r\n",WG_Count);
                printf("WG_Data=%lu\r\n",WG_Data);
                if(WG_Count == 34)
                 {
                    str[0] = WG_Data>>25 & 0xFF;
                    printf("str[0]=%d\r\n",str[0]);
                    str[1] = WG_Data>>17 & 0xFF;
                     printf("str[1]=%d\r\n",str[1]);
                    str[2] = WG_Data>>9 & 0xFF;
                    printf("str[2]=%d\r\n",str[2]);
                    str[3] = WG_Data>>1 & 0xFF;
                    printf("str[2]=%d\r\n",str[3]);
                    check34_even_odd(str);
                    printf("\r\nEVEN=%d  ODD=%d\r\n",EVEN,ODD);
                    printf("(WG_Data>>25 & 0x01)==%d\r\n",(WG_Data>>33 & 0x01));
                    printf("(WG_Data & 0x01)==%d\r\n",(WG_Data & 0x01));
                    printf("\r\n\r\n(WG_Data>>25)==%d\r\n",(WG_Data>>33));
                    if(EVEN == (WG_Data>>33 & 0x01) && ODD == (WG_Data & 0x01))
                    {
                            printf("111111111");
                            WG=34;
                            WG_State = 0;
                            WG_Data = 0;
                            WG_Count = 0;
                            return 1;
                    }	
                    else
                    {
                        printf("000000000");
                            WG_State = 0;
                            WG_Data = 0;
                            WG_Count = 0;
                            return 0; 
                 }
             }
                else if(WG_Count==26)
                {
                    str[0] = WG_Data>>17 & 0xFF;
                    printf("str[0]=%d\r\n",str[0]);
                    str[1] = WG_Data>>9 & 0xFF;
                    
                    printf("str[1]=%d\r\n",str[1]);
                    str[2] = WG_Data>>1 & 0xFF;
                    printf("str[2]=%d\r\n",str[2]);
                    check26_even_odd(str);
                    printf("\r\nEVEN=%d  ODD=%d\r\n",EVEN,ODD);
                    printf("(WG_Data>>25 & 0x01)==%d\r\n",(WG_Data>>25 & 0x01));
                    printf("(WG_Data & 0x01)==%d\r\n",(WG_Data & 0x01));
                    printf("\r\n\r\n(WG_Data>>25)==%d\r\n",(WG_Data>>25));
                    if(EVEN == (WG_Data>>25 & 0x01) && ODD == (WG_Data & 0x01))
                    {
                            printf("111111111");
                                 WG=26;
                            WG_State = 0;
                            WG_Data = 0;
                            WG_Count = 0;
                            return 1;
                    }	
                    else
                    {
                         printf("000000000");
                            WG_State = 0;
                            WG_Data = 0;
                            WG_Count = 0;
                            return 0;
                    }
                WG_State = 0;
			    WG_Data = 0;
		    	WG_Count = 0;
		    	return -1;
            }
		return -2;		
}
int check26_even_odd(unsigned char *str)
{
    unsigned char i, one_num	= 0;
	unsigned short check_temp;
    if(NULL == str)
		return -1;
     //偶校验
	check_temp = str[0];
    for(i = 0;i < 8;i++)
	{
		if(check_temp<<i & 0x80)
			one_num+=1;
	}
    check_temp = str[1];
	for(i = 0;i < 4;i++)
	{
		if(check_temp<<i & 0x80)
			one_num+=1;
	}	
    if(one_num % 2 )
		EVEN = 1;
	else
		EVEN = 0; 
    //奇校验
	one_num = 0;
	check_temp = str[1];
	for(i = 0;i < 4;i++)
	{
		if(check_temp>>i & 0x01)
			one_num+=1;
	}
    check_temp = str[2];
	for(i = 0;i < 8;i++)
	{
		if(check_temp<<i & 0x80)
			one_num+=1;
	}
    if(one_num % 2 )
		ODD = 0;
	else
		ODD = 1;	
	return 0;
}
int check34_even_odd(unsigned char *str)
{
	unsigned char i, one_num	= 0;
	unsigned short check_temp;
	unsigned char a=0,b=0;
		if(NULL == str)
		return -1;
    //偶校验
	check_temp = str[0];
	for(i = 0;i < 8;i++)
	{
		if(check_temp<<i & 0x80)
        {
            one_num+=1;
            a++;
        }
	}	
     printf("str[0]中1的个数=%d\t\n",a);
	check_temp = str[1];
    for(i = 0;i < 8;i++)
	{
		if(check_temp<<i & 0x80)
		{
            one_num+=1;
            b++;
        }	
	}
    printf("str[1]中1的个数=%d\t\n",b);
	if(one_num % 2 )
		EVEN = 1;
	else
		EVEN = 0; 
	
	//奇校验
    one_num = 0;
	check_temp = str[2];
	for(i = 0;i < 8;i++)
    {
		if(check_temp>>i & 0x01)
			one_num+=1;
	}
    check_temp = str[3];
	for(i = 0;i < 8;i++)
	{if(check_temp<<i & 0x80)
			one_num+=1;
	}
    if(one_num % 2 )
		ODD = 0;
	else
		ODD = 1;	
	return 0;
}

 

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Keil 5 C语言中实现韦根2634解码,可以按照以下步骤进行: 1. 定义中断服务函数:在程序中定义外部中断的中断服务函数,并在函数中实现对韦根码的捕获和解码。 2. 定义变量:定义相应的变量来存储韦根码的数据和状态信息。例如,可以定义一个字符数组来存储韦根码的二进制数据,以及一个整型变量来表示当前位的状态(高电平或低电平)。 3. 解码韦根码:根据韦根码的特点,通过对外部中断信号的状态变化进行分析,可以还原出韦根码的原始数据。对于韦根26码,可以通过分析26个位的状态变化,识别出卡号等信息;对于韦根34码,则需要分析34个位的状态变化。 4. 处理数据:解码出韦根码的原始数据后,可以将其保存到内存或外部存储器中,也可以发送到其他设备进行处理。 下面是一个简单的示例代码,可以用于韦根26码的解码: ``` #include <reg52.h> char cardNo[26]; // 存储卡号的字符串 int bitState; // 当前位的状态(0或1) int bitCount; // 当前位的计数器 // 中断服务函数 void externalInterrupt(void) interrupt 0 { if (bitState != (P3 & 0x01)) // 判断当前位的状态是否发生变化 { bitState = P3 & 0x01; // 更新当前位的状态 if (bitCount < 26) // 如果卡号还没有完全接收 { cardNo[bitCount++] = bitState + '0'; // 将当前位的状态转换为字符,存储到卡号字符串中 } else // 卡号接收完成 { // 处理卡号数据,例如校验数据、发送数据等 // ... bitCount = 0; // 重置计数器,准备接收下一张卡的数据 } } } void main() { bitState = 0; // 初始化位的状态 bitCount = 0; // 初始化计数器 // 配置外部中断的触发方式(例如下降沿触发) IT0 = 1; EX0 = 1; EA = 1; while (1) { // 主循环中可以进行其他任务,例如控制设备、显示数据等 // ... } } ``` 需要注意的是,在实际应用中,韦根码的格式和解码方式可能存在差异,具体实现方式需要根据具体的硬件设备和软件程序而定。同时,为了保证数据的可靠性,还需要考虑数据校验等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值