实现了定时器加DMA的等周期采集。
adc.c:
- #include "adc.h"
- #include "delay.h"
- ADC_HandleTypeDef ADC1_Handler;//ADC句柄
- DMA_HandleTypeDef ADC1DMA_Handler;
- ADC_ChannelConfTypeDef ADC1_ChanConf;
- TIM_HandleTypeDef TIM2_Handler;
- TIM_OC_InitTypeDef TIM2_CH2Handler;
- uint16_t buffer[128];
- static void MX_TIM2_Init(void)
- {
- __HAL_RCC_TIM2_CLK_ENABLE();
-
- HAL_NVIC_SetPriority(TIM2_IRQn, 1, 3);
- HAL_NVIC_EnableIRQ(TIM2_IRQn);
- TIM2_Handler.Instance = TIM2;
- TIM2_Handler.Init.Prescaler = 10800;
- TIM2_Handler.Init.CounterMode = TIM_COUNTERMODE_UP;
- TIM2_Handler.Init.Period = 20000;
- TIM2_Handler.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- HAL_TIM_PWM_Init(&TIM2_Handler);
- TIM2_CH2Handler.OCMode = TIM_OCMODE_PWM1;
- TIM2_CH2Handler.Pulse = 10000;
- TIM2_CH2Handler.OCPolarity = TIM_OCPOLARITY_HIGH;
- TIM2_CH2Handler.OCFastMode = TIM_OCFAST_DISABLE;
- HAL_TIM_PWM_ConfigChannel(&TIM2_Handler, &TIM2_CH2Handler, TIM_CHANNEL_2) ;
- __HAL_TIM_ENABLE_IT(&TIM2_Handler, TIM_IT_UPDATE);
- TIM_CCxChannelCmd(TIM2_Handler.Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
- __HAL_TIM_ENABLE(&TIM2_Handler);
- }
- void TIM2_IRQHandler(void)
- {
- HAL_TIM_IRQHandler(&TIM2_Handler);
- }
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- if (htim == (&TIM2_Handler))
- {
- printf("timer irq\r\n");
- }
- }
- void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- __HAL_RCC_TIM2_CLK_ENABLE();
- __HAL_RCC_GPIOA_CLK_ENABLE();
- GPIO_InitStruct.Pin = GPIO_PIN_1;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
- GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
- }
- //初始化ADC
- //ch: ADC_channels
- //通道值 0~16取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
- void MY_ADC_Init(void)
- {
- __HAL_RCC_DMA2_CLK_ENABLE();
- HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
- HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
- ADC1DMA_Handler.Instance = DMA2_Stream0;
- ADC1DMA_Handler.Init.Channel = DMA_CHANNEL_0;
- ADC1DMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY;
- ADC1DMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE; //外设非增量模式
- ADC1DMA_Handler.Init.MemInc = DMA_MINC_ENABLE; //存储器增量模式
- ADC1DMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; //外设数据长度:16位
- ADC1DMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; //存储器数据长度:16位
- ADC1DMA_Handler.Init.Mode = DMA_CIRCULAR; //传输一次就结束
- ADC1DMA_Handler.Init.Priority = DMA_PRIORITY_LOW; //中等优先级
- ADC1DMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE; /* 禁止FIFO*/
- HAL_DMA_Init(&ADC1DMA_Handler);
- __HAL_LINKDMA(&ADC1_Handler, DMA_Handle, ADC1DMA_Handler); //将DMA与ADC联系起来
- ADC1_Handler.Instance = ADC1;
- ADC1_Handler.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; //4分频,ADCCLK=PCLK2/4=108/4=27MHZ
- ADC1_Handler.Init.Resolution = ADC_RESOLUTION_12B; //12位模式
- ADC1_Handler.Init.ScanConvMode = ENABLE; //非扫描模式
- ADC1_Handler.Init.ContinuousConvMode = DISABLE; //关闭连续转换
- ADC1_Handler.Init.DiscontinuousConvMode = DISABLE; //禁止不连续采样模式
- ADC1_Handler.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; //使用软件触发
- ADC1_Handler.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_CC2; //软件触发
- ADC1_Handler.Init.DataAlign = ADC_DATAALIGN_RIGHT; //右对齐
- ADC1_Handler.Init.NbrOfConversion = 2; //1个转换在规则序列中 也就是只转换规则序列1
- ADC1_Handler.Init.DMAContinuousRequests = ENABLE; //关闭DMA请求
- ADC1_Handler.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
- HAL_ADC_Init(&ADC1_Handler);
- ADC1_ChanConf.Channel = ADC_CHANNEL_5; //通道
- ADC1_ChanConf.Rank = 1; //序列1
- ADC1_ChanConf.SamplingTime = ADC_SAMPLETIME_480CYCLES; //采样时间
- ADC1_ChanConf.Offset = 0;
- HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC1_ChanConf); //通道配置
- ADC1_ChanConf.Channel = ADC_CHANNEL_6; //通道
- ADC1_ChanConf.Rank = 2; //序列2
- ADC1_ChanConf.SamplingTime = ADC_SAMPLETIME_480CYCLES; //采样时间
- ADC1_ChanConf.Offset = 0;
- HAL_ADC_ConfigChannel(&ADC1_Handler, &ADC1_ChanConf); //通道配置
-
- MX_TIM2_Init();
- HAL_ADC_Start_DMA(&ADC1_Handler, (uint32_t *)buffer, 128);
- }
- //ADC底层驱动,引脚配置,时钟使能
- //此函数会被HAL_ADC_Init()调用
- //hadc:ADC句柄
- void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
- {
- GPIO_InitTypeDef GPIO_Initure;
- __HAL_RCC_ADC1_CLK_ENABLE(); //使能ADC1时钟
- __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
- GPIO_Initure.Pin = GPIO_PIN_5 | GPIO_PIN_6; //PA5
- GPIO_Initure.Mode = GPIO_MODE_ANALOG; //模拟
- GPIO_Initure.Pull = GPIO_NOPULL; //不带上下拉
- HAL_GPIO_Init(GPIOA, &GPIO_Initure);
- }
- void DMA2_Stream0_IRQHandler(void)
- {
- HAL_DMA_IRQHandler(&ADC1DMA_Handler);
- }
- void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
- {
- printf("DMA transfer complete\r\n");
- }
- void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc)
- {
- printf("DMA Half transfer complete\r\n");
- }
- void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
- {
- printf("DMA transfer error\r\n");
- }
复制代码
main.c:
- #include "sys.h"
- #include "delay.h"
- #include "usart.h"
- #include "adc.h"
- extern uint16_t buffer[128];
- void show()
- {
- int i;
- printf("\r\ndata:");
- for (i = 0; i < 128; i++)
- {
- if (i % 16 == 0) printf("\r\n");
- printf("%6d", buffer[i]);
- //buffer[i]=0;
- }
- printf("\r\n");
- }
- int main(void)
- {
- //Cache_Enable(); //打开L1-Cache
- HAL_Init(); //初始化HAL库
- Stm32_Clock_Init(432, 8, 2, 9); //设置时钟,216Mhz
- delay_init(216); //延时初始化
- uart_init(115200); //串口初始化
- printf("\r\n\r\n\r\n---------------------------------------\r\nstart\r\n");
- MY_ADC_Init(); //初始化ADC1通道5
-
- while (1)
- {
- show();
- //printf("cnt:%d\r\n",TIM2->CNT);
- delay_ms(1000);
- }
- }
复制代码
因为定时器是2s采集一次,主函数是1s打印一次,所以显示结果如下:
————————————————
版权声明:小盼你最萌哒
如有侵权请联系删除
|