绝对经典!单片机外部器件的应用项目实例

 

主要介绍数字温度传感器DS18B20、AT24C04、DS1302以及单片机常用的A-D转换器、D-A转换器等,进一步掌握复杂单片机系统的构成和程序设计。...

01

class
项目总览

项目12  数字温度计设计
项目13  AT24C04的应用

项目14  实时时钟DS1302的应用

项目15-1  A-D转换器ADC0832的应用

项目15-2  A-D转换器TLC549的应用

项目16  D-A转换器TLC5615的应用

项目17  驱动器ULN2003的应用

由于内容较多,此文只介绍其中三个项目实例,全部内容建议大家进行下载,文末会给出下载方式。
02

class
A-D转换器ADC0832的应用

1.功能原理ADC0832 是美国国家半导体公司生产的一种8位逐次比较型COMS双通道A-D转换器。该器件有8和14引脚两种封装,采用5V电源供电,模拟电压输入范围为0~5V,内部时钟250kHz时转换速度为32μs。封装图见图7所示。


图7  ADC0832封装
由于ADC0832采用串行通信,占用单片机I/O资源少,一般用于简单的模拟电压检测系统中。引脚功能见表1。
表1  ADC0832引脚功能

ADC0832 与单片机的连接应为4条信号线,分别是/CS、CLK、DO、DI。由于DO端与DI端在通信时并不是同时有效,且与单片机的接口是双向的,所以应用中可以将ADC0832的DO和DI 线并在一起接单片机的I/O。见图8所示。


图8  ADC0832仿真电路
ADC0832未工作时,/CS端应为高电平,此时芯片被禁用,CLK 和DO/DI 的电平可任意。当要进行A-D转换时,须先将使能端/CS置于低电平,并且保持直到转换完全结束。开始转换工作时,由单片机向ADC0832的CLK 输入时钟脉冲,DO/DI端则使用输入通道功能选择的信号。在第1个时钟脉冲的下降沿DI端必须是高电平,表示启始信号。在CLK第2、3个脉冲下降沿DI端应输入两位数据,用于选择通道。当此两位数据分别为1、0时,只对CH0进行单通道转换;当两位位数据为1、1时,只对CH1进行单通道转换;当2位数据为0、0时,将CH0作为正输入端IN+,CH1作为负输入端IN-进行输入;当2位数据为0、1时,将CH0作为负输入端IN-,CH1作为正输入端IN+。

CLK第3个脉冲的下降沿来到之后,DI端的输入电平就失去作用,此后DO/DI端则开始利用数据输出DO进行转换数据的读取。从第4个脉冲下降沿开始,由DO端输出8位转换数据的最高位,随后每一个脉冲下降沿,DO端输出一位数据。直到第11个脉冲时送出最低位数据,完成一次A-D转换。

2. ADC0832应用

由于ADC0832操作简单,因此ADC0832驱动只需依照该器件的工作情况设计即可。在图8所示的仿真电路中,调节电位器OP1可以产生一个模拟的0~5V电压源,输入ADC0832的CH0端口,ADC0832转换后的数据范围为0~255,由3位数码管输出。ADC0832的DI与DO线与后接单片机的P3.2接口,/CS接P3.0接口,CLK接P3.1接口。为了得到CH0通道转换得到的数据,程序中需要在CLK第2、3个下降沿来到时向DI发送1、0,然后才能接收ADC0832的转换数据,每次转换结束时让/CS 无效。

本例程序分主程序和子程序两部分。子程序为ADC0832驱动程序,主程序主要显示转换的数据,用来验证子程序的正确性。

(1)ADC0832驱动程序

ADC0832驱动程序包含对ADC0832的初始化函数、读取ADC0832数据函数,在读取数据的函数中,要对所用的A-D通道进行选择。ADC0832的驱动程序如下:

/*预处理*/

#include

#include

#define uchar unsigned char

#define nop _nop_()

sbit CS = P3^0;

sbit CLK = P3^1;

sbit DIDO = P3^2;

/****ADC0832初始化****/

void dac0832_init(void)

{

     CS = 1;nop;

     CLK = 1;

     CS = 0;

}

/*****对转换CH0通道的模拟信号*****/

uchar dac0832_ch0(void)//包含11CLK下降沿

{                

         uchari,dat1;

         dac0832_init();

         DIDO= 1;CLK = 0;nop;CLK = 1;nop;//SCK1个下降沿来到时,DI = 1启动DAC0832

         DIDO= 1;CLK = 0;nop;CLK = 1;nop;//SCK2个下降沿

         DIDO= 0;CLK = 0;nop;CLK = 1;nop;//SCK3个下降沿,发送10选择通道ch0

         DIDO= 1;//释放总线         for(i= 0;i < 8;i++)//SCK4个下降沿到第11个下降沿,

     {

             

              CLK = 0;nop;

              if(DIDO)dat1 =dat1 | 0x01;

              CLK = 1;nop;

              dat1 = dat1= 100)                                                         //0.5

        {

                    cp1 = 0;

                    dat_ad =dac0832_ch0();//0.5秒让ADC0832转换一次

           }

           P0 = 0xff;

           switch(cp2)

           {

                    case0:P0 = seven_seg[dat_ad  % 10];P2 =0x01;break;

                    case1:P0 = seven_seg[dat_ad % 100 / 10];P2 = 0x02;break;

                    case2:P0 = seven_seg[dat_ad / 100];P2 = 0x04;break;

           }

           cp2++;

           if(cp2 >= 3)

           cp2 = 0;

}

/*主函数*/

void main(void)

{

           timer0_init();

           dac0832_init(); 

           while(1);

}

在子程序的基础上,改变CLK第2、3下降沿到来时输入的DI数值,可以实现CH1通道数据转换。作为单通道模拟信号输入时,ADC0832的输入电压是0~5V, 8位分辨率,电压精度为19.53mV。如果由IN+与IN-输入时,可将电压值设定在某一个较大范围之内,从而提高转换的宽度。值得注意的是,在进行IN+与IN-的输入时,如果IN-的电压大于IN+的电压,则转换后的结果始终为00H。
03

class
A-D转换器TLC549的应用

1. TLC549工作原理TLC549有片内系统时钟,该时钟与I/O_CLOCK是独立工作的,无须特殊的速度或相位匹配。TLC549工作时序如图9所示。


9 TLC549工作时序图
当CS为高时,数据输出(DATA _OUT)端处于高阻状态,此时I/O_CLOCK不起作用。这种CS控制作用允许在同时使用多片TLC549时,共用I/O_CLOCK,以减少多路A-D转换器并用时占用的单片机I/O资源。TLC549一次转换操作过程如下:

(1)将CS置低。内部电路在测得CS下降沿后,再等待两个内部时钟上升沿和一个下降沿后,然后确认这一变化,最后自动将前一次转换结果的最高位(D7)位输出到DATA_OUT端上。

(2)前四个I/O_CLOCK周期的下降沿依次移出第2、3、4和第5位(D6、D5、D4、D3),片上采样保持电路在第4个I/O_CLOCK下降沿开始采样模拟输入。

(3)接下来的3个I/O_CLOCK周期的下降沿移出第6、7、8(D2、D1、D0)个转换位。

(4)最后,片上采样保持电路在第8个I/O_CLOCK周期的下降沿将移出第6、7、8(D2、D1、D0)个转换位。保持功能将持续4个内部时钟周期,然后开始进行32个内部时钟周期的A-D转换。第8个I/O_CLOCK后,CS必须为高电平,或I/O_CLOCK保持低电平,这种状态需要维持36个内部系统时钟周期,以等待保持和转换工作的完成。如果CS为低时I/O_CLOCK上出现一个有效干扰脉冲,则微处理器/控制器将与器件的I/O时序失去同步;若CS为高时出现一次有效低电平,则将使引脚重新初始化,从而脱离原转换过程。

在36个内部系统时钟周期结束之前,实施步骤(1)~(4),可重新启动一次A-D转换,正在进行的转换终止,此时的输出是前一次的转换结果而不是正在进行的转换结果。

若在特定的时刻采样模拟信号,应使第8个I/O_CLOCK时钟的下降沿与该时刻对应,因为芯片虽在第4个I/O_CLOCK时钟下降沿开始采样,却在第8个I/O_CLOCK的下降沿开始保存。

2.TLC549应用子程序

(1)测试电路

TLC549可方便地与具有串行外围接口(SPI)的单片机或微处理器配合使用,也可与MCS-51系列通用单片机连接使用。为了验证TLC549驱动程序的可靠性,可以在ADC0832应用电路显示部分基础上连接TLC549,TLC549与MCS-51系列单片机的接口如图10所示。其中TLC549的CS、DATA_OUT(SDO)、I/O_CLOCK分别连接单片机的P3.4、P3.5、P3.7接口。模拟电压利用一个电位器OP1产生,当调节电位器中心抽头的位置时,模拟电压变换范围我0~5V,经过TLC549转换后的8位数据通过串行传输方式给单片机,单片机显示数据范围为0~255,为了得到一个电压数字检测目的,本例中使数码管显示电压值,共通过程序计算得到检测结果。


图10  TLC549与AT89C51单片机的接口电路
(2)TLC549子程序

TLC549程序依照TLC549的时序和操作过程设计,包含器件初始化函数和数据转换函数,具体程序如下:

/*预处理*/

#include

#define uchar unsigned char

sbit sd = P3^5;          //数据线

sbit cs = P3^4;                              //片选

sbit scl = P3^7;                   //I/O口时钟

/*TLC549初始化*/

void tlc549_init(void)

{

         cs= 1;                                    //初始化,启动

       scl = 0;

       cs = 0;       

}

/*TLC549数据转换*/

uchar tlc549_ad(void)                       //TLC549处理

{

       uchar i,dat_temp = 0;

         tlc549_init();

       for(i = 0;i < 8;i++)       //读取采集数据,读取的是上一次采集数据

   {        

                scl= 1;

                   dat_temp= dat_temp = 100) //0.5

         {

                   cp1= 0;

                   dat_ad= tlc549_ad();

                   dat_ad= dat_ad * 1.96;//数据255对应模拟电压5V

         }

         P0= 0xff;//仿真时用于消隐

         switch(cp2)

         {

                   case0: P0 = seven_seg[dat_ad % 10];P2 = 0x01; break;     

                   case1: P0 = seven_seg[dat_ad / 10 ];P2 = 0x02; break;        

                   case2: P0 = seven_seg[dat_ad / 100]&0x7f;P2= 0x04; break;//加上小数点         }               

         cp2++;

         if(cp2>= 3)

         cp2= 0;

}

/*T0中断服务函数*/

void timer0_init (void)                         //timer0中断初始化函数

{                  

         TMOD= 0x01;                                 

         TL0= (65536 - 5000)%256;

         TH0= (65536 - 5000)/256;                                    

         ET0= 1;                    

         EA= 1;                     

         TR0= 1;                     

}

/*主函数*/                                                      

void main(void)                              //主程序



         timer0_init();

         tlc549_init();

         while(1);

}

由于TLC549只有1路A-D转换器,因此程序相比DAC8032简单一些。以上两种A-D转换芯片都是串行接口,减少了器件与MCU之间的连线数,同时占用了较少的单片机I/O资源,缺点是比同类并行A-D转换器速度慢。A-D转换器的时序比较简单,因此程序设计有较大的灵活性。
04

class
D-A转换器TLC5615的应用

1.TLC5615工作时序TLC5615的工作时序如图11所示。从图中可以看出,只有当片选端CS为低电平时,串行输入数据才能被移入16位TLC5615移位寄存器,期间每一个SCLK时钟的上升沿将 DIN的一位数据移入移位寄存器。注意,先发送数据的最高位。10位数据发送完毕后,CS的上升沿将16位移位寄存器的10位有效数据锁存于10位DAC寄存器,供DAC电路进行转换;当片选端CS为高电平时,数据禁止发送。注意,CS的上升和下降都必须发生在SCLK为低电平期间。


图11  TLC5615工作时序
TLC5615有两种工作方式。第一种为单片工作方式,16位移位寄存器分为高4位虚拟位、低2位填充位以及10位有效位。单片TLC5615工作时,只需要向16位移位寄存器按先后发送10位有效数据位和低2位填充位,2位填充位数据任意。单芯片应用时,发送数据需要12个SCLK脉冲。

第二种方式为级联方式,将一片TLC5615的DOUT接到下一片TLC5615的DIN,需要向16位移位寄存器按先后输入高4位虚拟位、10位有效位和低2位填充位,由于增加了高4位虚拟位,所以需要16个SCLK脉冲。

2.应用程序

(1)仿真测试电路

图12所示为TLC5615与单片机的连接电路,通过编辑Ptoteus仿真电路,可以验证TLC5615的应用程序。图12中TLC5615的/CS、DIN、SCLK分别连接单片机的P3.4、P3.6、P3.7接口。TLC5615转换输出的模拟电压信号可以通过电压表测试。基准电压REFIN接电源电压5V的一半,当TLC5615接收10位数据全为1时,理论上,OUT端输出电源电压5V,但实际应用时最高输出4.7V。即当TLC5615输入数据超过961时,输出电压将不再增加。因此在设计TLC5615应用程序时需要调整输入数据范围。


图12  TLC5615与单片机的连接电路
(2)应用程序

下面编写TLC5615应用程序来完成一个随时间变化的数据转换,同时数据在数码管上显示出来。具体程序如下:

/*预处理*/

include

#include

#define uchar unsigned char

#define uint unsigned int

const uchar seven_seg[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; 

uchar j;

uint moni,dat,i;

sbit din = P1^5;

sbit scl = P1^1;

sbit cs = P1^6;

tlc5615_init(void)

{

cs = 1;

scl = 0;

cs = 0;

}

/* TLC5615转换函数*/

void tlc5615(uint dat) //由于TLC5615是十位转换,定义一个16位的变量

{

uchar i;

[b]dat


    关注 机械工业出版社E视界


微信扫一扫关注公众号

0 个评论

要回复文章请先登录注册