1、實(shí)驗(yàn)環(huán)境
RT-Thread 4.03
STM32F407VET6
STM3F4庫(kù)版本 0.2.2
在SDK資源管理器中可以查看版本信息如下圖。(小編遇見(jiàn)過(guò)因版本不兼容出現(xiàn)的編譯錯(cuò)誤問(wèn)題)
2、創(chuàng)建RT-Thread項(xiàng)目
此時(shí)編譯結(jié)果沒(méi)有錯(cuò)誤
打開CubeMX軟件(不使用CubeMX Setting)step1:配置時(shí)鐘。step2、配置ADC+DMA。
根據(jù)自己板子晶振確定時(shí)鐘
根據(jù)ADC引腳配置
配置ADC1通道
配置DMA
ADC參數(shù)設(shè)置
生成項(xiàng)目
在RTT中如圖文件夾下新建源文件
從CubeMX生成的工程中復(fù)制如下圖函數(shù)到RTT文件中;具體代碼有所修改,可參考代碼部分
參考代碼
#include "stm32f4xx_hal.h"
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
static void MX_DMA_Init(void)
{
/* DMA controller clock enable /
__HAL_RCC_DMA2_CLK_ENABLE();
/ DMA interrupt init /
/ DMA2_Stream0_IRQn interrupt configuration /
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
void HAL_ADC_MspInit(ADC_HandleTypeDef hadc)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
MX_DMA_Init();
if(hadc->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspInit 0 /
/ USER CODE END ADC1_MspInit 0 /
/ Peripheral clock enable /
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/ADC1 GPIO Configuration
PC0 ------> ADC1_IN10
PC1 ------> ADC1_IN11
PC2 ------> ADC1_IN12
PC3 ------> ADC1_IN13
PA0-WKUP ------> ADC1_IN0
PA1 ------> ADC1_IN1
/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/ ADC1 DMA Init /
/ ADC1 Init /
hdma_adc1.Instance = DMA2_Stream0;
hdma_adc1.Init.Channel = DMA_CHANNEL_0;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_adc1);
__HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
/ USER CODE BEGIN ADC1_MspInit 1 /
/ USER CODE END ADC1_MspInit 1 /
}
}
void MX_ADC1_Init(void)
{
/ USER CODE BEGIN ADC1_Init 0 /
/ USER CODE END ADC1_Init 0 /
ADC_ChannelConfTypeDef sConfig = {0};
/ USER CODE BEGIN ADC1_Init 1 /
/ USER CODE END ADC1_Init 1 /
/ Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 6;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
HAL_ADC_Init(&hadc1);
/ Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
/ Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 2;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
/ * Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
/
sConfig.Channel = ADC_CHANNEL_13;
sConfig.Rank = 3;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
/ * Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
/
sConfig.Channel = ADC_CHANNEL_12;
sConfig.Rank = 4;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
/ * Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
/
sConfig.Channel = ADC_CHANNEL_11;
sConfig.Rank = 5;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
/ * Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
/
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = 6;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
/ USER CODE BEGIN ADC1_Init 2 /
/ USER CODE END ADC1_Init 2 /
}
void DMA2_Stream0_IRQHandler(void)
{
/ USER CODE BEGIN DMA2_Stream0_IRQn 0 /
/ USER CODE END DMA2_Stream0_IRQn 0 /
HAL_DMA_IRQHandler(&hdma_adc1);
// rt_kprintf("11111111 n");
/ USER CODE BEGIN DMA2_Stream0_IRQn 1 /
/ USER CODE END DMA2_Stream0_IRQn 1 */
}
配置RT-Thread Setting
編譯通過(guò),結(jié)果如下圖
修改drv_adc.c文件
編譯通過(guò),結(jié)果如下圖
3、添加業(yè)務(wù)測(cè)試代碼
新建user_adc.c源文件添加業(yè)務(wù)測(cè)試代碼如下
#include
#include
#include
rt_thread_t Adc_thread1= RT_NULL;
#define ADC_MAX_SAMPLE 12
#define ADC_MAX_CHANLE 6
extern ADC_HandleTypeDef hadc1;
extern rt_uint16_t value[ADC_MAX_SAMPLE][ADC_MAX_CHANLE];
rt_uint16_t ADC_ConvertedValue[ADC_MAX_SAMPLE][ADC_MAX_CHANLE];
rt_uint16_t ADC_AverageValue[ADC_MAX_CHANLE];
extern ADC_HandleTypeDef hadc1;
static void CalADC_Average(void)
{
unsigned short i, j;
unsigned short uIntMax,uIntMin,i_Max,i_Min;
unsigned int sum;
for(i=0;i<(ADC_MAX_CHANLE);i++)
{
uIntMax = ADC_ConvertedValue[0][i];
uIntMin = ADC_ConvertedValue[1][i];
i_Max = 0; i_Min = 1;
for(j=0;j if(uIntMax uIntMax=ADC_ConvertedValue[j][i];
i_Max = j;
}
if(uIntMin>ADC_ConvertedValue[j][i]){
uIntMin=ADC_ConvertedValue[j][i];
i_Min = j;
}
}
ADC_ConvertedValue[i_Max][i]=0;
ADC_ConvertedValue[i_Min][i]=0;
sum = 0;
for(j=0; j sum += ADC_ConvertedValue[j][i];
}
if(i_Min==i_Max){
ADC_AverageValue[i] = sum/(ADC_MAX_SAMPLE-1)/11.91;
}
else {
ADC_AverageValue[i] = sum/(ADC_MAX_SAMPLE-2)/11.91;
}
}
}
static void Adc_entry(void *parameter)
{
HAL_ADC_Start_DMA(&hadc1, ADC_ConvertedValue, (uint32_t)(ADC_MAX_SAMPLE * ADC_MAX_CHANLE));
while (1)
{
CalADC_Average();
rt_kprintf("/************************/n");
rt_kprintf("avg0 is :%d n",ADC_AverageValue[0]);
rt_kprintf("avg1 is :%d n",ADC_AverageValue[1]);
rt_kprintf("avg2 is :%d n",ADC_AverageValue[2]);
rt_kprintf("avg3 is :%d n",ADC_AverageValue[3]);
rt_kprintf("avg4 is :%d n",ADC_AverageValue[4]);
rt_kprintf("avg5 is :%d n",ADC_AverageValue[5]);
rt_thread_mdelay(500);
}
}
static int adc_deal(void)
{
rt_err_t ret = RT_EOK;
/*創(chuàng)建第一個(gè)線程,用于采集IN8的值*/
Adc_thread1 = rt_thread_create("adc1",
Adc_entry,
(void*)0,
512,
16,
20);
if(Adc_thread1 != RT_NULL)
rt_thread_startup(Adc_thread1);
else
ret = RT_ERROR;
return ret;
}
INIT_APP_EXPORT(adc_deal);
測(cè)試結(jié)果
本測(cè)試板模擬量是采集4~20MA電流。使用信號(hào)發(fā)生器輸出電流信號(hào)對(duì)各個(gè)通道測(cè)試正常。下圖是對(duì)chanle_10通道采集數(shù)據(jù)(12MA電流顯示118。其他通道接輸入信號(hào)也可以正常采集,其他通道不超過(guò)40為干擾信號(hào),不會(huì)計(jì)入有效采集)。
-
adc
+關(guān)注
關(guān)注
98文章
6503瀏覽量
544871 -
信號(hào)發(fā)生器
+關(guān)注
關(guān)注
28文章
1476瀏覽量
108805 -
dma
+關(guān)注
關(guān)注
3文章
561瀏覽量
100623 -
ADC采樣
+關(guān)注
關(guān)注
0文章
134瀏覽量
12850 -
RTThread
+關(guān)注
關(guān)注
8文章
132瀏覽量
40894 -
STM32F407VET6
+關(guān)注
關(guān)注
2文章
5瀏覽量
2946
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論