OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2931|回复: 5

小白求教 STM32F103R8T6 ADC问题

[复制链接]

1

主题

4

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2016-5-13
在线时间
5 小时
发表于 2016-5-13 13:19:46 | 显示全部楼层 |阅读模式
5金钱
本人第一次接触STM32,最近在做一个采集可燃气体浓度的设计,卡在了AD采集这块,我打算用PC0采集模拟量电压显示在OLED上,参照原子大哥的书配置如下:
void  Adc_Init(void)
{   
        //先初始化IO口
        RCC->APB2ENR|=1<<4;    //使能PORTC口时钟
        GPIOC->CRL&=0XFFFFFFF0;//PC0 anolog输入
        //通道10/11设置                         
        RCC->APB2ENR|=1<<9;    //ADC1时钟使能          
        RCC->APB2RSTR|=1<<9;   //ADC1复位
        RCC->APB2RSTR&=~(1<<9);//复位结束            
        RCC->CFGR&=~(3<<14);   //分频因子清零       
        //SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M!
        //否则将导致ADC准确度下降!
        RCC->CFGR|=2<<14;               

        ADC1->CR1&=0XF0FFFF;   //工作模式清零
        ADC1->CR1|=0<<16;      //独立工作模式  
        ADC1->CR1&=~(1<<8);    //非扫描模式          
        ADC1->CR2&=~(1<<1);    //单次转换模式
        ADC1->CR2&=~(7<<17);          
        ADC1->CR2|=7<<17;           //软件控制转换  
        ADC1->CR2|=1<<20;      //使用用外部触发(SWSTART)!!!        必须使用一个事件来触发
        ADC1->CR2&=~(1<<11);   //右对齐         
        ADC1->SQR1&=~(0XF<<20);                                                                                       
        ADC1->SQR1&=0<<20;     //1个转换在规则序列中 也就是只转换规则序列1                                
                  
        //设置通道1的采样时间
        ADC1->SMPR1&=~(7<<0);//通道10采样时间清空                   
        ADC1->SMPR1|=7<<0;      //通道10  239.5周期,提高采样时间可以提高精确度                

        ADC1->CR2|=1<<0;            //开启AD转换器         
        ADC1->CR2|=1<<3;        //使能复位校准  
        while(ADC1->CR2&1<<3);  //等待校准结束                          
    //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。                  
        ADC1->CR2|=1<<2;        //开启AD校准          
        while(ADC1->CR2&1<<2);  //等待校准结束
        //该位由软件设置以开始校准,并在校准结束时由硬件清除  
}                                  
//获得ADC值
//ch:通道值 0~16
u16 Get_Adc(u16 ch)   
{
        //设置转换序列                           
        ADC1->SQR2&=0XFFF07FFF;//规则序列1 通道ch                       
        ADC1->SQR2|=ch;                                                                     
        ADC1->CR2|=1<<22;       //启动规则转换通道                                
        while(!(ADC1->SR&1<<1));//等待转换结束                                   
        return ADC1->DR;                //返回adc值       
}  


主函数部分
while(1)
{
adcx=Get_Adc(ADC_CH10);      //ADC_CH10宏定义为10
OLED_ShowNum(40,16,adcx,4,16);
OLED_Refresh_Gram();
delay_ms(300);
}
结果OLED显示的电压(0~5V)数字量完全不符合预期,应该就是没有采集上来,急的我一头包。。。
麻烦各位大大帮忙看一下我的配置哪里出了问题,万分谢谢!!!

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-5-13 20:23:51 | 显示全部楼层
先用printf打印出来,看看数据是否正常。
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2016-5-13
在线时间
5 小时
 楼主| 发表于 2016-5-13 20:53:09 来自手机 | 显示全部楼层
正点原子 发表于 2016-5-13 20:23
先用printf打印出来,看看数据是否正常。

好的,我去试一下
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2016-5-13
在线时间
5 小时
 楼主| 发表于 2016-5-13 21:42:57 来自手机 | 显示全部楼层
正点原子 发表于 2016-5-13 20:23
先用printf打印出来,看看数据是否正常。

打印出来的数据和oled显示的一样,都不正常。我怀疑是不是SQR2那里设置通道10的那几句不对?
回复

使用道具 举报

3

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2016-4-28
在线时间
8 小时
发表于 2016-5-13 21:54:14 | 显示全部楼层
最近做毕设 107板子采集电压 是 uint16_t 类型的值,然后需要换算 电压实际=ADC值*LSB
LBS=Vref+/2的十二次方
例如:
ADC_ConvertedValue/4096*3.3;
不知道你的有没有?
Vref+ 为ADC模块连接的参考电压.
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2016-5-13
在线时间
5 小时
 楼主| 发表于 2016-5-13 22:13:40 来自手机 | 显示全部楼层
zhq566 发表于 2016-5-13 21:54
最近做毕设 107板子采集电压 是 uint16_t 类型的值,然后需要换算 电压实际=ADC值*LSB
LBS=Vref+/2的十二 ...

有的,我还没换算,事实上我还得把电压值转换成浓度ppm值。现在我让它显示的就是ad采集过来的数字量。我的参考电压是3.3v,传感器输出的模拟电压值是0.5左右,所以oled显示的数字量起码应该是4096*0.5/3.3约等于620,然而我现在显示的数字量一直在几十到200之间跳,可燃气体浓度提高,输出模拟量电压明显提高后oled显示的量也不变,肯定是没采集上来
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 03:29

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表