银杏科技有限公司旗下技术文档发布平台 | |||
技术支持电话 | 0379-69926675-801 | ||
技术支持邮件 | Gingko@vip.163.com | ||
版本 | 日期 | 作者 | 修改内容 |
---|---|---|---|
V1.0 | 2020-07-04 | gingko | 初次建立 |
(3)ADC采样时间寄存器(ADC_SMPR1和ADC_SMPR2),这两个寄存器用于设置通道0~18的采样时间,每个通道占用3个位。 ADC_SMPR1的各位描述如图所示:
(4)ADC状态寄存器(ADC_SR),该寄存器保存了ADC转换时的各种状态。该寄存器的各位描述如图所示:
int main(void) { int i; /* MCU 配置*/ /* 重置所有外围设备,初始化Flash接口和Systick */ HAL_Init(); /* 配置系统时钟 */ SystemClock_Config(); /* 初始化所有已配置的外围就设备 */ MX_GPIO_Init(); MX_ADC3_Init(); MX_USART6_UART_Init(); usart6.initialize(115200); LED_GREEN_ON; usart6.printf("\x0c"); //清屏 usart6.printf("\033[1;32;40m"); //设置终端字体为绿色 usart6.printf(" Hello, I am iCore4!\r\n"); /* 无限循环 */ while (1) { LED_GREEN_ON; HAL_Delay(500); LED_GREEN_OFF; //读取ADC for(i = 0;i < 5;i ++){ my_adc.read(i); } //打印系统供电电压 usart6.printf(" "); usart6.printf("[I] %3.0fmA , ",my_adc.value[0] / 2* 1000.); usart6.printf("[V] %4.2fV, ",my_adc.value[1] * 6.); usart6.printf("[3.3V] %4.2fV, ",my_adc.value[2] * 2.); usart6.printf("[2.5V] %4.2fV,",my_adc.value[3] * 2.); usart6.printf("[1.2V] %4.2fV\r",my_adc.value[4]); } }
typedef struct { ADC_TypeDef *Instance; //ADC1/ADC2/ADC3 ADC_InitTypeDef Init; //初始化结构体变量 __IO uint32_t NbrOfCurrentConversionRank;//当前转换序列 DMA_HandleTypeDef *DMA_Handle; //DMA方式使用 HAL_LockTypeDef Lock; //ADC锁定对象 __IO uint32_t State; //ADC通讯状态 __IO uint32_t ErrorCode; //ADC错误代码 }ADC_HandleTypeDef;
typedef struct { uint32_t ClockPrescaler; //时钟分频系数2/4/6/8分频 uint32_t Resolution; //分辨率12/10/8/6 位 uint32_t DataAlign; //对齐方式,左对齐还是右对齐 uint32_t ScanConvMode; //扫描模式 uint32_t EOCSelection; //EOC标志是否设置 uint32_t ContinuousConvMode; //开启连续转换模式或者单次转换模式 uint32_t NbrOfConversion; //规则序列中有多少个转换 uint32_t DiscontinuousConvMode; //不连续采样模式 uint32_t NbrOfDiscConversion; //不连续采样通道数 uint32_t ExternalTrigConv; //外部触发方式 uint32_t ExternalTrigConvEdge; //外部触发边沿 uint32_t DMAContinuousRequests; //开启 DMA 请求连续模式或者单独模式 }ADC_InitTypeDef;
void MX_ADC3_Init(void) { ADC_ChannelConfTypeDef sConfig; /**配置ADC的全局功能(时钟,分辨率,数据对齐和转换次数)*/ hadc3.Instance = ADC3; hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;//4分频 hadc3.Init.Resolution = ADC_RESOLUTION_12B;// 12 位模式 hadc3.Init.ScanConvMode = DISABLE; //非扫描模式 hadc3.Init.ContinuousConvMode = DISABLE; //关闭连续转换 hadc3.Init.DiscontinuousConvMode = DISABLE; //禁止不连续采样模式 hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; //使用软件触发 hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START; //软件触发 hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT; //右对齐 hadc3.Init.NbrOfConversion = 1; //1 个转换在规则序列中 hadc3.Init.DMAContinuousRequests = DISABLE; //关闭DMA请求 hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV; //EOC中断 if (HAL_ADC_Init(&hadc3) != HAL_OK) //初始化ADC3 { _Error_Handler(__FILE__, __LINE__); } /*为选定的ADC常规通道配置其在定序器中的相应等级及其采样时间 */ sConfig.Channel = ADC_CHANNEL_7; //通道 sConfig.Rank = 1; //第1个序列,序列1 sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; //采样时间 if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) //通道配置 { _Error_Handler(__FILE__, __LINE__); } }
int read_adc(int channel) { int i,k; unsigned long int temp[20] = {0}; unsigned long int value; unsigned short int data[100]; ADC_ChannelConfTypeDef channel_config; unsigned char channel_remap[5] = {ADC_CHANNEL_7,ADC_CHANNEL_12,ADC_CHANNEL_4,ADC_CHANNEL_5,ADC_CHANNEL_6}; channel_config.Channel = channel_remap[channel]; channel_config.Offset = 0; channel_config.Rank = 1; channel_config.SamplingTime = ADC_SAMPLETIME_480CYCLES; for(k = 0;k < 20;k++){ for(i = 0;i < 100;i ++){ HAL_ADC_ConfigChannel(&hadc3,&channel_config); HAL_ADC_Start(&hadc3); while(!__HAL_ADC_GET_FLAG(&hadc3,ADC_FLAG_EOC)); data[i] = HAL_ADC_GetValue(&hadc3); } sort(data,100); for(i = 40;i < 60;i++){ temp[k] += data[i]; } temp[k] = temp[k] / 20; } value = 0; for(k = 0;k < 20;k++){//获取平均值,用来提高准确度 value += temp[k]; } value /= 20; my_adc.value[channel] = value * ADC_REF / 4096; return value; }