新手上路
- 积分
- 38
- 金钱
- 38
- 注册时间
- 2017-9-2
- 在线时间
- 11 小时
|
10金钱
本帖最后由 d779708957ddd 于 2017-10-11 16:25 编辑
编写的程序使用的是ADC+DMA,但是我采样得到的数据都是0引脚是没问题的,我尝试把引脚用作读取高低电平,是能够读取的。
程序里面是用的PA6脚做ADC采样
PC8 PC9我是用作输出脚,来观察是否有采集到数据
劳烦大神花时间帮小弟看一下写的程序哪里有问题,谢谢了。
再附上程序压缩包
下面是adc.c里面的程序
#include "stm32f10x.h"
#include "adc.h"
#include "delay.h"
void Adc_Init(u32 cpar,u32 cmar)
{ DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC |RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_8 ;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_8);
GPIO_SetBits(GPIOC,GPIO_Pin_9);
//PA1 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
ADC_StructInit(&ADC_InitStructure);
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 = 1; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_55Cycles5 );
ADC_GetCalibrationStatus(ADC1);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1 //使能指定的ADC1的软件转换启动功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
DMA_DeInit(DMA1_Channel1); //将DMA的通道1寄存器重设为缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //内存作为数据传输的目的地
DMA_InitStructure.DMA_BufferSize = 1; //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(DMA1_Channel1, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道
}
下面是main.c里面的程序
#include "delay.h"
#include "sys.h"
#include "adc.h"
#define ADC1_DR_Address ((uint32_t)0x4001244C)
u16 AD_Value[1];
u16 volta[1];
u8 i;
int main(void)
{
SystemInit();
delay_init(); //延时初始化
Adc_Init((u32)ADC1_DR_Address,(u32)&AD_Value);
DMA_Cmd(DMA1_Channel1, ENABLE); //启动DMA通道
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //软件启动AD转换
GPIO_ResetBits(GPIOC,GPIO_Pin_9);
////////////////////////////////////////////////
这个脚在我自己设计的硬件板上是接一个LED灯的,加这个是因为我之前用正点原子教程里面那个ADC单通道采样程序修改,但是发现采样不了,然后加了几个GPIO_ResetBits,发现在下面这个程序的while里面卡死了
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结
//////////////////////////////////////////////
delay_ms(50);
while(1)
{ volta =AD_Value/4095*3300;
if (volta[0]==0) GPIO_ResetBits(GPIOC,GPIO_Pin_8|GPIO_Pin_9);
else GPIO_SetBits(GPIOC,GPIO_Pin_8|GPIO_Pin_9);
delay_ms(50);
}
听二楼的建议我将
u16 volta[1];改成了 float volta[1];
volta =AD_Value/4095*3300; 改成了volta =(float)AD_Value*(3300/4095);
但是还是不行,采样得到的值还是0
|
|