久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 1104|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

adc_dma進(jìn)行采集時(shí)打印數(shù)據(jù)為0,不開(kāi)dma數(shù)據(jù)能夠正常顯示,想問(wèn)一下是什么原因

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主

  1. /**
  2. ****************************************************************************************************
  3. * @file        adc.c
  4. * @author      正點(diǎn)原子團(tuán)隊(duì)(ALIENTEK)
  5. * @version     V1.3
  6. * @date        2020-04-24
  7. * @brief       ADC 驅(qū)動(dòng)代碼
  8. * @license     Copyright (c) 2020-2032, 廣州市星翼電子科技有限公司
  9. ****************************************************************************************************
  10. * @attention

  11. *
  12. * 修改說(shuō)明
  13. * V1.0 20200423
  14. * 第一次發(fā)布
  15. * V1.1 20200423
  16. * 1,支持ADC單通道DMA采集
  17. * 2,新增adc_dma_init和adc_dma_enable函數(shù).
  18. * V1.2 20200423
  19. * 1,支持ADC多通道DMA采集
  20. * 2,新增adc_nch_dma_init函數(shù).
  21. * V1.3 20200424
  22. * 1,支持內(nèi)部溫度傳感器溫度采集
  23. * 2,新增adc_temperature_init和adc_get_temperature函數(shù).
  24. *
  25. ****************************************************************************************************
  26. */

  27. #include "./BSP/ADC/adc.h"
  28. //#include "./BSP/DMA/dma.h"
  29. #include "./SYSTEM/delay/delay.h"
  30. #include "./SYSTEM/usart/usart.h"


  31. ADC_HandleTypeDef g_adc_handle;   /* ADC句柄 */
  32. DMA_HandleTypeDef g_dma_adc_handle;     /* 與ADC關(guān)聯(lián)的DMA句柄 */
  33. uint8_t g_adc_dma_sta = 0;              /* DMA傳輸狀態(tài)標(biāo)志, 0,未完成; 1, 已完成 */


  34. uint16_t g_adc_value[ADC_CH_NUM * ADC_COLL] = {0};  /* 存儲(chǔ)ADC原始值 */
  35. //float g_adc_u_value[ADC_CH_NUM] = {0};              /* 存儲(chǔ)ADC轉(zhuǎn)換后的電壓值 */

  36. /********************************************************************/
  37. /**
  38. * @brief       ADC初始化函數(shù)
  39. *   @note      本函數(shù)支持ADC1/ADC2任意通道, 但是不支持ADC3
  40. *              我們使用12位精度, ADC采樣時(shí)鐘=12M, 轉(zhuǎn)換時(shí)間為: 采樣周期 + 12.5個(gè)ADC周期
  41. *              設(shè)置最大采樣周期: 239.5, 則轉(zhuǎn)換時(shí)間 = 252 個(gè)ADC周期 = 21us
  42. * @param       無(wú)
  43. * @retval      無(wú)
  44. */
  45. void adc_init(void)
  46. {
  47.    ADC_ChannelConfTypeDef sConfig = {0};
  48.          
  49.          g_adc_handle.Instance = ADC_ADCX;
  50.          g_adc_handle.Init.ContinuousConvMode = ENABLE;
  51.          g_adc_handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  52.          g_adc_handle.Init.DiscontinuousConvMode = DISABLE;
  53.          g_adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  54.          g_adc_handle.Init.NbrOfConversion =  ADC_CH_NUM;
  55.          g_adc_handle.Init.NbrOfDiscConversion = 0;
  56.          g_adc_handle.Init.ScanConvMode = ENABLE;
  57.          HAL_ADC_Init(&g_adc_handle);
  58.          
  59.          HAL_ADCEx_Calibration_Start(&g_adc_handle);//ADC校準(zhǔn)

  60.          
  61.          sConfig.Channel = ADC_ADCX_CH4;
  62.          sConfig.Rank = 1;
  63.          sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
  64.          HAL_ADC_ConfigChannel(&g_adc_handle,&sConfig);
  65.          
  66.          sConfig.Channel = ADC_ADCX_CH5;
  67.          sConfig.Rank = 2;
  68.          sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
  69.          HAL_ADC_ConfigChannel(&g_adc_handle,&sConfig);
  70.          
  71.         __HAL_LINKDMA(&g_adc_handle, DMA_Handle ,g_dma_adc_handle);
  72.          
  73.          
  74. //                        HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,3,3);
  75. //                        HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
  76. //                        
  77. //      HAL_DMA_Start_IT(&g_dma_adc_handle, (uint32_t)&ADC1->DR, (uint32_t)g_adc_value, ADC_CH_NUM * ADC_COLL);
  78. //                        HAL_ADC_Start_DMA(&g_adc_handle,(uint32_t *)g_adc_value,ADC_CH_NUM * ADC_COLL);
  79. }



  80. void adc_dma_init(void)
  81. {
  82.     if ((uint32_t)ADC_ADCX_DMACx > (uint32_t)DMA1_Channel7)     /* 大于DMA1_Channel7, 則為DMA2的通道了 */
  83.     {
  84.         __HAL_RCC_DMA2_CLK_ENABLE();                            /* DMA2時(shí)鐘使能 */
  85.     }
  86.     else
  87.     {
  88.         __HAL_RCC_DMA1_CLK_ENABLE();                            /* DMA1時(shí)鐘使能 */
  89.     }
  90.         
  91.         g_dma_adc_handle.Instance = DMA1_Channel1;
  92.         g_dma_adc_handle.Init.Direction = DMA_PERIPH_TO_MEMORY;
  93.         g_dma_adc_handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
  94.         g_dma_adc_handle.Init.MemInc = DMA_MINC_ENABLE;
  95.         g_dma_adc_handle.Init.Mode = DMA_NORMAL;
  96.         g_dma_adc_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
  97.         g_dma_adc_handle.Init.PeriphInc =  DMA_PINC_DISABLE;
  98.         g_dma_adc_handle.Init.Priority = DMA_PRIORITY_MEDIUM;
  99.         HAL_DMA_Init(&g_dma_adc_handle);
  100.         
  101. //        __HAL_LINKDMA(&g_adc_handle, DMA_Handle ,g_dma_adc_handle);
  102.         
  103.                                 
  104.                         HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,1,3);
  105.                         HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
  106.                         
  107. //      HAL_DMA_Start_IT(&g_dma_adc_handle, (uint32_t)&ADC1->DR, (uint32_t)g_adc_value, ADC_CH_NUM * ADC_COLL);
  108.                         HAL_ADC_Start_DMA(&g_adc_handle,(uint32_t *)g_adc_value,ADC_CH_NUM * ADC_COLL);
  109.                
  110. //                if (HAL_ADC_Start_DMA(&g_adc_handle, (uint32_t *)g_adc_value, ADC_CH_NUM * ADC_COLL) != HAL_OK)
  111. //{
  112. //    // 處理錯(cuò)誤
  113. //        printf("error");
  114. //}

  115. }









  116. /**
  117. * @brief       ADC底層驅(qū)動(dòng),引腳配置,時(shí)鐘使能
  118.                 此函數(shù)會(huì)被HAL_ADC_Init()調(diào)用
  119. * @param       hadc:ADC句柄
  120. * @retval      無(wú)
  121. */
  122. void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
  123. {
  124.     if(hadc->Instance == ADC_ADCX)
  125.     {
  126.         GPIO_InitTypeDef GPIO_Initure;
  127.                         
  128.         ADC_ADCX_CHY_CLK_ENABLE();  //adc時(shí)鐘
  129.                         
  130.         ADC_ADCX_CH4_GPIO_CLK_ENABLE(); /* 開(kāi)啟GPIO時(shí)鐘 */
  131.         ADC_ADCX_CH5_GPIO_CLK_ENABLE(); /* 開(kāi)啟GPIO時(shí)鐘 */
  132.                         

  133.         /* AD采集引腳模式設(shè)置,模擬輸入 */
  134.         GPIO_Initure.Pin = ADC_ADCX_CH4_GPIO_PIN;        
  135.         GPIO_Initure.Mode = GPIO_MODE_ANALOG;
  136.         GPIO_Initure.Pull = GPIO_PULLUP;      
  137.         HAL_GPIO_Init(ADC_ADCX_CH4_GPIO_PORT, &GPIO_Initure);
  138.                         
  139.                                 /* AD采集引腳模式設(shè)置,模擬輸入 */
  140.         GPIO_Initure.Pin = ADC_ADCX_CH5_GPIO_PIN;        
  141.         GPIO_Initure.Mode = GPIO_MODE_ANALOG;
  142.         GPIO_Initure.Pull = GPIO_PULLUP;      
  143.         HAL_GPIO_Init(ADC_ADCX_CH5_GPIO_PORT, &GPIO_Initure);
  144.                         
  145.                         
  146.                         //ADC時(shí)鐘初始化
  147.                         RCC_PeriphCLKInitTypeDef adc_clk_init = {0};
  148.                         adc_clk_init.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  149.                         adc_clk_init.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  150.                         HAL_RCCEx_PeriphCLKConfig(&adc_clk_init);

  151.     }
  152. }




  153. void ADC_ADCX_DMASX_IRQHandler(void)
  154. {
  155.         HAL_DMA_IRQHandler(&g_dma_adc_handle);
  156.   g_adc_dma_sta = 1;  // 標(biāo)記DMA傳輸完成
  157. }


  158. uint16_t g_adc_val[ADC_CH_NUM];


  159. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
  160. {
  161.         uint32_t temp;
  162.         if(hadc->Instance == ADC_ADCX)
  163.         {
  164.                
  165. //                print_adc_values();
  166.                 HAL_ADC_Stop_DMA(hadc);
  167.                 calc_adc_val(g_adc_val);
  168.                 HAL_ADC_Start_DMA(&g_adc_handle,(uint32_t *)&g_adc_value,ADC_SUM);
  169.   }
  170. }


  171. //void print_adc_values(void)
  172. //{
  173. //    // 確保在打印之前進(jìn)行數(shù)據(jù)校驗(yàn),例如檢查數(shù)據(jù)個(gè)數(shù)和有效性
  174. //    for (int i = 0; i < ADC_CH_NUM * ADC_COLL; i++)
  175. //    {
  176. //        // 確認(rèn)數(shù)組中的數(shù)據(jù)是否有效
  177. //        if (g_adc_value[i] != 0) // 例如,不等于0表示有效
  178. //        {
  179. //            printf("g_adc_value[%d]: %u\r\n", i, g_adc_value[i]);
  180. //        }
  181. //    }
  182. //}




  183. /**
  184. * @brief       獲取通道ch的轉(zhuǎn)換值,取times次, 然后平均
  185. * @param       ch: 通道號(hào), 0~17
  186. * @retval      通道ch的times次轉(zhuǎn)換結(jié)果平均值
  187. */
  188. uint32_t adc_get_result_average(uint8_t ch)
  189. {
  190.         uint32_t temp_val = 0;
  191.         uint16_t t;
  192.         
  193.         for(t = ch; t < ADC_SUM; t += ADC_CH_NUM)
  194.         {
  195.                 temp_val += g_adc_value[t];
  196.         }
  197.         
  198.         return temp_val / ADC_COLL;
  199. }


  200. /**
  201. * @brief       計(jì)算ADC的平均值(濾波)
  202. * @param       * p :存放ADC值的指針地址
  203. * @note        此函數(shù)對(duì)電壓、溫度、電流對(duì)應(yīng)的ADC值進(jìn)行濾波
  204. * @retval      無(wú)
  205. */
  206. void calc_adc_val(uint16_t * p)
  207. {
  208.     uint32_t temp[ADC_CH_NUM] = {0,0};            /* 定義一個(gè)緩存數(shù)組 */
  209.     int i,j;
  210.     for(i = 0; i < ADC_COLL; i++)                   /* 循環(huán)采集ADC_COLL次數(shù) */
  211.     {
  212.         for(j = 0; j < ADC_CH_NUM; j++)             /* 根據(jù)ADC通道數(shù)循環(huán)獲取,并累加 */
  213.         {
  214.             temp[j] += g_adc_value[j+i*ADC_CH_NUM]; /* 將采集到的ADC值,各通道進(jìn)行累加 */
  215.         }
  216.     }
  217.     for(j = 0; j < ADC_CH_NUM; j++)
  218.     {
  219.         temp[j] /= ADC_COLL;                        /* 獲取平均值 */
  220.         p[j] = temp[j];                             /* 存到*p */
  221.     }
  222. }













  223. /**
  224. ****************************************************************************************************
  225. * @file        main.c
  226. * @author      正點(diǎn)原子團(tuán)隊(duì)(ALIENTEK)
  227. * @version     V1.0
  228. * @date        2020-04-24
  229. * @brief       SPI 實(shí)驗(yàn)
  230. * @license     Copyright (c) 2020-2032, 廣州市星翼電子科技有限公司
  231. ****************************************************************************************************
  232. * @attention
  233. *
  234. * 實(shí)驗(yàn)平臺(tái):正點(diǎn)原子 STM32F103開(kāi)發(fā)板
  235. *
  236. ****************************************************************************************************
  237. */

  238. #include "./SYSTEM/sys/sys.h"
  239. #include "./SYSTEM/usart/usart.h"
  240. #include "./SYSTEM/delay/delay.h"
  241. #include "./USMART/usmart.h"
  242. #include "./BSP/LED/led.h"
  243. #include "./BSP/LCD/lcd.h"
  244. #include "./BSP/KEY/key.h"
  245. #include "./BSP/NORFLASH/norflash.h"

  246. #include "./BSP/SPI/spi.h"
  247. #include "./BSP/ICM42688/icm42688.h"

  248. #include "./BSP/ESP8266USART/esp8266usart.h"
  249. #include "./BSP/ESP8266/esp8266.h"


  250. #include "./BSP/ADC/adc.h"


  251. //int time=50;
  252. int8_t accel1[3];
  253. int16_t accel[3];
  254. int16_t gyro[3];
  255. int16_t adc_result[ADC_CH_NUM];
  256. //uint8_t ret;

  257. uint8_t *frame = NULL;
  258. uint8_t result;

  259. extern uint16_t g_adc_value[ADC_CH_NUM * ADC_COLL] ;
  260. extern uint16_t g_adc_val[ADC_CH_NUM];
  261. extern uint8_t g_adc_dma_sta;
  262. extern ADC_HandleTypeDef g_adc_handle;   /* ADC句柄 */

  263. int main(void)
  264. {


  265.     HAL_Init();                         /* 初始化HAL庫(kù) */
  266.     sys_stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時(shí)鐘, 72Mhz */
  267.     delay_init(72);                     /* 延時(shí)初始化 */
  268.     usart_init(115200);                 /* 串口初始化為115200 */
  269. //    usmart_dev.init(72);                /* 初始化USMART */
  270. //    led_init();                         /* 初始化LED */

  271. //    key_init();                         /* 初始化按鍵 */

  272.         
  273.           spi2_init();
  274.           Icm42688_Init();
  275. //          ICM42688_Connect();
  276.         
  277.           esp8266_uart_init(115200);
  278.         
  279.           adc_init();
  280.     adc_dma_init();



  281. //

  282. //    // 等待DMA傳輸完成
  283. //    while (!g_adc_dma_sta)
  284. //    {
  285. //        // 等待DMA傳輸完成
  286. //        printf("Waiting for DMA transfer to complete...\r\n");
  287. //    }

  288. //    // 輸出第一個(gè)ADC值
  289. //    printf("g_adc_value[0]:%d\r\n", g_adc_value[0]);






  290. //    ESP8266_EN(0);
  291. //                result = esp8266_Init(115200);
  292. //                printf("result:%d\r\n",result);
  293. //           result = esp8266_send_at_cmd("AT","OK",500);
  294. //                 printf("result:%d\r\n",result);
  295.         
  296.         
  297. //     連接wifi成功
  298. //           result = esp8266_join_ap("xiao","312312312");
  299. //                 printf("result:%d\r\n",result);
  300. //for(int i = 0; i < 2 ;i++)
  301. //{
  302. //   printf("g_adc_value[%d]:%u\r\n",i,g_adc_val[i]);
  303. //}
  304. //   printf("wraeyrut");
  305. //         printf("g_adc_value");
  306. //         printf("x,y:%u\r\n",g_adc_val[0]);


  307.     while (1)
  308.     {
  309.                         
  310.                 //多通道ADC轉(zhuǎn)化,沒(méi)有DMA
  311. //                uint16_t adcx;
  312. //    adcx = adc_get_result(adc_result);
  313. //                printf("adcx:%d,adcy:%d,\r\n",adc_result[0],adc_result[1]);
  314.                         

  315.                   printf("adcx:%d,adcy:%d\r\n",g_adc_val[0],g_adc_val[1]);        
  316.                         
  317.                         
  318.                         
  319.                         
  320.                         
  321.                         
  322. //                //測(cè)試串口3是否正常
  323. //                //測(cè)試串口3是否正常
  324. //                //測(cè)試串口3是否正常
  325. //                frame = esp8266_uart_rx_get_frame();
  326. //                if (frame != NULL) {
  327. //        // 處理接收到的數(shù)據(jù),這里假設(shè)我們要打印接收到的數(shù)據(jù)
  328. //    esp8266_uart_printf("Received: %s\r\n", frame);

  329. //        // 處理完之后,重置接收狀態(tài)
  330. //        esp8266_uart_rx_restart(); // 重新啟動(dòng)接收
  331. //    } else {
  332. //        // 如果沒(méi)有接收到完整數(shù)據(jù),可以選擇處理超時(shí)或者其他邏輯
  333. //        esp8266_uart_printf("No complete frame received yet.\r\n");
  334. //    }
  335.                         
  336. //                          esp8266_uart_printf("AT\r\n");
  337. //                          printf("456\r\n");
  338. //                          delay_ms(1000);
  339. //                                frame = esp8266_uart_rx_get_frame();
  340. //                          printf("frame:%s\r\n",frame);
  341. //                          printf("123\r\n");
  342.                                 
  343.                         
  344.                         
  345.                         

  346.                         //測(cè)試ICM42688
  347. //                        ICM42688_Read_Data(accel,gyro);
  348. //                        printf("gyro_x:%d   gyro_y:%d   gyro_z:%d\r\n",gyro[0],gyro[1],gyro[2]);
  349. //                        printf("accel_x:%d  accel_y:%d  accel_z:%d\r\n",accel[0],accel[1],accel[2]);
  350. //                  delay_ms(1000);
  351.                         



  352.     }
  353. }
復(fù)制代碼
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:404160 發(fā)表于 2024-10-22 10:00 | 只看該作者
調(diào)整了以下幾點(diǎn)代碼,看可否解決DMA傳輸數(shù)據(jù)為0的問(wèn)題。修改點(diǎn)包括:

1. **確保DMA和ADC的初始化順序正確**。
2. **添加調(diào)試日志,監(jiān)控DMA傳輸狀態(tài)和數(shù)據(jù)**。
3. **確保DMA中斷優(yōu)先級(jí)和中斷處理函數(shù)工作正常**。
4. **保證ADC DMA啟動(dòng)后的數(shù)據(jù)讀取流程正確**。

### 修改后的代碼如下:

```c
#include "./BSP/ADC/adc.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"

ADC_HandleTypeDef g_adc_handle;   /* ADC句柄 */
DMA_HandleTypeDef g_dma_adc_handle;     /* 與ADC關(guān)聯(lián)的DMA句柄 */
uint8_t g_adc_dma_sta = 0;              /* DMA傳輸狀態(tài)標(biāo)志, 0,未完成; 1, 已完成 */

uint16_t g_adc_value[ADC_CH_NUM * ADC_COLL] = {0};  /* 存儲(chǔ)ADC原始值 */
uint16_t g_adc_val[ADC_CH_NUM] = {0};               /* 存儲(chǔ)處理后的ADC平均值 */

/********************************************************************/
/**
* @brief       ADC初始化函數(shù)
* @retval      無(wú)
*/
void adc_init(void)
{
    ADC_ChannelConfTypeDef sConfig = {0};

    g_adc_handle.Instance = ADC_ADCX;
    g_adc_handle.Init.ContinuousConvMode = ENABLE;
    g_adc_handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    g_adc_handle.Init.DiscontinuousConvMode = DISABLE;
    g_adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
    g_adc_handle.Init.NbrOfConversion = ADC_CH_NUM;
    g_adc_handle.Init.ScanConvMode = ENABLE;
    HAL_ADC_Init(&g_adc_handle);

    HAL_ADCEx_Calibration_Start(&g_adc_handle);  // ADC校準(zhǔn)

    sConfig.Channel = ADC_ADCX_CH4;
    sConfig.Rank = 1;
    sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
    HAL_ADC_ConfigChannel(&g_adc_handle, &sConfig);

    sConfig.Channel = ADC_ADCX_CH5;
    sConfig.Rank = 2;
    sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
    HAL_ADC_ConfigChannel(&g_adc_handle, &sConfig);
}

/********************************************************************/
/**
* @brief       DMA初始化函數(shù)
* @retval      無(wú)
*/
void adc_dma_init(void)
{
    if ((uint32_t)ADC_ADCX_DMACx > (uint32_t)DMA1_Channel7)     /* 大于DMA1_Channel7, 則為DMA2的通道了 */
    {
        __HAL_RCC_DMA2_CLK_ENABLE();                            /* DMA2時(shí)鐘使能 */
    }
    else
    {
        __HAL_RCC_DMA1_CLK_ENABLE();                            /* DMA1時(shí)鐘使能 */
    }

    g_dma_adc_handle.Instance = DMA1_Channel1;
    g_dma_adc_handle.Init.Direction = DMA_PERIPH_TO_MEMORY;
    g_dma_adc_handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    g_dma_adc_handle.Init.MemInc = DMA_MINC_ENABLE;
    g_dma_adc_handle.Init.Mode = DMA_CIRCULAR;  // 設(shè)置為循環(huán)模式,確保DMA持續(xù)工作
    g_dma_adc_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    g_dma_adc_handle.Init.PeriphInc = DMA_PINC_DISABLE;
    g_dma_adc_handle.Init.Priority = DMA_PRIORITY_MEDIUM;
    HAL_DMA_Init(&g_dma_adc_handle);

    __HAL_LINKDMA(&g_adc_handle, DMA_Handle, g_dma_adc_handle);  // 關(guān)聯(lián)DMA和ADC
}

/********************************************************************/
/**
* @brief       DMA傳輸完成中斷處理函數(shù)
* @retval      無(wú)
*/
void ADC_ADCX_DMASX_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&g_dma_adc_handle);
    g_adc_dma_sta = 1;  // 標(biāo)記DMA傳輸完成
}

/********************************************************************/
/**
* @brief       ADC轉(zhuǎn)換完成回調(diào)函數(shù)
* @retval      無(wú)
*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
    if (hadc->Instance == ADC_ADCX)
    {
        HAL_ADC_Stop_DMA(hadc);  // 停止DMA,防止數(shù)據(jù)被覆蓋
        calc_adc_val(g_adc_val);  // 計(jì)算ADC平均值
        g_adc_dma_sta = 1;  // 標(biāo)記DMA傳輸完成
        HAL_ADC_Start_DMA(hadc, (uint32_t *)g_adc_value, ADC_CH_NUM * ADC_COLL);  // 重新啟動(dòng)DMA
    }
}

/********************************************************************/
/**
* @brief       計(jì)算ADC的平均值(濾波)
* @param       *p : 存放ADC值的指針地址
* @retval      無(wú)
*/
void calc_adc_val(uint16_t *p)
{
    uint32_t temp[ADC_CH_NUM] = {0};  /* 緩存數(shù)組 */
    for (int i = 0; i < ADC_COLL; i++)
    {
        for (int j = 0; j < ADC_CH_NUM; j++)
        {
            temp[j] += g_adc_value[j + i * ADC_CH_NUM];  /* 累加 */
        }
    }
    for (int j = 0; j < ADC_CH_NUM; j++)
    {
        p[j] = temp[j] / ADC_COLL;  /* 計(jì)算平均值 */
    }
}

int main(void)
{
    HAL_Init();                         /* 初始化HAL庫(kù) */
    sys_stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時(shí)鐘, 72Mhz */
    delay_init(72);                     /* 延時(shí)初始化 */
    usart_init(115200);                 /* 串口初始化為115200 */

    adc_init();  // 初始化ADC
    adc_dma_init();  // 初始化DMA

    // 啟動(dòng)DMA
    if (HAL_ADC_Start_DMA(&g_adc_handle, (uint32_t *)g_adc_value, ADC_CH_NUM * ADC_COLL) != HAL_OK)
    {
        printf("ADC DMA start failed\r\n");
    }

    while (1)
    {
        if (g_adc_dma_sta)  // DMA傳輸完成
        {
            g_adc_dma_sta = 0;  // 重置標(biāo)志位
            printf("ADC Value Channel 1: %d, Channel 2: %d\r\n", g_adc_val[0], g_adc_val[1]);
        }
    }
}
```

### 程序修改了:
1. **DMA初始化**:確保正確初始化DMA,并關(guān)聯(lián)到ADC句柄。
2. **DMA模式**:將DMA模式設(shè)置為 `DMA_CIRCULAR`,這樣DMA會(huì)持續(xù)工作,而不需要手動(dòng)重新啟動(dòng)。
3. **中斷處理**:在 `ADC_ADCX_DMASX_IRQHandler()` 中設(shè)置DMA傳輸完成標(biāo)志位,并在 `HAL_ADC_ConvCpltCallback()` 中處理傳輸完成的邏輯。
4. **ADC轉(zhuǎn)換完成處理**:在回調(diào)函數(shù) `HAL_ADC_ConvCpltCallback()` 中停止DMA、計(jì)算ADC平均值,并重新啟動(dòng)DMA。
5. **主循環(huán)**:通過(guò)輪詢(xún) `g_adc_dma_sta` 檢測(cè)DMA傳輸完成,并在主循環(huán)中打印ADC轉(zhuǎn)換后的數(shù)據(jù)。

### 調(diào)試提示:
- 在 `HAL_ADC_Start_DMA()` 后面添加錯(cuò)誤處理,確保DMA和ADC啟動(dòng)正常。
- 你可以通過(guò)串口日志查看 `g_adc_val[]` 是否有正確的值輸出。如果還存在問(wèn)題,可以進(jìn)一步調(diào)試DMA的中斷是否正確觸發(fā)。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 热久久久久| 国产91久久精品一区二区 | 欧美区在线 | 狠狠操网站 | 成年人精品视频在线观看 | 18成人在线观看 | 91看片| 精品一二区| 日韩在线免费 | 男人的天堂久久 | 狠狠干美女 | 久草视频观看 | 日本不卡一区二区三区 | 天天插天天射天天干 | 亚洲精品www久久久久久广东 | 欧美天堂在线 | 欧州一区| 成人av影院| 一区二区三区精品在线视频 | 国产色网站 | 国产一区二区自拍 | 免费黄色大片 | 欧美日韩在线视频观看 | 欧美国产一区二区 | 在线观看亚洲专区 | 9久久婷婷国产综合精品性色 | 91精品国产乱码麻豆白嫩 | 黄色a视频| 国产综合精品一区二区三区 | 亚洲精品久久久久中文字幕欢迎你 | 国产精品特级毛片一区二区三区 | 一区二区三区四区电影 | 国产91色在线 | 亚洲 | 91久久婷婷 | 日韩av免费看 | xxx视频| 日韩av第一页 | 一本色道精品久久一区二区三区 | 国产一区二区久久久 | 国产精品不卡一区 | 91免费看片|