STM32 ADC电压测试实验报告
- 格式:docx
- 大小:532.87 KB
- 文档页数:7
测试报告1 测试内容STM32 407单片机为核心板,配合AD7656读取差模信号的16位A/D采样值。
2 测试方法2.1整体方案使用串口调试助手(Baud 115200、数据位8、停止位1、效验位无)做为下位机接收数据,通过Stm32 407单片机采样的值发送给串口助手显示十进制的A/D采样值。
分别输入不同的信号进行观察数据变化是否成线性并进行数据统计。
整体方案如图1所示。
图1 方案原理图2.1方法原理硬件电路连接好之后,先给板子供电,用万能表测量板子供电电压是否正确,测试前保证硬件电路正常。
根据说明手册连接好外围电路以及供电电源,供电电压选择+15V—15V的模拟电压,AD7656板子选用ADC3通道(总共有6个通道,使用哪一个注释其他的观察即可),ADC3接信号发生器的正接线柱、AD7656板子GND接信号发生器的接地接线柱(下载程序之前先关闭信号发生器的CH1),分别让信号发生器输出正弦波、余弦波,通过AD7656板子进行采集并进行观察,如果AD7656板子采集的数据跟信号发生器给的信号相似或者呈线性,则观察结果和理论相吻合。
主程序流程图如图2所示图2 AD采集主程序流程图观察结束后,分别设置软件其他通道的参数并把采集的数据打印出来,与其它通道进行对比,看各个通道的采集情况,并导入到Excel表格中进行观察.3 测试结果让信号发生器输出一个频率:10KHz,高电平:1V,低电平:-1V,占空比:50%的方波信号.用串口助手观察数据并把这些数据导出到Excel表格中进行观察.观察结果如图3所示图3.1 测试结果观察结果显示的是一个与输出信号相吻合的方波信号,数据跳动厉害是信号发生器的精度不准确原因导致的,所以实际测量值与理论测量值呈线性相关.其它五个通道的采集情况与ADC3采集的情况基本相似.4.1 问题1调试AD采集程序的时候,AD采集的数据在串口上不显示, 测试硬件电路供电是否正常,当只给AD板子供电时候,测试引脚电压为3.3V.当外围接入数字电压+5V时,只能烧进去程序.4.1.1解决方案回看原理图,发现AD7656板子的供电电压只有在+15时才能带动板子正常工作,所以给AD7656板子外加一个+15V电源,观察AD采集数据和信号发生器输出的信号相吻合。
实验报告课程名称:单片微机原理与车载系统学生姓名蒋昭立班级电科1601学号***********指导教师易吉良成绩2018年12 月17 日实验1 GPIO实验1.1 实验目的1)熟悉MDK开发环境;2)掌握STM32单片机的GPIO使用方法。
1.2 实验设备1)一台装有Keil和串口调试软件的计算机;2)一套STM32F103开发板;3)STlink硬件仿真器。
1.3 基本实验内容1)熟悉MDK开发环境,参考《STM32F1开发指南(精英版)-寄存器版本_V1.0》第3章,安装MDK 并新建test工程,运行例程,在串口窗宽观察结果,并记录如下:从图片可以看出,例程运行成功,没有错误。
2)按键输入实验,《STM32F1开发指南(精英版)-寄存器版本_V1.0》第8章。
实现功能:3 个按钮(KEY_UP、KEY0和KEY1),来控制板上的2 个LED(DS0 和DS1)和蜂鸣器,其中KEY_UP 控制蜂鸣器,按一次叫,再按一次停;KEY1 控制DS1,按一次亮,再按一次灭;KEY0 则同时控制DS0 和DS1,按一次,他们的状态就翻转一次。
理解连续按概念及其实现代码。
参数mode 为0 的时候,KEY_Scan 函数将不支持连续按,扫描某个按键,该按键按下之后必须要松开,才能第二次触发,否则不会再响应这个按键,这样的好处就是可以防止按一次多次触发,而坏处就是在需要长按的时候比较不合适。
当mode 为1 的时候,KEY_Scan 函数将支持连续按,如果某个按键一直按下,则会一直返回这个按键的键值,这样可以方便的实现长按检测。
寄存器方法实现不支持连续按的关键代码,以及程序运行后的效果。
由程序可知,给KEY_Scan函数输入的值为0,为不支持连按模式。
寄存器方法实现支持连续按的关键代码,以及程序运行后的效果。
由程序可知,给KEY_Scan函数输入的值为1,为支持连按模式。
3)采用库函数方法实现按键输入实验,参考《STM32F1开发指南(精英版)-库函数版本_V1.0》第8章。
48脚STM32内部基准电压校准ADC的一些心得记录在进行STM32内部基准电压校准ADC的过程中,我积累了一些心得和经验。
在此记录下来,分享给大家。
首先,基准电压是ADC精度的关键,因此校准过程十分重要。
基准电压在STM32系列芯片中默认为3V,但实际上可能存在差异。
因此,我们需要通过校准过程来提高ADC的测量精度。
校准前,我们需要做一些准备工作。
首先,确定使用的电压参考源,常用的有外部参考电压和内部基准电压两种。
相比于外部参考电压,内部基准电压的供电更加稳定和可靠。
接下来,我们需要配置ADC的工作模式和精度。
根据实际应用情况,选择合适的采样速率和转换模式。
在校准过程中,一般选择单次转换模式。
校准的关键在于获取两组参考电压值:理论值和测量值。
理论值是指校准前,我们已知的基准电压值。
测量值是指通过ADC测量得到的实际电压值。
首先,我们需要获取理论值。
根据STM32芯片的技术手册,可以查找到基准电压的精确数值。
然后,我们需要通过参考电压源提供一个已知电压,并将其连接到芯片的ADC通道上。
接下来,我们需要获取测量值。
通过ADC测量参考电压源的输出电压,并将结果保存在寄存器中。
在单次转换模式下,可以直接通过读取ADC_DR寄存器来获取测量值。
获取了理论值和测量值后,我们就可以计算出校准系数。
校准系数是理论值与测量值之间的比例关系。
通过将测量值除以理论值,即可得到校准系数。
然后,我们可以在程序中使用这个校准系数来校准ADC转换结果。
通过上述步骤,我们可以提高ADC的精度和准确性。
但需要注意的是,校准系数是基于当前环境和条件下得到的。
如果环境和条件发生变化,可能会导致校准系数失效。
因此,我们需要定期进行校准,以保证ADC的准确性。
总结一下,进行STM32内部基准电压校准ADC需要做以下几个步骤:确定使用的电压参考源、配置ADC的工作模式和精度、获取理论值和测量值、计算校准系数和使用校准系数来校准ADC转换结果。
双ADC通道测量电压值说明书
一:原理图
电压测量等功能电路图
二:工作原理
根据PA0和PA1输入的电压,可转换成不同的AD值,通过获取寄存器中的AD值,再将其转变为电压值。
开发板使用了3.3V的外部参考电压。
ADC的使用请参考《STM32中文参考资料》。
三:实验现象及操作
程序下载到开发板,并运行后,可以观察到数码管的左边三位和右边三位点亮。
并显示有精确到小数点后2位的数值。
当PA0或PA1槽没有任何接入时,不同的开发板可能显示的值有所不同,但对电压的测量没有影响。
先取一个电压值小于3.3V的电池,将电池的负极接EXT的GND槽,电池的正极接EXT 的PA0槽或PA1槽,根据正极接入不同的插槽,是的电压值显示的位置不同。
●左边三位形成的十进制值为PA0槽测到的电压值,精确到小数点后2位。
●右边三位形成的十进制值为PA1槽测到的电压值,精确到小数点后2位。
STM32实现双通道ADC采集电压电流值本次的实验是通过配置DMA来获取ADC采集到的数据的。
软件实现如下: adc.c⽂件#include "adc.h"#define ADC1_DR_Address ((u32)0x40012400+0x4c) //定义ADC1地址volatile uint16_t ADCConvertedValue[2]; //定义内存地址数组float AD_Value[2];static void ADC1_GPIO_Config(void){GPIO_InitTypeDef GPIO_InitStructure;/* Enable ADC1 and GPIOC clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);/* Configure PC.01 as analog input */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOB, &GPIO_InitStructure); // PB0,PB1 ,输⼊时不⽤设置速率}static void ADC1_DMA_Config(void){DMA_InitTypeDef DMA_InitStructure;/* DMA channel1 configuration */RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //使能DMA传输DMA_DeInit(DMA1_Channel1);DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(ADC1->DR); //ADC地址DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCConvertedValue; //内存地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize = 2;DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址固定DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址不固定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);}static void ADC1_Config(void){/* ADC1 configuration */ADC_InitTypeDef ADC_InitStructure;ADC_DeInit(ADC1);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); //使能ADC1时钟ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独⽴ADC模式ADC_InitStructure.ADC_ScanConvMode = ENABLE; //启动扫描模式,扫描模式⽤于多通道采集ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //开启连续转换模式,即不停地进⾏ADC转换ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使⽤外部触发转换ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集数据右对齐ADC_InitStructure.ADC_NbrOfChannel = 2; //要转换的通道数⽬2ADC_Init(ADC1, &ADC_InitStructure);/*配置ADC时钟,为PCLK2的6分频,即12Hz*/RCC_ADCCLKConfig(RCC_PCLK2_Div6);/*配置ADC1的通道8,9为239.5个采样周期,序列为1,2*/ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1 , ADC_SampleTime_239Cycles5);ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2 , ADC_SampleTime_239Cycles5);/* Enable ADC1 DMA */ADC_DMACmd(ADC1, ENABLE);/* Enable ADC1 */ADC_Cmd(ADC1, ENABLE);/*复位校准寄存器 */ADC_ResetCalibration(ADC1);/*等待校准寄存器复位完成 */while(ADC_GetResetCalibrationStatus(ADC1));/* ADC校准 */ADC_StartCalibration(ADC1);/* 等待校准完成*/while(ADC_GetCalibrationStatus(ADC1));}void adc1_start(void){ADC_SoftwareStartConvCmd(ADC1, ENABLE); //ADC1软计启动DMA_Cmd(DMA1_Channel1, ENABLE); //使能DMA通道1}void ADC1_Init(void){ADC1_GPIO_Config();ADC1_DMA_Config();ADC1_Config();}adc.h⽂件#ifndef __ADC_H#define __ADC_H#include <stm32f10x.h>void ADC1_Init(void);void adc1_start(void);#endif /*ADC_H*/main.c⽂件#include "adc.h"extern volatile uint16_t ADCConvertedValue[2]; //定义内存地址数组extern float AD_Value[2];int main(void){NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级组为组2,2位抢占优先级,2位响应优先级 USART1_Int(); //串⼝初始化ADC1_Init(); //ADC1初始化adc1_start();SysTick_Init(); //系统时钟初始化while(1){ AD_Value[0]=(float)ADCConvertedValue[0]/4096*3.3; //获取电压值 AD_Value[1]=(float)ADCConvertedValue[1]/4096*3.3; //获取电流值 printf("\r\n电压值为:%f V\r\n",AD_Value[0]); printf("\r\n电流值为:%f A\r\n",(AD_Value[1]-2.5)/0.185);}}本次实验的电流采集模块⽤的是ACS712模块,所以在打印输出时需要转换⼀下。
实验报告课程名称:单片微机原理与车载系统学生姓名蒋昭立班级电科1601学号16401700119指导教师易吉良成绩2018年12 月17 日实验1 GPIO实验1.1 实验目的1)熟悉MDK开发环境;2)掌握STM32单片机的GPIO使用方法。
1.2 实验设备1)一台装有Keil和串口调试软件的计算机;2)一套STM32F103开发板;3)STlink硬件仿真器。
1.3 基本实验内容1)熟悉MDK开发环境,参考《STM32F1开发指南(精英版)-寄存器版本_V1.0》第3章,安装MDK 并新建test工程,运行例程,在串口窗宽观察结果,并记录如下:从图片可以看出,例程运行成功,没有错误。
2)按键输入实验,《STM32F1开发指南(精英版)-寄存器版本_V1.0》第8章。
实现功能:3 个按钮(KEY_UP、KEY0和KEY1),来控制板上的2 个LED(DS0 和DS1)和蜂鸣器,其中KEY_UP 控制蜂鸣器,按一次叫,再按一次停;KEY1 控制DS1,按一次亮,再按一次灭;KEY0 则同时控制DS0 和DS1,按一次,他们的状态就翻转一次。
理解连续按概念及其实现代码。
参数mode 为0 的时候,KEY_Scan 函数将不支持连续按,扫描某个按键,该按键按下之后必须要松开,才能第二次触发,否则不会再响应这个按键,这样的好处就是可以防止按一次多次触发,而坏处就是在需要长按的时候比较不合适。
当mode 为1 的时候,KEY_Scan 函数将支持连续按,如果某个按键一直按下,则会一直返回这个按键的键值,这样可以方便的实现长按检测。
寄存器方法实现不支持连续按的关键代码,以及程序运行后的效果。
由程序可知,给KEY_Scan函数输入的值为0,为不支持连按模式。
寄存器方法实现支持连续按的关键代码,以及程序运行后的效果。
由程序可知,给KEY_Scan函数输入的值为1,为支持连按模式。
3)采用库函数方法实现按键输入实验,参考《STM32F1开发指南(精英版)-库函数版本_V1.0》第8章。
//内部AD可显示正确的电压值。
oh ye ah!调了我两天呀!总算调出来了yeah!//我第一个想到的就是与大家一起分享我的程序。
oh ye ah!还请各位大侠多多指教呀!大家一起学习交流。
/*********************************************************************** ********* F ile N ame :main.c* A uthor :Wuhan R&DCente r, Em best* Dat e Fir st Is sued : 08/08/2008* Desc ripti on : Mai n pro grambody************************************************************************ ********//* Incl udes------------------------------------------------------------------*/#inclu de "s tm32f10x_l ib.h"#inc lude"stdio.h"//#inc lude"moni tor.h"/************ 用于定义ITMViewe r相关的I TM激励寄存器端口************************//*#d efine ITM_Port8(n) (*((vola tileunsig ned c har *)(0xE0000000+4*n)))#defi ne IT M_Por t16(n) (*((vo latil e uns igned shor t*)(0xE0000000+4*n)))#de fineITM_P ort32(n) (*((volat ile u nsign ed lo ng *)(0xE0000000+4*n)))#defi ne DE MCR (*((vo latil e uns igned long *)(0xE000EDFC)))#d efine TRCE NA 0x01000000*//*用于定义是否使用ITMViewe r*///#def ine D BG_IT M /* P rivat e typ edef-----------------------------------------------------------*//*Priva te de fine------------------------------------------------------------*/#d efine ADC1_DR_A ddres s ((u32)0x4001244C)fl oat A D_val ue;i nt AD_valu e1;//stat ic un signe d lon g tic ks;//unsi gnedcharClock1s;u8 adc_1[10]={0};//用来存放经AD C转换后的电压值的每一位数值。
STM32 与M25P80的IO 接口对应关系如表1所示。
图2 STM32 的SPI1 硬件框图1 STM32 与M25P80 的IO 接口对应关系1.3 Key 按键介绍通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。
因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖。
消抖是为了避免在按键按下或是抬起时电平剧烈抖动带来的影响。
按键的消抖,可用硬件或软件两种方法。
Key 硬件框图如图3 所示,按键输入与PG8 口连接。
当按键不按下时,PG8 口输入高电平;当按键按下时,PG8 口输入低电平。
图3 Key 硬件框图41.4 定时器图5 主程序的流程框图如图5 所示,对于该流程框图的分析如下:1) 对STM32的初始化,其中包括ADC 初始化、SPI串口初始化、LCD 初始化等,初始化过程在其相应的子程序中执行。
2) 显示组员的信息和时间,正如实验七所学的,运用函数LCD_ShowString() ,即可在LCD 上显示自己所需要的信息,其显示的位置可以根据设定的坐标来设置。
3) 设置Key 键,当Key 键被按下时,开始采集数据并将其显示,而数据采集和显示的编程及其分析过程在前面的实验七中已经有过比较详细的介绍了,所以这里不再赘述。
同时,采集到的数据及时的将其存储在Flash中,Flash的设置在其初始化中已经完成。
4) 设置Temper键,当Temper 键被按下的时候,开始对之前采集到的数据进行绘图7 数据绘制子程序四、实验结果和分析1、软件的调试结果将程序烧录到STM32 中进行调试,调试结果如图8~9所示,从图中可知,程序满足实验要求。
图8 显示日期及组员信息。
STM32 ADC电压测试实验报告一、实验目的1.了解STM32的基本工作原理2. 通过实践来加深对ARM芯片级程序开发的理解3.利用STM32的ADC1通道0来采样外部电压值值,并在TFTLCD模块上显示出来二、实验原理STM32拥有1~3个ADC,这些ADC可以独立使用,也可以使用双重模式(提高采样率)。
STM32的ADC是12位逐次逼近型的模拟数字转换器。
它有18个通道,可测量16个外部和2个内部信号源。
各通道的A/D转换可以单次、连续、扫描或间断模式执行。
ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中接下来,我们介绍一下执行规则通道的单次转换,需要用到的ADC寄存器。
第一个要介绍的是ADC控制寄存器(ADC_CR1和ADC_CR2)。
ADC_CR1的各位描述如下:ADC_CR1的SCAN位,该位用于设置扫描模式,由软件设置和清除,如果设置为1,则使用扫描模式,如果为0,则关闭扫描模式,ADC_CR1[19:16]用于设置ADC的操作模式我们要使用的是独立模式,所以设置这几位为0就可以了。
第二个寄存器ADC_CR2,该寄存器的各位描述如下:ADCON位用于开关AD转换器。
而CONT位用于设置是否进行连续转换,我们使用单次转换,所以CONT位必须为0。
CAL和RSTCAL用于AD校准。
ALIGN用于设置数据对齐,我们使用右对齐,该位设置为0。
EXTSEL[2:0]用于选择启动规则转换组转换的外部事件,我们这里使用的是软件触发(SWSTART),所以设置这3个位为111。
第三个要介绍的是ADC采样事件寄存器(ADC_SMPR1和ADC_SMPR2),这两个寄存器用于设置通道0~17的采样时间,每个通道占用3个位对于每个要转换的通道,采样时间建议尽量长一点,以获得较高的准确度,但是这样会降低ADC的转换速率。
ADC的转换时间可以由下式计算:Tcovn=采样时间+12.5个周期第四个要介绍的是ADC规则序列寄存器(ADC_SQR1~3),第五个要介绍的是ADC规则数据寄存器(ADC_DR)。
STM32 ADC电压测试实验报告
一、实验目的
1.了解STM32的基本工作原理
2. 通过实践来加深对ARM芯片级程序开发的理解
3.利用STM32的ADC1通道0来采样外部电压值值,并在TFTLCD模块上显示出
来
二、实验原理
STM32拥有1~3个ADC,这些ADC可以独立使用,也可以使用双重模式(提高采样率)。
STM32的ADC是12位逐次逼近型的模拟数字转换器。
它有18个通道,可测量16个外部和2个内部信号源。
各通道的A/D转换可以单次、连续、扫描或间断模式执行。
ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中
接下来,我们介绍一下执行规则通道的单次转换,需要用到的ADC寄存器。
第一个要介绍的是ADC控制寄存器(ADC_CR1和ADC_CR2)。
ADC_CR1的各位描述如下:
ADC_CR1的SCAN位,该位用于设置扫描模式,由软件设置和清除,如果设置为1,则使用扫描模式,如果为0,则关闭扫描模式,ADC_CR1[19:16]用于设置ADC的操作模式
我们要使用的是独立模式,所以设置这几位为0就可以了。
第二个寄存器ADC_CR2,该寄存器的各位描述如下:
ADCON位用于开关AD转换器。
而CONT位用于设置是否进行连续转换,我们使用单次转换,所以CONT位必须为0。
CAL和RSTCAL用于AD校准。
ALIGN用于设置数据对齐,我们使用右对齐,该位设置为0。
EXTSEL[2:0]用于选择启动规则转换组转换的外部事件,我们这里使用的是软件触发(SWSTART),所以设置这3个位为111。
第三个要介绍的是ADC采样事件寄存器(ADC_SMPR1和ADC_SMPR2),这两个寄存器用于设置通道0~17的采样时间,每个通道占用3个位
对于每个要转换的通道,采样时间建议尽量长一点,以获得较高的准确度,但是这样会降低ADC的转换速率。
ADC的转换时间可以由下式计算:
Tcovn=采样时间+12.5个周期
第四个要介绍的是ADC规则序列寄存器(ADC_SQR1~3),
第五个要介绍的是ADC规则数据寄存器(ADC_DR)。
换时的各种状态。
三.实验内容
一.实验步骤
1)开启PA口时钟,设置PA0为模拟输入。
STM32F103RBT6的ADC通道0在PA0上,所以,我们先要使能PORTA的时钟,然后设置PA0为模拟输入。
2)使能ADC1时钟,并设置分频因子。
要使用ADC1,第一步就是要使能ADC1的时钟,在使能完时钟之后,进行一次ADC1的复位。
接着我们就可以通过RCC_CFGR设置ADC1的分频因子。
分频因子要确保ADC1的时钟(ADCCLK)不要超过14Mhz。
3)设置ADC1的工作模式。
在设置完分频因子之后,我们就可以开始ADC1的模式配置了,设置单次转换模式、触发方式选择、数据对齐方式等都在这一步实现。
4)设置ADC1规则序列的相关信息。
接下来我们要设置规则序列的相关信息,我们这里只有一个通道,并且是单次转换的,所以设置规则序列中通道数为1,然后设置通道0的采样周期。
5)开启AD转换器,并校准。
在设置完了以上信息后,我们就开启AD转换器,执行复位校准和AD校准,注意这两步是必须的!不校准将导致结果很不准确。
6)读取ADC值。
在上面的校准完成之后,ADC就算准备好了。
接下来我们要做的就是设置规则序列0里
面的通道,然后启动ADC转换。
在转换结束后,读取ADC1_DR里面的值就是了。
通过以上几个步骤的设置,我们就可以正常的使用STM32的ADC1来执行AD转换操作了。
二,程序代码
void Adc_Init(void)
{
//先初始化IO口
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
GPIOA->CRL&=0XFFFF0000;//PA0 1 2 3 anolog输入
//通道10/11设置
RCC->APB2ENR|=1<<9; //ADC1时钟使能
RCC->APB2RSTR|=1<<9; //ADC1复位
RCC->APB2RSTR&=~(1<<9);//复位结束
RCC->CFGR&=~(3<<14); //分频因子清零
//SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M!
//否则将导致ADC准确度下降!
RCC->CFGR|=2<<14;
ADC1->CR1&=0XF0FFFF; //工作模式清零
ADC1->CR1|=0<<16; //独立工作模式
ADC1->CR1&=~(1<<8); //非扫描模式
ADC1->CR2&=~(1<<1); //单次转换模式
ADC1->CR2&=~(7<<17);
ADC1->CR2|=7<<17; //软件控制转换
ADC1->CR2|=1<<20; //使用用外部触发(SWSTART) 必须使用一个事件来触发
ADC1->CR2&=~(1<<11); //右对齐
ADC1->SQR1&=~(0XF<<20);
ADC1->SQR1&=0<<20; //1个转换在规则序列中也就是只转换规则序列1
//设置通道0~3的采样时间
ADC1->SMPR2&=0XFFFFF000;//通道0,1,2,3采样时间清空
ADC1->SMPR2|=7<<9; //通道3 239.5周期,提高采样时间可以提高精确度
ADC1->SMPR2|=7<<6; //通道2 239.5周期,提高采样时间可以提高精确度
ADC1->SMPR2|=7<<3; //通道1 239.5周期,提高采样时间可以提高精确度
ADC1->SMPR2|=7<<0; //通道0 239.5周期,提高采样时间可以提高精确度
ADC1->CR2|=1<<0; //开启AD转换器
ADC1->CR2|=1<<3; //使能复位校准
while(ADC1->CR2&1<<3); //等待校准结束
//该位由软件设置并由硬件清除。
在校准寄存器被初始化后该位将被清除。
ADC1->CR2|=1<<2; //开启AD校准
while(ADC1->CR2&1<<2); //等待校准结束
//该位由软件设置以开始校准,并在校准结束时由硬件清除
}
//获得ADC值
//ch:通道值0~3
u16 Get_Adc(u8 ch)
{
//设置转换序列
ADC1->SQR3&=0XFFFFF
ADC1->CR2|=1<<22; //启动规则转换通道
while(!(ADC1->SR&1<<1));//等待转换结束
return ADC1->DR; //返回adc值
}。
接下来在adc.h文件里面输入如下代码:
#ifndef __ADC_H
#define __ADC_H
//Mini STM32开发板
//ADC 驱动代码
//正点原子@ALIENTEK
#define ADC_CH0 0 //通道0
#define ADC_CH1 1 //通道1
#define ADC_CH2 2 //通道2
#define ADC_CH3 3 //通道3
void Adc_Init(void);
u16 Get_Adc(u8 ch);
#endif
该部分代码很简单,这里我们就不多说了,这里定义的4个通道的宏定义,我们在main 函数将会用到ADC_CH0。
接下来我们在test.c里面,修改main函数如下:
int main(void)
{
u16 adcx;
float temp;
Stm32_Clock_Init(9);//系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600); //串口1初始化
LED_Init();
LCD_Init();
Adc_Init();
POINT_COLOR=RED;//设置字体为红色
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(60,150,"ADC_CH0_VOL:0.000V");
while(1)
{
LCD_ShowNum(156,150,adcx,1,16);//显示电压值
temp-=adcx;
temp*=1000;
LCD_ShowNum(172,150,temp,3,16);
LED0=!LED0;
delay_ms(250);
}。