如题,还想问一下对应的stm32f4单片机的像是设置输入的IO口,初始化ADC,设置输出串口之类的函数应该去哪里看啊?新上手完全找不到
2条回答 默认 最新
关注 - 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7450259
- 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:有关用STM32芯片自带的ADC测量电池电压,然后根据放电曲线得到电池容量的问题
- 除此之外, 这篇博客: STM32F4 ADC (单通道采集、多通道采集、双重交错模式、规则同步模式、三重模式)中的 话不多说,直接上程序,详情请看注释 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
//-------------.c 文件----------------------------------------------------------------------------------------------------------------------------------////
#include "adc.h" #include "usart.h" __IO uint32_t ADC_TripleModeConveredValue[3]; __IO uint16_t ADC_MultiModeConveredValue[8]; __IO uint16_t RegSimultModeConveredValue[4]; __IO uint32_t ADC_DualModeConveredValue; __IO uint16_t ADC_VBATMeasureValue; double Single_ADCx_Value = 0; //DMA2(CH0 CH4)-------------->ADC1 //DMA2(CH2 CH3)-------------->ADC2 //DMA2(CH0 CH1)-------------->ADC3
单通道采集
#if defined (ADC_Single_Channel) //单通道采集 void ADC_Single_Config(void) { ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_Single_GPIO,ENABLE); RCC_APB2PeriphClockCmd(RCC_Single_ADCx,ENABLE); GPIO_InitStructure.GPIO_Pin = ADC_Single_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(ADC_Single_PORT,&GPIO_InitStructure); ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; //ADC最大时钟是36MHz 故要在这里分频 84/4 = 21 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //只有在双重模式或者三重模式时才会设置 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //两个采样阶段之间的延迟,仅适用于双重模式或者三重模式 ADC_CommonInit(&ADC_CommonInitStructure); ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //使能连续转换 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐 ADC_InitStructure.ADC_NbrOfConversion = 1; //转换通道 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //分辨率: 12位 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //失能扫描模式,多通道采集才会用得到 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; // ADC_InitStructure.ADC_ExternalTrigConv = //采用软件触发,故这里不需要 ADC_Init(Single_ADCx,&ADC_InitStructure); //配置ADCx 通道转换顺序和转换周期 ADC_RegularChannelConfig(Single_ADCx,ADC_Single_Channel_x,1,ADC_SampleTime_56Cycles); //使能ADCx转换结束中断,在每次转换结束之后读取数据 ADC_ITConfig(Single_ADCx,ADC_IT_EOC,ENABLE); //使能ADCx ADC_Cmd(Single_ADCx,ENABLE); //开启软件转换 ADC_SoftwareStartConv(Single_ADCx); } void ADC_Single_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_Init(&NVIC_InitStructure); } void ADC_IRQHandler(void) { uint16_t val; if(ADC_GetFlagStatus(Single_ADCx,ADC_FLAG_EOC) == SET) { ADC_ClearITPendingBit(Single_ADCx,ADC_FLAG_EOC); val = ADC_GetConversionValue(Single_ADCx); Single_ADCx_Value = (double)val*3.3/4096; printf("\r\nADCx single value : %lf\n\r",Single_ADCx_Value); } }
多通道采集
#elif defined (ADC_Multi_Channel) //多通道采集,采集8个通道的数据 void Multi_ADC_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; //或者GPIO_Mode_AIN GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA,&GPIO_InitStructure); } void ADC_Multi_Config(void) { ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; DMA_InitTypeDef DMA_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA_x,ENABLE); DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环采集 DMA_InitStructure.DMA_Channel = DMA_Channel_x; //通道 三重模式只需使能 ADC1 的 DMA 通道。 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到内存 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //数据流优先级 DMA_InitStructure.DMA_BufferSize = 8; //设定待传输数据通道 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //失能FIFO模式 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//FIFO阈值,全部使用,由于上面失能该模式,故该设置无效 DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_MultiModeConveredValue; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //ADC是直接传输,要选单次模式 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //储存器数据宽度 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //地址自增 与 DMA_BufferSize 联系,1 --> 不自增 DMA_InitStructure.DMA_PeripheralBaseAddr = MultiMode_ADC_ADDR; //ADC1地址基地址 + ADC1数据寄存器偏移地址 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //ADC是直接传输,要选单次模式 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据宽度 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //无需设置为储存地址自增模式 DMA_Init(DMAx_Stream_x,&DMA_InitStructure); DMA_Cmd(DMAx_Stream_x,ENABLE); RCC_APB2PeriphClockCmd(MultiMode_ADCx_CLK,ENABLE); ADC_StructInit(&ADC_InitStructure); ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; //4分频 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;// ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles; ADC_CommonInit(&ADC_CommonInitStructure); ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //使能连续转换 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐 ADC_InitStructure.ADC_NbrOfConversion = 8; //转换通道 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //分辨率: 12位 ADC_InitStructure.ADC_ScanConvMode = ENABLE; //使能扫描模式,多通道采集才会用得到 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; // ADC_InitStructure.ADC_ExternalTrigConv = //采用软件触发,故这里不需要 ADC_Init(MultiMode_ADCx,&ADC_InitStructure); ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_0,1, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_1,2, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_2,3, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_3,4, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_4,5, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_5,6, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_6,7, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(MultiMode_ADCx,ADC_Channel_7,8, ADC_SampleTime_3Cycles); ADC_DMARequestAfterLastTransferCmd(MultiMode_ADCx, ENABLE);// 使能 DMA 请求 ADC_DMACmd(MultiMode_ADCx, ENABLE); ADC_Cmd(MultiMode_ADCx, ENABLE); ADC_SoftwareStartConv(MultiMode_ADCx); }
双重交错模式
#elif defined (ADC_DualModeInterleaved) //两个ADC同时采集一个通道 // ADC_Mode ADC_DMAAccessMode DMA_BufferSize DMA_MemoryDataSize DMA_MemoryInc DMA_PeripheralDataSize相互联系 void ADC_DualModeInterleaved_Config(void) { ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; RCC_AHB1PeriphClockCmd(DualModeInterleaved_GPIO_CLK,ENABLE); GPIO_InitStructure.GPIO_Pin = DualModeInterleaved_GPIO_Pinx; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; //或者GPIO_Mode_AIN GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(DualModeInterleaved_GPIO,&GPIO_InitStructure); // ADC1 使用 DMA2,数据流 0,通道 0,这个是手册固定死的 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE); DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环采集 DMA_InitStructure.DMA_Channel = DMA_Channel_0; //通道 三重模式只需使能 ADC1 的 DMA 通道。 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到内存 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //数据流优先级 DMA_InitStructure.DMA_BufferSize = 1; //设定待传输数据通道 高16位 ADC2 低16位 ADC1 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //失能FIFO模式 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//FIFO阈值,全部使用,由于上面失能该模式,故该设置无效 DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_DualModeConveredValue; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //ADC是直接传输,要选单次模式 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //储存器数据宽度 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //地址自增 与 DMA_BufferSize 联系,1 --> 不自增 DMA_InitStructure.DMA_PeripheralBaseAddr = DualModeInterleaved_ADC_ADDR; //ADC1地址基地址 + ADC1数据寄存器偏移地址 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //ADC是直接传输,要选单次模式 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //外设数据宽度 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //无需设置为储存地址自增模式 DMA_Init(DMA2_Stream0,&DMA_InitStructure); DMA_Cmd(DMA2_Stream0,ENABLE); RCC_APB2PeriphClockCmd(DualModeInterleaved_ADC1_CLK,ENABLE); RCC_APB2PeriphClockCmd(DualModeInterleaved_ADC2_CLK,ENABLE); ADC_StructInit(&ADC_InitStructure); ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_Interl; //双重ADC交替模式 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; //4分频 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;//DMA模式 2 高16位 ADC2 低16位 ADC1; 三个模式详细区别参考手册有详解 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles; ADC_CommonInit(&ADC_CommonInitStructure); ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //使能连续转换 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐 ADC_InitStructure.ADC_NbrOfConversion = 1; //转换通道 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //分辨率: 12位 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //失能扫描模式,多通道采集才会用得到 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; // ADC_InitStructure.ADC_ExternalTrigConv = //采用软件触发,故这里不需要 ADC_Init(DualModeInterleaved_ADC1,&ADC_InitStructure); ADC_RegularChannelConfig(DualModeInterleaved_ADC1,DualModeInterleaved_ADC_CHx,1, ADC_SampleTime_3Cycles); ADC_Init(DualModeInterleaved_ADC2,&ADC_InitStructure); ADC_RegularChannelConfig(DualModeInterleaved_ADC2,DualModeInterleaved_ADC_CHx,1, ADC_SampleTime_3Cycles); ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);//使能DMA请求,在 ADC 转换完后自动请求 DMA 进行数据传输 ADC_DMACmd(DualModeInterleaved_ADC1, ENABLE); ADC_Cmd(DualModeInterleaved_ADC1, ENABLE); ADC_Cmd(DualModeInterleaved_ADC2, ENABLE); ADC_SoftwareStartConv(DualModeInterleaved_ADC1); ADC_SoftwareStartConv(DualModeInterleaved_ADC2); }
规则同步模式
#elif defined (ADC_DualModeRegualSimult) //双ADC规则同步模式 //两个ADC各同时采集多个通道,ADC1触发 static void GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; /* ADC123 Channel 10 -> PC0 ADC123 Channel 11 -> PC1 ADC123 Channel 12 -> PC2 ADC123 Channel 13 -> PC2 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pinx_0 | GPIO_Pinx_1 | GPIO_Pinx_2 | GPIO_Pinx_3 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOC, &GPIO_InitStructure); } static void ADC1_CH_Config(void) { ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 2; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channels 10, 11 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_3Cycles); } static void ADC2_CH_Config(void) { ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 2; ADC_Init(ADC2, &ADC_InitStructure); /* ADC2 regular channels 12, 13 configuration */ ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 1, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 2, ADC_SampleTime_3Cycles); } static void DMA_Config(void) { DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_Channel = DMA_Channel_x; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_BufferSize = 4; //每个数据流的第十六位放采集的数据 DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; //这里需使能 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&RegSimultModeConveredValue; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DualModeRegualSimult_ADC_ADDR; 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_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMAx_Stream_x, &DMA_InitStructure); /* DMA2_Stream0 enable */ DMA_Cmd(DMAx_Stream_x, ENABLE); } void ADC_DualModeRegualSimult_Config(void) { ADC_CommonInitTypeDef ADC_CommonInitStructure; /* Enable peripheral clocks *************************************************/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA_x, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); DMA_Config(); GPIO_Config(); /* ADC Common Init */ ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInit(&ADC_CommonInitStructure); /* ADC1 regular channels 10, 11 configuration */ ADC1_CH_Config(); /* ADC2 regular channels 11, 12 configuration */ ADC2_CH_Config(); /* Enable DMA request after last transfer (Multi-ADC mode) */ ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC2 */ ADC_Cmd(ADC2, ENABLE); /* Start ADC1 Software Conversion */ ADC_SoftwareStartConv(ADC1); }
三重模式
#elif defined (ADC_TripleModeInterleaved) //三通道交错采集 //对一个ADC通道使用三个ADC轮流交错采样,并通过DMA存储到内存,具体配置过程需参考中文参考手册11.9 //ADC1为主器件 ADC2、ADC3为从器件 void ADC_TripleModeInterleaved_Config(void) { ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; RCC_AHB1PeriphClockCmd(TripleModeInterleaved_GPIO_CLK,ENABLE); GPIO_InitStructure.GPIO_Pin = TripleModeInterleaved_GPIO_Pinx; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(TripleModeInterleaved_GPIO,&GPIO_InitStructure); // ADC1 使用 DMA2,数据流 0,通道 0,这个是手册固定死的 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE); DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环采集 DMA_InitStructure.DMA_Channel = DMA_Channel_0; //通道 三重模式只需使能 ADC1 的 DMA 通道。 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到内存 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //数据流优先级 DMA_InitStructure.DMA_BufferSize = 3; //设定待传输数据通道 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //失能FIFO模式 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//FIFO阈值,全部使用,由于上面失能该模式,故该设置无效 DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_TripleModeConveredValue; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //ADC是直接传输,要选单次模式 DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word; //储存器数据宽度 整字 这与DMA模式2对应 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //地址自增 DMA_InitStructure.DMA_PeripheralBaseAddr = TripleModeInterleaved_ADC_ADDR; //ADC1地址基地址 + ADC1数据寄存器偏移地址 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //ADC是直接传输,要选单次模式 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //外设数据宽度 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //无需设置为储存地址自增模式 DMA_Init(DMA2_Stream0,&DMA_InitStructure); DMA_Cmd(DMA2_Stream0,ENABLE);//使能(找这个地方的错误找了半小时...) RCC_APB2PeriphClockCmd(TripleModeInterleaved_ADC1_CLK,ENABLE); RCC_APB2PeriphClockCmd(TripleModeInterleaved_ADC2_CLK,ENABLE); RCC_APB2PeriphClockCmd(TripleModeInterleaved_ADC3_CLK,ENABLE); ADC_StructInit(&ADC_InitStructure); ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_Interl; //三重ADC交替模式 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; //4分频 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;//DMA模式2 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles; ADC_CommonInit(&ADC_CommonInitStructure); ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //使能连续转换 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据右对齐 ADC_InitStructure.ADC_NbrOfConversion = 1; //转换通道 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //分辨率: 12位 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //失能扫描模式,多通道采集才会用得到 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; // ADC_InitStructure.ADC_ExternalTrigConv = //采用软件触发,故这里不需要 ADC_Init(TripleModeInterleaved_ADC1,&ADC_InitStructure); ADC_RegularChannelConfig(TripleModeInterleaved_ADC1,TripleModeInterleaved_ADC_CHx,1, ADC_SampleTime_3Cycles); ADC_Init(TripleModeInterleaved_ADC2,&ADC_InitStructure); ADC_RegularChannelConfig(TripleModeInterleaved_ADC2,TripleModeInterleaved_ADC_CHx,1, ADC_SampleTime_3Cycles); ADC_Init(TripleModeInterleaved_ADC3,&ADC_InitStructure); ADC_RegularChannelConfig(TripleModeInterleaved_ADC3,TripleModeInterleaved_ADC_CHx,1, ADC_SampleTime_3Cycles); ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);//使能DMA请求,在 ADC 转换完后自动请求 DMA 进行数据传输 ADC_DMACmd(TripleModeInterleaved_ADC1, ENABLE); ADC_Cmd(TripleModeInterleaved_ADC1, ENABLE); ADC_Cmd(TripleModeInterleaved_ADC2, ENABLE); ADC_Cmd(TripleModeInterleaved_ADC3, ENABLE); ADC_SoftwareStartConv(TripleModeInterleaved_ADC1); ADC_SoftwareStartConv(TripleModeInterleaved_ADC2); ADC_SoftwareStartConv(TripleModeInterleaved_ADC3); }
电源电压测量
#elif defined (ADC_VBATMeasurement) void ADC_VBATMeasure_Config(void) { ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; DMA_InitTypeDef DMA_InitStructure; /* Enable peripheral clocks *************************************************/ RCC_AHB1PeriphClockCmd(DMAx_CLK, ENABLE); RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE); /* DMA2_Stream0 channel0 configuration **************************************/ DMA_DeInit(DMA2_Stream0); DMA_InitStructure.DMA_Channel = DMA_Channel_x; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_VBATMeasurement_ADDR; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC_VBATMeasureValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; 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_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMAx_Stream_x, &DMA_InitStructure); /* DMA2_Stream0 enable */ DMA_Cmd(DMAx_Stream_x, ENABLE); /* ADC Common Init **********************************************************/ ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInit(&ADC_CommonInitStructure); /* ADC1 Init ****************************************************************/ ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 1; ADC_Init(ADCx, &ADC_InitStructure); /* Enable ADC1 DMA */ ADC_DMACmd(ADCx, ENABLE); /* ADC1 regular channel18 (VBAT) configuration ******************************/ ADC_RegularChannelConfig(ADCx, ADC_Channel_Vbat, 1, ADC_SampleTime_15Cycles);//此处的通道为ADC_Channel_Vbat /* Enable VBAT channel */ ADC_VBATCmd(ENABLE); /* Enable DMA request after last transfer (Single-ADC mode) */ ADC_DMARequestAfterLastTransferCmd(ADCx, ENABLE); /* Enable ADC1 **************************************************************/ ADC_Cmd(ADCx, ENABLE); ADC_SoftwareStartConv(ADCx); } #endif
//---------.h文件--------------------------------------------------------------------------------------------------------------------------------------------////
#ifndef __ADC_H #define __ADC_H #include "stm32f4xx.h" //=================模式选择===================// //#define ADC_Single_Channel //单通道独立模式 //#define ADC_Multi_Channel //多通道独立模式 //#define ADC_DualModeInterleaved //双重交错模式 //#define ADC_DualModeRegualSimult //双ADC规则同步模式 //#define ADC_TripleModeInterleaved //三重交错模式 #define ADC_VBATMeasurement //电源电压测量 //--------------------------SingleMode-----------------------------// #if defined (ADC_Single_Channel) //单通道采集 #define RCC_Single_ADCx RCC_APB2Periph_ADC3 #define RCC_Single_GPIO RCC_AHB1Periph_GPIOC #define ADC_Single_PORT GPIOC #define ADC_Single_PIN GPIO_Pin_3 //PC3 --> ADC123_IN13 #define ADC_Single_Channel_x ADC_Channel_13 #define Single_ADCx ADC3 void ADC_Single_Config(void); void ADC_Single_NVIC_Config(void); //--------------------------MultiMode-----------------------------// #elif defined (ADC_Multi_Channel) #define MultiMode_ADCx ADC1 #define MultiMode_ADC_ADDR ((u32)MultiMode_ADCx+0x4c) #define MultiMode_ADCx_CLK RCC_APB2Periph_ADC1 #define RCC_AHB1Periph_DMA_x RCC_AHB1Periph_DMA2 #define DMA_Channel_x DMA_Channel_0 #define DMAx_Stream_x DMA2_Stream0 void Multi_ADC_GPIO_Config(void); void ADC_Multi_Config(void); //----------------------DualModeInterleaved-------------------------// #elif defined (ADC_DualModeInterleaved) #define DualModeInterleaved_ADC_ADDR ((uint32_t)0x40012308) #define DualModeInterleaved_ADC1 ADC1 #define DualModeInterleaved_ADC2 ADC2 #define DualModeInterleaved_ADC1_CLK RCC_APB2Periph_ADC1 #define DualModeInterleaved_ADC2_CLK RCC_APB2Periph_ADC2 #define DualModeInterleaved_ADC_CHx ADC_Channel_2 #define DualModeInterleaved_GPIO_CLK RCC_AHB1Periph_GPIOA #define DualModeInterleaved_GPIO GPIOA #define DualModeInterleaved_GPIO_Pinx GPIO_Pin_2 void ADC_DualModeInterleaved_Config(void); //---------------------DualModeRegualSimult-------------------------// #elif defined (ADC_DualModeRegualSimult) #define DualModeRegualSimult_ADC_ADDR ((uint32_t)0x40012308) #define RCC_AHB1Periph_GPIOx RCC_AHB1Periph_GPIOC #define GPIOx GPIOC #define GPIO_Pinx_0 GPIO_Pin_0 //PC0 --> ADC123_IN10 #define GPIO_Pinx_1 GPIO_Pin_1 //PC1 --> ADC123_IN11 #define GPIO_Pinx_2 GPIO_Pin_2 //PC2 --> ADC123_IN12 #define GPIO_Pinx_3 GPIO_Pin_3 //PC3 --> ADC123_IN13 #define RCC_AHB1Periph_DMA_x RCC_AHB1Periph_DMA2 #define DMA_Channel_x DMA_Channel_0 //通道0 #define DMAx_Stream_x DMA2_Stream0 //DMA2的数据流0 void ADC_DualModeRegualSimult_Config(void); //---------------------TripleModeInterleaved------------------------// #elif defined (ADC_TripleModeInterleaved) //双重或者三重 ADC 需要使用通用规则数据寄存器 ADC_CDR,这点跟独立模式不同 #define TripleModeInterleaved_ADC_ADDR ((uint32_t)0x40012308) #define TripleModeInterleaved_ADC1 ADC1 #define TripleModeInterleaved_ADC2 ADC2 #define TripleModeInterleaved_ADC3 ADC3 #define TripleModeInterleaved_ADC1_CLK RCC_APB2Periph_ADC1 #define TripleModeInterleaved_ADC2_CLK RCC_APB2Periph_ADC2 #define TripleModeInterleaved_ADC3_CLK RCC_APB2Periph_ADC3 #define TripleModeInterleaved_ADC_CHx ADC_Channel_1 #define TripleModeInterleaved_GPIO_CLK RCC_AHB1Periph_GPIOA #define TripleModeInterleaved_GPIO GPIOA #define TripleModeInterleaved_GPIO_Pinx GPIO_Pin_1 void ADC_TripleModeInterleaved_Config(void); //-----------------------VBATMeasurement--------------------------// #elif defined (ADC_VBATMeasurement) //● 在 STM32F40xx 和 STM32F41xx 器件上将 VBAT/2 连接到 ADC1_IN18 输入通道 //● 在 STM32F42xx 和 STM32F43xx 器件上将 VBAT/4 连接到 ADC1_IN18 输入通道 #define VBATDIV 2 //这里用的是F407 #define ADC_VBATMeasurement_ADDR ((uint32_t)0x4001204C) #define ADCx_CLK RCC_APB2Periph_ADC1 #define ADCx ADC1 #define DMAx_CLK RCC_AHB1Periph_DMA2 #define DMA_Channel_x DMA_Channel_0 //通道0 #define DMAx_Stream_x DMA2_Stream0 //DMA2的数据流0 void ADC_VBATMeasure_Config(void); #endif #endif
//--------main.c--------------------------------------------------------------------------------------------------------------------------------------////
#include "sys.h" #include "delay.h" #include "usart.h" #include "adc.h" extern __IO uint32_t ADC_TripleModeConveredValue[3]; extern __IO uint32_t ADC_DualModeConveredValue; __IO float DualModeValue1; __IO float DualModeValue2; extern __IO uint16_t ADC_MultiModeConveredValue[8]; __IO float ADC_MultiModeValue[8]; extern __IO uint16_t RegSimultModeConveredValue[4]; extern __IO uint16_t ADC_VBATMeasureValue; __IO float VBAT_Value; int main(void) { delay_init(168); //初始化延时函数 uart_init(115200); //初始化串口波特率为115200 printf("\n\r||-----ADC TEST-----||\n\r"); #if defined (ADC_Single_Channel) //单通道采集 ADC_Single_Config(); ADC_Single_NVIC_Config(); while(1); #elif defined (ADC_Multi_Channel) //多通道采集 int i; Multi_ADC_GPIO_Config(); ADC_Multi_Config(); while(1) { for(i=0; i<8; i++) { ADC_MultiModeValue[i] = (float) ADC_MultiModeConveredValue[i]/4096*(float)3.3; printf("\r\nADC Channel_%d value = %f V \r\n",i,ADC_MultiModeValue[i]); if(i==8) i = 0; } } #elif defined (ADC_DualModeInterleaved) //双重采集模式 ADC_DualModeInterleaved_Config(); while(1) { delay_ms(10); printf("\r\n The current ADC = 0x%08x V \r\n",ADC_DualModeConveredValue);//由DMA模式2 --> 高四位为ADC2的值,低四位为ADC1的值, DualModeValue1 = (float)((uint16_t)ADC_DualModeConveredValue*3.3/4096); DualModeValue2 = (float)((ADC_DualModeConveredValue>>16)*3.3/4096); printf("\r\n The current ADC1 value = %f V \r\n" ,DualModeValue1); printf("\r\n The current ADC2 value = %f V \r\n\r\n",DualModeValue2); } #elif defined (ADC_DualModeRegualSimult) //双ADC规则同步模式 //DualModeRegualSimult_GPIO_Config(); ADC_DualModeRegualSimult_Config(); while(1) { delay_ms(10); printf("\r\n The current channel 10 value = %08x \r\n" ,RegSimultModeConveredValue[0]);//c0 printf("\r\n The current channel 11 value = %08x \r\n" ,RegSimultModeConveredValue[1]);//c1 printf("\r\n The current channel 12 value = %08x \r\n" ,RegSimultModeConveredValue[2]);//c1 printf("\r\n The current channel 13 value = %08x \r\n\r\n",RegSimultModeConveredValue[3]);//c2 printf("\r\n The current channel 10 value = %f V \r\n" ,(float)((uint16_t)RegSimultModeConveredValue[0]*3.3/4096)); printf("\r\n The current channel 11 value = %f V \r\n" ,(float)((uint16_t)RegSimultModeConveredValue[1]*3.3/4096)); printf("\r\n The current channel 10 value = %f V \r\n" ,(float)((uint16_t)RegSimultModeConveredValue[2]*3.3/4096)); printf("\r\n The current channel 11 value = %f V \r\n\r\n",(float)((uint16_t)RegSimultModeConveredValue[3]*3.3/4096)); } #elif defined (ADC_TripleModeInterleaved) //三通道交错采集 ADC_TripleModeInterleaved_Config(); while(1) { delay_ms(10); printf("\r\n The current ADC1 value = %f V \r\n",(float)((uint16_t)ADC_TripleModeConveredValue[0]*3.3/4096));//三重采集模式 根据选用的DMA模式2 顺序为1,3,2 printf("\r\n The current ADC3 value = %f V \r\n",(float)((uint16_t)ADC_TripleModeConveredValue[1]*3.3/4096)); printf("\r\n The current ADC2 value = %f V \r\n",(float)((uint16_t)ADC_TripleModeConveredValue[2]*3.3/4096)); } #elif defined (ADC_VBATMeasurement) //电源电压测量 ADC_VBATMeasure_Config(); while(1) { delay_ms(10); VBAT_Value = (float)((uint16_t)ADC_VBATMeasureValue*VBATDIV*3.3/4096); printf("\r\n\r\n The ADC value = %08x \r\n" ,ADC_VBATMeasureValue);//c0 printf("\r\n The VBATMeasure value = %f V\r\n",VBAT_Value);// } #endif }
- 以下回答由chatgpt基于相关博客总结生成:
可以直接用C语言在keil5中编写代码。需要先了解芯片的手册,了解芯片的IO口和ADC等资源的寄存器地址。 关于设置输入的IO口,可以使用GPIO库函数进行配置。需要调用GPIO_Init函数,具体可以参考上面参考资料中的adc.c中的GPIO配置,根据自己需要进行修改。 关于初始化ADC,可以参考上述参考资料中的adc.c中的adc_init函数进行配置。 关于设置输出串口,需要先了解自己使用的芯片是否支持串口。如果支持,则需要使用USART库函数进行配置。可以调用USART_Init函数进行串口初始化,配置波特率、数据位、停止位等参数,然后使用USART_SendData函数将需要发送的数据发送出去。 需要注意的是,在使用ADC时,转换的时间不能大于采样周期,需要根据硬件环境和转换位数确定转换时间,不能突破转换时间的限制。具体可参考上述参考资料中的段落0。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报
悬赏问题
- ¥20 有谁能看看我coe文件到底哪儿有问题吗?
- ¥20 我的这个coe文件到底哪儿出问题了
- ¥15 matlab使用自定义函数时一直报错输入参数过多
- ¥15 设计一个温度闭环控制系统
- ¥100 rtmpose姿态评估
- ¥15 java 通过反射找路径下的类,打包后就找不到
- ¥15 通联支付网上收银统一下单接口
- ¥15 angular有偿编写,
- ¥15 centos7系统下abinit安装时make出错
- ¥15 hbuildex运行微信小程序报错