你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 2871|回复: 5

转发:ARM®mbed OS入门开发(三 C)GPIO,模拟针脚读取...

[复制链接]

61

主题

1071

回帖

17

蝴蝶豆

论坛元老

最后登录
2020-12-9
发表于 2016-10-14 21:43:03 | 显示全部楼层 |阅读模式
现实世界大量的信号都是模拟信号,如温度、声音、加速度等,为了能够让微处理器能够处理这些信息,我们必须先把它们转换成数字信号,即完成模数转换(Anology to Digital Converter)工作,这在微处理器是由ADC组件完成的。对于用户来说,我们在ADC应用过程中需要关心ADC的采样精度(即模拟信号被量化成多大的数值空间)、参考电压(即模拟信号的电压范围,最大不能超过参考电压)、采样频率(即ADC采样的速度)。另外我们还可能关心ADC的路数和管脚数,路数表示同时可以进行的信号采样个数,管教数表示有多少个管脚可以用户ADC的输入,由于ADC采集其间会采用多路复用技术,所以可用管脚数必然会大于ADC路数,下图是ADC工作的原理图:

对于stm32来说,它的采用精度是12位,即ADC的数字输出范围是(0——2^12-1),最大采样频率是200kHZ,参考电压为Vdda的输入电压,建议为3.3V,一共有8个ADC管脚服用1路ADC组件。
考虑到现实世界需要的大量信号也是模拟信号,所以微处理器在完成必要的数字运算以后还需要把数字信号转换成模拟信号输出,这就是数模转换(DAC),实际上就是ADC的逆过程。对于DAC来说,我们同样需要关心转换精度、参考电压和转换频率,考虑到DAC在应用时一般都是连续输出,所以很少采用多路复用方式,即一路DAC只和一个GPIO管脚相连。对于STM32来说,它的DAC转换精度是12位,即DAC的数字输入范围是(0——2^12-1),参考电压也是Vdda,只有1路DAC1个GPIO管脚。
在mbed中,用AnalogIn表示ADC模拟输入,AnalogOut表示DAC模拟输出,主要API描述如下:
类名
方法
用途
AnalogIn
AnalogIn(PinName pin)
构造函数,把pin设定成模拟输入
float read()
读取ADC采样值,返回的是0-1之间的小数,即0代表0V,1代表3.3V
unsigned short read_u16()
读取ADC采样值,返回的是整数,,范围在0到65535之间
operator float()
操作符重载,相当于float read()
AnalogOut
AnalogOut(PinName pin)
构造函数,把pin设定成模拟输出
void write(float value)
设定DAC的输出值,范围为0-1之间的小数,即0代表0V,1代表3.3V
void write_u16(unsigned short value)
设定DAC的输出值,范围为0到65535之间
float read()
返回刚才DAC的0到1的输出值
AnalogOut& operator= (float percent)
操作符重载,相当于float read()
AnalogOut& operator= (AnalogOut& rhs)
操作符重载,相当于float read()
        mbed模拟输入输出初步应用
对于nucleo来说,A0,A1,A2,A3,A4,...可以设定成模拟输入功能,而只有P18能设定成模拟输出功能。首先,我们来体验一下mbed模拟输入的使用方法,在这里,我们使用了光敏电阻来体现外部模拟信号的变化。光敏电阻是一种随着光线强度变化而变化的电阻,标准参考值为10K欧姆,但随着光线的变暗它的电阻会升高,所以可以使用下面的电路来感知环境光的变化,其采样值越高,对应电路的采样值越大。

ad2.png
下面是对应的ADC采样代码,顺便还实现了类似光控开关的功能,当你把光敏电阻遮住的时候,LED1会被点亮,你还可以通过串口调试工具查看具体的采样值。
AnalogIn light(A0);
DigitalOut led1(D13);
float lvf=0;
ushort lvu=0;
int main()
{
    while(1)
    {
        lvf=(float)light;
        lvu=light.read_u16();
        printf("light adc count is %f , %d  \n",lvf,lvu);
        wait(0.5);
        if (lvf<0.7)
            led1=1;
        else
            led1=0;
    }

}
DAC模拟输出的体验相对来说比较困难,很多人都想到了LED的亮度,但实际上由于LED有导通电压,所以可以展现的亮度范围有限,所以效果并不明显,下面是对应的连接图和代码:

ad3.png
AnalogOut led(D13);
float ledvalue=1.0;
int main()
{
    while (1)
    {
        while(1)
        {
            led.write(ledvalue);
            wait (0.5);
            ledvalue=ledvalue-0.1;
            if (ledvalue<0.1)
                break;
        }
    }

}
当然,我们也可以直接将DAC输出与ADC输入相连,再通过串口输出查看DAC和ADC的效果,我们只需要把D13,A0相连即可,相应的代码如下:
AnalogOut ao(A0);
AnalogIn ai(A1);
float aoValue=0;
float aiValue=0;
int main()
{
    while (1)
    {
        while(1)
        {
            aoValue=aoValue+0.01;
            ao.write(aoValue);
            aiValue=ai.read();
            wait (0.5);
            printf("Aout is %f ,A in is %f, adc value is %f \n",aoValue, aiValue, aiValue*3.3);
        }
    }

}
     下面是它对应的输出片断:
Aout is 0.080000 ,A in is 0.077656, adc value is 0.256264
Aout is 0.090000 ,A in is 0.088156, adc value is 0.290916
Aout is 0.100000 ,A in is 0.107204, adc value is 0.353773
Aout is 0.110000 ,A in is 0.116484, adc value is 0.384396
Aout is 0.120000 ,A in is 0.126252, adc value is 0.416630
Aout is 0.130000 ,A in is 0.136020, adc value is 0.448864
Aout is 0.140000 ,A in is 0.137241, adc value is 0.452894



mbed的模拟输入输出原帖地址: http://mbed.smeshlink.com/cookbook/28-mbeda
已移植到nucleo上
回复

使用道具 举报

61

主题

1071

回帖

17

蝴蝶豆

论坛元老

最后登录
2020-12-9
 楼主| 发表于 2016-10-15 14:29:09 | 显示全部楼层
占楼备用
回复 支持 反对

使用道具 举报

31

主题

1951

回帖

0

蝴蝶豆

论坛元老

最后登录
2020-12-4
发表于 2016-10-15 20:20:48 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

31

主题

1951

回帖

0

蝴蝶豆

论坛元老

最后登录
2020-12-4
发表于 2016-10-15 20:23:35 | 显示全部楼层
很好的资料
回复 支持 反对

使用道具 举报

0

主题

159

回帖

0

蝴蝶豆

高级会员

最后登录
2017-3-9
发表于 2016-10-16 19:08:26 | 显示全部楼层
不错的教程
回复 支持 反对

使用道具 举报

6

主题

446

回帖

0

蝴蝶豆

金牌会员

最后登录
2017-5-24
发表于 2016-10-20 12:21:24 | 显示全部楼层
感谢分享
回复 支持 反对

使用道具 举报

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版