如题,还想问一下对应的stm32f4单片机的像是设置输入的IO口,初始化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
}
可以直接用C语言在keil5中编写代码。需要先了解芯片的手册,了解芯片的IO口和ADC等资源的寄存器地址。 关于设置输入的IO口,可以使用GPIO库函数进行配置。需要调用GPIO_Init函数,具体可以参考上面参考资料中的adc.c中的GPIO配置,根据自己需要进行修改。 关于初始化ADC,可以参考上述参考资料中的adc.c中的adc_init函数进行配置。 关于设置输出串口,需要先了解自己使用的芯片是否支持串口。如果支持,则需要使用USART库函数进行配置。可以调用USART_Init函数进行串口初始化,配置波特率、数据位、停止位等参数,然后使用USART_SendData函数将需要发送的数据发送出去。 需要注意的是,在使用ADC时,转换的时间不能大于采样周期,需要根据硬件环境和转换位数确定转换时间,不能突破转换时间的限制。具体可参考上述参考资料中的段落0。
先学再用。