2019-05-03 11:05:44 imxlw00 阅读数 452
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4003 人正在学习 去看看 朱有鹏
  • 模拟量:自然界连续变化的物理量。所谓连续,包含两个方面的含义;

    一方面从时间上来说,它是随时间连续变化的;
    另一方面从数值上来说,它的数值也是连续变化的。这种连续变化的物理量通常称为模拟量。

  • 数字量:计算机中处理的是不连续变化的量,离散性的数字量。

  • D/A 数模转换器 (Digital - Analog Convert)

  • A/D 模拟转换器(Analog - Digital Convert)

A/D转换器的主要技术指标

1、分辨率
ADC的分辨率是指使输出数字量变化一个相邻数码所需输入模拟电压的变化量。常用二进制的位数表示。例如12位ADC的分辨率就是12位,或者说分辨率为满刻度FS的1/2^12。

一个10V满刻度的12位ADC能分辨输入电压变化最小值是10V×1/2^12=2.4mV。
2、量化误差
ADC把模拟量变为数字量,用数字量近似表示模拟量,这个过程称为量化。量化误差是ADC的有限位数对模拟量进行量化而引起的误差。实际上,要准确表示模拟量,ADC的位数需很大甚至无穷大。一个分辨率有限的ADC的阶梯状转换特性曲线与具有无限分辨率的ADC转换特性曲线(直线)之间的最大偏差即是量化误差。
在这里插入图片描述
3、偏移误差
偏移误差是指输入信号为零时,输出信号不为零的值,所以有时又称为零值误差。假定ADC没有非线性误差,则其转换特性曲线各阶梯中点的连线必定是直线,这条直线与横轴相交点所对应的输入电压值就是偏移误差。
4、满刻度误差
满刻度误差又称为增益误差。ADC的满刻度误差是指满刻度输出数码所对应的实际输入电压与理想输入电压之差。
5、线性度
线性度有时又称为非线性度,它是指转换器实际的转换特性与理想直线的最大偏差。
6、绝对精度
在一个转换器中,任何数码所对应的实际模拟量输入与理论模拟输入之差的最大值,称为绝对精度。对于ADC而言,可以在每一个阶梯的水平中点进行测量,它包括了所有的误差。
7、转换速率
ADC的转换速率是能够重复进行数据转换的速度,即每秒转换的次数。而完成一次A/D转换所需的时间(包括稳定时间),则是转换速率的倒数。
A/D转换器的转速速度主要取决于转换电路的类型,不同类型的A/D转换器的转换速度相差很大。

  • 双积分A/D转换器的转换速度最慢,需几百毫秒左右;
  • 逐次逼近式A/D转换器的转换速度最快,需十几微秒;
  • 并行比较型A/D转换器的转换速度最快,仅需几十纳秒。

逐次逼近式ADC的转换原理

在这里插入图片描述
逐次逼近式AD转换器与计数式A/D转换类似,只是数字量由“逐次逼近寄存器SAR”产生。SAR使用“对分搜索法”产生数字量,以8位数字量为例,SAR首先产生8位数字量的一半,即10000000B,试探模拟量Vi的大小,若Vn>Vi,清除最高位,若Vn<Vi,保留最高位。在最高位确定后,SAR又以对分搜索法确定次高位,即以低7位的一半y1000000B(y为已确定位) 试探模拟量Vi的大小。在bit6确定后,SAR以对分搜索法确定bit5位,即以低6位的一半yy100000B(y为已确定位) 试探模拟量的大小。重复这一过程,直到最低位bit0被确定,转换结束。

PCF8591的介绍

PCF8591 是单电源,低功耗8 位CMOS 数据采集器件,具有4 个模拟输入、一个输出和一个串行I2C 总线接口。3 个地址引脚A0、A1 和A2 用于编程硬件地址,允许将最多8 个器件连接至I2C总线而不需要额外硬件。PCF8591由于其使用的简单方便和集成度高,在单片机应用系统中得到了广泛的应用。
特点:

  • 单电源供电
  • 工作电压:2.5 V ~ 6 V
  • I2C总线串行输入/输出
  • 通过3个硬件地址引脚编址
  • 采样速率取决于 I2C 总线传输速率决定
  • 4个模拟输入可编程为单端或差分输入
  • 自动增量通道选择
  • 8位逐次比较型A/D 转换
    在这里插入图片描述

管脚定义:

AIN0~AIN3:模拟量输入通道
AOUT:模拟输出通道
A0~A2:硬件设备地址
VDD:电源正极
VSS:电源负极
VREF:参考电压输入。
EXT:振荡器输入时,内部/外部的切换开关。
OSC:振荡器输入/输出。
SCL:I2C BUS时钟输入。
SDA:I2C BUS 数据输入/输出。
AGND:模拟地,模拟信号和基准电源的参考地

控制字格式

在这里插入图片描述
最高位默认为0

第6位是选择是否允许模拟电压输出,在DA转换时设置为1,AD转换时设置为0或1均可

第5/4位是选择模拟电压输出方式,一般选择00单端输入方式,其他的几种方式如下图所示
在这里插入图片描述
第3位默认为0

第2位是自动增量使能位,如果自动增量(auto-increment)标志置1,每次A/D 转换后通道号将自动增加。

第1/0为是在AD转换时选择哪一个通道输入的电压转换为数字量.

PCF8591的器件地址

每一个IIC器件都有一个器件地址,来区分不同的IIC设备,下面是PCF8591的地址
在这里插入图片描述
在这里插入图片描述
它的地址是由1001和A2A1A0组成的,在原理图中可以看出,A2A1A0均为0,所以器件地址为0x90/0x91,最后一位是读写方向位,0表示下一个字节往总线上写数据,1表示下一个字节从总线上读取数据.

2018-01-17 09:08:22 goodstudylinux 阅读数 7776
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4003 人正在学习 去看看 朱有鹏
    1.(概念)A/D 是模拟量到数字量的转换,依靠的是模数转换器(Analog to Digital Converter),简称ADC。D/A 是数字量到模拟量的转换,依靠的是数模转换器(Digital to Analog Converter),简

称 DAC。

    2.ADC 的位数:一个 n 位的 ADC 表示这个 ADC 共有 2 的 n 次方个刻度。8 位的 ADC,输出的是从 0~255 一共 256 个数字量,也就是 2 的 8 次方个数据刻度。

基准源:基准源,也叫基准电压,假如我们的基准源应该是 5V,但是实际上提供的却是 4.5V,这样误把 4.5V 当成了 5V 来处理的话,偏差也会比较大。

分辨率:分辨率是数字量变化一个最小刻度时,模拟信号的变化量,定义为满刻度量程与 2 n -1 的比值。假定 5V 的电压系统,使用 8 位的 ADC 进行测量,那么相当于 0~255 一共 256 个刻度把 5V 平均分成了 255 份,那么分辨率就是 5/255 = 0.0196V。

INL(积分非线性度)和 DNL(差分非线性度):INL 指的是 ADC 器件在所有的数值上对应的模拟值,和真实值之间误差最大的那一个点的误差值,是 ADC 最重要的一个精度指标,单位是 LSB。LSB(Least Significant Bit)是最低有效位的意思, 那么它实际上对应的就是 ADC的分辨率。 一个基准为5V的8位ADC,它的分辨率就是 0.0196V,用它去测量一个电压信号,得到的结果是 100,就表示它测到的电压值是 100*0.0196V=1.96V,假定它的 INL 是 1LSB,就表示这个电压信号真实的准确值是在1.9V~2.0V 之间的,按理想情况对应得到的数字应该是 99~101,测量误差是一个最低有效位,即 1LSB。DNL 表示的是 ADC 相邻两个刻度之间最大的差异,单位也是 LSB。

转换速率:转换速率, 是指 ADC 每秒能进行采样转换的最大次数, 单位是 sps (或 s/s、 sa/s, 即 samples
per second) ,它与 ADC 完成一次从模拟到数字的转换所需要的时间互为倒数关系。

    3 .PCF8591 的硬件接口:PCF8591 是一个单电源低功耗的 8 位 CMOS 数据采集器件,具有 4 路模拟输入,1 路模拟输出和一个串行 I 2 C 总线接口用来与单片机通信。3 个地址引脚 A0、A1、A2 用于编程硬件地址,允许最多 8 个器件连接到 I 2 C 总线而不需要额外的片选电路。


其中引脚 1、2、3、4 是 4 路模拟输入,引脚 5、6、7 是 I 2 C 总线的硬件地址,8 脚是数字地 GND,9 脚和 10 脚是 I 2 C 总线的 SDA 和 SCL。12 脚是时钟选择引脚,如果接高电平表示用外部时钟输入,接低电平则用内部时钟,这套电路用的是内部时钟,因此 12 脚直接接 GND,同时 11 脚悬空。13 脚是模拟地 AGND。

2019-02-25 20:04:11 Xiaomo_haa 阅读数 972
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4003 人正在学习 去看看 朱有鹏

 

A/D的主要指标

1、ADC的位数

一个n位的ADC表示这个ADC共有2的n次方个刻度。8位的ADC输出的是从0~255一共256个数字值,也就是2^{^{8}}个数据刻度。。

2、基准源

基准源也叫基准电压,是ADC的一个重要指标,要想把输入的ADC的信号测量准确,那么基准源首先要准,基准源的偏差会直接导致转换结果的偏差。

3、分辨率

分辨率是数字量变化一个最小刻度时,模拟信号的变化量,定义为满刻度量程与2^{_{n}}-1的比值。假定5.10V的电压系统,使用8位的ADC进行测量,那么相当于0~255一共256个刻度把5.10V平均分成了255份,那么分辨率就是5.10/255=0.02V。

4、INL(积分非线性度)和 DNL(差分非线性度)

ADC精度关系重大的两个指标是INL(IntegralNonLiner)和 DNL(Differencial NonLiner) 。

INL 指的是 ADC 器件在所有的数值上对应的模拟值,和真实值之间误差最大的那一个点的误差值,是 ADC 最重要的一个精度指标,单位是 LSB。

LSB(Least Significant Bit)是最低有效位的意思,那么它实际上对应的就是 ADC的分辨率。一个基准为5.10V的8位ADC,它的分辨率就是 0.02V,用它去测量一个电压信号,得到的结果是 100,就表示它测到的电压值是 100*0.02V=2V,假定它的 INL 是 1LSB,就表示这个电压信号真实的准确值是在1.98V~2.02V 之间的,按理想情况对应得到的数字应该是 99~101,测量误差是一个最低有效位,即 1LSB。

DNL 表示的是 ADC 相邻两个刻度之间最大的差异,单位也是 LSB。一把分辨率是 1 毫米的尺子,相邻的刻度之间并不都刚好是 1 毫米,而总是会存在或大或小的误差。同理,一个 ADC 的两个刻度线之间也不总是准确的等于分辨率,也是存在误差,这个误差就是 DNL。

一个基准为 5.10V 的 8 位 ADC,假定它的 DNL 是 0.5LSB,那么当它的转换结果从 100 增加到 101 时,理想情况下实际电压应该增加 0.02V,但 DNL 为 0.5LSB 的情况下实际电压的增加值是在 0.01~0.03V 之间。值得一提的是 DNL 并非一定小于 1LSB,很多时候它会等于或大于 1LSB,这就相当于是一定程度上的刻度紊乱,当实际电压保持不变时,ADC 得出的结果可能会在几个数值之间跳动,很大程度上就是由于这个原因(但并不完全是,因为还有无时无处不在的干扰的影响)。

5、转换速率 

转换速率,是指 ADC 每秒能进行采样转换的最大次数,单位是 sps (或 s/s、sa/s,即 samplesper second),它与 ADC 完成一次从模拟到数字的转换所需要的时间互为倒数关系。ADC 的种类比较多,其中积分型的 ADC 转换时间是毫秒级的,属于低速 ADC;逐次逼近型 ADC转换时间是微秒级的,属于中速 ADC;并行/串行的 ADC 的转换时间可达到纳秒级,属于高速 ADC。

PCF8591的硬件接口

PCF8591是一个单电源低功耗的 8 位 CMOS 数据采集器件,具有 4 路模拟输入,1 路模拟输出和一个串行 I 2 C 总线接口用来与单片机通信。与前面讲过的 24C02 类似,3 个地址引脚 A0、A1、A2 用于编程硬件地址,允许最多 8 个器件连接到I2C 总线而不需要额外的片选电路。器件的地址、控制以及数据都是通过 I2C 总线来传输。

其中引脚 1、2、3、4 是 4 路模拟输入,引脚 5、6、7 是 I 2 C 总线的硬件地址,8 脚是数字地 GND,9 脚和 10 脚是 I 2 C 总线的 SDA 和 SCL。12 脚是时钟选择引脚,如果接高电平表示用外部时钟输入,接低电平则用内部时钟,我们这套电路用的是内部时钟,因此 12 脚直接接 GND,同时 11 脚悬空。13 脚是模拟地 AGND,在实际开发中,如果有比较复杂的模拟电路,那么 AGND 部分在布局布线上要特别处理,而且和 GND 的连接也有多种方式,这个板子上没有复杂的模拟部分电路,所以我们把 AGND 和 GND 接到一起。14 脚是基准源,15 脚是 DAC 的模拟输出,16 脚是供电电源 VCC。

PCF8591 的 ADC 是逐次逼近型的,转换速率算是中速,但是它的速度瓶颈在 I 2 C 通信上。由于 I 2 C 通信速度较慢,所以最终的 PCF8591 的转换速度,直接取决于 I 2 C 的通信速率。由于 I 2 C 速度的限制,所以 PCF8591 得算是个低速的 AD 和 DA 的集成,主要应用在一些转换速度要求不高,希望成本较低的场合,比如电池供电设备,测量电池的供电电压,电压低于某一个值,报警提示更换电池等类似场合。

Vref 基准电压的提供有两种方法。一是采用简易的原则,直接接到 VCC 上去,但是由于 VCC 会受到整个线路的用电功耗情况影响,一来不是准确的 5V,实测大多在 4.8V 左右,二来随着整个系统负载情况的变化会产生波动,所以只能用在简易的、对精度要求不高的场合。方法二是使用专门的基准电压器件,比如 TL431,它可以提供一个精度很高的 2.5V 的电压基准。

对于AD 来说,只要输入信号超过 Vref 基准源,它得到的始终都是最大值,即 255,也就是说它实际上无法测量超过其 Vref 的电压信号的。需要注意的是,所有输入信号的电压值都不能超过 VCC,即+5V,否则可能会损坏 ADC 芯片。

在CT107D开发板上,Vref是直接接到了VCC上。

PCF8591编程

PCF8591 的通信接口是 I 2 C,那么编程肯定是要符合这个协议的。单片机对 PCF8591 进行初始化,一共发送三个字节即可。

第一个字节,和E2PROM类似,是器件地址字节,其中7位代表地址,一位代表读写方向。地址高四位固定是0b1001,低三位是A2、A1、A0,这三位在电路上都接到了GND,因此也就是0b00,如下图所示:

第二个字节,将被存储在控制寄存器里,用于控制PCF8591的功能。其中第3位和第7位是固定的0,另外66位各自有各自的作用,如下图所示:

控制字节的第 6 位是 DA 使能位,这一位置 1 表示 DA 输出引脚使能,会产生模拟电压输出功能。

第4位和第5位可以实现把PCF8591的4路模拟输入配置成单端模式和差分模式,是配置 AD输入方式的控制位。单端模式和差分模式的区别。 如下图所示:

控制字节的第 2 位是自动增量控制位,自动增量的意思就是,比如一共有 4 个通道,当全部使用的时候,读完了通道 0,下一次再读,会自动进入通道 1 进行读取,不需要我们指定下一个通道。 

注意:由于 A/D 每次读到的数据,都是上一次的转换结果,所以在使用自动增量功能的时候,要特别注意,当前读到的是上一个通道的值。 为了保持程序的通用性,代码没有使用这个功能,而是直接做了一个通用的程序。

控制字节的第 0 位和第 1 位就是通道选择位了,00、01、10、11 代表了从 0 到 3 的一共4 个通道选择。

第三个字节,D/A数据寄存器,表示D/A模拟输出的电压值。如果仅仅使用A/D功能,可不发送第三个字节!

ADC程序

/*******************************************************************************
* 函数名	:Read_AIN
* 输入值	:unsigned char chn
* 返回值	:unsigend char dat
* 作者		:小默haa
* 时间		:2019年2月25日
* 功能描述:读取PCF8591AIN采集数据
* 备注		:chn为PCF8591的通道
*******************************************************************************/
unsigned char Read_AIN(unsigned char chn)
{
	unsigned char dat;
	EA = 0;
	IIC_Start();				//IIC总线起始信号							
	IIC_SendByte(0x90); 		//PCF8591的写设备地址		
	IIC_WaitAck();  			//等待从机应答		
	IIC_SendByte(chn); 			//写入PCF8591的控制字节		
	IIC_WaitAck();  			//等待从机应答						
	IIC_Stop(); 				//IIC总线停止信号					
	
	IIC_Start();				//IIC总线起始信号									
	IIC_SendByte(0x91); 		//PCF8591的读设备地址		
	IIC_WaitAck(); 				//等待从机应答		
	dat = IIC_RecByte();		//读取PCF8591通道3的数据 			
	IIC_Ack(0); 				//产生非应答信号				
	IIC_Stop(); 				//IIC总线停止信号		
	EA = 1;
	return dat;	
}

/*******************************************************************************
* 函数名	:ValueToString
* 输入值	:unsigned char *str, unsigned char val
* 返回值	:none
* 作者		:小默haa
* 时间		:2019年2月25日
* 功能描述:将PCF8591AIN采集的数据转换为字符型
* 备注		:注意这里把电压扩大了10倍
*******************************************************************************/
void ValueToString(unsigned char *str, unsigned char val)
{
    val = (val * 50) / 255;  //电压5V,256个刻度分成255份!
    str[0] = val / 10;
    str[1] = ‘.’;
    str[2] = val % 10;
    str[3] = ‘V’;
}

注意:在程序里我设置开始读ADC值时关闭中断,避免ADC测量程序被中断打断,影响精准度。 

D/A输出

/*******************************************************************************
* 函数名	:SetDACOut
* 输入值	:unsigned char val
* 返回值	:none
* 作者		:小默haa
* 时间		:2019年2月25日
* 功能描述:输入电压值,设置DAC输出值
* 备注		:val为设定的电压值
*******************************************************************************/
void SetDACOut(unsigned char val)
{
    IIC_Start();
    if(IIC_WaitAck() == 1)
    {
			IIC_Stop();
      return;
    }
    IIC_SendByte(0x40);
    IIC_SendByte(val);
    IIC_Stop();
}

/*******************************************************************************
* 函数名	:KeyAction
* 输入值	:unsigned char keycode
* 返回值	:none
* 作者		:小默haa
* 时间		:2019年2月25日
* 功能描述:通过按键控制输出电压值
* 备注		:
*******************************************************************************/
void KeyAction(unsigned char keycode)
{
    static unsigned char volt = 0;

    if(keycode == 0x26)			//向上键,增加0.1V电压值
    {
        if(volt < 50)
        {
            volt++;
            SetDACOut((volt * 255) / 50);		//转换为AD输出值
        }
    }   
    else if(keycode == 0x28)		//向下键,减小0.1V电压值
    {
        if(volt > 0)
        {
            volt--;
            SetDACOut((volt * 255) / 50);		//转换为AD输出值
        }
    }
}

 

 

 

 

 

 

 

2015-08-07 13:01:47 u014249394 阅读数 1505
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4003 人正在学习 去看看 朱有鹏
  • 介绍

有些传感器的输出值有模拟值,这样的数值是不可读的,如果想要把这些模拟值变为可读的,就必须要用到数模转化模块。

PCF8591是一个单片集成、单独供电、低功耗、8-bit CMOS数据获取器件。PCF8591具有4个模拟输入、1个模拟输出和1个串行I2C总线接口。PCF8591的3个地址引脚A0, A1和A2可用于硬件地址编程,允许在同个I2C总线上接入8个PCF8591器件,而无需额外的硬件。在PCF8591器件上输入输出的地址、控制和数 据信号都是通过双线双向I2C总线以串行的方式进行传输。

  • 玉照

[caption id="attachment_1600" align="alignnone" width="270"]PCF8591数模转化模块 PCF8591数模转化模块[/caption]

 

  • 接口介绍

本模块左边和右边分别外扩2路排针接口,分别说明如下:
左边 AOUT 芯片DA输出接口
AINO 芯片模拟输入接口0
AIN1 芯片模拟输入接口1
AIN2 芯片模拟输入接口2
AIN3 芯片模拟输入接口3
右边 SCL  IIC时钟接口  接单片机IO口
SDA  IIC数字接口  接单片机IO口
GND  模块地       外接地
VCC  电源接口     外接3.3v-5v

 

模块共有3个红色短路帽,分别作用如下:
P4   接上P4短路帽,选择热敏电阻接入电路
P5   接上P5短路帽,选择光敏电阻接入电路
P6   接上P6短路帽,选择0-5V可调电压接入电路

  • 参考

http://baike.baidu.com/link?url=j9gRwR8fcU6H33GWfKSagJyQjNLH1WIYCo9yfviy7RrzVf98cF5iAaBJqADrDYeo45qBfF53wK4LtHA1xf1S6q

www.eeboard.com/bbs/thread-41467-1-3.html

http://www.eeboard.com/bbs/thread-40960-1-1.html

查看原文:http://surenpi.com/2015/05/11/%e6%95%b0%e6%a8%a1%e8%bd%ac%e6%8d%a2%e6%a8%a1%e5%9d%97pcf8591/

2017-02-08 21:50:19 Von_kent 阅读数 1919
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4003 人正在学习 去看看 朱有鹏

PS:上一讲我们讲到了ADC(模数转换),这一讲中,我们介绍一下DAC(数模转换),简而言之,数模转换所完成的工作和模数转换正好相反——数字量转化成模拟量

ADC的时候,我们的stm32是引脚是负责接收一个模拟量,并且把它转化成数字量,而DAC的时候,我们的引脚是负责处理内部的数字指令,将其转化成模拟量进行输出,此时的引脚作为一个输出使用~

这是德州仪器的一篇英文DAC的知识简介:
http://e2e.ti.com/blogs_/b/analogwire/archive/2013/02/25/dac-essentials-a-new-blog-series

wiki的介绍:
https://zh.wikipedia.org/wiki/%E6%95%B8%E4%BD%8D%E9%A1%9E%E6%AF%94%E8%BD%89%E6%8F%9B%E5%99%A8

模拟量和数字量之间的关系:
模拟量和数字量之间的关系,mathematica绘制


OK,接下来开始介绍关于stm32内部的DAC特性

stm32内部的DAC

说实话,和stm32对ADC的支持相比较,DAC的支持显得可能会稍稍薄弱(误差大概高了0.03V),不过,这并不影响我们使用它。

特点
· 和ADC不同,在stm32中,ADC的结果存储在一个16位的寄存器中,但是,DAC可以配置为8位或12位模式,也可以与DMA控制器配合使用,当配置为12位模式时,也需要考虑左对齐或者右对齐。
· DAC模块有2个输出通道(PA4,PA5),每个通道都有单独的转换器。
· 在双DAC模式下,2个通道可以独立地进行转换,也可以同时进行转换并同步地更新2个通道的输出

DAC的主要模块:

1.  2个DAC转换器:每个转换器对应1个输出通道
2. 八位或十二位的单调输出
3. 噪声波形生成
4. 三角波生成
5. 双DAC同时转换,亦可分别转换
6. 每个通道都有DMA功能

DAC的框图

DAC
PS:我么可以看到,DAC可以被通用定时器触发,也可以被外部中断9触发,但是,我们考虑到初学,先不用管这些组合的问题,先简单了解下DAC的库函数配置~

DAC输出电压的范围理论上是在0~Vref,但是,实际上stm32f103的芯片会比理论值大了0.03V。

VDAC=Vref*(DOR/4095),4095是十二位寄存器的最大值-_-.

DAC的库函数配置(以DAC1为例):

因为在使能DACx之后,相应的GPIO引脚会自动与DAC的模拟输出引脚相连,设置为输入,为例避开干扰RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );      //使能PORTA通道时钟 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;                // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //模拟输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_4)  ;//PA.4 输出高

2. 使能DAC1时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );      //使能DAC通道时钟 

3. 初始化DAC并且设置工作模式

DAC_InitType.DAC_Trigger=DAC_Trigger_None;  //不使用触发功能 TEN1=0
DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;    //DAC1输出缓存关闭 BOFF1=1
DAC_Init(DAC_Channel_1,&DAC_InitType);   //初始化DAC通道1

4. 使能DAC的转换通道

DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC1
  1. 设置DAC的输出值

    DAC_SetChannel1Data(DAC_Align_12b_R,temp);//12位右对齐数据格式设置DAC值
    配置过程一览

void Dac1_Init(void)
{

    GPIO_InitTypeDef GPIO_InitStructure;
    DAC_InitTypeDef DAC_InitType;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );    //使能PORTA通道时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );      //使能DAC通道时钟 

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;                // 端口配置
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //模拟输入
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_4)  ;//PA.4 输出高

    DAC_InitType.DAC_Trigger=DAC_Trigger_None;  //不使用触发功能 TEN1=0
    DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
    DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
    DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;    //DAC1输出缓存关闭 BOFF1=1
    DAC_Init(DAC_Channel_1,&DAC_InitType);   //初始化DAC通道1

    DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC1

    DAC_SetChannel1Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值

}

//设置通道1输出电压
//vol:0~3300,代表0~3.3V
void Dac1_Set_Vol(u16 vol)
{
    float temp=vol;
    temp/=1000;
    temp=temp*4096/3.3;
    DAC_SetChannel1Data(DAC_Align_12b_R,temp);//12位右对齐数据格式设置DAC值
}

嵌入式51单片机流水灯原理详解

博文 来自: liangmaoxuan
没有更多推荐了,返回首页