新手上路
- 积分
- 25
- 金钱
- 25
- 注册时间
- 2016-8-24
- 在线时间
- 65 小时
|
5金钱
采用原子精英板子做的ADC采集程序,用PC0-PC3做为模拟输入引脚,程序已经可以在LCD上显示,但接上PC0接上3.3V后,PC0的数字量为4095,但PC1由原来的1900+变为2800+,另两个引脚的值变化不大,或者PC1接上3.3V后,效果类似于PC0接上3.3V的效果。
ADC的代码:
#include "adc.h"
#include "delay.h"
#define M 4 //4路AD
//初始化ADC
//ADC1_CH10--> C0
//ADC1_CH11--> C1
//ADC1_CH12--> C2
//ADC1_CH13--> C3
void Adc_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC| RCC_APB2Periph_ADC1 , ENABLE );
//RCC_APB2Periph_GPIOx,x=GPIOx
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //72M/6=12,ADC最大时间不能超过14M
//PC0--ADC_IN10 PC1--ADC_IN11 PC2--ADC_IN12 PC3--ADC_IN13
//PC0~3 4路作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; //PC0/1/2/3 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
//**************************************ADC设置
ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode =ENABLE; //多信道扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模数转换工作在连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //外部触发转换关闭
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 4; //此处开6个信道(可开的为1~16)
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
//ADC常规信道配置
//ADC1,ADC通道x,规则采样顺序值为y,采样时间为239.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 4, ADC_SampleTime_239Cycles5 );
// 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)
ADC_DMACmd(ADC1, ENABLE); //使能ADC1的DMA传输
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1); //复位指定的ADC1的校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1)); //获取ADC1复位校准寄存器的状态,设置状态则等待
ADC_StartCalibration(ADC1); //开始指定ADC1的校准状态
while(ADC_GetCalibrationStatus(ADC1)); //获取指定ADC1的校准程序,设置状态则等待
}
DMA的代码 :
#include "dma.h"
//DMA1的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从外设模式->存储器/16位数据宽度/存储器增量模式
//DMA_CHx MA通道CHx //cpar:外设地址 //cmar:存储器地址//cndtr:数据传输量
void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA时钟
DMA_DeInit(DMA_CHx); //将DMA的通道1寄存器重设为缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外设基地址
DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,从外设发送到内存 DMA_CCRX位4
DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA缓存的大小
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; //内存数据宽度为16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在循环缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA_CHx, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
}
主函数的代码:
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "adc.h"
#include "dma.h"
#define ADC1_DR_Address ((uint32_t)0x4001244C)
#define N 10 //取50次平均值
#define M 4 //4路AD
u16 value[N][M];//存储ADC转换后N*M个数字量的数据
u16 aftervalue[M];//存储M个通道数字量的平均值
float avalue[M];//滤波后的通道采样电压值
u8 i=0,j=0;
////////////////滤波函数/////////////////////////////////////////////////////////////////////////
void filter(void)
{
int sum = 0;//sum 通道采样数值的总和
u8 count;//
for(i=0;i<M;i++)//每个通道进行循环滤波
{
for(count=0;count<N;count++)//采样N次循环
{
sum+=value[count][i];//计算出N次采样值的总和
}
aftervalue[i]=sum/N;//求出通道数字量的平均值
sum=0;//清零便于下次重新计算
}
}
/////////////////////////////主程序////////////////////////////////////////////////////////////
int main(void)
{
u8 x=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
delay_init(); //延时函数初始化
uart_init(115200); //串口初始化为115200
LED_Init(); //初始化与LED连接的硬件接口
LCD_Init();
Adc_Init(); //ADC初始化
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(60,8,200,16,16,"WARSHIP_STM32");
LCD_ShowString(60,24,200,16,16,"ADC+DMA TEST");
//显示提示信息
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(60,40,200,16,16,"ADC_CH0_VAL:");
LCD_ShowString(60,56,200,16,16,"ADC_CH1_VAL:");
LCD_ShowString(60,72,200,16,16,"ADC_CH2_VAL:");
LCD_ShowString(60,88,200,16,16,"ADC_CH3_VAL:");
POINT_COLOR=BRRED;
LCD_ShowString(60,168,200,16,16,"ADC_CH0_VOL:0.000V");
LCD_ShowString(60,184,200,16,16,"ADC_CH1_VOL:0.000V");
LCD_ShowString(60,200,200,16,16,"ADC_CH2_VOL:0.000V");
LCD_ShowString(60,216,200,16,16,"ADC_CH3_VOL:0.000V");
MYDMA_Config(DMA1_Channel1,(u32)&ADC1->DR,(u32)&value,M*N);//初始化DMA
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件打开ADC转换
DMA_Cmd(DMA1_Channel1, ENABLE); //打开DMA功能
while(1)
{
filter();//滤波,此处函数一定不能省,否则ADC不能正常工作
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowxNum(156,40,aftervalue[0],4,16,0);//显示ADC的值
LCD_ShowxNum(156,56,aftervalue[1],4,16,0);//显示ADC的值
LCD_ShowxNum(156,72,aftervalue[2],4,16,0);//显示ADC的值
LCD_ShowxNum(156,88,aftervalue[3],4,16,0);//显示ADC的值
///////////////计算出每个通道数字量对应的电压值的整数部分/////
for(i=0;i<M;i++)
{
avalue[i]=(float)aftervalue[i]*(3.3/4096);
aftervalue[i]=avalue[i];
}
/////////////////显示整数部分/////////////////////
LCD_ShowxNum(156,168, aftervalue[0],1,16,0);//显示电压值
LCD_ShowxNum(156,184, aftervalue[1],1,16,0);//显示电压值
LCD_ShowxNum(156,200, aftervalue[2],1,16,0);//显示电压值
LCD_ShowxNum(156,216, aftervalue[3],1,16,0);//显示电压值
//////////////计算出每个通道数字量对应的电压值的小数部分///////
for(i=0;i<M;i++)
{
avalue[i]-=aftervalue[i];
avalue[i]*=1000;//放大1000倍进行显示
}
/////////////////显示小数部分////////////////////
LCD_ShowxNum(172,168,avalue[0],3,16,0X80);
LCD_ShowxNum(172,184,avalue[1],3,16,0X80);
LCD_ShowxNum(172,200,avalue[2],3,16,0X80);
LCD_ShowxNum(172,216,avalue[3],3,16,0X80);
x++;
if(x==12)x=0;
LED0=!LED0;
delay_ms(200);
}
}
请教各位大神,是怎么回事!!!!!!
|
最佳答案
查看完整内容[请看2#楼]
1, PC0接3.3V,PC1接GND,读取结果如何?
2,单独测试PC0,PC1(不用DMA),测试结果如何?
|