零死角玩转STM32—F42930.4.2软件设计
这里只讲解核心的部分代码,有些变量的设置,头文件的包含等并没有涉及到,完整的代码请参考本章配套的工程。我们编写两个ADC驱动文件,bsp_adc.h和bsp_adc.c,用来存放ADC所用IO引脚的初始化函数以及ADC配置相关函数。1.编程要点
1)2)3)4)5)6)7)8)初始化配置ADC目标引脚为模拟输入模式;使能ADC时钟;配置通用ADC为独立模式,采样4分频;设置目标ADC为12位分辨率,1通道的连续转换,不需要外部触发;设置ADC转换通道顺序及采样时间;配置使能ADC转换完成中断,在中断内读取转换完数据;启动ADC转换;使能软件触发ADC转换。ADC转换结果数据使用中断方式读取,这里没有使用DMA进行数据传输。2.代码分析
ADC宏定义
代码清单30-1ADC宏定义12345678910#defineRheostat_ADC_IRQ#defineRheostat_ADC_INT_FUNCTION#defineRHEOSTAT_ADC_GPIO_PORT#defineRHEOSTAT_ADC_GPIO_PIN#defineRHEOSTAT_ADC_GPIO_CLK#defineRHEOSTAT_ADC#defineRHEOSTAT_ADC_CLK#defineRHEOSTAT_ADC_CHANNELADC_IRQnADC_IRQHandlerGPIOCGPIO_Pin_3RCC_AHB1Periph_GPIOCADC1RCC_APB2Periph_ADC1ADC_Channel_13使用宏定义引脚信息方便硬件电路改动时程序移植。ADCGPIO初始化函数
代码清单30-2ADCGPIO初始化1staticvoidRheostat_ADC_GPIO_Config(void)第451页共996
零死角玩转STM32—F4292{3456789101112131415}GPIO_InitTypeDefGPIO_InitStructure;//使能GPIO时钟RCC_AHB1PeriphClockCmd(RHEOSTAT_ADC_GPIO_CLK,ENABLE);//配置IOGPIO_InitStructure.GPIO_Pin=RHEOSTAT_ADC_GPIO_PIN;//配置为模拟输入GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//不上拉不下拉GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;GPIO_Init(RHEOSTAT_ADC_GPIO_PORT,&GPIO_InitStructure);使用到GPIO时候都必须开启对应的GPIO时钟,GPIO用于AD转换功能必须配置为模拟输入模式。配置ADC工作模式代码清单30-3ADC工作模式配置1staticvoidRheostat_ADC_Mode_Config(void)2{3ADC_InitTypeDefADC_InitStructure;4ADC_CommonInitTypeDefADC_CommonInitStructure;56//开启ADC时钟7RCC_APB2PeriphClockCmd(RHEOSTAT_ADC_CLK,ENABLE);89//-------------------ADCCommon结构体参数初始化--------------------10//独立ADC模式11ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;12//时钟为fpclkx分频13ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;14//禁止DMA直接访问模式15ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;16//采样时间间隔17ADC_CommonInitStructure.ADC_TwoSamplingDelay=18ADC_TwoSamplingDelay_10Cycles;19ADC_CommonInit(&ADC_CommonInitStructure);2021//-------------------ADCInit结构体参数初始化---------------------22//ADC分辨率23ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;24//禁止扫描模式,多通道采集才需要25ADC_InitStructure.ADC_ScanConvMode=DISABLE;26//连续转换27ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;28//禁止外部边沿触发29ADC_InitStructure.ADC_ExternalTrigConvEdge=30ADC_ExternalTrigConvEdge_None;31//使用软件触发,外部触发不用配置,注释掉即可32//ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T1_CC1;33//数据右对齐34ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;35//转换通道1个36ADC_InitStructure.ADC_NbrOfConversion=1;37ADC_Init(RHEOSTAT_ADC,&ADC_InitStructure);38//------------------------------------------------------------------39//配置ADC通道转换顺序为1,第一个转换,采样时间为56个时钟周期40ADC_RegularChannelConfig(RHEOSTAT_ADC,RHEOSTAT_ADC_CHANNEL,411,ADC_SampleTime_56Cycles);42第452页共996
零死角玩转STM32—F42943444546474849}//ADC转换结束产生中断,在中断服务程序中读取转换值ADC_ITConfig(RHEOSTAT_ADC,ADC_IT_EOC,ENABLE);//使能ADCADC_Cmd(RHEOSTAT_ADC,ENABLE);//开始adc转换,软件触发ADC_SoftwareStartConv(RHEOSTAT_ADC);首先,使用ADC_InitTypeDef和ADC_CommonInitTypeDef结构体分别定义一个ADC初始化和ADC通用类型变量,这两个结构体我们之前已经有详细讲解。我们调用RCC_APB2PeriphClockCmd()开启ADC时钟。接下来我们使用ADC_CommonInitTypeDef结构体变量ADC_CommonInitStructure来配置ADC为独立模式、分频系数为4、不需要设置DMA模式、20个周期的采样延迟,并调用ADC_CommonInit函数完成ADC通用工作环境配置。我们使用ADC_InitTypeDef结构体变量ADC_InitStructure来配置ADC1为12位分辨率、单通道采集不需要扫描、启动连续转换、使用内部软件触发无需外部触发事件、使用右对齐数据格式、转换通道为1,并调用ADC_Init函数完成ADC1工作环境配置。ADC_RegularChannelConfig函数用来绑定ADC通道转换顺序和时间。它接收4个形参,第一个形参选择ADC外设,可为ADC1、ADC2或ADC3;第二个形参通道选择,总共可选18个通道;第三个形参为转换顺序,可选为1到16;第四个形参为采样周期选择,采样周期越短,ADC转换数据输出周期就越短但数据精度也越低,采样周期越长,ADC转换数据输出周期就越长同时数据精度越高。PC3对应ADC通道ADC_Channel_13,这里我们选择ADC_SampleTime_56Cycles即56周期的采样时间。利用ADC转换完成中断可以非常方便的保证我们读取到的数据是转换完成后的数据而不用担心该数据可能是ADC正在转换时“不稳定”的数据。我们使用ADC_ITConfig函数使能ADC转换完成中断,并在中断服务函数中读取转换结果数据。ADC_Cmd函数控制ADC转换启动和停止。最后,如果使用软件触发需要调用ADC_SoftwareStartConvCmd函数进行使能配置。ADC中断配置
代码清单30-4ADC中断配置1staticvoidRheostat_ADC_NVIC_Config(void)2{3NVIC_InitTypeDefNVIC_InitStructure;45NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);67NVIC_InitStructure.NVIC_IRQChannel=Rheostat_ADC_IRQ;8NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;9NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;10NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;1112NVIC_Init(&NVIC_InitStructure);13}在Rheostat_ADC_NVIC_Config函数中我们配置了ADC转换完成中断,使用中断同时需要配置中断源和中断优先级。第453页共996
零死角玩转STM32—F429ADC中断服务函数
代码清单30-5ADC中断服务函数1voidADC_IRQHandler(void)2{3if(ADC_GetITStatus(RHEOSTAT_ADC,ADC_IT_EOC)==SET){4//读取ADC的转换值5ADC_ConvertedValue=ADC_GetConversionValue(RHEOSTAT_ADC);67}8ADC_ClearITPendingBit(RHEOSTAT_ADC,ADC_IT_EOC);910}中断服务函数一般定义在stm32f4xx_it.c文件内,我们只使能了ADC转换完成中断,在ADC转换完成后就会进入中断服务函数,我们在中断服务函数内直接读取ADC转换结果保存在变量ADC_ConvertedValue(在main.c中定义)中。ADC_GetConversionValue函数是获取ADC转换结果值的库函数,只有一个形参为ADC外设,可选为ADC1、ADC2或ADC3,该函数还返回一个16位的ADC转换结果值。主函数
代码清单30-6主函数1intmain(void)2{3/*初始化USART1*/4Debug_USART_Config();56/*初始化滑动变阻器用到的DAC,ADC采集完成会产生ADC中断,7在stm32f4xx_it.c文件中的中断服务函数更新ADC_ConvertedValue的值*/8Rheostat_Init();910printf(\----这是一个ADC实验(NODMA传输)----\\r\\n\);111213while(1){14Delay(0xffffee);15printf(\ThecurrentADvalue=0xX\\r\\n\,16ADC_ConvertedValue);17printf(\ThecurrentADvalue=%fV\\r\\n\,ADC_Vol);1819ADC_Vol=(float)(ADC_ConvertedValue*3.3/4096);//读取转换的AD值2021}22}主函数先调用USARTx_Config函数配置调试串口相关参数,函数定义在bsp_debug_usart.c文件中。接下来调用Rheostat_Init函数进行ADC初始化配置并启动ADC。Rheostat_Init函数是定义在bsp_adc.c文件中,它只是简单的分别调用Rheostat_ADC_GPIO_Config()、Rheostat_ADC_Mode_Config()和Rheostat_ADC_NVIC_Config()。Delay函数只是一个简单的延时函数。在ADC中断服务函数中我们把AD转换结果保存在变量ADC_ConvertedValue中,根据我们之前的分析可以非常清楚的计算出对应的电位器动触点的电压值。第454页共996
零死角玩转STM32—F429最后就是把相关数据打印至串口调试助手。30.4.3下载验证
用USB线连接开发板“USBTOUART”接口跟电脑,在电脑端打开串口调试助手,把编译好的程序下载到开发板。在串口调试助手可看到不断有数据从开发板传输过来,此时我们旋转电位器改变其电阻值,那么对应的数据也会有变化。30.5独立模式多通道采集实验
30.5.1硬件设计
开发板已通过排针接口把部分ADC通道引脚引出,我们可以根据需要选择使用。实际使用时候必须注意保存ADC引脚是单独使用的,不可能与其他模块电路共用同一引脚。30.5.2软件设计
这里只讲解核心的部分代码,有些变量的设置,头文件的包含等并没有涉及到,完整的代码请参考本章配套的工程。跟单通道例程一样,我们编写两个ADC驱动文件,bsp_adc.h和bsp_adc.c,用来存放ADC所用IO引脚的初始化函数以及ADC配置相关函数,实际上这两个文件跟单通道实验的文件是非常相似的。1.编程要点
1)2)3)4)5)6)7)8)9)初始化配置ADC目标引脚为模拟输入模式;使能ADC时钟和DMA时钟;配置DMA从ADC规矩数据寄存器传输数据到我们指定的存储区;配置通用ADC为独立模式,采样4分频;设置ADC为12位分辨率,启动扫描,连续转换,不需要外部触发;设置ADC转换通道顺序及采样时间;使能DMA请求,DMA在AD转换完自动传输数据到指定的存储区;启动ADC转换;使能软件触发ADC转换。ADC转换结果数据使用DMA方式传输至指定的存储区,这样取代单通道实验使用中断服务的读取方法。实际上,多通道ADC采集一般使用DMA数据传输方式更加高效方便。第455页共996
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库STM32库开发实战指南-M4:30-ADC—电压采集(3)在线全文阅读。
相关推荐: