初级会员

- 积分
- 130
- 金钱
- 130
- 注册时间
- 2019-7-8
- 在线时间
- 34 小时
|
void ADC_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA, ENABLE); //使能ADC和GPIOA时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置时钟(12MHz),在RCC里面还应配置APB2=AHB时钟72MHz
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA, ENABLE); //使能ADC和GPIOA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //采集电压的引脚为PA管脚2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入模式
GPIO_Init(GPIOA, &GPIO_InitStructure); //GPIO组
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //关闭通道扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //注意不要使用持续转换模式,否则只要触发一次,//后续的转换就会永不停歇(除非CONT清0),这样第一次以后的ADC,就不是由TIM2_CC2来触发了
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4;//配置TIM2_CC2为触发源
// ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;//配置TIM2_CC2为触发源
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_239Cycles5);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1,ENABLE);
ADC_ExternalTrigConvCmd(ADC1, ENABLE); //设置外部触发模式使能(这个“外部“其实仅仅是相//对于ADC模块的外部,实际上还是在STM32内部)
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1); //Start Calibration register
while(ADC_GetCalibrationStatus(ADC1)); //waiting for finishing the calibration
}
void ADC_DMA_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure; // 注:ADC为12位模数转换器,只有ADCConvertedValue的低12位有效
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;//串口1是DMA1_4通道 ADC
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//强占0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//子1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//DMA对应的外设基地址
// DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;//DMA对应的外设基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_RegularConvertedValueTab; //内存存储基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA的转换模式为SRC模式,由外设搬移到内存
DMA_InitStructure.DMA_BufferSize = N;//DMA缓存大小,1个
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //接收一次数据后,设备地址禁止后移
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //接收多次数据后,目标内存地址后移
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//定义外设数据宽度为16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //DMA搬移数据尺寸,HalfWord就是为16位
DMA_InitStructure.DMA_Mode =DMA_Mode_Circular;//循环转换模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA优先级高
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//M2M模式禁用
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);//使能传输完成中断
DMA_Cmd(DMA1_Channel1, ENABLE);
}
void DMA1_Channel1_IRQHandler(void) // 使用DMA中断采集数据,不会容易丢失数据
{
// int a=0;
int i;
if(DMA_GetITStatus(DMA1_IT_TC1)!=RESET)
{
DMA_ClearITPendingBit(DMA1_IT_TC1);
//自己的中断处理代码 但是记住程序不要太复杂 最好不要超过中断时间
for(i=0;i<N;i++)
{
sum += ADC_RegularConvertedValueTab[i]*3.3/4096.0f;
}
AVG = sum/N;
sum=0;
}
// DMA_Cmd(DMA1_Channel1, DISABLE);
} 同时使用串口通讯和ADC+DMA采样,发现串口通讯的数据有时候会发生错误,比如发送02收到0,单使用串口数据不会出错,请问该怎么解决
|
|