(一)CEU6的ADC

因为之前已经和F411CEU6先生打过招呼了,这次呢,我们就让F411CEU6先生帮助我们完成电压采集的工作,我们要用一下F411CEU6的ADC模块。

这是F411CEU6的寄存器界地址,上面这块是Cortex-M4部分,即内核部分。

查了一下,发现对于STM32F411xC/xE系列,只有一个ADC1外设

厂家在手册里面写得也很清楚,1 个ADC

在Datasheet Charpter 3 Functional Overview 中,也专门提到ADC

在芯片描述里面,提到所有的F411xE/xC芯片都有一个12-bit ADC

F411xC/xE内部总线、外设的联系

F411xC/xE有1个ADC,16个外部输入通道,有single-shot  mode和 scan mode两种采样模式。

厂家也交代了可以使用DMA, 并且在电压采样的时候会产生中断,厂家还提供了触发ADC的方法。

FunctionalState ADC_ScanConvMode;       /*!< Specifies whether the conversion is performed in Scan (multichannels) or Single (one channel) mode.This parameter can be set to ENABLE or DISABLE */ 

Scan Mode 就意味着我们在使用的时候,可以使用多个通道

作者特别指出, ADC1 的 ADC_IN18 input channel 和 芯片内部的温度传感器相连,不过也指出这个温度不能准确反映周围环境的温度,但可以侦察温度的变化。

(二)ADCCLK

ADC的时钟可以通过PCLK2通过分频得到,不过ADCCLK存在一个最大值。 参考手册说这个ADCCLK最大值在Datasheet 里面,但在第三章Functional Overview中,一直没有找到,一度怀疑参考手册会不会搞错了。

后来利用CTRL+F 搭配ADC关键字遍历,无意中发现第六章有所介绍。

这里厂家介绍了CEU6的ADC特性,发现在供电电压在2.4V~3.6V时,ADCCLK最大可以是36MHz,典型值是30MHz,和F407是一样的。事实证明,参考手册还是很靠谱的,不要轻易否定。

ADC1的通道

从图中可以看到,ADC1有16个外部通道,不过CEU6只有10个通道

(三)编写代码

实验采用中断的方式读取电压采集值

1、bsp_adc.h

#ifndef __BSP_ADC_H
#define __BSP_ADC_H#include "stm32f4xx.h"//ADC GPIO 宏定义
#define DEBUG_ADC_GPIO_PORT                 GPIOB
#define DEBUG_ADC_GPIO_PIN                  GPIO_Pin_1
#define DEBUG_ADC_GPIO_CLK                  RCC_AHB1Periph_GPIOB// ADC 序号宏定义
#define DEBUG_ADC                           ADC1
#define DEBUG_ADC_CLK                       RCC_APB2Periph_ADC1
#define DEBUG_ADC_CHANNEL                   ADC_Channel_9// ADC 中断宏定义
#define DEBUG_ADC_IRQ                       ADC_IRQn
#define DEBUG_ADC_INT_FUNCTION              ADC_IRQHandlervoid ADC_GPIO_Config(void);
void DEBUG_ADC_Mode_Config(void);
void ADC_NVIC_Config(void);#endif /* __BSP_ADC_H */

使用的是ADC1的通道9,注意ADC1挂载在APB2上。很多时候,代码烧录后没有现象,极有可能是时钟没有打开。

2、bsp_adc.c

#include "./adc/bsp_adc.h"void ADC_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(DEBUG_ADC_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = DEBUG_ADC_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(DEBUG_ADC_GPIO_PORT, &GPIO_InitStructure);
}void DEBUG_ADC_Mode_Config(void)
{ADC_InitTypeDef ADC_InitStructure;ADC_CommonInitTypeDef ADC_CommonInitStructure;RCC_APB2PeriphClockCmd(DEBUG_ADC_CLK , ENABLE);// -------------------ADC Common 结构体 参数 初始化------------------------// 独立ADC模式ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;// 时钟为fpclk x分频    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;// 禁止DMA直接访问模式   ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;// 采样时间间隔    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;  ADC_CommonInit(&ADC_CommonInitStructure);// -------------------ADC Init 结构体 参数 初始化--------------------------ADC_StructInit(&ADC_InitStructure);// ADC 分辨率ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;// 禁止扫描模式,多通道采集才需要 ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 连续转换   ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //禁止外部边沿触发ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//外部触发通道ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;//数据右对齐    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//转换通道 1个ADC_InitStructure.ADC_NbrOfConversion = 1;                                    ADC_Init(DEBUG_ADC, &ADC_InitStructure);//---------------------------------------------------------------------------// 配置 ADC 通道转换顺序为1,第一个转换,采样时间为3个时钟周期ADC_RegularChannelConfig(DEBUG_ADC, DEBUG_ADC_CHANNEL, 1, ADC_SampleTime_3Cycles);// ADC 转换结束产生中断,在中断服务程序中读取转换值// ADC interupt at the end of convert(EOC)ADC_ITConfig(DEBUG_ADC, ADC_IT_EOC, ENABLE);// 使能ADCADC_Cmd(DEBUG_ADC, ENABLE);
}// 配置中断优先级
void ADC_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);NVIC_InitStructure.NVIC_IRQChannel = DEBUG_ADC_IRQ;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}

3、中断

extern __IO uint16_t ADC_ConvertedValue;// ADC 转换完成中断服务程序
void ADC_IRQHandler(void)
{if(ADC_GetITStatus(ADC1,ADC_IT_EOC)==SET){// 读取ADC的转换值ADC_ConvertedValue = ADC_GetConversionValue(ADC1);}ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);}      

ADC_ConvertedValue 是在主函数内定义的一个变量,用来提取转换的VALUE值,因为是12-bit的ADC, 所以选用uint16_t是足够大的。

4、主函数

#include "stm32f4xx.h"
#include "./usart/bsp_debug_usart.h"
#include "./adc/bsp_adc.h"/*** @brief  main function* @param  none* @retval none*/void delay(uint32_t count)
{for(; count != 0; count-- );
}__IO uint16_t ADC_ConvertedValue;float ADC_Voltage;int main(void)
{Debug_USART_Config();ADC_GPIO_Config();DEBUG_ADC_Mode_Config();ADC_NVIC_Config();//开始adc转换,软件触发ADC_SoftwareStartConv(ADC1);while(1){printf("\r\n Sir, the converted value is 0x%03x. \r\n", ADC_ConvertedValue);ADC_Voltage = (float)((float) 3.3/4096)*ADC_ConvertedValue;printf("\r\n Sir, the voltage value is %0.2f V. \r\n", ADC_Voltage);delay(0xfffff);}}

调用USART6来查看ADC1的电压采集情况

(四)实验现象

ADC1已经可以正常读取采集到的电压值

F411CEU6_ADC1中断读取

(五)总结

至此,关于CEU6核心板的小实验就告结束了。简单进行一个小结;

  1. F411CEU6和F4其他系列芯片类似,完全可以使用固件库编程。网上有人说,这个F411只能通过HAL库进行烧写,这就很离谱了。从原理上看,只要能配置寄存器就能使用微控制器;从ST官方提供的固件库看,里面有关于F411CE芯片的相关宏定义,既然都有宏定义了,就肯定可以使用固件库开发呀;
  2. 当ST32芯片处于奇怪状态的时候,BOOT引脚可能会帮上大忙;
  3. 对于芯片的了解,必须要根据公司提供的参考手册和数据手册,以公司官方出厂的为准;
  4. 复位时尽量多按一会儿按键,确保实现程序复位,有时候可能是没有实现复位或程序没有真正烧写成功带来的问题;
  5. 确保正确开启各个外设的时钟,因为不同外设挂载在不同的总线上,如果外设时钟没有开,那么肯定是没有实验现象的。我在第一次对F411进行程序烧写的时候,当时程序烧录完之后,明明设置的是关闭板载的LED,但下载代码之后,进行复位,LED总是会亮。后来,我去下载厂家提供的代码,下载后LED闪烁了,说明程序成功烧录了。然后,我再次重新下载自己的程序,发现又可以了。我自己认为有三种可能性:第一种,时钟开启不正常;第二种,程序还是没有烧录成功;第三种,没有真正复位,复位按键应该多按一会儿。

STM32F411核心板固件库开发(四) ADC配置相关推荐

  1. STM32F411核心板固件库开发(二) USART配置

    (一)芯片USART信息 我自己手上的F411CEU6只有48个引脚,属于UFQFPN48封装.对于同一系列型号的芯片,封装不一样,引脚的个数也会不一样,芯片上的外设资源自然也会不一样.UFQFPN4 ...

  2. STM32F411核心板固件库开发(一) GPIO基本配置

    暑假这几天天气比较炎热,在宿舍和室友偶然谈起STM32芯片,他说他有块F411的核心板.鉴于我之前用的几款芯片主要是F103系列和F407系列,对于F411系列的核心板倒没怎么用过.我一时心血来潮,就 ...

  3. STM32F411核心板固件库开发(三) 按键检测

    对于自己手上的这款核心板,考虑到还有一个外部外设没有使用,为了比较充分地用好板上的资源,在这里使用一个按键检测. (一)按键外设 1.核心板 2.核心板原理图 按键上端和PA0引脚相连,按键下端接地. ...

  4. 【致敬未来的攻城狮计划】— 连续打卡第十天:FSP固件库开发及FSP配置详解。

    系列文章目录 1.连续打卡第一天:提前对CPK_RA2E1是瑞萨RA系列开发板的初体验,了解一下 2.开发环境的选择和调试(从零开始,加油) 3.欲速则不达,今天是对RA2E1 基础知识的补充学习. ...

  5. GD32F303固件库开发(7)----printf打印配置

    GD32F303固件库开发.7----printf打印配置 概述 视频教学 csdn课程 样品申请 硬件准备 keil配置 串口初始化 最后 串口重定向 打印测试 测试结果 概述 本章主要配置prin ...

  6. GD32F303固件库开发(10)----双ADC轮询模式扫描多个通道

    GD32F303固件库开发.10----双ADC轮询模式扫描多个通道 概述 视频教学 csdn课程 样品申请 硬件准备 keil配置 使能串口 串口重定向 ADC通道设置 ADC0初始化 ADC0配置 ...

  7. GD32F303固件库开发(11)----ADC在DMA模式下扫描多个通道

    GD32F303固件库开发.11----双ADC轮询模式扫描多个通道 概述 视频教学 csdn课程 样品申请 硬件准备 keil配置 使能串口 串口重定向 ADC通道设置 DMA设置 ADC0初始化 ...

  8. GD32F303固件库开发(16)----移植兆易创新SPI Nor Flash之GD25Q64Flash

    spi概述 SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的 ...

  9. GD32F303固件库开发

    GD32F303固件库开发 芯片申请 GD32F303固件库开发(1)----前期准备与烧录 GD32F303固件库开发(2)----读保护与写保护 GD32F303固件库开发(3)----使用固件库 ...

最新文章

  1. atitit.php中的dwr 设计模式
  2. H5添加QQ好友的链接
  3. 电脑广告弹窗多?安利一下:程序员常用 7 款Chrome去广告插件
  4. 排序字段设计_内容搜索排序表达式的最佳实践
  5. Mysql学习总结(22)——Mysql数据库中制作千万级测试表
  6. SameMovie HBOMax Video Downloader for Mac如何在 Mac 上下载 HBO Max 视频?
  7. Android开发——通过扫描二维码,打开或者下载Android应用
  8. python控制台小游戏代码_python小游戏实现代码
  9. 用php远程获取MySQL到本地,mysql本地从远程数据库导数据_MySQL
  10. 机器人开发--OS系统介绍
  11. 数据迁移软件|如何将旧电脑的数据传输到新电脑?
  12. 计算机高手纯键盘操作,没有鼠标,高手是如何纯键盘操作电脑的?
  13. C# 写入CSV文件
  14. 【推荐】程序员必读的三十本经典巨作
  15. Java之旅-Day3
  16. Drupal7_2:安装drupal
  17. Kafka(9)副本(leader、flower、isr说明)
  18. Android 微信原生登录,支付,以及一些奇奇怪怪的问题。(wxApi.isWXAppInstalled 一直返回false)
  19. 使用每步FTP服务在魔百盒CM201-2上建立FTP服务器
  20. GitHub的使用-----转载自PHP中文网

热门文章

  1. alluxio java_学习 Alluxio(四):Java API
  2. 无人机开发系列 Ubuntu18.04安装 含虚拟机与双系统
  3. 【USACO 2.1.4】荷斯坦奶牛
  4. (最小生成树)Codeforces Educational Codeforces Round 9 Magic Matrix
  5. Haproxy基础知识
  6. rsync 同步本地文件到远端
  7. 分治、CDQ分治小结(need to be updated)
  8. Junit新语法assertThat
  9. java集合类深度解析
  10. 二阶系统表达式 稳态灵敏度