4100卡調試記錄

1、參考資料

            參考文檔

 

2、採集電路

 

         

3、採集流程

            1)CLK每隔250ms給一個40us的125KHZ方波,然後AD口檢測高低電平來判斷是不是有卡。當有卡的時候,卡會吸收線圈上的能量,導致AD口的電平爲低

            2)如果檢測到有卡,CLK持續給125KHZ的方波,OUT供高,運放工作,然後採集SINGER的數據。4100卡採用的是2K編碼,用的是曼徹斯特編碼格式,所以我們採集的速率至少要4K才能還原信號

            3)採集完一定數據量後開始解碼

 

4、代碼

/********************************************
 *功能:4100驅動
 *輸入:無
 *輸出:無
 *條件:無
 *返回:無
 注意:
*********************************************/
static T_U8 u8SampleData[500];
static T_U8 u8SampleId[4];
T_VOID ID_Sample(T_VOID)
{
	T_U32 u32Cnt = 0;
	T_U32 u32Delay = 0;
	
	ID_OUT_H();
	ADVTIM_CtrlPWMOutputs(ADVTIM1, ENABLE);
	
	u32Delay = 5000; 
	while(u32Delay--);
	
	memset(u8SampleData, 0, sizeof(u8SampleData));
	
	while(1)
	{
		if(ID_SINGER_PORT->DI & ID_SINGER_PIN)
		{
			u8SampleData[u32Cnt/8] |= (1 << (u32Cnt%8));
		}
		
		u32Delay = 290; 
		while(u32Delay--);
		
		u32Cnt++;
		if(u32Cnt >= 8*sizeof(u8SampleData))
		{
			break;
		}
	}
	
	ID_OUT_L();
	ADVTIM_CtrlPWMOutputs(ADVTIM1, DISABLE);
}
T_U8* ID_GetId(T_U8 *pu8SpData, T_U32 u32SpLen)
{
	T_U32 u32Cnt = 0;
	T_U32 u32Step = 0;
	T_U32 u32NowFlg = 0,u32OldFlg = 0;
	T_U32 u32StartFlg = 0; //開始解碼標誌
	T_U32 u32LCnt = 0, u32HCnt = 0;
	T_U32 u32OneCnt = 0, u32OneFlg = 0;
	T_U32 u32BitCnt = 0;
	T_U8  u8BitArray[20] = {0};
	T_U32 u32Bit1Cnt = 0,u32Bit2Cnt = 0,u32Bit3Cnt = 0,u32Bit4Cnt = 0;
	
	memset(u8BitArray, 0 , sizeof(u8BitArray));
	
	//有找到起始碼 或者 解碼數據已經全部遍歷
	while(u32Cnt < u32SpLen)
	{
		u32NowFlg = (pu8SpData[u32Cnt/8]>>(u32Cnt%8)) & 0x1;
		
		if(u32OldFlg == 1 && u32NowFlg == 0)
		{
			if(u32StartFlg)
			{
				if(u32LCnt >= 3 
					&& u32LCnt <= 5
					&& u32HCnt >= 3
					&& u32HCnt <= 5)
				{
					if(1 == u32OneFlg)
					{
						u8BitArray[u32BitCnt/5] |= (1 << (u32BitCnt%5));
						u32BitCnt++;
						if(u32BitCnt >= 55)
						{
							goto Sample_Chk;
						}
					}
					
					u32OneCnt++;
					if(u32OneCnt == 9)
					{
						u32OneFlg = 1;
					}
				}else if(u32HCnt >= 7 
						&& u32HCnt <= 9 )
				{
					if(u32OneFlg)
					{
						u8BitArray[u32BitCnt/5] |= (1 << (u32BitCnt%5));
						u32BitCnt+=2;
						if(u32BitCnt >= 55)
						{
							goto Sample_Chk;
						}
					}
					u32Cnt += 4;//跳3
					u32OneCnt = 0;
				}else if(u32LCnt < 3 
						&& u32HCnt >= 3
						&& u32HCnt <= 5)
				{
					if(u32OneFlg)
					{
						u32BitCnt++;
						if(u32BitCnt >= 55)
						{
							goto Sample_Chk;
						}
					}
					
					u32Cnt += 4;//跳3
					u32OneCnt = 0;
				}else
				{
					u32OldFlg = u32NowFlg;
					u32OneCnt = 0;
				}
			}else
			{
				if(u32HCnt >= 7 
					&& u32HCnt <= 9 )
				{
					u32Cnt += 4;
					u32StartFlg = 1;  //開始解碼
					u32OneCnt = 0;
				}
			}
						
			u32LCnt = 0;
			u32HCnt = 0;
		}else{
			if(u32NowFlg)
			{
				u32HCnt++;
			}else
			{
				u32LCnt++;
			}
		}
		u32Cnt++;			
		u32OldFlg = u32NowFlg;
	}
	
	return T_NULL;
	
Sample_Chk :

	u8SampleId[0] = u8BitArray[2]&0xff;
	u8SampleId[0] += (u8BitArray[3]&0xff)*16;
	u8SampleId[1] = u8BitArray[4]&0xff;
	u8SampleId[1] += (u8BitArray[5]&0xff)*16;
	u8SampleId[2] = u8BitArray[6]&0xff;
	u8SampleId[2] += (u8BitArray[7]&0xff)*16;
	u8SampleId[3] = u8BitArray[8]&0xff;
	u8SampleId[3] += (u8BitArray[9]&0xff)*16;
	
	return u8SampleId;
#if 0	
	for(u32Cnt = 1; u32Cnt < 10; u32Cnt++)
	{
		if(u8BitArray[u32Cnt]>>0 & 0x1)
		{
			u32Bit1Cnt++;
		}
		if(u8BitArray[u32Cnt]>>1 & 0x1)
		{
			u32Bit2Cnt++;
		}
		if(u8BitArray[u32Cnt]>>2 & 0x1)
		{
			u32Bit3Cnt++;
		}
		if(u8BitArray[u32Cnt]>>3 & 0x1)
		{
			u32Bit4Cnt++;
		}
	}
	
	if(u32Bit1Cnt % 2)
	{
		u32Bit1Cnt = 1;
	}else{
		u32Bit1Cnt = 0;
	}
	if(u32Bit2Cnt % 2)
	{
		u32Bit2Cnt = 1;
	}else{
		u32Bit2Cnt = 0;
	}
	if(u32Bit3Cnt % 2)
	{
		u32Bit3Cnt = 1;
	}else{
		u32Bit3Cnt = 0;
	}
	if(u32Bit4Cnt % 2)
	{
		u32Bit4Cnt = 1;
	}else{
		u32Bit4Cnt = 0;
	}
	
	if( (u32Bit1Cnt == (u8BitArray[10]>>0&0x01))
	  &&(u32Bit2Cnt == (u8BitArray[10]>>1&0x01))
	  &&(u32Bit3Cnt == (u8BitArray[10]>>2&0x01))
      &&(u32Bit4Cnt == (u8BitArray[10]>>3&0x01))	
	){
		u8SampleId[0] = u8BitArray[2]&0xff;
		u8SampleId[0] += (u8BitArray[3]&0xff)*16;
		u8SampleId[1] = u8BitArray[4]&0xff;
		u8SampleId[1] += (u8BitArray[5]&0xff)*16;
		u8SampleId[2] = u8BitArray[6]&0xff;
		u8SampleId[2] += (u8BitArray[7]&0xff)*16;
		u8SampleId[3] = u8BitArray[8]&0xff;
		u8SampleId[3] += (u8BitArray[9]&0xff)*16;
		
		return u8SampleId;
	}
#endif	
	return T_NULL;
}
T_U32 ID_ReadChk(T_VOID)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStruct.GPIO_Pin = ID_AD_PIN;
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
	GPIO_Init(ID_AD_PORT, &GPIO_InitStruct);
	
	//GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
	//GPIO_Init(ID_AD_PORT, &GPIO_InitStruct);
	//GPIO_ResetBits(ID_AD_PORT, ID_AD_PIN);
	
	ADVTIM_CtrlPWMOutputs(ADVTIM1, ENABLE);
	//while(1);
	T_U32 u32Delay = 150; //調成40us
	while(u32Delay--);
	
	ADVTIM_CtrlPWMOutputs(ADVTIM1, DISABLE);
	
	
	ID_AD_PORT->DIR |= (GPIO_PIN_OUT_MODE << (uint8_t)6);
	ID_AD_PORT->DOCL = ID_AD_PIN;
	
	u32Delay = 80; //不靈敏延長這裏 增大靈敏增大
	while(u32Delay--);
	
	ID_AD_PORT->DIR &= ~(GPIO_PIN_OUT_MODE << (uint8_t)6);
	
	u32Delay = 10; //延時讀數據
	while(u32Delay--);
	
	if(ID_AD_PORT->DI & ID_AD_PIN)
	{
		ID_AD_PORT->DIR |= (GPIO_PIN_OUT_MODE << (uint8_t)6);
		ID_AD_PORT->DOCL = ID_AD_PIN;
		
		return 0;
	}else{
		return 1;
	}
}
T_VOID ID_ReadTask(T_VOID *pvData)
{
	if(1 == ID_ReadChk())
	{
		//有卡
		ID_Sample();
		
		T_U8 *pu8Data = T_NULL;
		
		pu8Data = ID_GetId(u8SampleData, 8*sizeof(u8SampleData));
		if(T_NULL != pu8Data)
		{
			g_stGpioCtl.u8PopFlag = 1;
			g_stGpioCtl.stGpio.u8Type |= E_GPIO_READ_TYPE_ID;
			memcpy(g_stGpioCtl.stGpio.u8Data, pu8Data, 4);
		}
	}

	MDL_DRVTIMER_AddTimerRelative(ID_ReadTask, T_NULL, 250);
}
static T_VOID ID_Pwm_Init(T_VOID)
{
	ADVTIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	ADVTIM_OCInitTypeDef  TIM_OCInitStructure;
	
	GPIOD->AFR = 0x00100000;
	
	TIM_TimeBaseStructure.TIM_Prescaler = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_Period = 186;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
	ADVTIM_TimeBaseInit(ADVTIM1, &TIM_TimeBaseStructure);

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
	TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period/2;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;                     
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
	ADVTIM_OC1Init(ADVTIM1, &TIM_OCInitStructure);
	
	ADVTIM_CtrlPWMOutputs(ADVTIM1, DISABLE);
	ADVTIM_Cmd(ADVTIM1, ENABLE);
	
}

static T_VOID ID_Init(T_VOID)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStruct.GPIO_Pin = ID_OUT_PIN;
	GPIO_Init(ID_OUT_PORT, &GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStruct.GPIO_Pin = ID_AD_PIN;
	GPIO_Init(ID_AD_PORT, &GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStruct.GPIO_Pin = ID_SINGER_PIN;
	GPIO_Init(ID_SINGER_PORT, &GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStruct.GPIO_Pin = ID_CLK_PIN;
	GPIO_Init(ID_CLK_PORT, &GPIO_InitStruct);
	
	ID_OUT_L();
	ID_Pwm_Init();
	
	MDL_DRVTIMER_AddTimerRelative(ID_ReadTask, T_NULL, 250);

}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章