日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32F0 定时器触发ADC,多通道采样、DMA传输数据的配置

發布時間:2025/6/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32F0 定时器触发ADC,多通道采样、DMA传输数据的配置 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 本塊代碼實現了定時器定時觸發ADC,多通道采樣,并通過DMA進行數據傳輸到內存的操作。
  • #include????"adc.h"??
  • [cpp]?view plaincopy
  • #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传输数据的配置的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。