单片机第一季:零基础13——AD和DA转换

这篇具有很好参考价值的文章主要介绍了单片机第一季:零基础13——AD和DA转换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1,AD转换基本概念

51 单片机系统内部运算时用的全部是数字量,即0 和1,因此对单片机系统而言,无法直接操作模拟量,必须将模拟量转换成数字量。所谓数字量,就是用一系列0 和1 组成的二进制代码表示某个信号大小的量。用数字量表示同一个模拟量时,数字位数可以多也可以少,位数越多则表示的精度越高,位数越少表示的精度就越低。 

ADC(analog to digital converter)也称为模数转换器,是指一个将模拟信号转变为数字信号。单片机在采集模拟信号时,通常都需要在前端加上A/D 芯片。 

 A(A,analog,模拟的,D,digital,数字的)现实世界是模拟的,连续分布的,无法被分成有限份;计算机世界是数字的,离散分布的,是可以被分成有限份的;AD转换就是把一个物理量从模拟的转换成数字的。

AD转换中的主要概念:
(1)位数,AD转换后转出来的二进制数由几位二进制来表示。位数越多,越细腻;
(2)量程,AD转换器可以接受的模拟量的范围;
(3)精度,简单理解就是转出来到底有多准;
(4)分辨率,AD转换器转出来的二进制数,每一格表示多少;
(5)转换速率(转换时间); 

例:输入电压范围0-5V,AD转换输出位数是10,精度是0.01V,则:量程为0-5V,分辨率为:(5-0)/2exp(10)=0.00488V,譬如一次AD转换后得到的数据是1010101010,则对应的电压值为:3.328V,考虑精度后为3.33V 。

AD转换在系统中存在的方式:
(1)CPU外部扩展专用AD芯片;
(2)CPU内部集成AD模块(内部外设); 

电池单体的电压采集芯片有一种叫AFE的(Anlog Front End),即是一种AD转换模块,采集单体的电压转换为数字量发给MCU。 

2,AD转换原理图和数据手册 

单片机第一季:零基础13——AD和DA转换,单片机,嵌入式硬件

 ET2046 AD转换模块通过AIN0/AIN1/AIN2分别连接滑线变阻器、热敏电阻、光敏电阻。与单片机连接的接口为CS(使能接口,低有效)、CLK(时钟信号)、DI(数据输入,从单片机到AD转换模块)、DO(数据输出、从AD转换模块到单片机)。

X+、Y+、VBAT 和AUX 模拟信号经过片内的控制寄存器选择后进入ADC,ADC 可以配置为单端或差分模式。选择VBAT和AUX 时应该配置为单端模式;作为触摸屏应用时,应该配置为差分模式。

单片机在对AD转换模块进行控制时,控制字节由DIN 输入的控制字命令格式如下所示:

单片机第一季:零基础13——AD和DA转换,单片机,嵌入式硬件

Bit7为开始位,为1表示一个新的控制字节到来,为0则忽略PIN引脚上的数据;

A2-A0为通道选择位,表示选择哪个通道的输入电压进行AD转换;

MODE为12/8位转换分辨率选择位,为1选择8位转换分辨率,为0选择12位分辨率;

SER/DFR:单端输入方式/差分输入方式选择,为1是单端输入方式,为0是差分输入方式;

PD1-PD0为低功耗模式选择位,若为11,器件总处于供电状态,若为00,器件在转换之间处于低功耗模式。

单端模式时采集通道的选择如下表所示(通过上述控制字节的A2-A1进行选择): 

单片机第一季:零基础13——AD和DA转换,单片机,嵌入式硬件

选择X+通道、12位分辨率、单端模式、低功耗模式的控制字节命令:0b1001 0100 = 0x94。 

AD转换模块的时序图如下所示: 

单片机第一季:零基础13——AD和DA转换,单片机,嵌入式硬件

从时序图上可见,转换模块进入工作状态时,CS为低,DCLK为低,DIN和DOUT不用关注;首先通过DIN数据线从单片机发送控制字节到AD转换模块,在DCLK的上升沿AD转换模块读入数据(从高到低进行读入),当8位控制字节命令发送完成后,转换模块进入busy状态,即转换模块开始进行AD转换,此时间可从数据手册获取,一般程序中通过延迟一段时间来进行处理;然后单片机在DOUT数据线读取转换模块发出的数据,每个DCLK的下降沿转换模块会将一位数据发送到DOUT数据线上,仍然是从高到低的顺序。

可见AD转换和单片机的通讯方式类似于SPI通讯。 

3,AD转换代码 

AD采样转换代码包括单片机和AD转换模块写入命令和读取数据的底层时序代码,通过串口显示采样数据代码,以及main文件。

ET2046.c底层时序代码: 

#include "ET2046.h"
#include <intrins.h>


void delay10us(void)   //误差 0us
{
    unsigned char a,b;
    for(b=1;b>0;b--)
        for(a=2;a>0;a--);
}

unsigned int read_AD_value(unsigned char cmd)
{
   unsigned char i = 0;
   unsigned int AD_Value = 0;
   CS = 0;
   SCLK = 0;

   for(i = 0;i < 8;i++)
   {
   	  DIN = cmd >> 7;
	  cmd <<= 1;   //注意将一个数据移位后再赋给本身的运算符位 <<=
	  SCLK = 1;
	  _nop_();
	  SCLK = 0;
	  _nop_();
   }

   delay10us();
   	SCLK = 1;	  			//发送一个时钟周期,清除BUSY
	_nop_();
	_nop_();
	SCLK = 0;
	_nop_();
	_nop_();
			  
   for(i = 0;i<12;i++)
   {
   	   AD_Value <<= 1;

	   SCLK = 1;
	   _nop_();
	   SCLK = 0;
	   _nop_();

	   AD_Value |= DOUT;

   }

   CS = 1;
   return AD_Value;

}

ET2046.h 


#ifndef __ET2046_H__
#define __ET2046_H__

#include <reg51.h>

sbit SCLK = P1^0;
sbit CS = P1^1;

sbit DIN = P1^2;
sbit DOUT = P1^3;

unsigned int read_AD_value(unsigned char cmd);



#endif

串口调试代码: 

#include "uart.h"


// 串口设置为: 波特率9600、数据位8、停止位1、奇偶校验无
// 使用的晶振是11.0592MHz的,注意12MHz和24MHz的不行
void uart_init(void)
{
	// 波特率9600
	SCON = 0x50;   	// 串口工作在模式1(8位串口)、允许接收
	PCON = 0x00;	// 波特率不加倍

	// 通信波特率相关的设置
	TMOD = 0x20;	// 设置T1为模式2
	TH1 = 253;
	TL1 = 253;	   	// 8位自动重装,意思就是TH1用完了之后下一个周期TL1会
					// 自动重装到TH1去

	TR1 = 1;		// 开启T1让它开始工作
//	ES = 1;
//	EA = 1;
}

// 通过串口发送1个字节出去
void uart_send_byte(unsigned char c)
{
   // 第1步,发送一个字节
   SBUF = c;

   // 第2步,先确认串口发送部分没有在忙
   while (!TI);

   // 第3步,软件复位TI标志位
   TI = 0;
}

void uart_send_adVal(unsigned int val)
{
	
	 uart_send_byte(val>>8);   //AD采样的数据为12位的,首先左移8位串口输出高4位
	 uart_send_byte(val);	   //再输出低8位
}

注意:因为AD采样的数据是12位的数据,串口每次只能发送8位数据,需要分两次将12位数据进行发送; 

#ifndef __UART_H__
#define __UART_H__

#include <reg51.h>


void uart_init(void);
void uart_send_byte(unsigned char c);
void uart_send_adVal(unsigned int val);



#endif

main.c函数 

#include "ET2046.h"
#include "uart.h"

#define AIN0 0x94	  //滑动变阻器
#define AIN1 0xd4	  //热敏电阻
#define AIN2 0xa4	  //光敏电阻

void delay1s(void)   //误差 0us
{
    unsigned char a,b,c;
    for(c=167;c>0;c--)
        for(b=171;b>0;b--)
            for(a=16;a>0;a--);
}

void main()
{
  unsigned int ad_val = 0;
  uart_init();

  //uart_send_adVal(0xabc);	  //测试代码
  //uart_send_byte(0x0d);
  //uart_send_byte(0x0a);

  //while(1);

  while(1)
  {
  	  ad_val= read_AD_value(AIN2);

      uart_send_adVal(ad_val);

	  uart_send_byte(0);      	//发送数据0区分每次采样数值

	  delay1s();				  //如何实现在串口调试助手中发送一次采样数据后换行?

  }


}

思考:上述代码中,main函数是通过while()不断采样和发送AD转换的数据,如何通过中断来采样和发送AD转换数据? 

4,AD转换代码-直接在串口显示电压值 

串口助手中看到的数据以16进制显示或以对应字符形式来显示,因此在显示AD转换的电压时不直观,为了直观显示采集到的电压值,通过对采集到的电压值根据ASCii表对每一个十进制数转化为对应的数字符号,如下图所示,入药显示电压值中的数字5,只需要发送5+48的十进制数,在串口助手中就可以看到对应的符号5。

单片机第一季:零基础13——AD和DA转换,单片机,嵌入式硬件

代码如下: 

5,DA转换 

待完善 文章来源地址https://www.toymoban.com/news/detail-646293.html

到了这里,关于单片机第一季:零基础13——AD和DA转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PCF8591芯片的AD/DA转换(适用于蓝桥杯单片机)

    目录 1、PCF8591的引脚介绍  2、用IIC发送或接收字节              发送的第一个字节         发送的第二个字节   发送第三个字节     3.发送和接收的字节转换  4.全部代码 IIC部分 接收电压数据 发送电压数据                      在和单片机实际应用中它的

    2024年02月05日
    浏览(35)
  • 单片机第一季:零基础2

    目录 1,第三章 2,第四章 51单片机发展史: 51单片机由Intel公司设计诞生 (1)1971年,Intel推出4位单片机Intel4004 (2)1972年,Intel推出8位单片机Intel8008 (3)期间还有别的公司如Motorola、Zilog等推出各自的单片机系列 (4)80年代初,Intel推出MCS-51系列单片机(即Intel8051) (5)后来Intel继续做

    2024年02月13日
    浏览(36)
  • 单片机第一季:零基础6——按键

    目录 1,独立按键 2,矩阵按键 (注意:文章中的代码仅供参考学习,实际使用时要根据需要修改) 按键管脚两端距离长的表示默认是导通状态,距离短的默认是断开状态, 如果按键按下,初始导通状态变为断开,初始断开状态变为导通。 由于机械点的弹性作用,按键开关

    2024年02月16日
    浏览(33)
  • 单片机第一季:零基础8——蜂鸣器

    蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。 蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。 想要压电式蜂鸣器发声,需提供一定

    2024年02月16日
    浏览(33)
  • 单片机第一季:零基础11——实时时钟DS1302

    目录 1,DS1302 时钟芯片介绍  2,BCD码介绍  3,涉及到的寄存器  3.1,控制寄存器 3.2,日历/时钟寄存器  3.3,DS1302 的读写时序  4,相关代码  这一章我们来学习DS1302 时钟芯片,该芯片是3 线SPI 接口,所以需要使用51单片机的3 个IO 口模拟SPI 时序与DS1302 时钟芯片通信,将时钟

    2024年02月16日
    浏览(46)
  • 单片机第一季:零基础10——串口通信和RS485

    目录 1,串口通讯基础 1.1,同步和异步 1.2,并行和串行  1.3,单工、半双工与全双工通信  1.4,通信速率  2,单片机串口通讯 2.1,接口标准  2.2,通讯协议  2.3,串口内部结构  3,串口相关寄存器  4,波特率计算  5,串口初始化  6,开发板硬件设计  7,串口发送和接收

    2024年02月04日
    浏览(40)
  • 单片机——C51实验含Proteus仿真(AD转换器(数字电压表),DA转换器(波形发生器))

    分为两部分:AD转换器实现数字电压表,DA转换器实现波形发生器(在仿真部分详细说明) 所用到的原理图:  AD转换器实现数字电压表部分         需要打开main函数中LCD_init(),ADC(),display()三个注释其中电压的输出显示用到了LCD1602关于这部分详情见(96条消息) 单片机——

    2024年02月08日
    浏览(44)
  • 单片机第一季:零基础9——直流电机和步进电机

    目录 1,直流电机 2,步进电机  直流电机是指能将直流电能转换成机械能(直流电动机)或将机械能转换成直流电能(直流发电机)的旋转电机。它是能实现直流电能和机械能互相转换的电机。当它作电动机运行时是直流电动机,将电能转换为机械能;作发电机运行时是直流

    2024年02月16日
    浏览(31)
  • 单片机第一季:零基础6——定时器和计时器

    目录 1,单片机定时器原理 2,51单片机定时器/计数器结构 3,定时器配置  4,示例代码-通过定时器控制LED灯间隔1s闪烁  51 单片机有两组定时器/计数器,因为既可以定时,又可以计数,故称之为定时器/计数器。 定时器/计数器和单片机的CPU 是相互独立的。定时器/计数器工作

    2024年02月15日
    浏览(45)
  • 单片机第一季:零基础12——I2C和EEPROM

    目录 1,EEPROM 2,I2C  2.1,I2C物理层  2.2,I2C协议层  3,AT24C02介绍  4,代码  为什么需要EEPROM? 单片机内部的ROM只能在程序下载时进行擦除和改写,但是程序运行本身是不能改写的。单片机内部的RAM中的数据程序运行时可以改,但是掉电就丢失了。有时候我们有一些数据要

    2024年02月14日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包