//main routine for ADC (linear) calibration testing void TestADCCalibration(void) { unsigned int * ADCBuffer; double * ADCRealValues; double P, Q; unsigned int i; unsigned int NumOfData; volatile double diffOrig; volatile double diffCalib; unsigned char DEBUG_STRING[30]; //set external clock (16MHz XTALL required) SetCPUClock(0); //allocate buffer space if ((ADCBuffer = malloc(ADC_BUFFER_SIZE * sizeof(ADCBuffer[0]))) == NULL) _asm("trap\n"); if ((ADCRealValues = malloc(ADC_BUFFER_SIZE * sizeof(ADCRealValues[0]))) == NULL) _asm("trap\n"); //main test { //collect data NumOfData = ADCCollectDataCalib(ADCBuffer, ADCRealValues); P= GetMultiplierCalib(ADCBuffer, ADCRealValues, NumOfData); diffOrig = GetErrorCalib(ADCBuffer, ADCRealValues, NumOfData, P, 0); //calib data ADCCalibratePQ(ADCBuffer, ADCRealValues, NumOfData, &P, &Q); diffCalib = GetErrorCalib(ADCBuffer, ADCRealValues, NumOfData, P, Q); //print errors sprintf(DEBUG_STRING, "Orig = %f", diffOrig); LCD_PrintString(LCD_LINE1, ENABLE, DISABLE, DEBUG_STRING); sprintf(DEBUG_STRING, "Calib= %f", diffCalib); LCD_PrintString(LCD_LINE2, ENABLE, DISABLE, DEBUG_STRING); delay(500000l);//to show results } //see real values after ADC calibration - for checking calibration LCD_Clear(); LCD_PrintString(LCD_LINE1, DISABLE, ENABLE, "Real calibrated U"); while(!JOY_SEL) { //start single conversion ADC2_StartConversion(); while (!ADC2_GetFlagStatus()); //clear end of conversion bit ADC2_ClearFlag(); //collect ADC value and display LCD_SetCursorPos(LCD_LINE2, 4);//set cursor position LCD_PrintDec4((P*ADC2_GetConversionValue() + Q)*1000); } //unallocate buffer free(ADCBuffer); }//TestADCCalibration
/**************************实现函数******************************************** *函数原型: unsigned int Get_ADCCH_Value(ADC2_Channel_TypeDef ADC_Channel) *功 能: 单次采样某个ADC通道 *******************************************************************************/ unsigned int Get_ADCCH_Value(ADC2_Channel_TypeDef ADC_Channel) { unsigned int SUM = 0;//临时和 unsigned char j; //配置ADC转换通道,单次采样模式,ADC结果右对齐 ADC2_Cmd(ENABLE); ADC2_ConversionConfig(ADC2_CONVERSIONMODE_SINGLE, ADC_Channel, ADC2_ALIGN_RIGHT); for (j = 0; j < 16 ; j++) { ADC2_StartConversion(); // 开始转换 while (ADC2_GetFlagStatus() == RESET); // 等待转换完成 SUM += ADC2_GetConversionValue(); // 求和 ADC2_ClearFlag(); } SUM = SUM>>4; ADC2_Cmd(DISABLE); return(SUM); }
#endif /*STM8S208 or STM8S207 or STM8AF52Ax or STM8AF62Ax */ #if defined(STM8S207) || defined(STM8S007) || defined(STM8S208) || defined (STM8AF52Ax) || defined (STM8AF62Ax) /** * @brief ADC2 interrupt routine. * @param None * @retval None */ INTERRUPT_HANDLER(ADC2_IRQHandler, 22) { /* In order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction. */ /* Get converted value */ Conversion_Value = ADC2_GetConversionValue(); if (Conversion_Value == 0x0) { /* Turn off LED1..4*/ STM_EVAL_LEDOff(LED1); STM_EVAL_LEDOff(LED2); STM_EVAL_LEDOff(LED3); STM_EVAL_LEDOff(LED4); } else if ((Conversion_Value <= 0xFF) && (Conversion_Value > 0x0)) { /* Turn on LED1 */ STM_EVAL_LEDOn(LED1); /* Turn off LED2..4 */
//collection of ADC data and also real precise values from external voltmeter //external data is entered with joystick movement as 0.000 number static unsigned int ADCCollectDataCalib(unsigned int * ADCBuffer, double * ADCRealValues) { unsigned int i; unsigned int multiplier; signed int Voltage; unsigned char cursorPos; unsigned char ArrowChar = '^'; unsigned char JoyUp,JoyDown,JoyLeft,JoyRight,JoySel; //disable ADC interrupts ADC2_ITConfig(DISABLE); //enable ADC ADC2_Init(ADC2_CONVERSIONMODE_SINGLE, ADC2_CHANNEL_12, ADC2_PRESSEL_FCPU_D6, ADC2_EXTTRIG_TIM, DISABLE, ADC2_ALIGN_RIGHT, ADC2_SCHMITTTRIG_CHANNEL12, DISABLE); //clear end of conversion bit ADC2_ClearFlag(); //for joystick control (init) //pull-ups on on all used buttons GPIOB->CR1 |= 0xF0; GPIOD->CR1 |= 0x80; Voltage = 0; multiplier = 1000; cursorPos = 2; //print values on LCD display LCD_Clear(); LCD_SetCursorPos(LCD_LINE1, 1); LCD_PrintDec4(Voltage); LCD_PrintString(LCD_LINE1, DISABLE, ENABLE, " =Real U"); LCD_SetCursorPos(LCD_LINE2, cursorPos/2); LCD_PrintChar(ArrowChar); //set external voltage - measure it with external voltmeter - enter voltmeter //value into LCD - measure ADC data - store real and ADC data to buffers //finish data collecting by KEY button on PCB board for(i=0; i<ADC_BUFFER_SIZE; i++) { LCD_SetCursorPos(LCD_LINE2, 0); LCD_PrintDec2(i); while(JOY_SEL); while(!JOY_SEL) { if(BUTTON_LOW) break; JoyUp = JOY_UP; JoyDown = JOY_DOWN; JoyLeft = JOY_LEFT; JoyRight= JOY_RIGHT; JoySel = JOY_SEL; if(JoyLeft)//increase multiplier { if (cursorPos!=2) { multiplier *= 10; cursorPos -= 1; } } if(JoyRight)//decrease multiplier { if (cursorPos!=5) { multiplier /= 10; cursorPos += 1; } } if(JoyRight || JoyLeft)//repaint cursor position { LCD_PrintString(LCD_LINE2, DISABLE, DISABLE, " ");//clear cursor LCD_SetCursorPos(LCD_LINE2, cursorPos/2);//set cursor position if(cursorPos & 1) LCD_PrintChar(' ');//print space LCD_PrintChar(ArrowChar);//print cursor while (JOY_RIGHT || JOY_LEFT); delay(1000l); } if(JoyUp)//increase real value { Voltage += multiplier; } if(JoyDown)//decrease real value { Voltage -= multiplier; } if(JoyUp || JoyDown)//repaint real value { LCD_PrintString(LCD_LINE1, DISABLE, DISABLE, " ");//clear voltage if (Voltage<0) { LCD_SetCursorPos(LCD_LINE1, 1); LCD_PrintDec4(-Voltage); LCD_SetCursorPos(LCD_LINE1, 0); LCD_PrintChar('-');//print sign } else { LCD_SetCursorPos(LCD_LINE1, 1); LCD_PrintDec4(Voltage); LCD_SetCursorPos(LCD_LINE1, 0); LCD_PrintChar('+');//print sign } while (JOY_UP || JOY_DOWN); delay(1000l); } //start single conversion ADC2_StartConversion(); while (!ADC2_GetFlagStatus()); //clear end of conversion bit ADC2_ClearFlag(); //collect ADC value and display it LCD_SetCursorPos(LCD_LINE2, 5);//set cursor position LCD_PrintDec4(ADC2_GetConversionValue()); } //stop collecting if KEY buttom pressed if(BUTTON_LOW) { break; } //otherwise collect ADC data (+ real data) and store them else { //start single conversion ADC2_StartConversion(); while (!ADC2_GetFlagStatus()); //clear end of conversion bit ADC2_ClearFlag(); //collect ADC value ADCBuffer[i] = ADC2_GetConversionValue(); //collect real value ADCRealValues[i] = (double)Voltage/1000; } } return i; }//ADCCollectDataCalib
int sysProcess(msg_t *pMsg) { int iRet = TRUE; u16 u16Ret = 0xffff; u16 u16Tmp; u16 temp1, temp2; msg_t msg; u8 ucArr[24]; //u8 u8Ret = 0xff; switch(pMsg->msgType) { case CACT_TOUT: /** 一段动作完成 **/ actProcess(&g_actionQueue); break; case CPMT_TOUT: /** 一段prompt动作完成 **/ actProcess(&g_promptQueue); break; case CBLK_TOUT: /** 一段blink动作完成 **/ actProcess(&g_blinkQueue); break; case CBLK_OVER: /** 全部blink动作完成 **/ blinkInit(); break; case CADC_TOUT: temp1 = ADC2_GetConversionValue(); adcSample_In(&g_adcData, temp1); //OLED_ShowNum12x24(2, 5, temp1, 7, 24); //???????????????????????????????????????????? //if((g_flag & (1<<8)) == 0) { /** ADC电压采样完成了吗? **/ if(adcSample_Out(&g_adcData, &temp2) == TRUE) { /** ADC电压采样完成, 取均值 **/ adcSample_Stop(&g_adcData); temp1 = VOL_getRefValue(); if(temp1 < temp2) { g_flag &= ~(1 << 9); /** 测得电压在参考电压之上 **/ } else { g_flag |= (1 << 9); /** 低电报警 **/ } } break; /*************************************************************************** * mcu与指纹传感器的通信及处理层次: * 通信层--数据层--处理层 * mcu与指纹传感器的通信数据分类: * 1.通信失败(信道故障或干扰,导致没收到正确数据)。可继续偿试。 * 2.通信没问题,取得图像数据失败。原因,如指纹不清晰,图像不正确, 比对时间超时(传感器层次的)等。可继续偿试。 * (从方程式指纹传感器使用反馈中,可以猜测认为,在图象不正确或不清晰时,持续比对)。 * 3.采集到正确的指纹图像,比对后没有发现匹配的模板。确认为一次失败。 * 4.正确返回,找到匹配的指纹模板。 ***************************************************************************/ case CMSG_COMRX: //u16Ret = FP_GetRespData(0, ucArr); u16Ret = FP_GetRespData(0, ucArr); MFPACK_FIFO_CLEAN(x); if(u16Ret != 0) { /** 收到有效数据 **/ u16Ret = FP_RespChk(ucArr); /** data valid or not **/ if(u16Ret == CMD_ACK_SUM_ERR) { /** 指纹操作数据-失败 **/ msg.msgType = CMSG_FGCOMFAIL; //通信校验错。可以重试 msgq_in_irq(&g_msgq, &msg); } else if(u16Ret == CMD_ACK_OK) { /******************************************* * now, we ensure that the data is valid * * we check several type of response *******************************************/ u16Ret = FP_RespGetType(ucArr); switch(u16Ret) { /*************************************************************** * 指纹录入的5种返回结果: * 1. 0x00 - 指令处理成功 * 2. 0x01 - 指令处理失败 * 3. 0x60 - 指定的Template号码无效 * 4. 0x14 - 指定号码中已存在Template * 5. 0xFFF1/0xFFF2/0xFFF3/0xFFF4 - 录入等待/离开手指 * 6. 0x23 - Timeout时间内没有检测到指纹的输入 * 7. 0x21 - 指纹图像不好 * 8. 0x30 - 登记的Template的制作失败 ***************************************************************/ case FP_ENROLL: u16Ret = FP_RespGetResult(ucArr); if(u16Ret == (u16)CRESP_ERR_SUCCESS) { /** 注册指纹-正常返回 **/ u16Ret = FP_RespGetLen(ucArr); if(u16Ret == 4) { u16Tmp = FP_RespGetId(ucArr); if(((u16Tmp >> 8 ) & 0xff) == 0xff) { if(((u16Tmp & 0xff) >= 0xf1) && ((u16Tmp & 0xff) <= 0xf4)) { msg.msgType = CMSG_FGRGSTING; msgq_in_irq(&g_msgq, &msg); } } else { } } else if(u16Ret == 6) {