小弟最近再写STM32的ADC,看了很多网的例程都是用DMA接数据,但是我想直接用AD读到寄存器,再拿出来处理。
在写程序的时候发现个问题,while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)); 这个while循环总是过不去,真心很郁闷……有哪位大神遇到过类似的问题吗? 求帮忙解决下 下面附上我的初始化以及读ADC程序
/************************ADC初始化***************************/
void ADC_Config(void)
{
ADC_InitTypeDef ADC_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE); //使能ADC1时钟
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; //配置对应的ADC通道IO口
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOC,&GPIO_InitStruct);
ADC_DeInit(ADC1); //将ADC所有寄存器值恢复默认
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; //ADC1与ADC2工作在独立工作模式
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; //DISABLE工作在单次模式;ENABLE工作在连续模式
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //定义触发方式,此处为软件触发
ADC_InitStruct.ADC_NbrOfChannel = 1; //ADC通道数目
ADC_InitStruct.ADC_ScanConvMode = ENABLE; //ADC工作在单通道还是多通道模式
ADC_ITConfig(ADC1,ADC_IT_EOC,DISABLE);
ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
ADC_Init(ADC1,&ADC_InitStruct);
/***************设置指定ADC的规则组通道,设置它们的转化顺序和采样时间****************/
/***************使能ADC的通道13,采样序列号为1,采样周期为71.5周期*******************/
ADC_RegularChannelConfig(ADC1,ADC_Channel_11,1,ADC_SampleTime_71Cycles5);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1); //重置ADC的校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1)); //获取ADC重置校准寄存器状态,直到校准寄存器重设完成
ADC_StartCalibration(ADC1); //开始指定ADC的校准
while(ADC_GetCalibrationStatus(ADC1)); //获取指定ADC的校准程序,直到校准完成
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1的软件转换启动功能
}
/***********读ADC程序*********************/
void Read_ADC(void)
{
unsigned short result = 0;
unsigned short id;
unsigned char a,b,c,d,i;
for(i=0;i<1;i++)
{
ADC_SoftwareStartConvCmd(ADC1,ENABLE); //启动ADC1转换
/* do{
id = ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC); //读取转换标志
}while(!id);*/
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
ADC_SoftwareStartConvCmd(ADC1,DISABLE);
result += ADC_GetConversionValue(ADC1);
Delay_ARMJISHU(8000000);
}
result = result>>3; //取8次平均值
result = (unsigned int)(((unsigned long)result)*3300>>12); //把采集到的数值转换成电压数据
a = result / 1000;
b = (result - a*1000)/100;
c = (result - a*1000 - b*100)/10;
d = result - a*1000 - b*100 - c*10;
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, 0x56);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, 0x3d);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, a+48);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1,0x2e);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, b+48);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, c+48);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, d+48);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1,0x56);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, 0x0d);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1,0x0a);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
}
用DMA没什么不好,配置好后直接读全局变量就可以了,也不会占用什么资源。
回复 楼主xinsuiwuhen 的帖子
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
试一下.
回复 板凳Study_Stellaris 的帖子
谢谢版主。。我刚刚试过了,还是不行,问题比较纠结,我后来想试试,会不会触发这个接收完成中断(ADC_IT_EOC),一样的问题,这个中断也完全不会触发。 但是我再我程序上附加DMA的接收,完全正常(我觉得这个可以说明我ADC初始化应该没大问题吧)………… 我实在想不明白为什么ADC_FLAG_EOC这个中断标志上过不去。。。。 版主有这方面的经验吗?求教啊
回复 板凳Study_Stellaris 的帖子
额,不好意思版主。。。 我刚才没烧对程序,改了之后确实通了。。。。。。。 版主求教啊,这个是为什么呢? 跪谢啊
问下,你后来解决了吗?我出现这个问题但是改了之后发现还是不行
回复 5楼xinsuiwuhen 的帖子
问下,你后来解决了吗?我出现这个问题但是改了之后发现还是不行
我最近也碰到过这个问题,但是最后发现犯得错误很二,,,是由于ADC的初始化函数没有加入到头文件中去,,啊,,,多么痛的领悟,,,
今天我也出现这个问题,发现DMA方式没有问题。另外如果编译选项改为-O1就可以了。
如果编译选项选择-O2或者-Otime就会有楼主说的问题。
原因还在查找当中。
如果FLASH运行较慢的话,读的时候已经清零了。
直接操作寄存器快一点 while((ADC1->SR & ADC_FLAG_EOC) == RESET);//等待转换结束 。应该就可以了