赞
踩
Windows 10 20H2
HLK-W806-V1.0-KIT
WM_SDK_W806_v0.6.0
摘自《W806 芯片设计指导书 V1.0》、《W806 MCU 芯片规格书 V2.0》
基于 Sigma-Delta ADC 的采集模块,集成 4 路 16 比特 ADC,完成最多 4 路模拟信号的采集,或两路差分信号采集,采样率通过外部输入时钟控制,最高采样率 1KHz,可采集输入电压,也可采集芯片温度,支持输入校准和温度补偿校准。
芯片 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);
结构体和枚举类型
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;
宏参数
#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
#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__))
#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); }
#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); }
#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); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。