STM32F0 定时器触发ADC,多通道采样、DMA传输数据的配置
- 本块代码实现了定时器定时触发ADC,多通道采样,并通过DMA进行数据传输到内存的操作。
- #include "adc.h"
- #define DMA_BUFFER_SIZE 6
- uint8 sample_finish = 0;
- int16 adc_dma_tab[6] = { 0 };
- uint8 sample_index = 0;
- //采样点数据
- int16 sample_1[128] = { 0 };
- int16 sample_2[128] = { 0 };
- int16 sample_3[128] = { 0 };
- int16 sample_4[128] = { 0 };
- int16 sample_5[128] = { 0 };
- int16 sample_6[128] = { 0 };
- void user_adc_init()
- {
- adc_gpio_init();
- adc_config(); // 注意此处的初始化顺序,否则采样传输的数据容易出现数据错位的结果
- adc_dma_init(); //
- adc_timer_init(); //
- }
- void adc_config()
- {
- ADC_InitTypeDef adc_init_structure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC时钟
- ADC_DeInit(ADC1); //复位ADC
- ADC_StructInit(&adc_init_structure); //初始化ADC结构体
- adc_init_structure.ADC_ContinuousConvMode = DISABLE; //禁用连续转换模式
- adc_init_structure.ADC_DataAlign = ADC_DataAlign_Right; //采样数据右对齐
- adc_init_structure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; //外部触发设置为TIM2
- adc_init_structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;//上升沿触发
- adc_init_structure.ADC_Resolution = ADC_Resolution_12b; //12位分辨率
- adc_init_structure.ADC_ScanDirection = ADC_ScanDirection_Upward;//向上扫描0-18通道
- ADC_Init(ADC1, &adc_init_structure);
- ADC_OverrunModeCmd(ADC1, ENABLE); //使能数据覆盖模式
- ADC_ChannelConfig(ADC1, ADC_Channel_0 | ADC_Channel_1 | ADC_Channel_2
- | ADC_Channel_8 | ADC_Channel_14 | ADC_Channel_15,
- ADC_SampleTime_13_5Cycles); //配置采样通道,采样时间125nS
- ADC_GetCalibrationFactor(ADC1); //使能前校准ADC
- ADC_Cmd(ADC1, ENABLE); //使能ADC1
- while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN) == RESET); //等待ADC1使能完成
- ADC_DMACmd(ADC1, ENABLE); //使能ADC_DMA
- ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular); //配置DMA请求模式为循环模式
- ADC_StartOfConversion(ADC1); //开启一次转换(必须)
- }
- void adc_gpio_init()
- {
- GPIO_InitTypeDef gpio_init_structure;
- //使能GPIO时钟
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC, ENABLE);
- GPIO_StructInit(&gpio_init_structure);
- //GPIOA //PA-0~3用作ADC
- gpio_init_structure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3);
- gpio_init_structure.GPIO_Mode = GPIO_Mode_AN; //使用附加(模拟)功能
- gpio_init_structure.GPIO_OType = GPIO_OType_PP; //推挽输出
- gpio_init_structure.GPIO_Speed = GPIO_Speed_50MHz; //Fast speed
- gpio_init_structure.GPIO_PuPd= GPIO_PuPd_UP; //上拉
- GPIO_Init(GPIOA, &gpio_init_structure);
- //GPIOB
- gpio_init_structure.GPIO_Pin = GPIO_Pin_0; //PB-0 用作ADC
- GPIO_Init(GPIOB, &gpio_init_structure);
- //GPIOC
- gpio_init_structure.GPIO_Pin = (GPIO_Pin_4 | GPIO_Pin_5); //PC-4~5用作ADC
- GPIO_Init(GPIOC, &gpio_init_structure);
- }
- void adc_dma_init()
- {
- DMA_InitTypeDef dma_init_structure;
- NVIC_InitTypeDef nvic_init_structure;
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA时钟
- nvic_init_structure.NVIC_IRQChannel = DMA1_Channel1_IRQn; //选择DMA1通道中断
- nvic_init_structure.NVIC_IRQChannelCmd = ENABLE; //中断使能
- nvic_init_structure.NVIC_IRQChannelPriority = 0; //优先级设为0
- NVIC_Init(&nvic_init_structure);
- DMA_DeInit(DMA1_Channel1); //复位DMA1_channel1
- DMA_StructInit(&dma_init_structure); //初始化DMA结构体
- dma_init_structure.DMA_BufferSize = DMA_BUFFER_SIZE; //DMA缓存数组大小设置
- dma_init_structure.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA方向:外设作为数据源
- dma_init_structure.DMA_M2M = DISABLE; //内存到内存禁用
- dma_init_structure.DMA_MemoryBaseAddr = (uint32)&adc_dma_tab[0];//缓存数据数组起始地址
- dma_init_structure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//数据大小设置为Halfword
- dma_init_structure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址递增
- dma_init_structure.DMA_Mode = DMA_Mode_Circular; //DMA循环模式,即完成后重新开始覆盖
- dma_init_structure.DMA_PeripheralBaseAddr = (uint32) &(ADC1->DR);//取值的外设地址
- dma_init_structure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设取值大小设置为Halfword
- dma_init_structure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址递增禁用
- dma_init_structure.DMA_Priority = DMA_Priority_High; //DMA优先级设置为高
- DMA_Init(DMA1_Channel1, &dma_init_structure);
- DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); //使能DMA中断
- DMA_ClearITPendingBit(DMA_IT_TC); //清除一次DMA中断标志
- DMA_Cmd(DMA1_Channel1, ENABLE); //使能DMA1
- }
- void adc_timer_init()
- {
- TIM_TimeBaseInitTypeDef timer_init_structure;
- NVIC_InitTypeDef nvic_init_structure;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能TIM2时钟
- nvic_init_structure.NVIC_IRQChannel = TIM2_IRQn; //选择TIM2中断通道
- nvic_init_structure.NVIC_IRQChannelCmd = ENABLE; //使能TIM2中断
- nvic_init_structure.NVIC_IRQChannelPriority = 0; //优先级为0
- NVIC_Init(&nvic_init_structure);
- TIM_DeInit(TIM2); //复位TIM2
- TIM_TimeBaseStructInit(&timer_init_structure); //初始化TIMBASE结构体
- timer_init_structure.TIM_ClockDivision = TIM_CKD_DIV1; //系统时钟,不分频,48M
- timer_init_structure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
- timer_init_structure.TIM_Period = 312; //每312 uS触发一次中断,开启ADC
- timer_init_structure.TIM_Prescaler = 48-1; //计数时钟预分频,f=1M,systick=1 uS
- timer_init_structure.TIM_RepetitionCounter = 0x00; //发生0+1次update事件产生中断
- TIM_TimeBaseInit(TIM2, &timer_init_structure);
- TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //使能TIM2中断
- TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); //选择TIM2的update事件更新为触发源
- TIM_Cmd(TIM2, ENABLE); //使能TIM2
- }
- /****************************中断服务程序****************************/
- void TIM2_IRQHandler()
- {
- if(TIM_GetITStatus(TIM2, TIM_IT_Update)) //判断发生update事件中断
- {
- TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除update事件中断标志
- }
- }
- void DMA1_Channel1_IRQHandler()
- {
- if(DMA_GetITStatus(DMA_IT_TC)) //判断DMA传输完成中断
- {
- if(sample_finish == 0)
- {
- sample_1[sample_index] = adc_dma_tab[0];
- sample_2[sample_index] = adc_dma_tab[1];
- sample_3[sample_index] = adc_dma_tab[2];
- sample_4[sample_index] = adc_dma_tab[3];
- sample_5[sample_index] = adc_dma_tab[5];
- sample_6[sample_index] = adc_dma_tab[4];
- sample_index++;
- }
- if(sample_index >= 128) //注意防止数组越界导致未知错误
- {
- sample_index = 0;
- TIM_Cmd(TIM2, DISABLE); //完成周波采样,停止定时器
- DMA_Cmd(DMA1_Channel1, DISABLE); //完成周波采样,停止DMA
- sample_finish = 1; //置采样完成标志位
- }
- }
- DMA_ClearITPendingBit(DMA_IT_TC); //清除DMA中断标志位
- }
STM32F0 定时器触发ADC,多通道采样、DMA传输数据的配置相关推荐
- dma和通道的区别_STM32 定时器触发 ADC 多通道采集,DMA搬运至内存
引言 ADC 的功能是将模拟信号采样得到数字信号,而有些时候,我们需要使用到定时采样,比如在计算一个采集的波形的频率的时候,我们需要精确的知道采样频率,也就是 1 s 内采集的点数,这个时候,就需要使 ...
- STM32F4时钟触发ADC双通道采样DMA传输进行FFT+测频率+采样频率可变+显示波形(详细解读)...
此文转载自:https://blog.csdn.net/qq_45620831/article/details/110819495 写在前面的婆婆妈妈的话 本人大三,参加过数次电赛,来CSDN好久, ...
- STM32F4时钟触发ADC双通道采样DMA传输进行FFT+测频率+采样频率可变+显示波形(详细解读)
写在前面的婆婆妈妈的话(代码链接在最下方) 本人大三,参加过数次电赛,来CSDN好久, 每次都是在绝望中从这里找到了希望,每次都仿佛一个即将被怪兽打翻的小船突然被危险流浪者救起来.是众多前辈的智慧,让 ...
- STM32F103C8T6制作舵机测试仪详细图文教程 | 定时器触发ADC | DMA传输 | PWM输出 | RTC实时时钟 | USART串口输出 | OLED IIC显示
自主学习STM32已有一周,先实现一个小demo,算是给自己一个动力叭,有目标的学习收获会更多.虽然本科也修了嵌入式课程,但那种走马观花式的学习,最后真正得到的知识实在寥寥无几.个人理解,学习STM3 ...
- STM8单片机通过PWM触发ADC同步采样
在做数字开关电源开发过程中使用最多的就是PWM功能和ADC采样功能.ADC采样时采样的时间点很重要,必须在PWM输出高电平的时候取采样,这样采样出来的数据才是最准确的.在STM8单片机中,可以通过 ...
- STM8学习笔记---ADC多通道采样
STM8S003单片机ADC采样通道总共有5个,从AIN2---AIN6,多通道采样时需要将ADC转换设置为单次转换模式,每次切换采样通道后,需要重新初始化 ADC,采样结果在中断中读取. IO口初始 ...
- STM32F030 使用CUBEMX配置ADC多通道采集 DMA传输
STM32CubeMX的配置 以下为测试代码 //usart重定向,注意使用前需要包含头文件<stdio.h> int fputc(int ch, FILE *f) {HAL_UART_T ...
- 【STM32】定时器TIM触发ADC采样,DMA搬运到内存(超详细讲解)
TIM+ADC+DMA原理 一般情况下,当我们需要进行采样的时候,需要用到ADC.例如:需要对某个信号进行定时采样(也就是隔一段时间,比如说2ms). 本文提供的解决方案是:使用ADC的定时器触发AD ...
- STM8单片机ADC采样功能通过定时器触发
在使用STM8单片机的ADC功能时,读取ADC数据时一般有两种方式,一种是通常不断地读取采样标志位,来判断ADC采样是否结束,一种是通过中断的方式来通知系统采样是否结束. 有时候采样ADC数据 ...
最新文章
- zeroclipboard 粘贴板的应用示例, 兼容 Chrome、IE等多浏览器
- 安装SQL2000,挂起无法安装问题
- UVA 10594 Data Flow
- erlang精要(4)-列表及运算
- 快速准备电子设计大赛
- 红黑联盟c语言教程,1.1.2 C语言的特点
- 2013与2014之流水
- mysql往前一天同一时间_Mysql时间轴数据 获取同一天数据的前三条
- Kettle入门--作业和转换的使用
- html定位 浏览器兼容,IE6浏览器不支持固定定位(position:fixed)解决方案
- php pear mail 发送邮件,PHP用pear自带的mail类库发邮件
- 80%的销售来源于第4至11次的跟踪!
- 无法定位程序输入点于动态链接库(更新)
- visio 画箭头_visio2013中画箭头的具体操作步骤
- php一年过去多少天,php获取一年有多少天
- 南邮——计算机图像学——会动的立方体(变换)
- Bootstrap抽样和Monte Carlo思想
- 图解分布式一致性协议Paxos
- 如何查看自己的CSDN积分
- 依靠国家资源,发展人工智能