w806 adc 中断扫描通道采集

用到了该芯片adc 扫描4个adc 通道,官方的死循环等待非常浪费时间,这里改用adc 中断采集方式,记录一下

int32_t  adcFilterSum[4]={0};
int32_t detec_adc_value[4]={0};//mV
int16_t detec_convt_ok[4]={0};/*is OK*/
ADC_HandleTypeDef hadc;

void w80x_adc_init(void){
	__HAL_RCC_ADC_CLK_ENABLE();
	__HAL_AFIO_REMAP_ADC(GPIOA,GPIO_PIN_1);
	__HAL_AFIO_REMAP_ADC(GPIOA,GPIO_PIN_2);
	__HAL_AFIO_REMAP_ADC(GPIOA,GPIO_PIN_3);
	__HAL_AFIO_REMAP_ADC(GPIOA,GPIO_PIN_4);
	
	hadc.Instance = ADC;
	hadc.Init.channel = ADC_ANA_CR_CH_0;
	hadc.Init.freq = 1000;
	HAL_ADC_Init(&hadc);
	
	ADC->ADC_CR |=ADC_ADC_CR_ADCIE;/*interrupt enable*/
	NVIC_ClearPendingIRQ((IRQn_Type)ADC_IRQn);
	NVIC_EnableIRQ((IRQn_Type)ADC_IRQn);
	
	HAL_ADC_Start(&hadc);//start adc
}

#define		__ADC_VALUE_CONVT(value)((value & 0x20000)?(value&0x1FFFF):(value|0x20000))
#define 		ADC_I_FILTER_SHIFT  		6
__attribute__((isr)) void ADC_IRQHandler(void){
static uint8_t data_error_count =0;
	if(++data_error_count>=4){/*Wait for it to stabilize*/
		data_error_count =0;
		int tempval=ADC->DR & 0x3FFFC;
		tempval = __ADC_VALUE_CONVT(tempval);

		uint32_t reg_cr = ADC->ANA_CR;
		uint32_t channelx = 0x3&(reg_cr>>8);
		detec_convt_ok[channelx] =1;
		tempval =tempval -hadc.offset;
		float vale = (float)tempval *0.03159075 + 1196;
		adcFilterSum[channelx] = adcFilterSum[channelx] - (adcFilterSum[channelx] >> ADC_I_FILTER_SHIFT) + (int32_t)vale;
		detec_adc_value[channelx] = adcFilterSum[channelx] >> ADC_I_FILTER_SHIFT;/*filter*/
			
		if(++channelx>=4){channelx =0;}
		reg_cr =(0xff®_cr) |(channelx<<8);
		WRITE_REG(ADC->ANA_CR,reg_cr);	
	}
	WRITE_REG(ADC->IF, ADC_IF_ADC|ADC_IF_CMP);
}

W802使用该函数有的时候引脚悬空会得到一个-17 mV ,并且通道编号有错乱,,无解。。。  detec_adc_value[4]得到的mV值,detec_convt_ok[4] 大于0 转换完毕,实际使用后需要清除。

你可能感兴趣的:(单片机,嵌入式硬件)