绝对经典!单片机外部器件的应用项目实例
主要介绍数字温度传感器DS18B20、AT24C04、DS1302以及单片机常用的A-D转换器、D-A转换器等,进一步掌握复杂单片机系统的构成和程序设计。...
01
class
项目总览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的应用class
1.功能原理ADC0832 是美国国家半导体公司生产的一种8位逐次比较型COMS双通道A-D转换器。该器件有8和14引脚两种封装,采用5V电源供电,模拟电压输入范围为0~5V,内部时钟250kHz时转换速度为32μs。封装图见图7所示。
图7 ADC0832封装
表1 ADC0832引脚功能
ADC0832 与单片机的连接应为4条信号线,分别是/CS、CLK、DO、DI。由于DO端与DI端在通信时并不是同时有效,且与单片机的接口是双向的,所以应用中可以将ADC0832的DO和DI 线并在一起接单片机的I/O。见图8所示。图8 ADC0832仿真电路
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)//包含11个CLK下降沿
{
uchari,dat1;
dac0832_init();
DIDO= 1;CLK = 0;nop;CLK = 1;nop;//SCK第1个下降沿来到时,DI = 1启动DAC0832
DIDO= 1;CLK = 0;nop;CLK = 1;nop;//SCK第2个下降沿
DIDO= 0;CLK = 0;nop;CLK = 1;nop;//SCK第3个下降沿,发送1、0选择通道ch0
DIDO= 1;//释放总线 for(i= 0;i < 8;i++)//SCK第4个下降沿到第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的应用class
1. TLC549工作原理TLC549有片内系统时钟,该时钟与I/O_CLOCK是独立工作的,无须特殊的速度或相位匹配。TLC549工作时序如图9所示。
图9 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单片机的接口电路
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的应用class
1.TLC5615工作时序TLC5615的工作时序如图11所示。从图中可以看出,只有当片选端CS为低电平时,串行输入数据才能被移入16位TLC5615移位寄存器,期间每一个SCLK时钟的上升沿将 DIN的一位数据移入移位寄存器。注意,先发送数据的最高位。10位数据发送完毕后,CS的上升沿将16位移位寄存器的10位有效数据锁存于10位DAC寄存器,供DAC电路进行转换;当片选端CS为高电平时,数据禁止发送。注意,CS的上升和下降都必须发生在SCLK为低电平期间。
图11 TLC5615工作时序
第二种方式为级联方式,将一片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与单片机的连接电路
下面编写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视界
微信扫一扫关注公众号