赞
踩
在上一次的博客中重新学习了DMA(附上链接:点击打开链接),这次我们便学以致用了,ADC的概念想必大家都是十分清楚了,模拟转数字,可以用在测信号,测电压,在我们的生活中有着十分巨大的作用,这次我们就来看看ADC又有哪些操作吧!
ADC流程,首先ADC采集一个信号(信号范围大都为0-3.3V,ps:3.3V可通过更改Vref寄存器修改),每隔相同时间菜一次数值发送到一个可变16位数中,下面是我们的数组定义:
__IO uint16_t ADC_ConvertedValue; //定义该16位数用来传输数据,原因是我们使用的12位AD,由于寄存器的定义方便,因此使用16位数
下面是ADC的初始化和配置代码:
- void ADC1_Init(void)
- {
- ADC1_GPIO_Config(); //下面有详细的代码配置
- ADC1_Mode_Config();
- }
-
- static void ADC1_GPIO_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure; //定义写入寄存器的结构体
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能时钟,注意使能的是DMA1
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE); //本实验使用的是GPIOC1,使能ADC1,GPIO时钟
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //配置为PC.1
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //设置为模拟输入
- GPIO_Init(GPIOC, &GPIO_InitStructure); // 初始化写入寄存器中
- }
-
- static void ADC1_Mode_Config(void)
- {
- DMA_InitTypeDef DMA_InitStructure; //定义写入DMA寄存器的结构体
- ADC_InitTypeDef ADC_InitStructure; //定义写入ADC寄存器的结构体
- DMA_DeInit(DMA1_Channel1); //复位初始化,配置为复位模式,下面我们再重新配置(不知道有用没)
- DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //设置源地址
- DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue; //设置内存地址
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 设置传输方向
- DMA_InitStructure.DMA_BufferSize = 1; //因为我们最后一直改变一个变量,所以只有一位
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址固定
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //内存地址固定
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设传输数据大小为半字
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //内存传输数据大小为半字
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环模式
- DMA_InitStructure.DMA_Priority = DMA_Priority_High; //高优先级
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止内存间传输数据
- DMA_Init(DMA1_Channel1, &DMA_InitStructure); //将结构体写入寄存器中
-
- DMA_Cmd(DMA1_Channel1, ENABLE); //使能DMA寄存器的1通道
-
- /* ADC1 configuration */
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //因为只有一个通道,所以为独立ADC模式
- ADC_InitStructure.ADC_ScanConvMode = DISABLE ; //一个通道,所以不使能扫描模式
- ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //开启连续转换,就是不停转换
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使用外部触发,外部触发只有几个固定引脚,详情看手册
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //我们定义16位数,采集12位,所以要定义对齐方向,在这我们采取右对齐
- ADC_InitStructure.ADC_NbrOfChannel = 1; //要转换的通道数目
- ADC_Init(ADC1, &ADC_InitStructure); 将结构体写入寄存器中
-
- RCC_ADCCLKConfig(RCC_PCLK2_Div8); //72M时钟8分频为9M PS:ADC最大时钟速率为14M,后面解释
-
- ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5); //初始化,采样时间为55.5us,采样序号是1,PS:采样时间最 // 为1.5us,转换时间为固定12.5us,所以相当于采集完一次数为14us
- ADC_DMACmd(ADC1, ENABLE); // 使能DMA1
- ADC_Cmd(ADC1, ENABLE); //使能ADC1
- ADC_ResetCalibration(ADC1); //复位校准寄存器
- while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准寄存器完成
- ADC_StartCalibration(ADC1); //ADC校准
- while(ADC_GetCalibrationStatus(ADC1)); //等待校准完成
- ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1的软件触发
- }
以上就是我们用到的ADC的配置代码,若要读出ADC的数值,只需要调用我们的输出寄存器值就可完成,下面有个小例子,结合之前的串口通信代码,可将采集到的AD数值发送到电脑串口调试助手上
- while (1)
- {
- ADC_ConvertedValueLocal =(float) ADC_ConvertedValue/4096*3.3; // 转化 PS:将0-3.3分成4096份,ADC读出的是多少份,所以以这 //样计算
- printf("\r\n The current AD value = 0x%04X \r\n", ADC_ConvertedValue);
- printf("\r\n The current AD value = %f V \r\n",ADC_ConvertedValueLocal); //打印,USART代码 链接:点击打开链接
- Delay(0xffffee); //延时
- }
以上,有问题或有建议的同学可在下面评论或者私信我,我都会看的哈哈!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。