研究生
最后登录1970-1-1
在线时间 小时
注册时间2017-1-23
|
发表于 2017-11-8 15:38:49
|
显示全部楼层
- /*****************************************************************
- 四路ADC采用连续转换 扫描模式,每路采集100个值后开启DMA中断,
- 在DMA中断中进行平均值滤波处理
- *****************************************************************/
- #include "ADC.h"
- #include "delay.h"
- uint16_t ADC_ConvertedValue[4]={0,0,0,0}; // ADC1转换的电压值通过 MDA 方式传到 SRAM
- float ADC_ConvertedValueLocal[4]; //转换后电压值
- uint16_t AD_Value[100][4]; //AD采样值
- uint16_t After_filter[4]; //AD滤波后
- uint16_t TEMP0,TEMP1; //左侧,右侧设置温度值
- float Temp[4] ={0};//转换后温度值
- u8 TempValue_change = 0;//采集的值变化标志位
- /**
- * @brief ADC GPIO 初始化
- * @param 无
- * @retval 无
- */
- static void ADC1_GPIO_Config(void) //使用ADC1的channel 10,11,12,13,IO口为PC0~PC3
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- // 打开 ADC IO端口时钟
- RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC, ENABLE);
-
- // 配置 ADC IO 引脚模式
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //TC1
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //TC2
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //ADC1
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //ADC2
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
-
- // 初始化 ADC IO
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- }
- /**
- * @brief 配置DMA1工作模式
- * @param 无
- * @retval 无
- */
- static void DMA1_Mode_Config(void)
- {
- DMA_InitTypeDef DMA_InitStructure;
-
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// 打开DMA时钟
-
- DMA_DeInit(DMA1_Channel1); // 复位DMA控制器
-
- // 配置 DMA 初始化结构体
- DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t)0x40012400+0x4c); // 外设基址为:ADC 数据寄存器地址
- DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&AD_Value; // 存储器地址
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 数据源来自外设
- DMA_InitStructure.DMA_BufferSize = 400; // 缓冲区大小,应该等于数据目的地的大小
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设寄存器只有一个,地址不用递增
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 存储器地址递增
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// 外设数据大小为半字,即两个字节
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 内存数据大小也为半字,跟外设数据大小相同
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 循环传输模式
- DMA_InitStructure.DMA_Priority = DMA_Priority_High; // DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 禁止存储器到存储器模式,因为是从外设到存储器
-
- DMA_Init(DMA1_Channel1, &DMA_InitStructure); // 初始化DMA
- DMA_Cmd(DMA1_Channel1 , ENABLE); // 使能 DMA 通道
- DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);
- }
- static void DMA1_NVIC_Config(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
-
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//中断组为1,2个抢占优先级,8个响应优先级
-
- NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0; //抢占优先级
- NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //响应优先级
- NVIC_Init(&NVIC_InitStructure);
- }
- /**
- * @brief 配置ADC工作模式
- * @param 无
- * @retval 无
- */
- static void ADC1_Mode_Config(void)
- {
-
- ADC_InitTypeDef ADC_InitStructure;
-
- RCC_APB2PeriphClockCmd (RCC_APB2Periph_ADC1, ENABLE); // 打开ADC时钟
-
- // ADC 模式配置
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // 只使用一个ADC,属于单模式
- ADC_InitStructure.ADC_ScanConvMode = ENABLE ; // 扫描模式
- ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 连续转换模式,
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 不用外部触发转换,软件开启即可
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 转换结果右对齐
- ADC_InitStructure.ADC_NbrOfChannel = 4; // 转换通道个数
-
-
- ADC_Init(ADC1, &ADC_InitStructure); // 初始化ADC
-
- RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 配置ADC时钟为CLK2的8分频,即9MHz 确保ADC时钟不超过14M
-
- // 配置ADC 通道的转换顺序和采样时间
- ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_239Cycles5); //PC0 ->TC1
- ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_239Cycles5); //PC1 ->TC2
- ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_239Cycles5); //PC2 ->ADC1
- ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 4, ADC_SampleTime_239Cycles5); //PC3 ->ADC2
-
- ADC_DMACmd(ADC1, ENABLE); // 使能ADC DMA 请求
- ADC_Cmd(ADC1, ENABLE); // 开启ADC ,并开始转换
-
- /* 必须执行复位校准和AD校准,不准将导致结果不准确*/
-
- ADC_ResetCalibration(ADC1); // 初始化ADC 复位校准寄存器
- while(ADC_GetResetCalibrationStatus(ADC1));// 等待校准寄存器初始化完成
- ADC_StartCalibration(ADC1); // ADC开始校准
- while(ADC_GetCalibrationStatus(ADC1)); // 等待校准完成
-
- ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 由于没有采用外部触发,所以使用软件触发ADC转换
- }
- /**
- * @brief ADC初始化
- * @param 无
- * @retval 无
- */
- void ADC1_Init(void)
- {
- DMA1_Mode_Config();
- DMA1_NVIC_Config();
- ADC1_GPIO_Config();
- ADC1_Mode_Config();
- }
- void filter(void) //在中断中滤波
- {
- int sum = 0;
- u8 count,i;
- for(i=0;i<4;i++)
- {
- for(count=0;count<100;count++)
- {
- sum += AD_Value[count][i];
- }
- After_filter[i] = sum/100;
- sum = 0;
- }
- TEMP0 = After_filter[0]*70/4096; //左侧设置温度值
- TEMP1 = After_filter[1]*70/4096; //右侧设置温度值
- TempValue_change =1;
- }
- void DMA1_Channel1_IRQHandler(void)
- {
- if(DMA_GetITStatus(DMA1_IT_TC1) != RESET)
- {
- filter();
- DMA_ClearITPendingBit(DMA1_IT_TC1);
- }
- }
- void Get_ADC() //换算电压值(调试用)
- {
- int i = 0;
- // for(i = 0;i<2;i++)
- // {
- // ADC_ConvertedValueLocal[i] =(float) ADC_ConvertedValue[i]/4096*3.22; //设置电压值
- // }
- for(i=2;i<4;i++)
- {
- ADC_ConvertedValueLocal[i] =(float) After_filter[i]/4096*3.20; //实际电压值
- }
- }
- /*********************************************END OF FILE**********************/
复制代码 |
|