ADC的DMA多通道数据采集(雨滴传感器+光敏传感器)
生活随笔
收集整理的這篇文章主要介紹了
ADC的DMA多通道数据采集(雨滴传感器+光敏传感器)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
AADC1跟ADC3可以用DMA,因為多通道,然而ADC只有一個數據寄存器,因此可以用DMA開一個數組來存數據
?ADC1只能用DMA1的通道1
??ADC3只能用DMA2的通道5
最近在學模擬量的測試,我用了光敏傳感器和雨滴傳感器,跟上一篇的光敏傳感器差不多,只不過這里多了DMA的初始,可以實現獨立ADC的多通道數據采集。
adc.h
#ifndef ADC_H #define ADC_H#include "sys.h"void ADC3_Init(void); //u16 ADC3_Get(u8 ch); u16 ADC3_GetLightValue(void); u16 ADC3_GetYuDiValue(void); //u16 ADC3_GetSmogValue(void); #endif /* ADC_H */adc.c
#include "adc.h" #include "delay.h" #include "usart.h"//ADC3使用的是DMA2的通道5u16 ADC_ConversionValue[2] = {0,0}; void ADC3_Init(void) {DMA_InitTypeDef DMA_InitStruct;ADC_InitTypeDef ADC_InitStruct;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE); //開啟時鐘RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,ENABLE); //復位RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,DISABLE); //關閉RCC_ADCCLKConfig(RCC_PCLK2_Div6); //時鐘分頻,ADC不能超過14Mhz,不然會不精準,系統內部時鐘是72Mhz,所以要分頻//DMA設置DMA_DeInit(DMA2_Channel5);DMA_InitStruct.DMA_PeripheralBaseAddr = (u32)(&ADC3->DR);//外設的基地址DMA_InitStruct.DMA_MemoryBaseAddr = (u32)&ADC_ConversionValue; //內存存儲地址,即數據的基地址DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;//數據來源于外設DMA_InitStruct.DMA_BufferSize = 2;//緩沖區大小,數組的長度DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//只有一個外設,地址不增DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//內存地址遞增,即數組地址增DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外設數據大小為半字,也就是兩個字節DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//內存大小為半字,也就是兩個字節DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;//循環傳輸DMA_InitStruct.DMA_Priority = DMA_Priority_High;//DMA通道優先級為高,當使用一個DMA通道是,優先級不影響DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; //外設到內存模式DMA_Init(DMA2_Channel5, &DMA_InitStruct);DMA_Cmd(DMA2_Channel5, ENABLE);//ADC設置ADC_DeInit(ADC3);ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; //獨立模式ADC_InitStruct.ADC_ScanConvMode = ENABLE; //模數轉換工作在多通道模式ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; //連續轉換ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使用外部觸發ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; //轉換結果右對齊,放在低12位ADC_InitStruct.ADC_NbrOfChannel = 2; //順序進行規則轉換的ADC通道的數目ADC_Init(ADC3, &ADC_InitStruct);ADC_RegularChannelConfig(ADC3, ADC_Channel_4, 1, ADC_SampleTime_55Cycles5);//規則通道,ADC3,通道4,第一個轉換,采樣時間為55.5周期ADC_RegularChannelConfig(ADC3, ADC_Channel_5, 2, ADC_SampleTime_55Cycles5);//規則通道,ADC3,通道5,第一個轉換,采樣時間為55.5周期 // ADC_RegularChannelConfig(ADC3, ADC_Channel_6, 3, ADC_SampleTime_55Cycles5);ADC_DMACmd(ADC3, ENABLE); //使能ADC的DMA請求ADC_Cmd(ADC3, ENABLE);ADC_ResetCalibration(ADC3); //重置指定的ADC3的復位寄存器while(ADC_GetResetCalibrationStatus(ADC3)); //獲取ADC3重置校準寄存器的狀態,設置狀態則等待ADC_StartCalibration(ADC3); //開啟精準計算while(ADC_GetCalibrationStatus(ADC3));ADC_SoftwareStartConvCmd(ADC3, ENABLE); //使能指定的ADC3的軟件轉換啟動功能}u16 ADC3_GetLightValue(void) { // printf("ADC_ConversionValue[0]:%d\r\n", ADC_ConversionValue[0]);return (u16)ADC_ConversionValue[0]; }u16 ADC3_GetYuDiValue(void) { // printf("ADC_ConversionValue[1]:%d\r\n", ADC_ConversionValue[0]);return (u16)ADC_ConversionValue[1]; } // //u16 ADC3_GetSmogValue(void) //{ // printf("ADC_ConversionValue[1]:%d\r\n", ADC_ConversionValue[0]); // return (u16)ADC_ConversionValue[2]; //}光敏傳感器
lightsensor.h
?
?
lightsensor.c
#include "lightsensor.h" #include "adc.h" #include "delay.h" #include "led.h" #include "usart.h"//extern u16 ADC_ConversionValue[2] = {0,0}; //光敏傳感器PF6/ADC3_IN4 void LighrSensor_Init(void) //初始化GPIO {GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; //采用ADC的時候,這里要用模擬輸入模式GPIO_Init(GPIOF, &GPIO_InitStruct);ADC3_Init(); } //光敏傳感器模擬值0-100 u8 LightSensor_Val(void) {u32 temp = 0;u8 t;for(t=0;t<LightSensor_read_time;t++) // LightSensor_read_time:采集次數{ // temp += ADC3_Get(LSENS_ch); //多次采集的數據和temp =temp + ADC3_GetLightValue(); // printf("temp:%d\r\n", temp);delay_ms(5);}temp /= LightSensor_read_time; // 平均值:多次采集的數據和除以采集次數printf("temp:%d\r\n", temp);if(temp > 4000) {temp = 4000;}else{LED1 = 0;}return (u8)(100-(temp/40)); //模擬量輸出范圍為 0-100 }雨滴傳感器
mdrh.h
#ifndef __MHRD_H #define __MHRD_H#include "sys.h"#define YU_DO PAin(5)// PB5void DO_Init(void);//這個是雨滴傳感器作為TTL的高低電平初始化 void MHRD_AO_Init(void);//這個雨滴傳感器的模擬初始化 u8 YuDi_Val(void); #endif /* __MHRD_H */mdrh.c
#include "mhrd.h" #include "adc.h" #include "delay.h" #include "beep.h" //PA5 - DO 低電平有效 void DO_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA端口時鐘GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //DO-->PA.5 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHzGPIO_Init(GPIOB, &GPIO_InitStructure); //根據設定參數初始化GPIOA.5GPIO_SetBits(GPIOA,GPIO_Pin_5); //PB.5 輸出高,關閉}void MHRD_AO_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE); //使能PF端口時鐘GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //AO-->PF.7 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模擬輸入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHzGPIO_Init(GPIOF, &GPIO_InitStructure); //根據設定參數初始化GPIOF7ADC3_Init(); }//雨滴傳感器模擬值0-200 u8 YuDi_Val(void) {u32 temp = 0;u8 t;for(t=0;t<10;t++) // LightSensor_read_time:采集次數{ // temp += ADC3_Get(LSENS_ch); //多次采集的數據和temp += ADC3_GetYuDiValue();delay_ms(5);}temp /= 10; // 平均值:多次采集的數據和除以采集次數if(temp > 4000) {temp = 4000;BEEP(1); //蜂鳴器響,這個是用來檢測沒有水的時候,蜂鳴器會響,雨滴的值為0}else{BEEP(0);}return (u8)(200-(temp/20)); //模擬量輸出范圍為 0-200 }?
總結
以上是生活随笔為你收集整理的ADC的DMA多通道数据采集(雨滴传感器+光敏传感器)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CesiumJS 2022^ 原理[2]
- 下一篇: 小谈深度优先搜索