#include "adc.h"
#include "delay.h"
#define ADC1_DR_ADDRESS ((uint32_t)0x4001204C)
/* 变量 ----------------------------------------------------------------------*/
extern __IO uint16_t ADC1ConvertedValue[64][3];
//初始化ADC
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能 ADC1, DMA2 和 GPIO 时钟 ****************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA, ENABLE); //使能GPIOA,DMA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//使能ADC1时钟
/* DMA2 Stream0 channel0 配置 **************************************/
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS; //DMA外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADC1ConvertedValue;//DMA 存储器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//外设到储存器
DMA_InitStructure.DMA_BufferSize = 128; //数据传输量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据长度:8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //存储器数据长度:8位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //DMA工作在循环模式
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(DMA2_Stream0, &DMA_InitStructure); //初始化DMA Stream
DMA_Cmd(DMA2_Stream0, ENABLE); //开启DMA传输
/* 配置ADC1通道3、5引脚为模拟输入模式******************************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1| GPIO_Pin_4 ;//|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; //模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/****************************************************************************
PCLK2 = HCLK / 2
下面选择的是2分频
ADCCLK = PCLK2 /2 = HCLK / 4 = 168 / 4 = 42M
ADC采样频率: Sampling Time + Conversion Time = 3 + 12 cycles = 15cyc
Conversion Time = 42MHz / 15cyc = 2.8Mbps.
*****************************************************************************/
/* ADC公共部分初始化**********************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;//预分频4分频
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //两个采样阶段之间的延迟5个时钟
ADC_CommonInit(&ADC_CommonInitStructure);//初始化
/* ADC1 初始化 ****************************************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
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 = 3;//3个转换在规则序列中
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 规则 channel3、5 配置 *************************************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_112Cycles);//ADC1,ADC通道,112个周期,提高采样时间可以提高精确度
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_112Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 3, ADC_SampleTime_112Cycles);
/* 使能DMA请求(单ADC模式) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* 使能 ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE); //adc开启DMA传输
/* 使能 ADC1 */
ADC_Cmd(ADC1, ENABLE); //开启AD转换器
/* 软件启动ADC转换 */
ADC_SoftwareStartConv(ADC1);
}
主程序
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "adc.h"
//ALIENTEK 探索者STM32F407开发板 实验18
//ADC模数转换实验-库函数版本
//技术支持:
www.openedv.com
//淘宝店铺:
http://eboard.taobao.com
//广州市星翼电子科技有限公司
//作者:正点原子 @ALIENTEK
__IO uint16_t ADC1ConvertedValue[64][3];
__IO uint32_t ADC1ConvertedVoltage[3];
int main(void)
{
u8 i;
u8 j;
// u8 k;
float temp1,temp2,temp3;//temp3;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
LCD_Init(); //初始化LCD接口
Adc_Init(); //初始化ADC
POINT_COLOR=RED;
LCD_ShowString(200,70,200,16,24,"UESTC");
while(1)
{
ADC1ConvertedVoltage[0] = 0;
ADC1ConvertedVoltage[1] = 0;
ADC1ConvertedVoltage[2] = 0;
for(i=0;i<3;i++)
{
for(j=0;j<64;j++)
{
ADC1ConvertedVoltage
+= ADC1ConvertedValue[j];
}
ADC1ConvertedVoltage = ADC1ConvertedVoltage/64;
}
temp1 = ADC1ConvertedVoltage[0]*3.3/4096;
temp2 = ADC1ConvertedVoltage[1]*3.3/4096;
temp3 = ADC1ConvertedVoltage[2]*3.3/4096;
printf("AD1:%d Vol:%4.2fV AD2:%d Vol:%4.2fV
",ADC1ConvertedVoltage[0],temp1,ADC1ConvertedVoltage[1],temp2);
LCD_ShowxNum(134,130,ADC1ConvertedVoltage[0],4,16,0); //显示ADCC采样后的原始值
i=temp1; //赋值整数部分给adcx变量,因为adcx为u16整形
LCD_ShowxNum(134,150,i,1,16,0); //显示电压值的整数部分,3.1111的话,这里就是显示3
temp1-=i; //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
temp1*=1000; //小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。
LCD_ShowxNum(150,150,temp1,3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.
LCD_ShowxNum(134,170,ADC1ConvertedVoltage[1],4,16,0); //显示ADCC采样后的原始值
i=temp2; //赋值整数部分给adcx变量,因为adcx为u16整形
LCD_ShowxNum(134,190,i,1,16,0); //显示电压值的整数部分,3.1111的话,这里就是显示3
temp2-=i; //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
temp2*=1000; //小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。
LCD_ShowxNum(150,190,temp2,3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.
LCD_ShowxNum(134,230,ADC1ConvertedVoltage[2],4,16,0); //显示ADCC采样后的原始值
i=temp3; //赋值整数部分给adcx变量,因为adcx为u16整形
LCD_ShowxNum(134,250,i,1,16,0); //显示电压值的整数部分,3.1111的话,这里就是显示3
temp3-=i; //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
temp3*=1000; //小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。
LCD_ShowxNum(150,250,temp3,3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.
LED0=!LED0;
delay_ms(1000);
}
为什么我采集两个通道的时候可以,采集三个的时候就采集不到了,求大神帮我看看程序哪里不对
一周热门 更多>