STM8L052 IAR环境下ADC奇怪的现象

2019-12-17 21:29发布

本帖最后由 add00 于 2016-9-21 18:50 编辑

STM8L052 IAR环境下ADC单次采样,出现一个问题? 判断EOC后读出来的值和ADC_Cmd(ADC1,ENABLE)与ADC_SoftwareStartConv(ADC1)之间的延迟时间相关;
之前都说第一次采样的值不对,其实是第一次ADC_Cmd(ADC1,ENABLE)与ADC_SoftwareStartConv(ADC1)之间的延迟时间不够,当你加入足够的延时时,你会发现第一次采样的值也是正确的的。

IAR环境 HSI不分频
  1. while(1)
  2. {
  3.         /* Config ADC Channel AIN7 */
  4.         GPIO_Init(GPIOB,GPIO_Pin_1,GPIO_Mode_In_FL_No_IT );  
  5.   
  6.           /* Enable ADC clock */
  7.         CLK_PeripheralClockConfig(CLK_Peripheral_ADC1,ENABLE);
  8.        
  9.         ADC_DeInit(ADC1);
  10.        
  11.         /* Initialize and configure ADC1 */
  12.         ADC_Init(ADC1,ADC_ConversionMode_Single,ADC_Resolution_12Bit,ADC_Prescaler_2);
  13.                                                                                         //单次转换 12位 2分频16/8 =2M
  14.         /* Config ADC Sampling Time */       
  15.         ADC_SamplingTimeConfig(ADC1,ADC_Group_SlowChannels,ADC_SamplingTime_384Cycles);

  16.         ADC_Cmd(ADC1,ENABLE);                                                //使能ADC       
  17.        
  18.         /* Enable ADC1 Channel 17*/
  19.         ADC1->SQR[1] =0x02;
  20. //        ADC_ChannelCmd(ADC1,ADC_Channel_17, ENABLE);
  21.        
  22.         /* Disable EOC interrupt */
  23. //        ADC_ITConfig(ADC1,ADC_IT_EOC,DISABLE);                        //禁止ADC中断
  24.        
  25.         ADC_DMACmd(ADC1,DISABLE);                                        //禁止DMA

  26.         Delay(2000);
  27.         Delay(2000);       
  28.         Delay(2000);       
  29.         Delay(2000);
  30.         Delay(2000);       
  31.        
  32.         ADC1->SR &=(~ADC_FLAG_EOC);                                        //清FLAG
  33.         ADC_SoftwareStartConv(ADC1);                                        //启动AD采样       
  34.         do
  35.         {
  36.                 End_Of_Conver =ADC1->SR;
  37.         }
  38.         while(0==(End_Of_Conver & ADC_FLAG_EOC));
  39.         BAT_AD=0;
  40.         BAT_AD=(uint8_t)(ADC_GetConversionValue(ADC1) >> 4);//取AD采样值高6位

  41. //        ADC_ChannelCmd(ADC1, ADC_Channel_17, DISABLE);
  42.         ADC1->SQR[1] =0x00;
  43.        
  44.         ADC_Cmd(ADC1,DISABLE);                                                //禁止ADC采样
  45.        
  46.         GPIO_Init(GPIOB,GPIO_Pin_1,GPIO_Mode_Out_PP_Low_Slow);        //端口输出拉低       
  47.        
  48.         CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, DISABLE);         //时钟停止
  49. }
复制代码

特殊应用,HALT ,所以每次初始化;
加断点时间最长        读数最大0932,200延时04CF,400延时0738,600延时0836,800延时08AC,1000延时08F0
具体效果见图
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
add00
1楼-- · 2019-12-18 01:48
是否可以认为,ADC端口上电到电平稳定采样需要一个充电时间,在这个稳定时间之后采样的数据才有效?
没仔细看文档,不知道官方有解释没?
20061002838
2楼-- · 2019-12-18 03:12
 精彩回答 2  元偷偷看……
add00
3楼-- · 2019-12-18 06:01
20061002838 发表于 2016-9-21 19:12
ADC_ChannelCmd 这个函数为什么不用
转换一次结果是错的,那连续转换两次呢,第二次的对吗 ...

原来用的,只是寄存器少几个操作周期,想AAA电池用7年,一步步的切换到寄存器,
实验了只要延时够长,第一次采样就是对的,如果延时不够,第二次也不一定对
20061002838
4楼-- · 2019-12-18 10:42
add00 发表于 2016-9-21 19:35
原来用的,只是寄存器少几个操作周期,想AAA电池用7年,一步步的切换到寄存器,
实验了只要延时够长,第 ...

我的ADC测量是没有问题的啊,代码如下:
你先使能ADC,再初始化试一下
还有就是 ADC_SchmittTriggerConfig 这个函数,禁止IO口上面的施密特触发器,你试下
  1.     /* Enable ADC1 clock */
  2.     CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE);

  3.     /* de-initialize ADC */
  4.     ADC_DeInit(ADC1);

  5.     ADC_Cmd(ADC1, ENABLE);
  6.     ADC_Init(ADC1, ADC_ConversionMode_Single, ADC_Resolution_12Bit, ADC_Prescaler_2);
  7.     ADC_SamplingTimeConfig(ADC1, ADC_Group_SlowChannels, ADC_SamplingTime_384Cycles);
  8.     ADC_ChannelCmd(ADC1, ADC_Channels, ENABLE);

  9.     for(i = 8; i > 0; i--)
  10.     {
  11.         /* start ADC convertion by software */
  12.         ADC_SoftwareStartConv(ADC1);
  13.         /* wait until end-of-covertion */
  14.         while( ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == 0 );
  15.         /* read ADC convertion result */
  16.         val += ADC_GetConversionValue(ADC1);
  17.     }
  18.     val = val >> 3;
  19.    
  20.     ADC_Cmd(ADC1, DISABLE);
复制代码
add00
5楼-- · 2019-12-18 13:42
20061002838 发表于 2016-9-21 19:53
我的ADC测量是没有问题的啊,代码如下:
你先使能ADC,再初始化试一下
还有就是 ADC_SchmittTriggerConfi ...

谢谢你的建议,问题找到了,不在ADC 和ADC_SchmittTriggerConfig 影响也不大,问题果然在端口;
你试下单次采样完后将IO配置GPIO_Init(GPIOB,GPIO_Pin_1,GPIO_Mode_Out_PP_Low_Slow);
初始化时将将IO配置GPIO_Init(GPIOB,GPIO_Pin_1,GPIO_Mode_In_FL_No_IT );  
问题马上就出来了;
因为做低功耗 io口配置要拉低,先就这样了
20061002838
6楼-- · 2019-12-18 16:50
add00 发表于 2016-9-22 10:12
谢谢你的建议,问题找到了,不在ADC 和ADC_SchmittTriggerConfig 影响也不大,问题果然在端口;
你试下单 ...

我的程序没把IO输出低电平
总功耗还可以,加上一个触摸IC,3.5uA左右
改天我试试,看能不能进一步降低

一周热门 更多>