当前位置:   article > 正文

【联盛德W806上手笔记】十、ADC_w806 与 adion 2560

w806 与 adion 2560

Windows 10 20H2
HLK-W806-V1.0-KIT
WM_SDK_W806_v0.6.0


       摘自《W806 芯片设计指导书 V1.0》、《W806 MCU 芯片规格书 V2.0》

ADC

       基于 Sigma-Delta ADC 的采集模块,集成 4 路 16 比特 ADC,完成最多 4 路模拟信号的采集,或两路差分信号采集,采样率通过外部输入时钟控制,最高采样率 1KHz,可采集输入电压,也可采集芯片温度,支持输入校准和温度补偿校准。
在这里插入图片描述

ADC 电路设计

       芯片 19 ~ 21 脚可以作为普通 ADC 使用,输入电压范围 0~2.4V。当高于 2.4V 时外部需做分压处理后才可进入 ADC 接口。为提高精度,R1 和 R2 需使用高精度电阻。根据 Sensor 输出电压值选择合适的 R1,R2电阻值分压。
在这里插入图片描述

库函数

打开wm_adc.h,有如下内容:

函数

HAL_StatusTypeDef       HAL_ADC_Init(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef       HAL_ADC_DeInit(ADC_HandleTypeDef *hadc);
void                    HAL_ADC_MspInit(ADC_HandleTypeDef* hadc);
void                    HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc);


// AD转换功能以查询方式实现所对应的开始、停止、查询是否转换完成、获取转换结果
HAL_StatusTypeDef       HAL_ADC_Start(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef       HAL_ADC_Stop(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef 		HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc);
int                		HAL_ADC_GetValue(ADC_HandleTypeDef* hadc);

// 该接口调用了以上接口,实现了一个完整的查询转换过程,并返回结果,可以直接调用该接口获取转换结果,返回值单位mv
int 					HAL_ADC_GET_INPUT_VOLTAGE(ADC_HandleTypeDef* hadc);

// AD转换功能以中断方式实现所对应的开始、停止、中断回调函数
HAL_StatusTypeDef       HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef       HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc);
void                    HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);

// AD比较功能以中断方式实现所对应的开始、停止、中断回调函数
HAL_StatusTypeDef		HAL_ADC_Start_Compare_IT(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef       HAL_ADC_Stop_Compare_IT(ADC_HandleTypeDef* hadc);
void                    HAL_ADC_CompareCallback(ADC_HandleTypeDef* hadc);


void                    HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc);


int adc_get_inputvolt(uint8_t channel);

uint32_t adc_get_offset(void);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

参数

结构体和枚举类型

typedef struct
{
	uint32_t channel;	/* 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 */
	
	uint32_t freq;		/* 307hz ~ 2khz */
	
	uint32_t cmp_val;	/* compare value */
	
	uint32_t cmp_pol;	/* CMP_POL_0 :  when adc_result >= cmp_val interrupt
						 * CMP_POL_1 :  whrn adc_result < cmp_val interrtup */
	
}ADC_InitTypeDef;

typedef struct __ADC_HandleTypeDef
{
	ADC_TypeDef                   *Instance;
	
	ADC_InitTypeDef               Init;
	
	HAL_LockTypeDef               Lock;
	
	int				  	  		  offset;
	
}ADC_HandleTypeDef;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

宏参数

#define ADC                ((ADC_TypeDef *)ADC_BASE)

#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_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

#define CMP_POL_0	0x0UL
#define CMP_POL_1	ADC_ADC_CR_CMPPOL

#define HAL_ADC_STATE_RESET             0x00000000U
#define HAL_ADC_STATE_READY             0x00000001U
#define HAL_ADC_STATE_BUSY_INTERNAL     0x00000002U
#define HAL_ADC_STATE_TIMEOUT           0x00000004U
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

#define IS_ADC_ALL_INSTANCE(INSTANCE) ((INSTANCE) == ADC)

#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_CHANNEL_0)           || \
                                 ((CHANNEL) == ADC_CHANNEL_1)           || \
                                 ((CHANNEL) == ADC_CHANNEL_2)           || \
                                 ((CHANNEL) == ADC_CHANNEL_3)           || \
                                 ((CHANNEL) == ADC_CHANNEL_0_1)           || \
                                 ((CHANNEL) == ADC_CHANNEL_2_3)            )
								 
#define IS_ADC_CMP_POL(POL)		(((POL) == CMP_POL_0) || \
								 ((POL) == CMP_POL_1))
								 
#define IS_ADC_FREQUENCY(FREQ)  (((FREQ) >= ADC_FREQ_MIN) && ((FREQ) <= ADC_FREQ_MAX))

#define __HAL_ADC_ENABLE(__HANDLE__)	(MODIFY_REG((__HANDLE__)->Instance->ANA_CR, ADC_ANA_CR_CH | ADC_ANA_CR_PD | ADC_ANA_CR_RST | ADC_ANA_CR_LDOEN, \
													(__HANDLE__)->Init.channel | ADC_ANA_CR_RST | ADC_ANA_CR_LDOEN))
													
#define __HAL_ADC_DISABLE(__HANDLE__)	(MODIFY_REG((__HANDLE__)->Instance->ANA_CR, ADC_ANA_CR_PD | ADC_ANA_CR_RST | ADC_ANA_CR_LDOEN, \
													ADC_ANA_CR_PD))

#define __HAL_ADC_CLEAR_FLAG(__HANDLE__, __FLAG__)   	\
		(WRITE_REG((__HANDLE__)->Instance->IF, (__FLAG__)))
		
#define __HAL_ADC_INT_ENABLE(__HANDLE__, __FLAG__)	(SET_BIT((__HANDLE__)->Instance->ADC_CR, __FLAG__))

#define __HAL_ADC_INT_DISABLE(__HANDLE__, __FLAG__)	(CLEAR_BIT((__HANDLE__)->Instance->ADC_CR, __FLAG__))

#define __HAL_ADC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__)                     \
  (((__HANDLE__)->Instance->ADC_CR & (__INTERRUPT__)) == (__INTERRUPT__))
  
#define __HAL_ADC_GET_FLAG(__HANDLE__, __FLAG__)                               \
  ((((__HANDLE__)->Instance->IF) & (__FLAG__)) == (__FLAG__))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

Demo中的例程

main.c


#include <stdio.h>
#include "wm_hal.h"

void Error_Handler(void);
static void ADC_Init(void);
ADC_HandleTypeDef hadc;

int main(void)
{
	int value;
	
	SystemClock_Config(CPU_CLK_160M);
	printf("enter main\r\n");

	ADC_Init();
	while (1)
	{
		value = HAL_ADC_GET_INPUT_VOLTAGE(&hadc);
		printf("value = %dmv\r\n", value);
		HAL_Delay(1000);
	}
}

static void ADC_Init(void)
{
	hadc.Instance = ADC;
	hadc.Init.channel = ADC_CHANNEL_0;
	hadc.Init.freq = 1000;
	
	if (HAL_ADC_Init(&hadc) != HAL_OK)
	{
		Error_Handler();
	}
}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
	
}

void Error_Handler(void)
{
	while (1)
	{
	}
}

void assert_failed(uint8_t *file, uint32_t line)
{
	printf("Wrong parameters value: file %s on line %d\r\n", file, line);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

wm_hal_msp.c

#include "wm_hal.h"

void HAL_MspInit(void)
{

}

void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
	if (hadc->Instance == ADC)
	{
		__HAL_RCC_ADC_CLK_ENABLE();
		__HAL_RCC_GPIO_CLK_ENABLE();
		
		//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
		if (hadc->Init.channel == ADC_CHANNEL_0)
		{
			__HAL_AFIO_REMAP_ADC(GPIOA, GPIO_PIN_1);
		}
		else if (hadc->Init.channel == ADC_CHANNEL_1)
		{
			__HAL_AFIO_REMAP_ADC(GPIOA, GPIO_PIN_4);
		}
		else if (hadc->Init.channel == ADC_CHANNEL_2)
		{
			__HAL_AFIO_REMAP_ADC(GPIOA, GPIO_PIN_3);
		}
		else if (hadc->Init.channel == ADC_CHANNEL_3)
		{
			__HAL_AFIO_REMAP_ADC(GPIOA, GPIO_PIN_2);
		}
		else if (hadc->Init.channel == ADC_CHANNEL_0_1)
		{
			__HAL_AFIO_REMAP_ADC(GPIOA, GPIO_PIN_1);
			__HAL_AFIO_REMAP_ADC(GPIOA, GPIO_PIN_4);
		}
		else if (hadc->Init.channel == ADC_CHANNEL_2_3)
		{
			__HAL_AFIO_REMAP_ADC(GPIOA, GPIO_PIN_3);
			__HAL_AFIO_REMAP_ADC(GPIOA, GPIO_PIN_2);
		}
		
		// 如果用到中断方式需要使能中断
		HAL_NVIC_SetPriority(ADC_IRQn, 0);
		HAL_NVIC_EnableIRQ(ADC_IRQn);
	}
}

void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
{
	__HAL_RCC_ADC_CLK_DISABLE();
	HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1);
	HAL_NVIC_DisableIRQ(ADC_IRQn);
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

wm_it.c


#include "wm_hal.h"

extern ADC_HandleTypeDef hadc;

#define readl(addr) ({unsigned int __v = (*(volatile unsigned int *) (addr)); __v;})
__attribute__((isr)) void CORET_IRQHandler(void)
{
	readl(0xE000E010);
	HAL_IncTick();
}

__attribute__((isr)) void ADC_IRQHandler(void)
{
 	HAL_ADC_IRQHandler(&hadc);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/288326
推荐阅读
相关标签
  

闽ICP备14008679号