W806/W801/W800多通道ADC同时使用

本文使用环境:
电脑:windows10
主控:W806(240MHZ)
兼容:W800 W801
编译环境:平头哥的CDK

注意:本文默认已经搭建好平台。

参考文章:
W806-ADC-PWM-TIM尝鲜

本文github地址

写在前面:
最近有比较多的同学问到了多路ADC如何使用的问题,官方的demo只给出了单路ADC,因此本文就详细讲解一下。

一、文档

首先翻阅芯片的手册,查看ADC对应的端口和特性,这里直接查看上一篇文章的第1.1小节。

二、编程

2.1、定义ADC端口和ADC的结构体

定义单片机所有的ADC端口,一共有4个外接端口和一个电压、一个温度(共6个)。对应的IO注释在定义后面。在main函数定义如下:

//ADC
/* 
 * ADC_CHANNEL_0 	: channel 0
 * ADC_CHANNEL_1 	: channel 1
 * ADC_CHANNEL_2 	: channel 2
 * ADC_CHANNEL_3 	: channel 3
 * ADC_CHANNEL_0_1 	: channel 0 and channel 1 differential input
 * ADC_CHANNEL_2_3 	: channel 2 and channel 3 differential input */
					 
 /* 307hz ~ 2khz */
 
//ADC编号
#define ADC_1		0 	//PA1
#define ADC_2		1	//PA4
#define ADC_3		2	//PA3
#define ADC_4		3	//PA2
#define ADC_TEMP	4
#define ADC_VOL		5

//一共6个端口所以定义六个结构体数组
ADC_HandleTypeDef hadc[6];

注意: 由于官方的demo存在bug,所以需要做如下修改,否者下面的步骤编译会报错。
wm_adc.h文件中,添加如下定义ADC_CHANNEL_VOL。注意下图可以看出adc的频率在307-2000之间,记住这里。

#define ADC_CHANNEL_0		ADC_ANA_CR_CH_0
#define ADC_CHANNEL_1		ADC_ANA_CR_CH_1
#define ADC_CHANNEL_2		ADC_ANA_CR_CH_2
#define ADC_CHANNEL_3		ADC_ANA_CR_CH_3
#define ADC_CHANNEL_0_1		ADC_ANA_CR_CH_8
#define ADC_CHANNEL_2_3		ADC_ANA_CR_CH_9
//add by zxx start
#define ADC_CHANNEL_VOL		ADC_ANA_CR_CH_VOL
//add by zxx end
#define ADC_CHANNEL_TEMP	ADC_ANA_CR_CH_TEMP
#define ADC_CHANNEL_OFFSET	ADC_ANA_CR_CH_OFFSET
#define ADC_FREQ_MIN		307
#define ADC_FREQ_MAX		2000

2.2、修改初始化代码

官方的demo只给出了一个init函数,若需要使用多个需要自己单独多次修改,不是很方便,因此对官方的demo稍加修改。函数入口参数改为adc_numfreq,分别表示通道数和频率。通道数使用2.1小节定义的宏,频率直接写数字就行。
注意: 从上小节可以看出频率要保持在307-2000之间。但手册写的是1000,我也不是很理解。

static void ADC_Init(uint32_t adc_num, uint32_t freq)
{
    
    
	/* 
		//ADC_CHANNEL_0 : PA1
		//ADC_CHANNEL_1 : PA4
		//ADC_CHANNEL_2 : PA3
		//ADC_CHANNEL_3 : PA2
		//ADC_CHANNEL_0_1 : PA1 and PA4
		//ADC_CHANNEL_2_3 : PA3 and PA2
						 
	#define ADC_CHANNEL_0		ADC_ANA_CR_CH_0
	#define ADC_CHANNEL_1		ADC_ANA_CR_CH_1
	#define ADC_CHANNEL_2		ADC_ANA_CR_CH_2
	#define ADC_CHANNEL_3		ADC_ANA_CR_CH_3
	#define ADC_CHANNEL_0_1		ADC_ANA_CR_CH_8
	#define ADC_CHANNEL_2_3		ADC_ANA_CR_CH_9
	#define ADC_CHANNEL_VOL		ADC_ANA_CR_CH_VOL
	#define ADC_CHANNEL_TEMP	ADC_ANA_CR_CH_TEMP
	#define ADC_CHANNEL_OFFSET	ADC_ANA_CR_CH_OFFSET
*/

	uint32_t ADC_CHANNEL;
	 /* 307hz ~ 2khz */
	switch(adc_num)
	{
    
    
		case 0: ADC_CHANNEL = ADC_CHANNEL_0; break; 	//PA1
		case 1: ADC_CHANNEL = ADC_CHANNEL_1; break;		//PA4
		case 2: ADC_CHANNEL = ADC_CHANNEL_2; break;		//PA3
		case 3: ADC_CHANNEL = ADC_CHANNEL_3; break;		//PA2
		case 4: ADC_CHANNEL = ADC_CHANNEL_TEMP; break;
		case 5: ADC_CHANNEL = ADC_CHANNEL_VOL; break;
		default : printf("adc init ADC_CHANNEL err, The number of channels is not between 0 and 3 \r\n");return; break;
	}
	
	if(freq > 2000 || freq < 304)
		printf("adc freq too larger than 2khz or too lower than 307hz...please check...\n");
	
	hadc[adc_num].Instance = ADC;
	hadc[adc_num].Init.channel = ADC_CHANNEL;
	hadc[adc_num].Init.freq = freq;
	
	if (HAL_ADC_Init(&hadc[adc_num]) != HAL_OK)
	{
    
    
		printf("adc init err...\n");
	}
}

2.3、主函数



int main(void)
{
    
    
	int value[6] = {
    
    0};
	
	SystemClock_Config(CPU_CLK_160M);
	printf("enter main\r\n");

	ADC_Init(ADC_1,1000);
	ADC_Init(ADC_2,1000);
	ADC_Init(ADC_3,1000);
	ADC_Init(ADC_4,1000);
	ADC_Init(ADC_TEMP,1000);
	ADC_Init(ADC_VOL,1000);
	

	while (1)
	{
    
    
		value[0] = HAL_ADC_GET_INPUT_VOLTAGE(&hadc[ADC_1]);
		value[1] = HAL_ADC_GET_INPUT_VOLTAGE(&hadc[ADC_2]);
		value[2] = HAL_ADC_GET_INPUT_VOLTAGE(&hadc[ADC_3]);
		value[3] = HAL_ADC_GET_INPUT_VOLTAGE(&hadc[ADC_4]);
		value[4] = HAL_ADC_GET_INPUT_VOLTAGE(&hadc[ADC_TEMP]);
		value[5] = HAL_ADC_GET_INPUT_VOLTAGE(&hadc[ADC_VOL]);
		for(int i=0;i<6;i++)
			printf("value%d: = %d ",i,value[i]);
		printf("\n");
		HAL_Delay(1000);
	}
}

三、测试

下载程序到开发板,并串口输出:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_37280428/article/details/124616013
w