ADC单通道连续采集数据,通过DMA传输给串口发送给上位机。使用DMA传输即可让数据绕开CPU,数据不需要进出SRAM。DMA控制器使用系统总线,直接将ADC数据寄存器的数据传输给串口发送数据寄存器,对串口发送数据寄存器的写操作将触发串口传输,从而将数据发送给上位机。在DMA传输过程中,CPU可以进行其他操作,DMA与CPU分时使用系统总线。
为了让ADC1转换与串口发送同步,将DMA传输模式设置为常规(一次传输),即完成指定数量数据的传输后,DMA将自动关闭,而不再响应DMA请求(当传输模式为循环模式时,DMA配置完成后,当有DMA请求信号时,DMA便开始工作,不停地通过系统总线传输数据),打开ADC的转换完成中断,并且在中断函数中重新开启DMA。这样。ADC每完成一个数据的转换,便触发一次DMA传输,传输完成后DMA自动关闭,下一次ADC转换完成时,重新开启DMA,如此反复便实现了ADC1转换与串口发送的同步。而在整个过程中,CPU可以做其他工作。
下面为核心代码:
ADC1 GPIO配置:
GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIOB外设时钟 (STM32在对外设寄存器操作之前需要开启相应外设时钟) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //设置为模拟输入 GPIO_Init(GPIOB, &GPIO_InitStructure); //PB0为ADC1通道8模拟输入
ADC1模式配置:
RCC_AHBPeriphClockCmd(RCC_AHB2Periph_ADC1, ENABLE); //开启ADC1外设时钟 ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立ADC模 ADC_InitStructure.ADC_ScanConvMode = DISABLE ; //禁止扫描模式,扫描模式用于多通道采集 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //开启连续转换模式,即不停地进行ADC转换 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使用外部触发转换 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; //要转换的通道数目1 ADC_Init(ADC1, &ADC_InitStructure); ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); //打开ADC1转换完成中断 RCC_ADCCLKConfig(RCC_PCLK2_Div8) //配置ADC时钟,为PCLK2的8分频率 ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5); //配置ADC1通道8,通道转换顺序为1, 转换时间为55.5个时钟周期 ADC_DMACmd(ADC1, ENABLE); //打开ADC1的DMA请求,即ADC转换完成后将触发DMA开始传输 ADC_Cmd(ADC1, ENABLE); //打开ADC1 ADC_ResetCalibration(ADC1); //复位校准寄存器 while(ADC_GetResetCalibrationStatus(ADC1)); //等待校准寄存器复位完成 ADC_StartCalibration(ADC1); //ADC校准 while(ADC_GetCalibrationStatus(ADC1)); //等待ADC校准完成 ADC_SoftwareStartConvCmd(ADC1,Enable) //打开ADC软件触发
DMA1配置:
DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //开启DMA1外设时钟 DMA_DeInit(DMA1_Channel1); //默认设置 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR; //Peripheral指向 ADC1数据寄存器 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&USART1->DR; //Memory指向 USART1发送数据寄存器 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //方向由 ADC——>USART1 DMA_InitStructure.DMA_BufferSize = 2; //发送两个数据 (由于ADC精度为12位,数据寄存器为16位,分两个字节发送) DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;// Peripheral按字节自增1指向ADC1数据寄存器 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; // Memory指向串口发送数据寄存器不变(串口数据宽度为8位) DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度1字节 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度1字节 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //一次传输 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //高优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止M2M DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_Cmd(DMA1_Channel1, ENABLE); //开启DMA1通道1,ADC1的DMA通道为DMA1通道1
附DMA请求映射:
串口
时间: 2024-10-19 19:53:06