STM32C8T6有2个ADC,ADC1和ADC2
一:介绍
1:简历
ADC(Analog-Digital Converter)模拟-数字转换器
ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁
12位逐次逼近型ADC,1us转换时间
输入电压范围:0~3.3V,转换结果范围:0~4095
18个输入通道,可测量16个外部(GPIO)和2个内部信号源(内部温度传感器和内部参考电压)
规则组和注入组两个转换单元
模拟看门狗自动监测
输入电压范围 STM32F103C8T6 ADC资源:ADC1、ADC2,10个外部输入通道
12位逐次逼近型ADC,1us转换时间 :
分辨率 : 一般用多少位来表示,12位AD值,它的表示范围就是0~2^12-1,量化结果的范围是0~4095 , 位数越高,量化结果就越精细,对应分辨率就越高
转换时间: 就是转化频率AD转换是需要花一小段时间的,这里1us就表示从AD转换开始到产生结果,需要花1us的时间。对应AD转换的频率就是1MHZ , 这个就是STM32 ADC的最快转换频率
规则组和注入组两个转换单元:
普通的AD转换流程是,启动一次转换、读一次值 , 然后再启动、再读值,这样的流程 ;
STM32的ADC就比较高级: 可以列一个组,一次性启动一个组,连续转换多个值 , 并且有两个组,一个是用于常规使用的规则组 ,一个是用于突发事件的注入组
注入组:相当于中断,可以打断规则组,用于处理紧急的事件
2:逐次逼近型ADC
ADC0809 : 独立的8位逐次逼近型ADC芯片
EOC是End of Convert : 转换结束信号
START : 是开始转换,给一个输入脉冲,开始转换
CLOCK : 是ADC时钟,因为ADC内部是一步一步进行判断的
REF+和VREF- : DAC的参考电压
3:ADC基本结构
4:输入通道
5:规则组的4种转换模式
在初始化ADC时配置的参数
单次转化 : ADC 执行一次转换,然后,ADC 停止
连续转化: 与单次转换不同的是,它在一次转换结束后不会停止 , 而是立刻开始下一轮的转换,然后一直持续下去 , 这样就只需要最开始触发一次,之后就可以一直转换了
扫描模式 : 在组中填几个通道几个通道就有效 , 填入多个的时候应避免覆盖的问题, 使用使用DMA
非扫描模式 : 这个组就只有第一个序列1(Rank排名)的位置有效 , 这时选中一组的方式就退化为简单地选中一个的方式了。序列1(Rank排名)可以放任意的通道。
X.ADC_ContinuousConvMode=DISABLE;//选择是连续转换还是单次转换---单X.ADC_ScanConvMode=DISABLE;//可以选择是扫描模式还是非扫描模式---非扫描模式
1:单次转化,非扫描模式
在非扫描的模式下,这个组就只有第一个序列1的位置有效 , 这时选中一组的方式就退化为简单地选中一个的方式了
我们可以在序列1的位置指定我们想转换的通道 , 比如通道2 , 然后,我们就可以触发转换,ADC就会对这个通道2进行模数转换 , 过一段时间转化完成 , 转换结果放在数据寄存器里,同时给EOC标志位置1----转换过程就结束了 . 我们判断这个EOC标志位,如果转换完了 , 可以在数据寄存器里读取结果了 , 如果我们想再启动一次转换,那就需要再触发一次 , 转换结束,置EOC标志位,读结果
2:连续转化,非扫描模式
首先,它还是非扫描模式,所以组列表就只用第一个 , 与单次转换不同的是,它在一次转换结束后不会停止 , 而是立刻开始下一轮的转换,然后一直持续下去 , 这样就只需要最开始触发一次,之后就可以一直转换了
优点 : 开始转换之后不需要等待一段时间的 , 它一直都在转换,所以你就不需要手动开始转换了 , 也不用判断是否结束的 , 想要读AD值的时候,直接从数据寄存器取就是了
3:单次转化,扫描模式
这个模式也是单次转换,所以每触发一次 , 转换结束后,就会停下来 , 下次转换就得再触发能开始
扫描模式 : 会用到这个组了 , 在序列中填入通道 , 这里每个位置是通道几可以任意指定,并且也是可以重复的 , 初始化结构体里还会有个参数,就是通道数目 (x.ADC_NbrOfChannel=) 比如这里指定通道数目为7,那它就只看前7个位置,那么x.ADC_NbrOfChannel=7, 它就会只对前7个AD通道进行转化, 转换结果都放在数据寄存器里 , 这里为了防止数据被覆盖,就需要用DMA及时将数据挪走 , 那7个通道转换完成之后,产生EOC信号(EOC置1),转换结束 , 然后再触发下一次,就又开始新一轮的转换
使用DMA---避免通道数据覆盖
因为这里只有一个规则组的数据寄存器 , 如果使用了 扫描模式在一个组中开启了7个通道, 只会有最后一个通道被保留下来, 前面的6个通道会被覆盖掉. 最后只会得到一个通道.
使用这里使用MDA在下一个通道来之前, 把现在的数据放到了MDA中, 避免出现通道的覆盖问题
4:单次转化,扫描模式
次转换完成后,立刻开始下一次的转换 , 也开启组
6:触发控制
下面是规则组的触发源
注入组的触发源
7:数据对齐
ADC初始化中的配置---X.ADC_DataAlign
我们这个ADC是12位的,它的转换结果就是一个12位的数据 , 但是这个数据寄存器是16位的,所以就存在一个数据对齐的问题
右对齐 : 就是12位的数据向右靠 , 就是12位的数据向有靠 , 高位多出来的几位就补0 ,一般
使用右对齐, 这样读取这个16位寄存器,直接就是转换结果
左对齐 : 是12位的数据向左靠 , 低位多出来的几位补0 , 得到的数据会比实际的大 , 数据左对齐实际上就是把数据左移了4次 ,数据左移一次,就等效于把这个数据乘2 , 直接读取的话相当于把数据扩大了16倍 .
8:转化时间
9:校准
ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差
建议在每次上电后执行一次校准
启动校准前, ADC必须处于关电状态超过至少两个ADC时钟周期
10:间断模式
规则组:
扫描模式下的一个细分。
- 间断模式:区别于扫描模式连续扫描完整的一组通道,间断模式将一组通道分为多个短序列,每次外部触发事件执行一个短序列的扫描转换。
- 必须使能扫描模式,禁止使用连续模式(为了方便我们的观察,可以禁止,手册中没有强制的要求),必须避免同时为规则和注入为间断模式。
n:一个子组中几个成员。上面为3个
每次一个信号的到来,转化一个字组。
注入组:
注入组间断模式和规则组是一样。
唯一的不同是:注入组的n=1;不能为其他的数,规定。
注入组和规则组的中断触发时机不同。
规则组:
当完成一个子组(即n个通道)的转换后,会触发一个中断请求,进入中断回调函数。
HAL_ADC_ConvCpltCallback
注入组:
当所有的子组完成,进入中断回调函数中去。
HAL_ADCEx_InjectedConvCpltCallb()
11:ADC的硬件电路
12:温度传感器
STM32F103C8T6内部的ADC(模拟数字转换器)的温度传感器在微控制器中起着关键作用,主要用于测量和监控芯片内部的温度。
- 该温度传感器在-40℃至+125℃的范围内进行测量。
- 由于是内置的简化温度传感器,其精度相对较低,大约为±1.5℃。
- ADC的分辨率为12位,这意味着它能够提供相对较高的温度测量精度
ADC_in16和ADC_IN17是内部的通道,没有物理引脚。
接下 来我们介绍一下和温度传感器设置相关的2个地方。
第一个地方,我们要使用STM32的内部温度传感器,必须先激活ADC的内部通道,这里 通过ADC_CR2的AWDEN位(bit23)设置。设置该位为1则启用内部温度传感器。
第二个地方,STM32的内部温度传感器固定的连接在ADC的通道16上,所以,我们在设 置好ADC之后只要读取通道16的值,就是温度传感器返回来的电压值了。根据这个值,我们 就可以计算出当前温度。
公式
温度 = (V25-Vsense ) / Avg_Slope + 25°C
V25 是温度传感器在25°C时的输出电压。(典型值为:1.43)
Vsense 是当前温度下的温度传感器输出电压,可以通过ADC读数转换得到。
Avg_Slope 是温度传感器输出电压随温度变化的平均斜率(单位:mV/°C)。//4.3
25°C 是参考温度,即V25对应的温度。
如电压为3v时
温度=(3.0-1.43)/4.3+25
二:HAL配置
三:案例
规则组单管道
A:ADC时钟配置
ADC时钟的最大时钟源为:14MHZ,所以它的时钟源需要单独配置。
/*HSE外部高速时钟做为系统时钟*/
void sys_stm32_clock_init(uint32_t plln)
{
HAL_StatusTypeDef ret = HAL_ERROR;
RCC_OscInitTypeDef RCC_OscInit = {0};
RCC_ClkInitTypeDef RCC_ClkInit={0};
RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInit={0}; //ADC时钟需要单独配置
//HSE外部时钟做为PLL时钟源
RCC_OscInit.OscillatorType=RCC_OSCILLATORTYPE_HSE;/*选择振荡器类型*/
RCC_OscInit.HSEState=RCC_HSE_ON; /*选择HSL状态*/
RCC_OscInit.HSEPredivValue=RCC_HSE_PREDIV_DIV1; /*HSE的分频系数*/
RCC_OscInit.PLL.PLLState=RCC_PLL_ON;
RCC_OscInit.PLL.PLLSource=RCC_PLLSOURCE_HSE;
RCC_OscInit.PLL.PLLMUL=plln; //RCC_PLL_MUL9
ret=HAL_RCC_OscConfig(&RCC_OscInit);
if (ret !=HAL_OK)
{
while (1);
}
//PLL做为系统时钟
RCC_ClkInit.ClockType=RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInit.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInit.AHBCLKDivider=RCC_HCLK_DIV1;
RCC_ClkInit.APB1CLKDivider=RCC_HCLK_DIV2;
RCC_ClkInit.APB2CLKDivider=RCC_HCLK_DIV1;
ret=HAL_RCC_ClockConfig(&RCC_ClkInit,FLASH_LATENCY_2);
if (ret !=HAL_OK)
{
while (1);
}
//ADC的时钟源需要单独配置:72/6=12MHZ
RCC_PeriphCLKInit.PeriphClockSelection=RCC_PERIPHCLK_ADC;
RCC_PeriphCLKInit.AdcClockSelection=RCC_ADCPCLK2_DIV6;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInit);
}
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 函数在文件:stm32f1xx hal rcc_ex.c
重要函数:
// 定义一个结构体类型 RCC_PeriphCLKInitTypeDef
typedef struct
{
// 选择要配置的扩展时钟
// 此参数可以是 RCCEx_Periph_Clock_Selection 枚举中的一个值
uint32_t PeriphClockSelection;
// 指定RTC时钟源
// 此参数可以是 RCC_RTC_Clock_Source 枚举中的一个值
uint32_t RTCClockSelection;
// ADC时钟源
// 此参数可以是 RCCEx_ADC_Prescaler 枚举中的一个值
uint32_t AdcClockSelection;
// 特定于STM32F103xE、STM32F103xG、STM32F105xC 和 STM32F107xC 设备的字段
#if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC)\
|| defined(STM32F107xC)
// I2S2时钟源
// 此参数可以是 RCCEx_I2S2_Clock_Source 枚举中的一个值
uint32_t I2s2ClockSelection;
// I2S3时钟源
// 此参数可以是 RCCEx_I2S3_Clock_Source 枚举中的一个值
uint32_t I2s3ClockSelection;
// 特定于STM32F105xC 和 STM32F107xC 设备的字段
#if defined(STM32F105xC) || defined(STM32F107xC)
// 当PLLI2S被选为I2S2或I2S3的时钟源时,这个参数将用于配置PLL I2S的结构参数
RCC_PLLI2SInitTypeDef PLLI2S;
#endif /* STM32F105xC || STM32F107xC */
#endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
// 特定于STM32F102x6、STM32F102xB、STM32F103x6、STM32F103xB、STM32F103xE、STM32F103xG、STM32F105xC 和 STM32F107xC 设备的字段
#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
|| defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
|| defined(STM32F105xC) || defined(STM32F107xC)
// USB时钟源
// 此参数可以是 RCCEx_USB_Prescaler 枚举中的一个值
uint32_t UsbClockSelection;
#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
} RCC_PeriphCLKInitTypeDef;
B:规则组 单通道 单次转换 轮询方式
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init();
//HAL_ADC_GetValue读取常规组寄存器的数据
HAL_ADC_PollForConversion(&ADC1_Handle,1000); //轮询方式:等待ADC常规组转换完成
printf("ADC1_IN0:%d \r\n",HAL_ADC_GetValue(&ADC1_Handle)); //串口1输出数字量
while (1)
{
}
}
#include "stm32f1xx_hal.h"
ADC_HandleTypeDef ADC1_Handle;
void ADC1_Init(void)
{
ADC_ChannelConfTypeDef ADC_Channel;
ADC1_Handle.Instance=ADC1;
ADC1_Handle.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC1_Handle.Init.ScanConvMode=ADC_SCAN_DISABLE; //扫描模式:失能
ADC1_Handle.Init.ContinuousConvMode=DISABLE; //连续模式:DISABLE(单次模式)
ADC1_Handle.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC1_Handle.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC1_Handle);
ADC_Channel.Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel.Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC1_Handle,&ADC_Channel);
HAL_ADCEx_Calibration_Start(&ADC1_Handle); //自校准
HAL_ADC_Start(&ADC1_Handle);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
}
}
采样时间:
我们配置的ADC的时钟为12MHZ
自校准
HAL_ADCEx_Calibration_Start(&ADC1_Handle); 自校准
HAL_ADC_Start(&ADC1_Handle);
所以自校准要在ADC_Start之前完成。
在stm32f1xx hal adc_ex.c里。
重要参数:
C:规则组 单通道单次or连续转换 中断方式
探索 规则组 单通道,单次中断方式和连续转换 中断方式的区别。
中断连续模式
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
ADC_HandleTypeDef ADC1_Handle;
void ADC1_Init(void)
{
ADC_ChannelConfTypeDef ADC_Channel;
ADC1_Handle.Instance=ADC1;
ADC1_Handle.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC1_Handle.Init.ScanConvMode=ADC_SCAN_DISABLE; //扫描模式:失能
ADC1_Handle.Init.ContinuousConvMode=ENABLE; //连续模式:ENABLE连续模式
ADC1_Handle.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC1_Handle.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC1_Handle);
ADC_Channel.Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel.Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC1_Handle,&ADC_Channel);
HAL_ADCEx_Calibration_Start(&ADC1_Handle); //自校准
HAL_ADC_Start_IT(&ADC1_Handle);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_1;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
HAL_NVIC_SetPriority(ADC1_2_IRQn,1,0);
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
}
}
void ADC1_2_IRQHandler()
{
HAL_ADC_IRQHandler(&ADC1_Handle);
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("ADC1_IN0:%d \r\n",HAL_ADC_GetValue(&ADC1_Handle)); //串口1输出数字量
delay_ms(1000);
}
}
单次模式:
因为单次模式执行一次就会关闭,如果在单次模式下需要达到连续模式的效果:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("ADC1_IN0:%d \r\n",HAL_ADC_GetValue(&ADC1_Handle)); //串口1输出数字量
HAL_ADC_Start_IT(&ADC1_Handle);
delay_ms(1000);
}
}
D:规则组 单通道 DMA方式 均值滤波
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
uint16_t DMA_buff[10];
void ADC1_Init(void)
{
ADC_ChannelConfTypeDef ADC_Channel;
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE; //扫描模式:失能
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式:ENABLE连续模式
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel.Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel.Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10); //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_2;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,1,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
}
//void ADC1_2_IRQHandler()
//{
// HAL_ADC_IRQHandler(&ADC_HandleType);
//}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint32_t num;
uint8_t i;
if(hadc->Instance==ADC1)
{
num=0;
for(i=0;i<10;i++)
{
num+=DMA_buff[i];
}
printf("ADC1_IN0:%f V \r\n",(num/10.0)*(3.3/4096.0)); //串口1输出数字量
delay_ms(1000);
}
}
DMA传输方向的选取
DMA_PERIPH_TO_MEMORY (0x00000000U)
- 含义:此宏表示从外设(Peripheral)到内存(Memory)的数据传输方向。
- 选择:当您需要将数据从某个外设(如UART、SPI、GPIO等)读取到系统内存(如SRAM、SDRAM等)时,您应该选择此宏。
- 应用:在配置DMA传输时,将此宏的值设置为DMA控制器的相关寄存器字段,以指示数据流动的方向。
DMA_MEMORY_TO_PERIPH ((uint32_t)DMA_CCR_DIR)
- 含义:此宏表示从内存(Memory)到外设(Peripheral)的数据传输方向。
- 选择:当您需要将数据从系统内存写入某个外设时,您应该选择此宏。
- 应用:与DMA_PERIPH_TO_MEMORY类似,将此宏的值设置为DMA控制器的相关寄存器字段。
- 注意:这里的
DMA_CCR_DIR
可能是一个预定义的位掩码,用于设置DMA通道配置寄存器(CCR)中的DIR位,该位控制DMA传输的方向。DMA_MEMORY_TO_MEMORY ((uint32_t)DMA_CCR_MEM2MEM)
- 含义:此宏表示内存到内存(Memory-to-Memory)的数据传输方向。
- 选择:当您需要在系统内的两个内存位置之间传输数据时,您应该选择此宏。
- 应用:将此宏的值设置为DMA控制器的相关寄存器字段。
- 注意:这里的
DMA_CCR_MEM2MEM
可能是一个预定义的位掩码,用于设置DMA通道配置寄存器(CCR)中的MEM2MEM位(或其他相关位),该位(或位组合)控制DMA传输的模式为内存到内存。
E:规则组 外部触发定时器的CC事件
当外部触发信号被选为ADC规则或注入转换时,只有它的上升沿可以启动转换。
定时器1的cc事件
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init(); //0.2s=200ms 0.2*10=2S==DMA的时间
IC_TIMX_CHX_init(2000-1,7200-1); //T=((ARR+1)*(PSC+1)) / 72 000 000;
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
uint16_t DMA_buff[10];
void ADC1_Init(void)
{
ADC_ChannelConfTypeDef ADC_Channel;
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE; //扫描模式:失能
ADC_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式:DISABLE(单次模式)
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T1_CC1;//触发方式:TIM1的cc事件
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel.Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel.Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10); //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_2;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,1,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
}
//void ADC1_2_IRQHandler()
//{
// HAL_ADC_IRQHandler(&ADC_HandleType);
//}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint32_t num;
uint8_t i;
if(hadc->Instance==ADC1)
{
num=0;
for(i=0;i<10;i++)
{
num+=DMA_buff[i];
}
printf("ADC1_IN0:%f V \r\n",(num/10.0)*(3.3/4096.0)); //串口1输出数字量
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_OC_InitTypeDef TIM_OC_Init={0};
HandleTIMXCHX.Instance=TIM1; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.RepetitionCounter =0; //设置重复次数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_OC_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;
TIM_OC_Init.Pulse=100; //比较值
TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值 :PWM1:CNT<CCR输出有效电平
TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE; //关闭快速模式
HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX, &TIM_OC_Init,TIM_CHANNEL_1);
HAL_TIM_OC_Start_IT(&HandleTIMXCHX,TIM_CHANNEL_1);
}
void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM1)
{
__HAL_RCC_GPIOA_CLK_ENABLE() ;
__HAL_RCC_TIM1_CLK_ENABLE();
//来自片上的内部信号,PA8引脚输出化,随便可以开,可以不开。
//PA8---TIM_CH1
// GPIO_InitTypeDef GPIO_InitType;
// GPIO_InitType.Mode=GPIO_MODE_AF_PP; /*复用推完输出*/
// GPIO_InitType.Pin=GPIO_PIN_8;
// GPIO_InitType.Speed=GPIO_SPEED_FREQ_LOW;
// HAL_GPIO_Init(GPIOA,&GPIO_InitType);
HAL_NVIC_SetPriority(TIM1_CC_IRQn, 1, 3); /* 抢占1,子优先级3 */
HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); /* 开启ITMx中断 */
}
}
/* 定时器1中断服务函数 */
void TIM1_CC_IRQHandler(void)
{
HAL_TIM_IRQHandler(&HandleTIMXCHX); /* 定时器HAL库共用处理函数 */
}
//定时器的CC通道的输出比较
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM1)
{
if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1)
{
printf("定时器1通道1匹配成功\r\n");
}
}
}
配置时候注意通道:
TIM通道的配置。我们的CC事件是通过片上定时器的内部信号触发的(所以,在定时器1中PA8为定时器1_CH1,PA8开不开都可以。)
F:规则组 外部触发 定时器3的TRGO 更新事件
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init(); //0.2s=200ms 0.2*10=2S==DMA的时间
IC_TIMX_CHX_init(2000-1,7200-1); //T=((ARR+1)*(PSC+1)) / 72 000 000;
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
uint16_t DMA_buff[10];
void ADC1_Init(void)
{
ADC_ChannelConfTypeDef ADC_Channel;
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE; //扫描模式:失能
ADC_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式:DISABLE(单次模式)
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_TRGO;//触发方式:TIM3的TRGO事件
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel.Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel.Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10); //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_2;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,1,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
}
//void ADC1_2_IRQHandler()
//{
// HAL_ADC_IRQHandler(&ADC_HandleType);
//}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint32_t num;
uint8_t i;
if(hadc->Instance==ADC1)
{
num=0;
for(i=0;i<10;i++)
{
num+=DMA_buff[i];
}
printf("ADC1_IN0:%f V \r\n",(num/10.0)*(3.3/4096.0)); //串口1输出数字量
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_MasterConfigTypeDef TIM_MasterConfig={0};
HandleTIMXCHX.Instance=TIM3; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_Base_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_UPDATE;
TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE; //主从模式:关闭
HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);
HAL_TIM_Base_Start_IT(&HandleTIMXCHX);
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
__HAL_RCC_TIM3_CLK_ENABLE();
HAL_NVIC_SetPriority(TIM3_IRQn, 1, 3);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
}
}
/* 定时器1中断服务函数 */
void TIM3_IRQHandler(void)
{
HAL_TIM_IRQHandler(&HandleTIMXCHX); /* 定时器HAL库共用处理函数 */
}
//定时器的CC通道的输出比较
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
printf("定时器3TRGO事件\r\n");
}
}
定时器配置TRGO事件需要使用到
HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim,
TIM_MasterConfigTypeDef *sMasterConfig)
在stm32f1xx hal tim ex.c文件里面。
G:规则组 外部触发 定时器3的TRGO 捕获事件
这个捕获只能发生在通道1上。
关于复用:
ADC1_IN6引脚在PA6上面,我们的定时器的通道6也在PA6上面,(PA6是在通道6),为了防止我们在做扫描模式的时候引脚冲突,我们在这里直接把他引脚重新定义为PB4上面;--这个实验做不做复用都一样,后面的扫描模式的使用。
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init();
IC_TIMX_CHX_init(0XFFFF-1,36000-1); //T=((ARR+1)*(PSC+1)) / 72 000 000;
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
uint16_t DMA_buff[10];
void ADC1_Init(void)
{
ADC_ChannelConfTypeDef ADC_Channel;
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE; //扫描模式:失能
ADC_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式:DISABLE(单次模式)
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_TRGO;//触发方式:TIM3的TRGO事件
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel.Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel.Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10); //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_2;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
}
//void ADC1_2_IRQHandler()
//{
// HAL_ADC_IRQHandler(&ADC_HandleType);
//}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint32_t num;
uint8_t i;
if(hadc->Instance==ADC1)
{
num=0;
for(i=0;i<10;i++)
{
num+=DMA_buff[i];
}
printf("ADC1_IN0:%f V \r\n",(num/10.0)*(3.3/4096.0)); //串口1输出数字量
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_MasterConfigTypeDef TIM_MasterConfig={0};
TIM_IC_InitTypeDef TIM_IC_Init={0};
HandleTIMXCHX.Instance=TIM3; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_IC_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_OC1; //主定时器通道1捕获时发送信号
TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE; //主从模式:关闭
HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);
TIM_IC_Init.ICFilter=0x8;
TIM_IC_Init.ICPolarity=TIM_ICPOLARITY_RISING; //极性:上升沿
TIM_IC_Init.ICSelection=TIM_ICSELECTION_DIRECTTI; //直连
TIM_IC_Init.ICPrescaler=TIM_ICPSC_DIV1;
HAL_TIM_IC_ConfigChannel(&HandleTIMXCHX,&TIM_IC_Init,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&HandleTIMXCHX,TIM_CHANNEL_1);
}
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
__HAL_RCC_GPIOB_CLK_ENABLE(); //打开B口时钟
__HAL_RCC_TIM3_CLK_ENABLE(); //打开定时器3的时钟
__HAL_RCC_AFIO_CLK_ENABLE(); //应为要重映射,所以打开AFIO时钟
__HAL_AFIO_REMAP_TIM3_PARTIAL(); //定时器3重映射
__HAL_AFIO_REMAP_SWJ_NOJTAG(); //关闭JTAG,保留SW,释放PB4
//重映射CH1为PB4
GPIO_InitTypeDef GPIO_InitType;
GPIO_InitType.Pin = GPIO_PIN_4; //配置PIN4
GPIO_InitType.Mode = GPIO_MODE_AF_INPUT; //复用功能 输入方向
GPIO_InitType.Pull = GPIO_PULLDOWN; //开启IO口内部的下拉电阻
HAL_GPIO_Init(GPIOB,&GPIO_InitType); //配置PB4
HAL_NVIC_SetPriority(TIM3_IRQn,3,0); //定时器3的中断优先级
HAL_NVIC_EnableIRQ(TIM3_IRQn); //开定时器3的中断
}
}
/* 定时器1中断服务函数 */
void TIM3_IRQHandler(void)
{
HAL_TIM_IRQHandler(&HandleTIMXCHX); /* 定时器HAL库共用处理函数 */
}
//定时器的CC通道的输出比较
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1)
{
printf("定时器3通道1上升沿捕获成功\r\n");
}
}
}
H:如何一次触发信号使得DMA完成转换
上面的都为每发生一次事件(更新事件或者为捕获事件)都会触发一次AD的转化,不过我们开启了DMA的转运,每次ADC的转化DMA会把数据拿到我们指定的内存(数组中),一共转化10次ADC,才会触发一次DMA中断。所以我们需要按下10次按键才会触发一次数据的打印。
这个代码解决这个问题,按一次,打印一次。不过需要开启连续转化模式。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10);
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
IC_TIMX_CHX_init(0XFFFF-1,36000-1); //T=((ARR+1)*(PSC+1)) / 72 000 000;
ADC1_Init();
while (1)
{
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
uint16_t DMA_buff[10];
void ADC1_Init(void)
{
ADC_ChannelConfTypeDef ADC_Channel;
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE; //扫描模式:失能
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式:DISABLE(单次模式) ENABLE
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_TRGO;//触发方式:TIM3的TRGO事件
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel.Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel.Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10); //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_2;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
}
//void ADC1_2_IRQHandler()
//{
// HAL_ADC_IRQHandler(&ADC_HandleType);
//}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint32_t num;
uint8_t i;
if(hadc->Instance==ADC1)
{
//ADC_HandleType.Instance->CR2 &=~ ADC_CR2_CONT;
num=0;
for(i=0;i<10;i++)
{
num+=DMA_buff[i];
}
printf("ADC1_IN0:%f V \r\n",(num/10.0)*(3.3/4096.0)); //串口1输出数字量
hadc->Instance->CR2 |= ADC_CR2_CONT;
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_MasterConfigTypeDef TIM_MasterConfig={0};
TIM_IC_InitTypeDef TIM_IC_Init={0};
HandleTIMXCHX.Instance=TIM3; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_IC_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_OC1; //主定时器通道1捕获时发送信号
TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE; //主从模式:关闭
HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);
TIM_IC_Init.ICFilter=0x8;
TIM_IC_Init.ICPolarity=TIM_ICPOLARITY_RISING; //极性:上升沿
TIM_IC_Init.ICSelection=TIM_ICSELECTION_DIRECTTI; //直连
TIM_IC_Init.ICPrescaler=TIM_ICPSC_DIV1;
HAL_TIM_IC_ConfigChannel(&HandleTIMXCHX,&TIM_IC_Init,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&HandleTIMXCHX,TIM_CHANNEL_1);
}
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
__HAL_RCC_GPIOB_CLK_ENABLE(); //打开B口时钟
__HAL_RCC_TIM3_CLK_ENABLE(); //打开定时器3的时钟
__HAL_RCC_AFIO_CLK_ENABLE(); //应为要重映射,所以打开AFIO时钟
__HAL_AFIO_REMAP_TIM3_PARTIAL(); //定时器3重映射
__HAL_AFIO_REMAP_SWJ_NOJTAG(); //关闭JTAG,保留SW,释放PB4
//重映射CH1为PB4
GPIO_InitTypeDef GPIO_InitType;
GPIO_InitType.Pin = GPIO_PIN_4; //配置PIN4
GPIO_InitType.Mode = GPIO_MODE_AF_INPUT; //复用功能 输入方向
GPIO_InitType.Pull = GPIO_PULLDOWN; //开启IO口内部的下拉电阻
HAL_GPIO_Init(GPIOB,&GPIO_InitType); //配置PB4
HAL_NVIC_SetPriority(TIM3_IRQn,3,0); //定时器3的中断优先级
HAL_NVIC_EnableIRQ(TIM3_IRQn); //开定时器3的中断
}
}
/* 定时器1中断服务函数 */
void TIM3_IRQHandler(void)
{
HAL_TIM_IRQHandler(&HandleTIMXCHX); /* 定时器HAL库共用处理函数 */
}
//定时器的CC通道的输出比较
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1)
{
printf("定时器3通道1上升沿捕获成功\r\n");
ADC_HandleType.Instance->CR2 &=~ ADC_CR2_CONT;
}
}
}
在主函数中他TIM定时器的初始化需要在ADC初始化前面。否则会发送未知的错误。
I:规则组 外部触发 EXTI11 启动转化
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
uint16_t DMA_buff[10];
void ADC1_Init(void)
{
ADC_ChannelConfTypeDef ADC_Channel;
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE; //扫描模式:失能
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式:DISABLE(单次模式) ENABLE
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel.Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel.Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel.SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10); //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_2;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_IT_RISING; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_11;
GPIO_InitType.Pull=GPIO_PULLUP;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
HAL_NVIC_SetPriority(EXTI15_10_IRQn,4,0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
void EXTI15_10_IRQHandler()
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint32_t num;
uint8_t i;
if(hadc->Instance==ADC1)
{
num=0;
for(i=0;i<10;i++)
{
num+=DMA_buff[i];
}
printf("ADC1_IN0:%f V \r\n",(num/10.0)*(3.3/4096.0)); //串口1输出数字量
hadc->Instance->CR2 |= ADC_CR2_CONT;
}
}
//EXT_IT11的中断回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin==GPIO_PIN_11)
{
printf("PB11产生中断\r\n");
ADC_HandleType.Instance->CR2 &=~ ADC_CR2_CONT;
}
}
因为ADC的触发方式配置为:
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11中断
所以在配置PB11引脚的时候,需要注意(只能在下面选):
PB11不能使用:
GPIO_MODE_INPUT
GPIO_MODE_AF_INPUT
GPIO_MODE_ANALOG
规则组 扫描模式
A:规则组10通道扫描 单次转换DMA方式
因为开启了扫描模式,在扫描模式中开启的10个通道,一个组中的10个通道全部转化完毕,中断标志位才会置位。然而我们只有一个数据寄存器(DR),会导致我们的数据出现覆盖。所以不能使用中断或者轮询
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];
uint16_t DMA_buff[10];
void ADC1_Init(void)
{
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=15; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式:DISABLE(单次模式)
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:EXT_IT11
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
ADC_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC_Channel[6].Rank=ADC_REGULAR_RANK_7; //排名
ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);
ADC_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC_Channel[7].Rank=ADC_REGULAR_RANK_8; //排名
ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);
ADC_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC_Channel[8].Rank=ADC_REGULAR_RANK_9; //排名
ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);
ADC_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC_Channel[9].Rank=ADC_REGULAR_RANK_10; //排名
ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10); //DMA将连续读取10个ADC转换结果并存储到DMA_buff中。
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_NORMAL; //模式:普通(单次)
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint8_t i;
if(hadc->Instance==ADC1)
{
for(i=0;i<10;i++)
{
printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0)); //串口1输出数字量
}
}
}
B:规则组10通道扫描 连续转换 DMA均值滤波
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];
uint16_t DMA_buff[100];
void ADC1_Init(void)
{
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
ADC_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC_Channel[6].Rank=ADC_REGULAR_RANK_7; //排名
ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);
ADC_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC_Channel[7].Rank=ADC_REGULAR_RANK_8; //排名
ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);
ADC_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC_Channel[8].Rank=ADC_REGULAR_RANK_9; //排名
ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);
ADC_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC_Channel[9].Rank=ADC_REGULAR_RANK_10; //排名
ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,100);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint8_t i,j;
uint32_t num;
if(hadc->Instance==ADC1)
{
for(i=0;i<10;i++)
{
num=0;
for(j=0;j<10;j++)
{
num+=DMA_buff[j*10+i];
}
printf("ADC1_IN[%d]:%f V \r\n",i,(num/10.0)*(3.3/4096.0)); //串口1输出数字量
}
}
}
C:规则组10通道扫描定时器CC事件 触发转换
一次上升沿可以触发一次扫描(组),一个组中开启的10个通道。所以10次上升沿可以触发AD转化100次。------次DMA完成中断,需要10次的周期时间
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
IC_TIMX_CHX_init(3600-1,7200-1); //T=((ARR+1)*(PSC+1)) / 72 000 000; t=0.36s 10t=3.6s
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];
uint16_t DMA_buff[100];
void ADC1_Init(void)
{
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 失能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T2_CC2;//触发方式:TIM2的CC2(通道2)
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
ADC_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC_Channel[6].Rank=ADC_REGULAR_RANK_7; //排名
ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);
ADC_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC_Channel[7].Rank=ADC_REGULAR_RANK_8; //排名
ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);
ADC_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC_Channel[8].Rank=ADC_REGULAR_RANK_9; //排名
ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);
ADC_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC_Channel[9].Rank=ADC_REGULAR_RANK_10; //排名
ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,100);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint8_t i,j;
uint32_t num;
if(hadc->Instance==ADC1)
{
for(i=0;i<10;i++)
{
num=0;
for(j=0;j<10;j++)
{
num+=DMA_buff[j*10+i];
}
printf("ADC1_IN[%d]:%f V \r\n",i,(num/10.0)*(3.3/4096.0)); //串口1输出数字量
}
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_OC_InitTypeDef TIM_OC_Init={0};
HandleTIMXCHX.Instance=TIM2; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_OC_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;
TIM_OC_Init.Pulse=100; //比较值(CCR)
TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值 :PWM1:CNT<CCR输出有效电平
TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX, &TIM_OC_Init,TIM_CHANNEL_2);
HAL_TIM_OC_Start_IT(&HandleTIMXCHX,TIM_CHANNEL_2);
}
void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM2)
{
__HAL_RCC_TIM2_CLK_ENABLE(); //打开定时器3的时钟
//信号为内部触发所以,定时器2_CH2引脚可以使用初始化
HAL_NVIC_SetPriority(TIM2_IRQn,3,0); //定时器3的中断优先级
HAL_NVIC_EnableIRQ(TIM2_IRQn); //开定时器3的中断
}
}
/* 定时器1中断服务函数 */
void TIM2_IRQHandler(void)
{
HAL_TIM_IRQHandler(&HandleTIMXCHX); /* 定时器HAL库共用处理函数 */
}
//定时器的CC通道的输出比较
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM2)
{
if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2)
{
printf("定时器2通道2更新\r\n");
}
}
}
D:规则组 10通道扫描 定时器3 TRGO更新事件 触发转换
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
IC_TIMX_CHX_init(3600-1,7200-1); //T=((ARR+1)*(PSC+1)) / 72 000 000; t=0.36s 10t=3.6s
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];
uint16_t DMA_buff[100];
void ADC1_Init(void)
{
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 失能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_TRGO;//触发方式:TIM3的TRGO事件
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
ADC_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC_Channel[6].Rank=ADC_REGULAR_RANK_7; //排名
ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);
ADC_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC_Channel[7].Rank=ADC_REGULAR_RANK_8; //排名
ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);
ADC_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC_Channel[8].Rank=ADC_REGULAR_RANK_9; //排名
ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);
ADC_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC_Channel[9].Rank=ADC_REGULAR_RANK_10; //排名
ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,100);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint8_t i,j;
uint32_t num;
if(hadc->Instance==ADC1)
{
for(i=0;i<10;i++)
{
num=0;
for(j=0;j<10;j++)
{
num+=DMA_buff[j*10+i];
}
printf("ADC1_IN[%d]:%f V \r\n",i,(num/10.0)*(3.3/4096.0)); //串口1输出数字量
}
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_MasterConfigTypeDef TIM_MasterConfig={0};
TIM_OC_InitTypeDef TIM_OC_Init={0};
HandleTIMXCHX.Instance=TIM3; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_Base_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_UPDATE; //主定时器通道1捕获时发送信号
TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE; //主从模式:关闭
HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);
HAL_TIM_Base_Start_IT(&HandleTIMXCHX);
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
__HAL_RCC_TIM3_CLK_ENABLE(); //打开定时器3的时钟
//信号为内部触发所以,定时器2_CH2引脚可以使用初始化
HAL_NVIC_SetPriority(TIM3_IRQn,3,0); //定时器3的中断优先级
HAL_NVIC_EnableIRQ(TIM3_IRQn); //开定时器3的中断
}
}
/* 定时器1中断服务函数 */
void TIM3_IRQHandler(void)
{
HAL_TIM_IRQHandler(&HandleTIMXCHX); /* 定时器HAL库共用处理函数 */
}
//定时器的CC通道的输出比较
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
printf("定时器3更新事件\r\n");
}
}
E:规则组 10通道扫描 定时器3 TRGO捕获事件 触发转换
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
IC_TIMX_CHX_init(3600-1,7200-1); //T=((ARR+1)*(PSC+1)) / 72 000 000; t=0.36s 10t=3.6s
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];
uint16_t DMA_buff[100];
void ADC1_Init(void)
{
//DISABLE ENABLE
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_TRGO;//触发方式:TIM3的TRGO事件
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
ADC_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC_Channel[6].Rank=ADC_REGULAR_RANK_7; //排名
ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);
ADC_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC_Channel[7].Rank=ADC_REGULAR_RANK_8; //排名
ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);
ADC_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC_Channel[8].Rank=ADC_REGULAR_RANK_9; //排名
ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);
ADC_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC_Channel[9].Rank=ADC_REGULAR_RANK_10; //排名
ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,100);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint32_t num,i,j;
if(hadc->Instance==ADC1)
{
ADC_HandleType.Instance->CR2 &=~ ADC_CR2_CONT;
for(i=0;i<10;i++)
{
num=0;
for(j=0;j<10;j++)
{
num+=DMA_buff[j*10+i];
}
printf("ADC1_IN[%d]:%f V \r\n",i,(num/10.0)*(3.3/4096.0)); //串口1输出数字量
}
hadc->Instance->CR2 |= ADC_CR2_CONT;
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_MasterConfigTypeDef TIM_MasterConfig={0};
TIM_IC_InitTypeDef TIM_IC_Init={0};
HandleTIMXCHX.Instance=TIM3; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_IC_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_OC1; //主定时器通道1捕获时发送信号
//TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE; //主从模式:关闭
HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);
TIM_IC_Init.ICFilter=0x8;
TIM_IC_Init.ICPolarity=TIM_ICPOLARITY_RISING; //极性:上升沿
TIM_IC_Init.ICSelection=TIM_ICSELECTION_DIRECTTI; //直连
TIM_IC_Init.ICPrescaler=TIM_ICPSC_DIV1;
HAL_TIM_IC_ConfigChannel(&HandleTIMXCHX,&TIM_IC_Init,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&HandleTIMXCHX,TIM_CHANNEL_1);
}
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
__HAL_RCC_GPIOB_CLK_ENABLE(); //打开B口时钟
__HAL_RCC_TIM3_CLK_ENABLE(); //打开定时器3的时钟
__HAL_RCC_AFIO_CLK_ENABLE(); //应为要重映射,所以打开AFIO时钟
__HAL_AFIO_REMAP_TIM3_PARTIAL(); //定时器3重映射
__HAL_AFIO_REMAP_SWJ_NOJTAG(); //关闭JTAG,保留SW,释放PB4
//重映射CH1为PB4
GPIO_InitTypeDef GPIO_InitType;
GPIO_InitType.Pin = GPIO_PIN_4; //配置PIN4
GPIO_InitType.Mode = GPIO_MODE_AF_INPUT; //复用功能 输入方向
GPIO_InitType.Pull = GPIO_PULLDOWN; //开启IO口内部的下拉电阻
HAL_GPIO_Init(GPIOB,&GPIO_InitType); //配置PB4
HAL_NVIC_SetPriority(TIM3_IRQn,3,0); //定时器3的中断优先级
HAL_NVIC_EnableIRQ(TIM3_IRQn); //开定时器3的中断
}
}
/* 定时器1中断服务函数 */
void TIM3_IRQHandler(void)
{
HAL_TIM_IRQHandler(&HandleTIMXCHX); /* 定时器HAL库共用处理函数 */
}
//定时器的CC通道的输出比较
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1)
{
printf("定时器3通道1上升沿捕获成功\r\n");
}
}
}
注意:不管哪个TRGO事件的比较脉冲(输入捕获),使用哪个定时器,必须走通道1
F:规则组 10通道扫描 EXIT11事件 触发转换
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];
uint16_t DMA_buff[100];
void ADC1_Init(void)
{
//DISABLE ENABLE
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11中断
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
ADC_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC_Channel[6].Rank=ADC_REGULAR_RANK_7; //排名
ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);
ADC_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC_Channel[7].Rank=ADC_REGULAR_RANK_8; //排名
ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);
ADC_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC_Channel[8].Rank=ADC_REGULAR_RANK_9; //排名
ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);
ADC_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC_Channel[9].Rank=ADC_REGULAR_RANK_10; //排名
ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,100);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_IT_RISING; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_11;
GPIO_InitType.Pull=GPIO_PULLUP;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint32_t num,i,j;
if(hadc->Instance==ADC1)
{
ADC_HandleType.Instance->CR2 &=~ ADC_CR2_CONT;
for(i=0;i<10;i++)
{
num=0;
for(j=0;j<10;j++)
{
num+=DMA_buff[j*10+i];
}
printf("ADC1_IN[%d]:%f V \r\n",i,(num/10.0)*(3.3/4096.0)); //串口1输出数字量
}
hadc->Instance->CR2 |= ADC_CR2_CONT;
}
}
因为ADC的触发方式配置为:
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11中断
所以在配置PB11引脚的时候,需要注意(只能在下面选):
PB11不能使用:
GPIO_MODE_INPUT
GPIO_MODE_AF_INPUT
GPIO_MODE_ANALOG
间断模式
A:规则组扫描 间断模式 EXIT11事件 触发转换
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
//IC_TIMX_CHX_init(3600-1,7200-1); //T=((ARR+1)*(PSC+1)) / 72 000 000; t=0.36s 10t=3.6s
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle;
ADC_ChannelConfTypeDef ADC_Channel[10];
uint16_t count;
uint16_t DMA_buff[2];
void ADC1_Init(void)
{
//DISABLE ENABLE
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 失能
ADC_HandleType.Init.DiscontinuousConvMode=ENABLE; //规则组的间断模式
ADC_HandleType.Init.NbrOfDiscConversion=2; //规则组的间断模式子组的成员数量
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11中断
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
ADC_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC_Channel[6].Rank=ADC_REGULAR_RANK_7; //排名
ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);
ADC_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC_Channel[7].Rank=ADC_REGULAR_RANK_8; //排名
ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);
ADC_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC_Channel[8].Rank=ADC_REGULAR_RANK_9; //排名
ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);
ADC_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC_Channel[9].Rank=ADC_REGULAR_RANK_10; //排名
ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,2);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_IT_RISING; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_11;
GPIO_InitType.Pull=GPIO_PULLUP;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
//取余取的是被除数的余,不是除数的余。
printf("ADC1_IN[%d]:%f V \r\n",(count%5)*2, DMA_buff[0]*(3.3/4096.0)); //串口1输出数字量
printf("ADC1_IN[%d]:%f V \r\n\r\n",(count%5)*2+1, DMA_buff[1]*(3.3/4096.0)); //串口1输出数字量
count++;
}
}
一共开启了10个通道:0~9
ADC_HandleType.Init.NbrOfDiscConversion=2; //规则组的间断模式子组的成员数量
每个子组2个通道,所以一共5个子组。
第1子组:通道0,1
第2子组:通道2,3
第3子组:通道4,5
第4子组:通道6,7
第5子组:通道8,9
每按下一次转化一个子组,按下第6次,转化第一子组。以此类推,,,,,
按下一次进入一次中断回调函数。
注入组
A:规则组 6通道扫描+注入组4通道 自动注入方式
自动注入必须使用软件触发
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection; //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle; //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10]; //规则组通道
uint16_t DMA_buff[6]; //储存DMA数据的内存地址
void ADC1_Init(void)
{
//规则组的配置
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=6; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
//ADC_HandleType.Init.NbrOfDiscConversion=2; //规则组的间断模式子组的成员数量
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
//注入组配置---配置为自动注入
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=DISABLE; //租入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=ENABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START; //触发方式:软件,自动注入下必须禁止注入通道的外部触发
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{
HAL_ADC_IRQHandler(&ADC_HandleType);
}
//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("DMA完成中断\r\n");
for(uint16_t i=0;i<6;i++)
{
printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0)); //串口1输出数字量
}
}
}
//注入租中断回调函数
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("注入组完成中断\r\n");
printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));
printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));
printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));
printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));
__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
//HAL_ADC_IRQHandler函数中会关闭我们的注入组的中断标志为所以我们需要自己在打开一下
}
}
关于能不能使用中断或者轮询
规则组:
规则组只有一个DR寄存器,因为开启了扫描模式,在扫描模式中开启的6个通道,一个组中的6个通道全部转化完毕,中断标志位才会置位。然而我们只有一个数据寄存器(DR),会导致我们的数据出现覆盖。所以不能使用中断或者轮询
注入组:
注入组一共有4个通道,每个对应一个寄存器,所以可以使用中断和轮询方式,不会出现数据的覆盖问题。
中断问题
注入组使用的是我们ADC的中断方式所以,需要打开中断和NVIC.
ADC中断函数会关闭我们注入组的中断标志位,所以我们需要自己在注入组的回调函数中自己在开一遍
void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)
/* Determine whether any further conversion upcoming on group injected */
/* by external trigger, scan sequence on going or by automatic injected */
/* conversion from group regular (same conditions as group regular */
/* interruption disabling above). */
/* Note: On STM32F1 devices, in case of sequencer enabled */
/* (several ranks selected), end of conversion flag is raised */
/* at the end of the sequence. */
if(ADC_IS_SOFTWARE_START_INJECTED(hadc) 判断注入组是否开启了软件触发
||
(HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) 判断是否清除的自动注入&&
(ADC_IS_SOFTWARE_START_REGULAR(hadc) 是否开启的规则组的软件触发 &&
(hadc->Init.ContinuousConvMode == DISABLE)规则组是否开启了连续转换位 ) ) )
{
/* Disable ADC end of conversion interrupt on group injected */
__HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
/* Set ADC state */
CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
{
SET_BIT(hadc->State, HAL_ADC_STATE_READY);
}
}
/* Conversion complete callback */
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
hadc->InjectedConvCpltCallback(hadc);
#else
HAL_ADCEx_InjectedConvCpltCallback(hadc); 注入组中断回调函数
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
/* Clear injected group conversion flag */
__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JSTRT | ADC_FLAG_JEOC));
}
}
中断优先级
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
2个优先级必须一样 。 自动注入的工作方式:如果设置了JAUTO位(打开自动注入),在规则组通道之后,注入组通道被自动转换。
优先级:DMA(规则组)>ADC(注入组):一直转化规则组的,注入组无法转化。
优先级:DMA(规则组)<ADC(注入组):一直转化注入组的,规则组无法转化。
注入组函数参数配置:
B:规则组 外部触发 6通道扫描+注入组4通道 自动注入方式
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
//IC_TIMX_CHX_init(3600-1,7200-1); //T=((ARR+1)*(PSC+1)) / 72 000 000; t=0.36s 10t=3.6s
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection; //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle; //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10]; //规则组通道
uint16_t DMA_buff[6]; //储存DMA数据的内存地址
void ADC1_Init(void)
{
//规则组的配置
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=6; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 失能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
//ADC_HandleType.Init.NbrOfDiscConversion=2; //规则组的间断模式子组的成员数量
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11触发
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
//注入组配置---配置为自动注入
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=DISABLE; //租入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=ENABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START; //触发方式:软件,自动注入下必须禁止注入通道的外部触发
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_IT_RISING;
GPIO_InitType.Pull=GPIO_PULLUP;
GPIO_InitType.Pin=GPIO_PIN_11;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{
HAL_ADC_IRQHandler(&ADC_HandleType);
}
//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("DMA完成中断\r\n");
for(uint16_t i=0;i<6;i++)
{
printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0)); //串口1输出数字量
}
}
}
//注入租中断回调函数
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("注入组完成中断\r\n");
printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));
printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));
printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));
printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));
__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
//HAL_ADC_IRQHandler函数中会关闭我们的注入组的中断标志为所以我们需要自己在打开一下
}
}
C:注入组 偏移值 效果测试
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
//IC_TIMX_CHX_init(3600-1,7200-1); //T=((ARR+1)*(PSC+1)) / 72 000 000; t=0.36s 10t=3.6s
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection; //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle; //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10]; //规则组通道
uint16_t DMA_buff[6]; //储存DMA数据的内存地址
void ADC1_Init(void)
{
//规则组的配置
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=6; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 失能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
//ADC_HandleType.Init.NbrOfDiscConversion=2; //规则组的间断模式子组的成员数量
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_EXT_IT11;//触发方式:EXT_IT11触发
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
//注入组配置---配置为自动注入
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=3000; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=DISABLE; //租入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=ENABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START; //触发方式:软件,自动注入下必须禁止注入通道的外部触发
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=20; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=100; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=2000; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_IT_RISING;
GPIO_InitType.Pull=GPIO_PULLUP;
GPIO_InitType.Pin=GPIO_PIN_11;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{
HAL_ADC_IRQHandler(&ADC_HandleType);
}
//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("DMA完成中断\r\n");
for(uint16_t i=0;i<6;i++)
{
printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0)); //串口1输出数字量
}
}
}
//注入租中断回调函数
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("注入组完成中断\r\n");
printf("ADC1_IN[6]:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1));
printf("ADC1_IN[7]:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2));
printf("ADC1_IN[8]:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3));
printf("ADC1_IN[9]:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4));
__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
//HAL_ADC_IRQHandler函数中会关闭我们的注入组的中断标志为所以我们需要自己在打开一下
//JOFFSETx[11:0]:注入通道x的数据偏移 (Data offset for injected channel x) 位11:0
//为16位,所以int16_t;不使用32位的
// printf("注入组完成中断\r\n");
// printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));
// printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));
// printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));
// printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));
// __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
// //HAL_ADC_IRQHandler函数中会关闭我们的注入组的中断标志为所以我们需要自己在打开一下
}
}
D:规则组6通道扫描 注入组定时器CC事件 触发转换
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
IC_TIMX_CHX_init(3600-1,7200-1); //T=((ARR+1)*(PSC+1)) / 72 000 000; t=0.36s 10t=3.6s
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection; //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle; //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10]; //规则组通道
uint16_t DMA_buff[6]; //储存DMA数据的内存地址
void ADC1_Init(void)
{
//规则组的配置
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=6; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
//ADC_HandleType.Init.NbrOfDiscConversion=2; //规则组的间断模式子组的成员数量
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_T1_CC4; //触发方式:TIM1的通道4
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
HAL_NVIC_SetPriority(ADC1_2_IRQn,2,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{
HAL_ADC_IRQHandler(&ADC_HandleType);
}
//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("DMA完成中断\r\n");
for(uint16_t i=0;i<6;i++)
{
printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0)); //串口1输出数字量
}
}
}
//注入租中断回调函数
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("----------------------------------------注入组完成中断\r\n");
printf("DMA剩余没有转换的通道量:%d\r\n",__HAL_DMA_GET_COUNTER(&DMA_Handle));
printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));
printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));
printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));
printf("ADC1_IN[9]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_OC_InitTypeDef TIM_OC_Init={0};
HandleTIMXCHX.Instance=TIM1; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.RepetitionCounter = 0; //设置重复次数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_OC_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;
TIM_OC_Init.Pulse=100; //比较值(CCR)
TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值 :PWM1:CNT<CCR输出有效电平
TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX,&TIM_OC_Init,TIM_CHANNEL_4);
HAL_TIM_OC_Start(&HandleTIMXCHX,TIM_CHANNEL_4);
}
void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM1)
{
__HAL_RCC_TIM1_CLK_ENABLE(); //打开定时器1的时钟
// HAL_NVIC_SetPriority(TIM1_CC_IRQn,1,0); //定时器3的中断优先级
// HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); //开定时器3的中断
}
}
注入组可以打断规则组。
注入组:自动注入和外部触发不能共存在。自动注入相当于放弃了优先级。外部触发可以打断规则组。
关于要不要在注入回调函数中再一次打开中断:判断它有没有关闭。(这里没有关闭,所以我们不要再次打开。)
void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)
/* Determine whether any further conversion upcoming on group injected */
/* by external trigger, scan sequence on going or by automatic injected */
/* conversion from group regular (same conditions as group regular */
/* interruption disabling above). */
/* Note: On STM32F1 devices, in case of sequencer enabled */
/* (several ranks selected), end of conversion flag is raised */
/* at the end of the sequence. */
if(ADC_IS_SOFTWARE_START_INJECTED(hadc) 判断注入组是否开启了软件触发
||
(HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) 判断是否清除的自动注入&&
(ADC_IS_SOFTWARE_START_REGULAR(hadc) 是否开启的规则组的软件触发 &&
(hadc->Init.ContinuousConvMode == DISABLE)规则组是否开启了连续转换位 ) ) )
{
/* Disable ADC end of conversion interrupt on group injected */
__HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
/* Set ADC state */
CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
{
SET_BIT(hadc->State, HAL_ADC_STATE_READY);
}
}
/* Conversion complete callback */
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
hadc->InjectedConvCpltCallback(hadc);
#else
HAL_ADCEx_InjectedConvCpltCallback(hadc); 注入组中断回调函数
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
/* Clear injected group conversion flag */
__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JSTRT | ADC_FLAG_JEOC));
}
}
E:注入组 定时器TRGO之下 更新事件 触发转换
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
IC_TIMX_CHX_init(3600-1,7200-1); //T=((ARR+1)*(PSC+1)) / 72 000 000; t=0.36s 10t=3.6s
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection; //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle; //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10]; //规则组通道
uint16_t DMA_buff[6]; //储存DMA数据的内存地址
void ADC1_Init(void)
{
//规则组的配置
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=6; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
//ADC_HandleType.Init.NbrOfDiscConversion=2; //规则组的间断模式子组的成员数量
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_T1_TRGO; //触发方式:TIM1的通道TRGO事件
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
HAL_NVIC_SetPriority(ADC1_2_IRQn,2,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{
HAL_ADC_IRQHandler(&ADC_HandleType);
}
//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("DMA完成中断\r\n");
for(uint16_t i=0;i<6;i++)
{
printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0)); //串口1输出数字量
}
}
}
//注入租中断回调函数
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("----------------------------------------注入组完成中断\r\n");
printf("DMA剩余没有转换的通道量:%d\r\n",__HAL_DMA_GET_COUNTER(&DMA_Handle));
printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));
printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));
printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));
printf("ADC1_IN[9]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_MasterConfigTypeDef TIM_MasterConfig={0};
TIM_OC_InitTypeDef TIM_OC_Init={0};
HandleTIMXCHX.Instance=TIM1; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.RepetitionCounter = 0; //设置重复次数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_Base_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
// TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;
// TIM_OC_Init.Pulse=100; //比较值(CCR)
// TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值 :PWM1:CNT<CCR输出有效电平
// TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;
// HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX,&TIM_OC_Init,TIM_CHANNEL_4);
TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_UPDATE; //主定时器通道1捕获时发送信号
TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE; //主从模式:关闭
HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);
HAL_TIM_Base_Start(&HandleTIMXCHX);
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM1)
{
__HAL_RCC_TIM1_CLK_ENABLE(); //打开定时器1的时钟
// HAL_NVIC_SetPriority(TIM1_CC_IRQn,1,0); //定时器3的中断优先级
// HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); //开定时器3的中断
}
}
F:注入组 定时器TRGO之下 输入捕获事件 触发转换
注意:不管哪个TRGO事件的比较脉冲(输入捕获),使用哪个定时器,必须走通道1
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
IC_TIMX_CHX_init(0xFFFF,36000-1);
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection; //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle; //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10]; //规则组通道
uint16_t DMA_buff[6]; //储存DMA数据的内存地址
void ADC1_Init(void)
{
//规则组的配置
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=6; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
//ADC_HandleType.Init.NbrOfDiscConversion=2; //规则组的间断模式子组的成员数量
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_T1_TRGO; //触发方式:TIM1的通道TRGO事件
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{
HAL_ADC_IRQHandler(&ADC_HandleType);
}
//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("DMA完成中断\r\n");
for(uint16_t i=0;i<6;i++)
{
printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0)); //串口1输出数字量
}
}
}
//注入租中断回调函数
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("----------------------------------------注入组完成中断\r\n");
printf("DMA剩余没有转换的通道量:%d\r\n",__HAL_DMA_GET_COUNTER(&DMA_Handle));
printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));
printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));
printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));
printf("ADC1_IN[9]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_MasterConfigTypeDef TIM_MasterConfig={0};
TIM_IC_InitTypeDef TIM_IC_Init={0};
HandleTIMXCHX.Instance=TIM1; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.RepetitionCounter = 0; //设置重复次数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_IC_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_IC_Init.ICFilter=0x8;
TIM_IC_Init.ICPolarity=TIM_ICPOLARITY_RISING; //极性:上升沿
TIM_IC_Init.ICSelection=TIM_ICSELECTION_DIRECTTI; //直连
TIM_IC_Init.ICPrescaler=TIM_ICPSC_DIV1;
TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_OC1; //主定时器通道1捕获时发送信号
TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE; //主从模式:关闭
HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);
HAL_TIM_IC_ConfigChannel(&HandleTIMXCHX,&TIM_IC_Init,TIM_CHANNEL_1);
HAL_TIM_IC_Start(&HandleTIMXCHX,TIM_CHANNEL_1);
}
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_TIM1_CLK_ENABLE(); //打开定时器1的时钟
GPIO_InitTypeDef GPIO_InitType;
//TIM1——CH1--PA8
GPIO_InitType.Mode=GPIO_MODE_AF_INPUT;
GPIO_InitType.Pin=GPIO_PIN_8;
GPIO_InitType.Pull=GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
}
}
G:注入组 EXIT15线事件 触发转换
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
//IC_TIMX_CHX_init(0xFFFF,36000-1);
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection; //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle; //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10]; //规则组通道
uint16_t DMA_buff[6]; //储存DMA数据的内存地址
void ADC1_Init(void)
{
//规则组的配置
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=6; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
//ADC_HandleType.Init.NbrOfDiscConversion=2; //规则组的间断模式子组的成员数量
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_EXT_IT15; //触发方式:EXT_IT15
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_IT_RISING;
GPIO_InitType.Pull=GPIO_PULLDOWN;
GPIO_InitType.Pin=GPIO_PIN_15;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{
HAL_ADC_IRQHandler(&ADC_HandleType);
}
//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("DMA完成中断\r\n");
for(uint16_t i=0;i<6;i++)
{
printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0)); //串口1输出数字量
}
}
}
//注入租中断回调函数
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("----------------------------------------注入组完成中断\r\n");
printf("DMA剩余没有转换的通道量:%d\r\n",__HAL_DMA_GET_COUNTER(&DMA_Handle));
printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));
printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));
printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));
printf("ADC1_IN[9]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));
}
}
H:注入组 间断模式 触发转换
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
//IC_TIMX_CHX_init(0xFFFF,36000-1);
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection; //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle; //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10]; //规则组通道
uint16_t DMA_buff[6]; //储存DMA数据的内存地址
void ADC1_Init(void)
{
//规则组的配置
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=6; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
//ADC_HandleType.Init.NbrOfDiscConversion=2; //规则组的间断模式子组的成员数量
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=ENABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_EXT_IT15; //触发方式:EXT_IT15
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_IT_RISING;
GPIO_InitType.Pull=GPIO_PULLDOWN;
GPIO_InitType.Pin=GPIO_PIN_15;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{
HAL_ADC_IRQHandler(&ADC_HandleType);
}
//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
// if(hadc->Instance==ADC1)
// {
// printf("DMA完成中断\r\n");
// for(uint16_t i=0;i<6;i++)
// {
// printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0)); //串口1输出数字量
// }
//
// }
}
//注入租中断回调函数
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("----------------------------------------注入组完成中断\r\n");
printf("DMA剩余没有转换的通道量:%d\r\n",__HAL_DMA_GET_COUNTER(&DMA_Handle));
printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));
printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));
printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));
printf("ADC1_IN[9]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));
}
}
我们开启了注入组的间断模式,一共使用了4个通道,因为n固定为1,所以每按下一次转化一个子组,等组(4个子组)全部转化完毕,才可以进去中断回调函数中去。也就是说我们需要按下4次才会进入中断回调函数。
HAL_ADCEx_InjectedConvCpltCallback()
模拟看门狗
可以参考我写的:
CSDNhttps://mp.csdn.net/mp_blog/creation/editor/136916809
我们的ADC是12位的,也就是说取值范围为:0X000----0XFFF
我们选取一个上限制和一个下限制,当我们的值在这个范围内属于正常值。一但高于或者低于就属于异常值,会触发模拟看门狗中断。
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
//IC_TIMX_CHX_init(0xFFFF,36000-1);
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection; //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle; //DMA句柄
ADC_AnalogWDGConfTypeDef adc1_dog; //ADC1的模拟看门狗的结构体
ADC_ChannelConfTypeDef ADC_Channel[10]; //规则组通道
uint16_t DMA_buff[6]; //储存DMA数据的内存地址
void ADC1_Init(void)
{
//规则组的配置
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=6; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
//ADC_HandleType.Init.NbrOfDiscConversion=2; //规则组的间断模式子组的成员数量
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC_Injection.InjectedChannel=ADC_CHANNEL_4; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=ENABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START; //触发方式:软件
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_5; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
adc1_dog.WatchdogMode = ADC_ANALOGWATCHDOG_SINGLE_REG; //工作模式
adc1_dog.Channel = ADC_CHANNEL_2; //设置单一模式下,监控的通道
adc1_dog.ITMode = ENABLE; //使用中断模式
adc1_dog.HighThreshold = 0xFFF; //设置高阈值
adc1_dog.LowThreshold = 0x3FF; //设置低阈值
HAL_ADC_AnalogWDGConfig(&ADC_HandleType,&adc1_dog); //这是模拟看门狗
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,6);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_IT_RISING;
GPIO_InitType.Pull=GPIO_PULLDOWN;
GPIO_InitType.Pin=GPIO_PIN_15;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
HAL_NVIC_SetPriority(ADC1_2_IRQn,3,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
//注入组是以ADC中断执行的
void ADC1_2_IRQHandler()
{
HAL_ADC_IRQHandler(&ADC_HandleType);
}
//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
// if(hadc->Instance==ADC1)
// {
// printf("DMA完成中断\r\n");
// for(uint16_t i=0;i<6;i++)
// {
// printf("ADC1_IN[%d]:%f V \r\n",i,DMA_buff[i]*(3.3/4096.0)); //串口1输出数字量
// }
//
// }
}
//注入租中断回调函数
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("----------------------------------------注入组完成中断\r\n");
printf("DMA剩余没有转换的通道量:%d\r\n",__HAL_DMA_GET_COUNTER(&DMA_Handle));
printf("ADC1_IN[6]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_1)*(3.3/4096.0));
printf("ADC1_IN[7]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_2)*(3.3/4096.0));
printf("ADC1_IN[8]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_3)*(3.3/4096.0));
printf("ADC1_IN[9]:%f V \r\n",HAL_ADCEx_InjectedGetValue(hadc,ADC_INJECTED_RANK_4)*(3.3/4096.0));
}
}
//模拟看门狗的中断回调
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1){
printf("模拟看门狗的中断回调\r\n");
}
}
双ADC模式
A:双ADC模式 软件触发 ADC1 ADC2同步规则模式
有软件触发
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init();
ADC2_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType; //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType; //ADC2为从模式
ADC_ChannelConfTypeDef ADC_Channel[10]; //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10]; //ADC2为从模式的通道
uint32_t DMA_buff[10];
DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
ADC_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC_Channel[6].Rank=ADC_REGULAR_RANK_7; //排名
ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);
ADC_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC_Channel[7].Rank=ADC_REGULAR_RANK_8; //排名
ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);
ADC_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC_Channel[8].Rank=ADC_REGULAR_RANK_9; //排名
ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);
ADC_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC_Channel[9].Rank=ADC_REGULAR_RANK_10; //排名
ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);
}
void ADC2_Init(void)
{
ADC2_HandleType.Instance=ADC2;
ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC2_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC2_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC2_HandleType);
ADC_MultiModeTypeDef ADC_MultiMode={0};
ADC2_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC2_Channel[0].Rank=ADC_REGULAR_RANK_10; //排名
ADC2_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[0]);
ADC2_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC2_Channel[1].Rank=ADC_REGULAR_RANK_9; //排名
ADC2_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[1]);
ADC2_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC2_Channel[2].Rank=ADC_REGULAR_RANK_8; //排名
ADC2_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[2]);
ADC2_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC2_Channel[3].Rank=ADC_REGULAR_RANK_7; //排名
ADC2_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,& ADC2_Channel[3]);
ADC2_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC2_Channel[4].Rank=ADC_REGULAR_RANK_6; //排名
ADC2_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[4]);
ADC2_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC2_Channel[5].Rank=ADC_REGULAR_RANK_5; //排名
ADC2_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[5]);
ADC2_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC2_Channel[6].Rank=ADC_REGULAR_RANK_4; //排名
ADC2_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[6]);
ADC2_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC2_Channel[7].Rank=ADC_REGULAR_RANK_3; //排名
ADC2_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[7]);
ADC2_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC2_Channel[8].Rank=ADC_REGULAR_RANK_2; //排名
ADC2_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[8]);
ADC2_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC2_Channel[9].Rank=ADC_REGULAR_RANK_1; //排名
ADC2_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[9]);
//配置ADC双模式:同步规则模式
ADC_MultiMode.Mode=ADC_DUALMODE_REGSIMULT;
HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);
HAL_ADCEx_Calibration_Start(&ADC2_HandleType); //自校准
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADC_Start(&ADC2_HandleType);
HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
else if (hadc->Instance==ADC2)
{
__HAL_RCC_ADC2_CLK_ENABLE();
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("DMA完成中断\r\n");
printf("ADC1_IN0:%d\r\n",DMA_buff[0]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN1:%d\r\n",DMA_buff[1]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN2:%d\r\n",DMA_buff[2]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN3:%d\r\n",DMA_buff[3]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN4:%d\r\n",DMA_buff[4]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN5:%d\r\n",DMA_buff[5]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN6:%d\r\n",DMA_buff[6]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN7:%d\r\n",DMA_buff[7]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN8:%d\r\n",DMA_buff[8]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN9:%d\r\n",DMA_buff[9]&0x0000FFFF); //串口1输出电压值
printf("----------------------------------------\r\n");
printf("ADC2_IN9:%d\r\n",(DMA_buff[0]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN8:%d\r\n",(DMA_buff[1]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN7:%d\r\n",(DMA_buff[2]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN6:%d\r\n",(DMA_buff[3]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN5:%d\r\n",(DMA_buff[4]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN4:%d\r\n",(DMA_buff[5]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN3:%d\r\n",(DMA_buff[6]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN2:%d\r\n",(DMA_buff[7]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN1:%d\r\n",(DMA_buff[8]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN0:%d\r\n",(DMA_buff[9]&0xFFFF0000)>>16); //串口1输出电压值
}
}
关于ADC1_Init ()和ADC2_Init
我们在主函数中首先初始化的是ADC1,在初始化ADC2。所以基本上开启什么的通道都放在了ADC2上面。
在同步规则模式中,必须转换具有相同时间长度的序列(软件触发)
ADC1和ADC2的通道数必须相同。
B:双ADC 外部信号触发 ADC1 ADC2同步规则模式
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
IC_TIMX_CHX_init(10000-1,7200-1); //T=((ARR+1)*(PSC+1)) / 1S
ADC1_Init();
ADC2_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType; //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType; //ADC2为从模式
ADC_ChannelConfTypeDef ADC_Channel[10]; //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10]; //ADC2为从模式的通道
uint32_t DMA_buff[10];
DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 失能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T1_CC1;//触发方式:TIM1的通道1
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
ADC_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC_Channel[6].Rank=ADC_REGULAR_RANK_7; //排名
ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);
ADC_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC_Channel[7].Rank=ADC_REGULAR_RANK_8; //排名
ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);
ADC_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC_Channel[8].Rank=ADC_REGULAR_RANK_9; //排名
ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);
ADC_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC_Channel[9].Rank=ADC_REGULAR_RANK_10; //排名
ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);
}
void ADC2_Init(void)
{
ADC2_HandleType.Instance=ADC2;
ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC2_HandleType.Init.NbrOfConversion=8; //扫描模式下规则组的数量
ADC2_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式:失能
ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC2_HandleType);
ADC_MultiModeTypeDef ADC_MultiMode={0};
ADC2_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC2_Channel[2].Rank=ADC_REGULAR_RANK_8; //排名
ADC2_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[2]);
ADC2_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC2_Channel[3].Rank=ADC_REGULAR_RANK_7; //排名
ADC2_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,& ADC2_Channel[3]);
ADC2_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC2_Channel[4].Rank=ADC_REGULAR_RANK_6; //排名
ADC2_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[4]);
ADC2_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC2_Channel[5].Rank=ADC_REGULAR_RANK_5; //排名
ADC2_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[5]);
ADC2_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC2_Channel[6].Rank=ADC_REGULAR_RANK_4; //排名
ADC2_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[6]);
ADC2_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC2_Channel[7].Rank=ADC_REGULAR_RANK_3; //排名
ADC2_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[7]);
ADC2_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC2_Channel[8].Rank=ADC_REGULAR_RANK_2; //排名
ADC2_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[8]);
ADC2_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC2_Channel[9].Rank=ADC_REGULAR_RANK_1; //排名
ADC2_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[9]);
//配置ADC双模式:同步规则模式
ADC_MultiMode.Mode=ADC_DUALMODE_REGSIMULT;
HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);
HAL_ADCEx_Calibration_Start(&ADC2_HandleType); //自校准
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADC_Start(&ADC2_HandleType);
HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
else if (hadc->Instance==ADC2)
{
__HAL_RCC_ADC2_CLK_ENABLE();
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
printf("DMA完成中断\r\n");
printf("ADC1_IN0:%d\r\n",DMA_buff[0]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN1:%d\r\n",DMA_buff[1]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN2:%d\r\n",DMA_buff[2]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN3:%d\r\n",DMA_buff[3]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN4:%d\r\n",DMA_buff[4]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN5:%d\r\n",DMA_buff[5]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN6:%d\r\n",DMA_buff[6]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN7:%d\r\n",DMA_buff[7]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN8:%d\r\n",DMA_buff[8]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN9:%d\r\n",DMA_buff[9]&0x0000FFFF); //串口1输出电压值
printf("----------------------------------------\r\n");
printf("ADC2_IN9:%d\r\n",(DMA_buff[0]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN8:%d\r\n",(DMA_buff[1]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN7:%d\r\n",(DMA_buff[2]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN6:%d\r\n",(DMA_buff[3]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN5:%d\r\n",(DMA_buff[4]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN4:%d\r\n",(DMA_buff[5]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN3:%d\r\n",(DMA_buff[6]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN2:%d\r\n",(DMA_buff[7]&0xFFFF0000)>>16); //串口1输出电压值
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_OC_InitTypeDef TIM_OC_Init={0};
HandleTIMXCHX.Instance=TIM1; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.RepetitionCounter = 0; //设置重复次数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_OC_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;
TIM_OC_Init.Pulse=100; //比较值(CCR)
TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值 :PWM1:CNT<CCR输出有效电平
TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX,&TIM_OC_Init,TIM_CHANNEL_1);
HAL_TIM_OC_Start(&HandleTIMXCHX,TIM_CHANNEL_1);
}
C:双ADC 外部信号触发 ADC1 ADC2同步注入模式
在注入组的模式中,我们只能使用外部触发的模式,没有软件触发的模式
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
IC_TIMX_CHX_init(10000-1,7200-1); //T=((ARR+1)*(PSC+1)) / 1S
ADC1_Init();
ADC2_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType; //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType; //ADC2为从模式
ADC_ChannelConfTypeDef ADC_Channel[10]; //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10]; //ADC2为从模式的通道
ADC_InjectionConfTypeDef ADC_Injection; //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection; //ADC1从模式的注入组
uint32_t DMA_buff[10];
DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
ADC_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC_Channel[6].Rank=ADC_REGULAR_RANK_7; //排名
ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);
ADC_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC_Channel[7].Rank=ADC_REGULAR_RANK_8; //排名
ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);
ADC_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC_Channel[8].Rank=ADC_REGULAR_RANK_9; //排名
ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);
ADC_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC_Channel[9].Rank=ADC_REGULAR_RANK_10; //排名
ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_T4_TRGO; //触发方式:EXT_IT15
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
}
void ADC2_Init(void)
{
ADC2_HandleType.Instance=ADC2;
ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC2_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC2_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 使能
ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式
HAL_ADC_Init(&ADC2_HandleType);
ADC_MultiModeTypeDef ADC_MultiMode={0};
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC2_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
ADC2_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC2_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC2_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC2_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START; //触发方式
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//配置ADC双模式:同步规则模式
ADC_MultiMode.Mode=ADC_DUALMODE_INJECSIMULT;
HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);
HAL_ADCEx_Calibration_Start(&ADC2_HandleType); //自校准
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组ADC1主模式
HAL_ADCEx_InjectedStart(&ADC2_HandleType); //开启注入组ADC2从模式
HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
else if (hadc->Instance==ADC2)
{
__HAL_RCC_ADC2_CLK_ENABLE();
HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
void ADC1_2_IRQHandler(void)
{
HAL_ADC_IRQHandler(&ADC_HandleType);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
// printf("DMA完成中断\r\n");
// printf("ADC1_IN0:%d\r\n",DMA_buff[0]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN1:%d\r\n",DMA_buff[1]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN2:%d\r\n",DMA_buff[2]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN3:%d\r\n",DMA_buff[3]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN4:%d\r\n",DMA_buff[4]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN5:%d\r\n",DMA_buff[5]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN6:%d\r\n",DMA_buff[6]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN7:%d\r\n",DMA_buff[7]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN8:%d\r\n",DMA_buff[8]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN9:%d\r\n",DMA_buff[9]&0x0000FFFF); //串口1输出电压值
// printf("----------------------------------------\r\n");
// printf("ADC2_IN9:%d\r\n",(DMA_buff[0]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN8:%d\r\n",(DMA_buff[1]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN7:%d\r\n",(DMA_buff[2]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN6:%d\r\n",(DMA_buff[3]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN5:%d\r\n",(DMA_buff[4]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN4:%d\r\n",(DMA_buff[5]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN3:%d\r\n",(DMA_buff[6]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN2:%d\r\n",(DMA_buff[7]&0xFFFF0000)>>16); //串口1输出电压值
}
}
//注入组完成中断
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1){
printf("---------------------------------------------ADC1注入组完成\r\n");
printf("ADC1_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_1)); //串口1输出电压值
printf("ADC1_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_2)); //串口1输出电压值
printf("ADC1_IN8:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_3)); //串口1输出电压值
printf("ADC1_IN9:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_4)); //串口1输出电压值
printf("---------------------------------------------ADC2注入组完成\r\n");
printf("ADC2_IN9:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_1)); //串口1输出电压值
printf("ADC2_IN8:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_2)); //串口1输出电压值
printf("ADC2_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_3)); //串口1输出电压值
printf("ADC2_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_4)); //串口1输出电压值
//__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_MasterConfigTypeDef TIM_MasterConfig={0};
TIM_IC_InitTypeDef TIM_IC_Init={0};
HandleTIMXCHX.Instance=TIM4; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_IC_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_MasterConfig.MasterOutputTrigger=TIM_TRGO_OC1; //主定时器通道1捕获时发送信号
//TIM_MasterConfig.MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE; //主从模式:关闭
HAL_TIMEx_MasterConfigSynchronization(&HandleTIMXCHX,&TIM_MasterConfig);
TIM_IC_Init.ICFilter=0x8;
TIM_IC_Init.ICPolarity=TIM_ICPOLARITY_RISING; //极性:上升沿
TIM_IC_Init.ICSelection=TIM_ICSELECTION_DIRECTTI; //直连
TIM_IC_Init.ICPrescaler=TIM_ICPSC_DIV1;
HAL_TIM_IC_ConfigChannel(&HandleTIMXCHX,&TIM_IC_Init,TIM_CHANNEL_1);
HAL_TIM_IC_Start(&HandleTIMXCHX,TIM_CHANNEL_1);
}
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM4)
{
__HAL_RCC_GPIOB_CLK_ENABLE(); //打开B口时钟
__HAL_RCC_TIM4_CLK_ENABLE(); //打开定时器3的时钟
GPIO_InitTypeDef GPIO_InitType;
GPIO_InitType.Pin = GPIO_PIN_6; //配置PIN4
GPIO_InitType.Mode = GPIO_MODE_AF_INPUT; //复用功能 输入方向
GPIO_InitType.Pull = GPIO_PULLDOWN; //开启IO口内部的下拉电阻
HAL_GPIO_Init(GPIOB,&GPIO_InitType); //配置PB4
}
}
关于中断:打开任意一个就ok了。
打开主模式(ADC1)的中断,在注入组中断回调函数中不需要再使能注入组的中断。(中断不会被关闭)
打开从模式(ADC2)的中断,需要再注入组的中断回调函数中再次打开注入组中断。(中断被关闭)
void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)
/* Determine whether any further conversion upcoming on group injected */
/* by external trigger, scan sequence on going or by automatic injected */
/* conversion from group regular (same conditions as group regular */
/* interruption disabling above). */
/* Note: On STM32F1 devices, in case of sequencer enabled */
/* (several ranks selected), end of conversion flag is raised */
/* at the end of the sequence. */
if(ADC_IS_SOFTWARE_START_INJECTED(hadc) 判断注入组是否开启了软件触发
||
(HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) 判断是否清除的自动注入&&
(ADC_IS_SOFTWARE_START_REGULAR(hadc) 是否开启的规则组的软件触发 &&
(hadc->Init.ContinuousConvMode == DISABLE)规则组是否开启了连续转换位 ) ) )
{
/* Disable ADC end of conversion interrupt on group injected */
__HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
/* Set ADC state */
CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
{
SET_BIT(hadc->State, HAL_ADC_STATE_READY);
}
}
/* Conversion complete callback */
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
hadc->InjectedConvCpltCallback(hadc);
#else
HAL_ADCEx_InjectedConvCpltCallback(hadc); 注入组中断回调函数
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
/* Clear injected group conversion flag */
__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JSTRT | ADC_FLAG_JEOC));
}
}
D:双ADC 外部信号触发 ADC1 ADC2交替触发模式
没有软件触发,只有外部触发
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
IC_TIMX_CHX_init(10000-1,7200-1); //T=((ARR+1)*(PSC+1)) / 1S
ADC1_Init();
ADC2_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType; //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType; //ADC2为从模式
ADC_ChannelConfTypeDef ADC_Channel[10]; //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10]; //ADC2为从模式的通道
ADC_InjectionConfTypeDef ADC_Injection; //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection; //ADC1从模式的注入组
uint32_t DMA_buff[10];
DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
ADC_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC_Channel[6].Rank=ADC_REGULAR_RANK_7; //排名
ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);
ADC_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC_Channel[7].Rank=ADC_REGULAR_RANK_8; //排名
ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);
ADC_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC_Channel[8].Rank=ADC_REGULAR_RANK_9; //排名
ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);
ADC_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC_Channel[9].Rank=ADC_REGULAR_RANK_10; //排名
ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_T2_CC1; //触发方式:TIM2的CC1(通道1)
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
}
void ADC2_Init(void)
{
ADC2_HandleType.Instance=ADC2;
ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC2_HandleType.Init.NbrOfConversion=0; //扫描模式下规则组的数量
ADC2_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 使能
ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式
HAL_ADC_Init(&ADC2_HandleType);
ADC_MultiModeTypeDef ADC_MultiMode={0};
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC2_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
ADC2_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC2_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC2_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC2_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START; //触发方式
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//配置ADC双模式:交替触发模式
ADC_MultiMode.Mode=ADC_DUALMODE_ALTERTRIG;
HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);
HAL_ADCEx_Calibration_Start(&ADC2_HandleType); //自校准
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组ADC1主模式
HAL_ADCEx_InjectedStart_IT(&ADC2_HandleType); //中断方式开启注入组ADC2从模式
//配置规则组
HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
else if (hadc->Instance==ADC2)
{
__HAL_RCC_ADC2_CLK_ENABLE();
HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
void ADC1_2_IRQHandler(void)
{
HAL_ADC_IRQHandler(&ADC_HandleType);
HAL_ADC_IRQHandler(&ADC2_HandleType);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
// printf("DMA完成中断\r\n");
// printf("ADC1_IN0:%d\r\n",DMA_buff[0]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN1:%d\r\n",DMA_buff[1]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN2:%d\r\n",DMA_buff[2]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN3:%d\r\n",DMA_buff[3]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN4:%d\r\n",DMA_buff[4]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN5:%d\r\n",DMA_buff[5]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN6:%d\r\n",DMA_buff[6]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN7:%d\r\n",DMA_buff[7]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN8:%d\r\n",DMA_buff[8]&0x0000FFFF); //串口1输出电压值
// printf("ADC1_IN9:%d\r\n",DMA_buff[9]&0x0000FFFF); //串口1输出电压值
// printf("----------------------------------------\r\n");
// printf("ADC2_IN9:%d\r\n",(DMA_buff[0]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN8:%d\r\n",(DMA_buff[1]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN7:%d\r\n",(DMA_buff[2]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN6:%d\r\n",(DMA_buff[3]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN5:%d\r\n",(DMA_buff[4]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN4:%d\r\n",(DMA_buff[5]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN3:%d\r\n",(DMA_buff[6]&0xFFFF0000)>>16); //串口1输出电压值
// printf("ADC2_IN2:%d\r\n",(DMA_buff[7]&0xFFFF0000)>>16); //串口1输出电压值
}
}
//注入组完成中断
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1){
printf("---------------------------------------------ADC1注入组完成\r\n");
printf("ADC1_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_1)); //串口1输出电压值
printf("ADC1_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_2)); //串口1输出电压值
printf("ADC1_IN8:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_3)); //串口1输出电压值
printf("ADC1_IN9:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_4)); //串口1输出电压值
//__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
}
else if(hadc->Instance == ADC2){
printf("---------------------------------------------ADC2注入组完成\r\n");
printf("ADC2_IN9:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_1)); //串口1输出电压值
printf("ADC2_IN8:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_2)); //串口1输出电压值
printf("ADC2_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_3)); //串口1输出电压值
printf("ADC2_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_4)); //串口1输出电压值
__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_OC_InitTypeDef TIM_OC_Init={0};
HandleTIMXCHX.Instance=TIM2; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_OC_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;
TIM_OC_Init.Pulse=100; //比较值(CCR)
TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值 :PWM1:CNT<CCR输出有效电平
TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX, &TIM_OC_Init,TIM_CHANNEL_1);
HAL_TIM_OC_Start(&HandleTIMXCHX,TIM_CHANNEL_1);
}
void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM2)
{
__HAL_RCC_TIM2_CLK_ENABLE(); //打开定时器3的时钟
//信号为内部触发所以,定时器2_CH2引脚可以使用初始化
HAL_NVIC_SetPriority(TIM2_IRQn,3,0); //定时器3的中断优先级
HAL_NVIC_EnableIRQ(TIM2_IRQn); //开定时器3的中断
}
}
E:双ADC 外部信号触发 ADC1 ADC2交替触发模式+间断模式
没有软件触发,只有外部触发
所有的东西和D一样,不过就是开启了ADC1和ADC2的注入模式。
ADC_Injection.InjectedDiscontinuousConvMode=ENABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
F:双ADC 外部信号触发 ADC1 ADC2快速交叉模式
没有软件触发,只有外部触发
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
IC_TIMX_CHX_init(5000-1,3600-1); //T=((ARR+1)*(PSC+1)) / 0.25s 0.25*10=2.5s因为DMA转运10次进入一次DMA中断
ADC1_Init();
ADC2_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType; //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType; //ADC2为从模式
ADC_ChannelConfTypeDef ADC_Channel[10]; //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10]; //ADC2为从模式的通道
ADC_InjectionConfTypeDef ADC_Injection; //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection; //ADC1从模式的注入组
uint32_t DMA_buff[10];
DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE; //扫描模式:失能
//ADC_HandleType.Init.NbrOfConversion=1; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T2_CC2;//触发方式
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_1CYCLE_5; //周期:
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
}
void ADC2_Init(void)
{
ADC2_HandleType.Instance=ADC2;
ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE; //扫描模式:失能
//ADC2_HandleType.Init.NbrOfConversion=1; //扫描模式下规则组的数量
ADC2_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 使能
ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式
HAL_ADC_Init(&ADC2_HandleType);
ADC_MultiModeTypeDef ADC_MultiMode={0};
ADC2_Channel[0].Channel=ADC_CHANNEL_3; //通道编号
ADC2_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC2_Channel[0].SamplingTime=ADC_SAMPLETIME_1CYCLE_5; //周期:
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[0]);
//配置ADC双模式:快速交叉模式
ADC_MultiMode.Mode=ADC_DUALMODE_INTERLFAST;
HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_Calibration_Start(&ADC2_HandleType); //自校准
HAL_ADC_Start(&ADC2_HandleType);
//配置规则组
HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitType.Mode = GPIO_MODE_ANALOG; //ADC功能
HAL_GPIO_Init(GPIOA,&GPIO_InitType); //配置PA0 1 2 3 4 5 6 7
GPIO_InitType.Pin = GPIO_PIN_0|GPIO_PIN_1; //配置PIN0 1
GPIO_InitType.Mode = GPIO_MODE_ANALOG; //ADC功能
HAL_GPIO_Init(GPIOB,&GPIO_InitType); //配置PB0 1
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0); //DMA通道1的中断优先级
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); //开DMA通道1的中断
}
else if (hadc->Instance==ADC2)
{
__HAL_RCC_ADC2_CLK_ENABLE();
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint32_t i,sum;
if(hadc->Instance==ADC1)
{
sum = 0;
for(i=0;i<10;i++){
sum += DMA_buff[i];
}
printf("DMA完成中断\r\n");
printf("ADC1_IN3:%f\r\n",((sum&0x0000FFFF)/10.0)*(3.3/4096.0)); //串口1输出电压值
printf("ADC2_IN3:%f\r\n",(((sum&0xFFFF0000)>>16)/10.0)*(3.3/4096.0)); //串口1输出电压值
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_OC_InitTypeDef TIM_OC_Init={0};
HandleTIMXCHX.Instance=TIM2; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_OC_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;
TIM_OC_Init.Pulse=100; //比较值(CCR)
TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值 :PWM1:CNT<CCR输出有效电平
TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX, &TIM_OC_Init,TIM_CHANNEL_2);
HAL_TIM_OC_Start(&HandleTIMXCHX,TIM_CHANNEL_2);
}
void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM2)
{
__HAL_RCC_TIM2_CLK_ENABLE(); //打开定时器3的时钟
//信号为内部触发所以,定时器2_CH2引脚可以使用初始化
}
}
G:双ADC 外部信号触发 ADC1 ADC2慢速交叉模式
没有软件触发,只有外部触发
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
IC_TIMX_CHX_init(50000-1,7200-1); //T=((ARR+1)*(PSC+1)) / 5s 5*10=50s因为DMA转运10次进入一次DMA中断
ADC1_Init();
ADC2_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType; //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType; //ADC2为从模式
ADC_ChannelConfTypeDef ADC_Channel[10]; //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10]; //ADC2为从模式的通道
ADC_InjectionConfTypeDef ADC_Injection; //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection; //ADC1从模式的注入组
uint32_t DMA_buff[10];
DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE; //扫描模式:失能
//ADC_HandleType.Init.NbrOfConversion=1; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T2_CC2;//触发方式
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_1CYCLE_5; //周期:
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
}
void ADC2_Init(void)
{
ADC2_HandleType.Instance=ADC2;
ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE; //扫描模式:失能
//ADC2_HandleType.Init.NbrOfConversion=1; //扫描模式下规则组的数量
ADC2_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 使能
ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式
HAL_ADC_Init(&ADC2_HandleType);
ADC_MultiModeTypeDef ADC_MultiMode={0};
ADC2_Channel[0].Channel=ADC_CHANNEL_3; //通道编号
ADC2_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC2_Channel[0].SamplingTime=ADC_SAMPLETIME_1CYCLE_5; //周期:
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[0]);
//配置ADC双模式:慢交叉模式
ADC_MultiMode.Mode=ADC_DUALMODE_INTERLSLOW;
HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_Calibration_Start(&ADC2_HandleType); //自校准
HAL_ADC_Start(&ADC2_HandleType);
//配置规则组
HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitType.Mode = GPIO_MODE_ANALOG; //ADC功能
HAL_GPIO_Init(GPIOA,&GPIO_InitType); //配置PA0 1 2 3 4 5 6 7
GPIO_InitType.Pin = GPIO_PIN_0|GPIO_PIN_1; //配置PIN0 1
GPIO_InitType.Mode = GPIO_MODE_ANALOG; //ADC功能
HAL_GPIO_Init(GPIOB,&GPIO_InitType); //配置PB0 1
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0); //DMA通道1的中断优先级
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); //开DMA通道1的中断
}
else if (hadc->Instance==ADC2)
{
__HAL_RCC_ADC2_CLK_ENABLE();
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint32_t i,sum;
if(hadc->Instance==ADC1)
{
sum = 0;
for(i=0;i<10;i++){
sum += DMA_buff[i];
}
printf("DMA完成中断\r\n");
printf("ADC1_IN3:%f\r\n",((sum&0x0000FFFF)/10.0)*(3.3/4096.0)); //串口1输出电压值
printf("ADC2_IN3:%f\r\n",(((sum&0xFFFF0000)>>16)/10.0)*(3.3/4096.0)); //串口1输出电压值
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_OC_InitTypeDef TIM_OC_Init={0};
HandleTIMXCHX.Instance=TIM2; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_OC_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;
TIM_OC_Init.Pulse=100; //比较值(CCR)
TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值 :PWM1:CNT<CCR输出有效电平
TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX, &TIM_OC_Init,TIM_CHANNEL_2);
HAL_TIM_OC_Start(&HandleTIMXCHX,TIM_CHANNEL_2);
}
void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM2)
{
__HAL_RCC_TIM2_CLK_ENABLE(); //打开定时器3的时钟
//信号为内部触发所以,定时器2_CH2引脚可以使用初始化
}
}
H:双ADC混合模式 ADC1 ADC2同步规则+同步注入模式
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init();
ADC2_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType; //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType; //ADC2为从模式
ADC_ChannelConfTypeDef ADC_Channel[10]; //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10]; //ADC2为从模式的通道
ADC_InjectionConfTypeDef ADC_Injection; //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection; //ADC1从模式的注入组
uint32_t DMA_buff[10];
DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
ADC_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC_Channel[6].Rank=ADC_REGULAR_RANK_7; //排名
ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);
ADC_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC_Channel[7].Rank=ADC_REGULAR_RANK_8; //排名
ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);
ADC_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC_Channel[8].Rank=ADC_REGULAR_RANK_9; //排名
ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);
ADC_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC_Channel[9].Rank=ADC_REGULAR_RANK_10; //排名
ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_EXT_IT15; //触发方式:_EXT_IT15
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
}
void ADC2_Init(void)
{
ADC2_HandleType.Instance=ADC2;
ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC2_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC2_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式
HAL_ADC_Init(&ADC2_HandleType);
ADC_MultiModeTypeDef ADC_MultiMode={0};
ADC2_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC2_Channel[0].Rank=ADC_REGULAR_RANK_10; //排名
ADC2_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[0]);
ADC2_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC2_Channel[1].Rank=ADC_REGULAR_RANK_9; //排名
ADC2_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[1]);
ADC2_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC2_Channel[2].Rank=ADC_REGULAR_RANK_8; //排名
ADC2_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[2]);
ADC2_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC2_Channel[3].Rank=ADC_REGULAR_RANK_7; //排名
ADC2_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,& ADC2_Channel[3]);
ADC2_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC2_Channel[4].Rank=ADC_REGULAR_RANK_6; //排名
ADC2_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[4]);
ADC2_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC2_Channel[5].Rank=ADC_REGULAR_RANK_5; //排名
ADC2_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[5]);
ADC2_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC2_Channel[6].Rank=ADC_REGULAR_RANK_4; //排名
ADC2_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[6]);
ADC2_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC2_Channel[7].Rank=ADC_REGULAR_RANK_3; //排名
ADC2_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[7]);
ADC2_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC2_Channel[8].Rank=ADC_REGULAR_RANK_2; //排名
ADC2_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[8]);
ADC2_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC2_Channel[9].Rank=ADC_REGULAR_RANK_1; //排名
ADC2_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[9]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC2_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
ADC2_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC2_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC2_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC2_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START; //触发方式
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//配置ADC双模式:交替触发模式
ADC_MultiMode.Mode=ADC_DUALMODE_REGSIMULT_INJECSIMULT;
HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);
HAL_ADCEx_Calibration_Start(&ADC2_HandleType); //自校准
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组ADC1主模式
HAL_ADCEx_InjectedStart(&ADC2_HandleType); //中断方式开启注入组ADC2从模式
HAL_ADC_Start(&ADC2_HandleType);
//配置规则组
HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_IT_RISING; //模拟输入
GPIO_InitType.Pull=GPIO_PULLDOWN;
GPIO_InitType.Pin=GPIO_PIN_15;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
else if (hadc->Instance==ADC2)
{
__HAL_RCC_ADC2_CLK_ENABLE();
HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
void ADC1_2_IRQHandler(void)
{
HAL_ADC_IRQHandler(&ADC_HandleType);
}
//ADC的DMA的完成中断回调
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1){ //判断是不是ADC1进入的中断回调
printf("DMA完成中断\r\n");
printf("ADC1_IN0:%d\r\n",DMA_buff[0]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN1:%d\r\n",DMA_buff[1]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN2:%d\r\n",DMA_buff[2]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN3:%d\r\n",DMA_buff[3]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN4:%d\r\n",DMA_buff[4]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN5:%d\r\n",DMA_buff[5]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN6:%d\r\n",DMA_buff[6]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN7:%d\r\n",DMA_buff[7]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN8:%d\r\n",DMA_buff[8]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN9:%d\r\n",DMA_buff[9]&0x0000FFFF); //串口1输出电压值
printf("----------------------------------------\r\n");
printf("ADC2_IN9:%d\r\n",(DMA_buff[0]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN8:%d\r\n",(DMA_buff[1]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN7:%d\r\n",(DMA_buff[2]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN6:%d\r\n",(DMA_buff[3]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN5:%d\r\n",(DMA_buff[4]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN4:%d\r\n",(DMA_buff[5]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN3:%d\r\n",(DMA_buff[6]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN2:%d\r\n",(DMA_buff[7]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN1:%d\r\n",(DMA_buff[8]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN0:%d\r\n",(DMA_buff[9]&0xFFFF0000)>>16); //串口1输出电压值
}
}
//注入组完成中断
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1){
printf("---------------------------------------------ADC1注入组完成\r\n");
printf("ADC1_IN4:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_1)); //串口1输出电压值
printf("ADC1_IN5:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_2)); //串口1输出电压值
printf("ADC1_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_3)); //串口1输出电压值
printf("ADC1_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_4)); //串口1输出电压值
printf("---------------------------------------------ADC2注入组完成\r\n");
printf("ADC2_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_1)); //串口1输出电压值
printf("ADC2_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_2)); //串口1输出电压值
printf("ADC2_IN5:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_3)); //串口1输出电压值
printf("ADC2_IN4:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_4)); //串口1输出电压值
//__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
}
}
I:双ADC混合模式 ADC1 ADC2同步规则+交替注入模式
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
ADC1_Init();
ADC2_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType; //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType; //ADC2为从模式
ADC_ChannelConfTypeDef ADC_Channel[10]; //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10]; //ADC2为从模式的通道
ADC_InjectionConfTypeDef ADC_Injection; //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection; //ADC1从模式的注入组
uint32_t DMA_buff[10];
DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
ADC_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC_Channel[1].Rank=ADC_REGULAR_RANK_2; //排名
ADC_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[1]);
ADC_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[2].Rank=ADC_REGULAR_RANK_3; //排名
ADC_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[2]);
ADC_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC_Channel[3].Rank=ADC_REGULAR_RANK_4; //排名
ADC_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,& ADC_Channel[3]);
ADC_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC_Channel[4].Rank=ADC_REGULAR_RANK_5; //排名
ADC_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[4]);
ADC_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC_Channel[5].Rank=ADC_REGULAR_RANK_6; //排名
ADC_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[5]);
ADC_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC_Channel[6].Rank=ADC_REGULAR_RANK_7; //排名
ADC_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[6]);
ADC_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC_Channel[7].Rank=ADC_REGULAR_RANK_8; //排名
ADC_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[7]);
ADC_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC_Channel[8].Rank=ADC_REGULAR_RANK_9; //排名
ADC_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[8]);
ADC_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC_Channel[9].Rank=ADC_REGULAR_RANK_10; //排名
ADC_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[9]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_EXT_IT15; //触发方式:_EXT_IT15
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
}
void ADC2_Init(void)
{
ADC2_HandleType.Instance=ADC2;
ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC2_HandleType.Init.NbrOfConversion=10; //扫描模式下规则组的数量
ADC2_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式
HAL_ADC_Init(&ADC2_HandleType);
ADC_MultiModeTypeDef ADC_MultiMode={0};
ADC2_Channel[0].Channel=ADC_CHANNEL_0; //通道编号
ADC2_Channel[0].Rank=ADC_REGULAR_RANK_10; //排名
ADC2_Channel[0].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[0]);
ADC2_Channel[1].Channel=ADC_CHANNEL_1; //通道编号
ADC2_Channel[1].Rank=ADC_REGULAR_RANK_9; //排名
ADC2_Channel[1].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[1]);
ADC2_Channel[2].Channel=ADC_CHANNEL_2; //通道编号
ADC2_Channel[2].Rank=ADC_REGULAR_RANK_8; //排名
ADC2_Channel[2].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[2]);
ADC2_Channel[3].Channel=ADC_CHANNEL_3; //通道编号
ADC2_Channel[3].Rank=ADC_REGULAR_RANK_7; //排名
ADC2_Channel[3].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,& ADC2_Channel[3]);
ADC2_Channel[4].Channel=ADC_CHANNEL_4; //通道编号
ADC2_Channel[4].Rank=ADC_REGULAR_RANK_6; //排名
ADC2_Channel[4].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[4]);
ADC2_Channel[5].Channel=ADC_CHANNEL_5; //通道编号
ADC2_Channel[5].Rank=ADC_REGULAR_RANK_5; //排名
ADC2_Channel[5].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[5]);
ADC2_Channel[6].Channel=ADC_CHANNEL_6; //通道编号
ADC2_Channel[6].Rank=ADC_REGULAR_RANK_4; //排名
ADC2_Channel[6].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[6]);
ADC2_Channel[7].Channel=ADC_CHANNEL_7; //通道编号
ADC2_Channel[7].Rank=ADC_REGULAR_RANK_3; //排名
ADC2_Channel[7].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[7]);
ADC2_Channel[8].Channel=ADC_CHANNEL_8; //通道编号
ADC2_Channel[8].Rank=ADC_REGULAR_RANK_2; //排名
ADC2_Channel[8].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[8]);
ADC2_Channel[9].Channel=ADC_CHANNEL_9; //通道编号
ADC2_Channel[9].Rank=ADC_REGULAR_RANK_1; //排名
ADC2_Channel[9].SamplingTime=ADC_SAMPLETIME_41CYCLES_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[9]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC2_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
ADC2_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC2_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC2_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC2_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START; //触发方式
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//配置ADC双模式:混合的同步规则+交替触发模式
ADC_MultiMode.Mode=ADC_DUALMODE_REGSIMULT_ALTERTRIG;
HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);
HAL_ADCEx_Calibration_Start(&ADC2_HandleType); //自校准
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组ADC1主模式
HAL_ADCEx_InjectedStart_IT(&ADC2_HandleType); //中断方式开启注入组ADC2从模式
HAL_ADC_Start(&ADC2_HandleType);
//配置规则组
HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_IT_RISING; //模拟输入
GPIO_InitType.Pull=GPIO_PULLDOWN;
GPIO_InitType.Pin=GPIO_PIN_15;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
else if (hadc->Instance==ADC2)
{
__HAL_RCC_ADC2_CLK_ENABLE();
HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
void ADC1_2_IRQHandler(void)
{
HAL_ADC_IRQHandler(&ADC_HandleType);
HAL_ADC_IRQHandler(&ADC2_HandleType);
}
//ADC的DMA的完成中断回调
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1){ //判断是不是ADC1进入的中断回调
printf("DMA完成中断\r\n");
printf("ADC1_IN0:%d\r\n",DMA_buff[0]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN1:%d\r\n",DMA_buff[1]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN2:%d\r\n",DMA_buff[2]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN3:%d\r\n",DMA_buff[3]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN4:%d\r\n",DMA_buff[4]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN5:%d\r\n",DMA_buff[5]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN6:%d\r\n",DMA_buff[6]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN7:%d\r\n",DMA_buff[7]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN8:%d\r\n",DMA_buff[8]&0x0000FFFF); //串口1输出电压值
printf("ADC1_IN9:%d\r\n",DMA_buff[9]&0x0000FFFF); //串口1输出电压值
printf("----------------------------------------\r\n");
printf("ADC2_IN9:%d\r\n",(DMA_buff[0]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN8:%d\r\n",(DMA_buff[1]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN7:%d\r\n",(DMA_buff[2]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN6:%d\r\n",(DMA_buff[3]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN5:%d\r\n",(DMA_buff[4]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN4:%d\r\n",(DMA_buff[5]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN3:%d\r\n",(DMA_buff[6]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN2:%d\r\n",(DMA_buff[7]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN1:%d\r\n",(DMA_buff[8]&0xFFFF0000)>>16); //串口1输出电压值
printf("ADC2_IN0:%d\r\n",(DMA_buff[9]&0xFFFF0000)>>16); //串口1输出电压值
}
}
//注入组完成中断
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1){
printf("---------------------------------------------ADC1注入组完成\r\n");
printf("ADC1_IN4:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_1)); //串口1输出电压值
printf("ADC1_IN5:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_2)); //串口1输出电压值
printf("ADC1_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_3)); //串口1输出电压值
printf("ADC1_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_4)); //串口1输出电压值
//__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
}
else if(hadc->Instance == ADC2)
{
printf("---------------------------------------------ADC2注入组完成\r\n");
printf("ADC2_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_1)); //串口1输出电压值
printf("ADC2_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_2)); //串口1输出电压值
printf("ADC2_IN5:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_3)); //串口1输出电压值
printf("ADC2_IN4:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_4)); //串口1输出电压值
__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
}
}
H:双ADC混合模式 ADC1 ADC2同步注入+交叉模式
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
IC_TIMX_CHX_init(2000-1,7200-1); //T=((ARR+1)*(PSC+1)) / T=0.2S 0.2*10=2S
ADC1_Init();
ADC2_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_HandleTypeDef ADC_HandleType; //ADC1为主模式
ADC_HandleTypeDef ADC2_HandleType; //ADC2为从模式
ADC_ChannelConfTypeDef ADC_Channel[10]; //ADC1为主模式的通道
ADC_ChannelConfTypeDef ADC2_Channel[10]; //ADC2为从模式的通道
ADC_InjectionConfTypeDef ADC_Injection; //ADC1主模式的注入组
ADC_InjectionConfTypeDef ADC2_Injection; //ADC1从模式的注入组
uint32_t DMA_buff[10];
DMA_HandleTypeDef DMA_Handle;
void ADC1_Init(void)
{
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=1; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC_HandleType.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T2_CC2;//触发方式
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_2; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_1CYCLE_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
ADC_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC_Injection.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_EXT_IT15; //触发方式:_EXT_IT15
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
//注入组配置
ADC_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC_HandleType,&ADC_Injection);
}
void ADC2_Init(void)
{
ADC2_HandleType.Instance=ADC2;
ADC2_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC2_HandleType.Init.ScanConvMode=ADC_SCAN_ENABLE; //扫描模式:使能
ADC2_HandleType.Init.NbrOfConversion=1; //扫描模式下规则组的数量
ADC2_HandleType.Init.ContinuousConvMode=DISABLE; //连续模式: 使能
ADC2_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
ADC2_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式
HAL_ADC_Init(&ADC2_HandleType);
ADC_MultiModeTypeDef ADC_MultiMode={0};
ADC2_Channel[0].Channel=ADC_CHANNEL_2; //通道编号
ADC2_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC2_Channel[0].SamplingTime=ADC_SAMPLETIME_1CYCLE_5; //周期:41.5个 41.5+12.5=54个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC2_HandleType,&ADC2_Channel[0]);
//注入组配置---配置为自动注入
//自动注入和外部触发不可能共存
ADC2_Injection.InjectedChannel=ADC_CHANNEL_6; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_4; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
ADC2_Injection.InjectedNbrOfConversion=4; //注入组的转化通道:max=4
ADC2_Injection.InjectedDiscontinuousConvMode=DISABLE; //注入组间断模式;不可能同时使用自动注入和间断模式
ADC2_Injection.AutoInjectedConv=DISABLE; //自动注入
ADC2_Injection.ExternalTrigInjecConv=ADC_INJECTED_SOFTWARE_START; //触发方式
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_7; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_3; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_8; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_2; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//注入组配置
ADC2_Injection.InjectedChannel=ADC_CHANNEL_9; //需要配置的通道
ADC2_Injection.InjectedRank=ADC_INJECTED_RANK_1; //注入组的排名
ADC2_Injection.InjectedSamplingTime=ADC_SAMPLETIME_41CYCLES_5; //采用周期
ADC2_Injection.InjectedOffset=0; //偏移量
HAL_ADCEx_InjectedConfigChannel(&ADC2_HandleType,&ADC2_Injection);
//配置ADC双模式:同步注入+规则组快速交叉
ADC_MultiMode.Mode=ADC_DUALMODE_INJECSIMULT_INTERLFAST;
HAL_ADCEx_MultiModeConfigChannel(&ADC_HandleType,&ADC_MultiMode);
HAL_ADCEx_Calibration_Start(&ADC2_HandleType); //自校准
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
HAL_ADCEx_InjectedStart_IT(&ADC_HandleType); //中断方式开启注入组ADC1主模式
HAL_ADCEx_InjectedStart(&ADC2_HandleType); //中断方式开启注入组ADC2从模式
HAL_ADC_Start(&ADC2_HandleType);
//配置规则组
HAL_ADCEx_MultiModeStart_DMA(&ADC_HandleType,DMA_buff,10);//双adc下使用这个API配置主adc
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitType;
//模拟输入不用设置上下拉电阻
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4/
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_ANALOG; //模拟输入
GPIO_InitType.Pin=GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
GPIO_InitType.Mode=GPIO_MODE_IT_RISING; //模拟输入
GPIO_InitType.Pull=GPIO_PULLDOWN;
GPIO_InitType.Pin=GPIO_PIN_15;
HAL_GPIO_Init(GPIOB,&GPIO_InitType);
HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_WORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,4,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
else if (hadc->Instance==ADC2)
{
__HAL_RCC_ADC2_CLK_ENABLE();
HAL_NVIC_SetPriority(ADC1_2_IRQn,4,0); //ADC的中断优先级
HAL_NVIC_EnableIRQ(ADC1_2_IRQn); //开ADC的中断
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
void ADC1_2_IRQHandler(void)
{
HAL_ADC_IRQHandler(&ADC_HandleType);
}
//ADC的DMA的完成中断回调
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint32_t sum,i;
if(hadc->Instance == ADC1){ //判断是不是ADC1进入的中断回调
sum=0;
for(i=0;i<10;i++)
{
sum+=DMA_buff[i];
}
printf("DMA完成中断\r\n");
printf("ADC1_IN2:%f\r\n",((sum&0x0000FFFF)/10.0)*(3.3/4096)); //串口1输出电压值
printf("----------------------------------------\r\n");
printf("ADC2_IN2:%f\r\n",(((sum&0xFFFF0000)>>16)/10.0)*(3.3/4096)); //串口1输出电压值
}
}
//注入组完成中断
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance == ADC1){
printf("---------------------------------------------ADC1注入组完成\r\n");
printf("ADC1_IN4:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_1)); //串口1输出电压值
printf("ADC1_IN5:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_2)); //串口1输出电压值
printf("ADC1_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_3)); //串口1输出电压值
printf("ADC1_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC_HandleType,ADC_INJECTED_RANK_4)); //串口1输出电压值
printf("---------------------------------------------ADC2注入组完成\r\n");
printf("ADC2_IN7:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_1)); //串口1输出电压值
printf("ADC2_IN6:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_2)); //串口1输出电压值
printf("ADC2_IN5:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_3)); //串口1输出电压值
printf("ADC2_IN4:%d\r\n",(int16_t)HAL_ADCEx_InjectedGetValue(&ADC2_HandleType,ADC_INJECTED_RANK_4)); //串口1输出电压值
//__HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
}
}
#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "ADC.h"
//输入捕获功能
TIM_HandleTypeDef HandleTIMXCHX;
//TIM1的CC1事件
void IC_TIMX_CHX_init(uint16_t arr,uint16_t psc)
{
TIM_OC_InitTypeDef TIM_OC_Init={0};
HandleTIMXCHX.Instance=TIM2; //基地址
HandleTIMXCHX.Init.Period=arr;
HandleTIMXCHX.Init.Prescaler=psc;
HandleTIMXCHX.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数
HandleTIMXCHX.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //设置自动重载值 预装载使能位
HandleTIMXCHX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置分频因子
HAL_TIM_OC_Init(&HandleTIMXCHX);
//清除跟新中断标志位
__HAL_TIM_CLEAR_FLAG(&HandleTIMXCHX,TIM_FLAG_UPDATE);
TIM_OC_Init.OCMode=TIM_OCMODE_PWM1;
TIM_OC_Init.Pulse=100; //比较值(CCR)
TIM_OC_Init.OCPolarity=TIM_OCPOLARITY_LOW;//有效值 :PWM1:CNT<CCR输出有效电平
TIM_OC_Init.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_OC_ConfigChannel(&HandleTIMXCHX, &TIM_OC_Init,TIM_CHANNEL_2);
HAL_TIM_OC_Start(&HandleTIMXCHX,TIM_CHANNEL_2);
}
void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM2)
{
__HAL_RCC_TIM2_CLK_ENABLE(); //打开定时器3的时钟
//信号为内部触发所以,定时器2_CH2引脚可以使用初始化
HAL_NVIC_SetPriority(TIM2_IRQn,3,0); //定时器3的中断优先级
HAL_NVIC_EnableIRQ(TIM2_IRQn); //开定时器3的中断
}
}
因为扫描模式是对于规则组和注入组共有的,注入组开启了4个通道,所有必须开启扫描模式。
温度传感器
int main(void)
{
uint8_t res=0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
Uart_Init(115200);
//IC_TIMX_CHX_init(0xFFFF,36000-1);
ADC1_Init();
while (1)
{
}
}
#include "stm32f1xx_hal.h"
#include "UART.h"
#include <stdarg.h>
#include "stdio.h"
#include "Delay.h"
#include "TIM.h"
ADC_InjectionConfTypeDef ADC_Injection; //注入组句柄
ADC_HandleTypeDef ADC_HandleType;
DMA_HandleTypeDef DMA_Handle; //DMA句柄
ADC_ChannelConfTypeDef ADC_Channel[10]; //规则组通道
uint16_t DMA_buff[10]; //储存DMA数据的内存地址
void ADC1_Init(void)
{
//规则组的配置
ADC_HandleType.Instance=ADC1;
ADC_HandleType.Init.DataAlign=ADC_DATAALIGN_RIGHT; //对齐方式:右对齐
ADC_HandleType.Init.ScanConvMode=ADC_SCAN_DISABLE; //扫描模式:使能
ADC_HandleType.Init.NbrOfConversion=0; //扫描模式下规则组的数量
ADC_HandleType.Init.ContinuousConvMode=ENABLE; //连续模式: 使能
ADC_HandleType.Init.DiscontinuousConvMode=DISABLE; //规则组的间断模式
//ADC_HandleType.Init.NbrOfDiscConversion=2; //规则组的间断模式子组的成员数量
ADC_HandleType.Init.ExternalTrigConv=ADC_SOFTWARE_START;//触发方式:软件触发
HAL_ADC_Init(&ADC_HandleType);
ADC_Channel[0].Channel=ADC_CHANNEL_16; //通道编号
ADC_Channel[0].Rank=ADC_REGULAR_RANK_1; //排名
ADC_Channel[0].SamplingTime=ADC_SAMPLETIME_239CYCLES_5; //周期:41.5个 71.5+12.5=84个
//配置规则组通道
HAL_ADC_ConfigChannel(&ADC_HandleType,&ADC_Channel[0]);
HAL_ADCEx_Calibration_Start(&ADC_HandleType); //自校准
//DMA将连续读取100个ADC转换结果并存储到DMA_buff中,并产生DMA中断。
HAL_ADC_Start_DMA(&ADC_HandleType,(uint32_t*)DMA_buff,10);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
//DMA配置:方向寄存器(外设)-->数组(内存)
DMA_Handle.Instance=DMA1_Channel1;
DMA_Handle.Init.Direction=DMA_PERIPH_TO_MEMORY; //传输方向:寄存器(外设)->数组(内存)
DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE; //寄存器(外设)是否递增加
DMA_Handle.Init.MemInc=DMA_MINC_ENABLE; //数组(内存)是否递增加
DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据宽度(半字=2个字节)
DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //数组(内存)数据宽度
DMA_Handle.Init.Mode=DMA_CIRCULAR; //模式:循环
DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;
//__HAL_LINKDMA(hadc,DMA_Handle,DMA_Handle); //或者下面的写法
__HAL_LINKDMA(&ADC_HandleType,DMA_Handle,DMA_Handle); //链接
//DMA的配置
HAL_DMA_Init(&DMA_Handle);
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
}
void DMA1_Channel1_IRQHandler()
{
HAL_DMA_IRQHandler(&DMA_Handle);
}
//DMA将连续读取10个ADC转换结果并存储到DMA_buff中,后进入中断
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
uint32_t sum,i;
float temperature;
if(hadc->Instance==ADC1)
{
sum=0;
for(i=0;i<10;i++)
{
sum+=DMA_buff[i];
}
printf("DMA完成中断\r\n");
printf("ADC1_IN6的电压为:%f V \r\n",((sum/10.0)*(3.3/4096.0))); //串口1输出数字量
printf("温度为:%f \r\n",(1.43-((sum/10.0)*(3.3/4096.0)))/4.3+25.0); //串口1输出数字量
}
}