基于PCF8951单片机设计教材Word文件下载.docx
《基于PCF8951单片机设计教材Word文件下载.docx》由会员分享,可在线阅读,更多相关《基于PCF8951单片机设计教材Word文件下载.docx(15页珍藏版)》请在冰豆网上搜索。
通道1;
10:
通道2;
11:
通道3。
D2:
自动增量允许位,为1时,每对一个通道转换后自动切换到下一通道进行转换,为0时不自动进行通道转换,可通过软件修改进行通道转换D3:
特征位,固定位0。
D4,D5:
模拟量输入方式选择位。
00:
输入方式0,四路单端输入;
01:
输入方式1,三路差分输入;
10:
输入方式2,二路单端输入,一路差分输入;
输入方式3,两路差分输入。
D6:
模拟输出允许位,A/D转换时设置为(地址选择字D0位此时设置为1),D/A转换时设置为1(地址选择字位此时设置为)。
D7:
特征位,固定为0。
PCF8591的A/D转换为逐次比较型,在A/D转换周期中借用DAC及高增益比较器对PCF8591进行写读操作后便立即启动A/D转换,并读出A/D转换结果在每个应答信号的后沿触发转换周期,采样模拟电压并读出前一次转换后的结果。
A/D转换中,一旦A/D采样周期被触发,所选择通道的采样电压便保存在采样,保持电路中,并转换成8位二进制码(单端输入)或二进制补码(差分输入)存放在ADC数据寄存器中等待器件读出。
如果控制字节中自动增量选择位置1,则一次A/D转换完毕后自动选择下一通道。
读周期中读出的第一个字节为前一个周期的转换结果。
上电复位后读出的第一字节为80H。
PCF8591的A/D转换亦使用的是I2C总线的读方式操作完成的。
其数据操作格式如图2.4所示。
图2.4A/D转换数据操作格式
其中data0~datan为A/D的转换结果,分别对应于前一个数据读取期间所采样的模拟电压。
A/D转换结束后,先发送一个非应答信号位A再发送结束信号位P。
灰底位由主机发出,白底位是由PCF8591产生。
上电复位后控制字节状态为00H,在A/D转换时须设置控制字,即须在读操作之前进行控制字节的写入操作。
逻辑操作波形时序图如图2.5所示。
图2.5A/D转换逻辑操作波形时序图
2)LCD1602
LCD1602液晶显示容量:
16×
2个字符,芯片工作电压:
4.5—5.5V,工作电流:
2.0mA(5.0V),模块最佳工作电压:
5.0V,字符尺寸:
2.95×
4.35(W×
H)mm。
1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。
(说明:
1为高电平、0为低电平)指令1:
清显示,指令码01H,光标复位到地址00H位置。
指令2:
光标复位,光标返回到地址00H。
指令3:
光标和显示模式设置I/D:
光标移动方向,高电平右移,低电平左移S:
屏幕上所有文字是否左移或者右移。
高电平表示有效,低电平则无效。
指令4:
显示开关控制。
D:
控制整体显示的开与关,高电平表示开显示,低电平表示关显示C:
控制光标的开与关,高电平表示有光标,低电平表示无光标B:
控制光标是否闪烁,高电平闪烁,低电平不闪烁。
指令5:
光标或显示移位S/C:
高电平时移动显示的文字,低电平时移动光标。
指令6:
功能设置命令DL:
高电平时为4位总线,低电平时为8位总线N:
低电平时为单行显示,高电平时双行显示F:
低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。
指令7:
字符发生器RAM地址设置。
指令8:
DDRAM地址设置。
指令9:
读忙信号和光标地址BF:
为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。
指令10:
写数据。
指令11:
读数据。
2.1.2设计思路
本次设计要求设计利用带有IIC接口的PCF8592模数与数模转换芯片,实现对直流电机转速的控制。
利用PCF8591芯片通道0采集到的模拟量,再次由AD转换成模拟量输出去控制直流电机的转速,由于D/A输出的的电流普遍偏小,而此不能直接驱动电机,要加上放大电路,而选用的直流电机是12V的DA的最大输出电压是5V,因此要先进行电压放大,采用LM358运放,将电压放大两倍,这样最高输出电压是10V,由于运放的驱动能力还是很弱,因此要进行电流放大,这边采用三极管进行电压放大,以射极跟随器的方式进行放大。
2.1.3电路设计
由设计思路在Ptotues上面画出总的电路图如下:
图2.6总的电路图
2)放大电路及直流电机驱动电路如图2.7
图2.7放大电路
如图所示PCF8591的D/A输出经过电阻R6接到运放LM358的同向输入端,设DA的输出电压为VDA,LM358运放的输出电压为VDA*(1+R5/R4)=2*VDA,所以LM358对PCF8591的D/A输出电压放大两倍,LM358输出的电压经过三极管S8050组成的射极跟随器后的输出到直流电机的电压为2*VDA-Vbe(三极管基极和发射极的导通电压)。
这样就组成了对D/A输出的电压,进行电压放大和电流放大,最后去驱动直流电机的驱动电路。
3)PCF8591应用电路如下图2.8
图2.8PCF8591应用电路
PCF8591应用电路如上图所示,IIC接口SCL,SDA各接一个10K的上拉电阻。
A0、A1、A2接地,这样对PCF8591写话地址为0x90,对PCF8591写的话地址为0x90。
PCF8591的VREF参考电压引脚接+5V,这样A/D的最大输入电压是5V,D/A的最大输出电压也是5V,PCF8591的四个A/D道道接四个可调电阻,用来改变输入电压的大小。
4)单片机最小系统电路
图2.9单片机最小系统电路
单片机最小系统电路主要包含两个部分,一个是由电阻电容组成的上电复位电路,让单片机在上电时先复位一下,再继续工作,另外一部分是由无源晶振和瓷片电容组成的时钟电路,为单片机提供工作时的必要的时钟信号。
3测试
实验的结果测试如图所示在A0电压为5V时,电机转速为235
图3.1在A0电压为5V时电机的转速
如图3.2在A0通道电压为3V时电机的转速为205
图3.2在A0电压为3V时电机的转速
如图3.3在A0通道电压为1.3V时,电机的转速为80.2转
图3.3在A0通道电压为1.3V时电机的转速
4总结
采用PCF8591对A0-A3的四个通道模拟量的采样,并在LCD1602液晶上面显示,对应的值,并将A0通道采集到到值输出给D/A去控制直流电机的转速,由于D/A的驱动能力很弱,因此加上了由LM358组成的电压放大电路,和由S8050三极管组成的电流放大电路再去驱动直流电机,通过在Protues仿真验证此方案是合理可行的。
附录A:
源程序
#include<
reg52.h>
//PCF8591相关定义
sbitSCL=P2^0;
//时钟脉冲
sbitSDA=P2^1;
//双向输入输出数据端
#defineSCL_SETSCL=1
#defineSCL_CLRSCL=0
#defineSDA_SETSDA=1
#defineSDA_CLRSDA=0
#defineAddWr0x90//写数据地址
#defineAddRd0x91//读数据地址
#defineadCon0x40//AD控制字节
//LCD1602相关定义
sbitRS=P2^6;
sbitRW=P2^5;
sbitE=P2^7;
#definesetRSRS=1
#defineclrRSRS=0
#definesetRWRW=1
#defineclrRWRW=0
#definesetEE=1
#defineclrEE=0
unsignedinttime=0;
unsignedcharADFlag=0;
unsignedcharstr[8]="
Ain.mv"
;
//延时1US
voiddelay(unsignedintcnt)
{
while(--cnt);
}
//延时1MS
voiddelayms(unsignedinttime)
unsignedinti;
for(i=0;
i<
time;
i++)
delay(120);
//写数据,P0
voidwriteData(unsignedcharData)
setRS;
clrRW;
delay
(1);
setE;
P0=Data;
delay(5);
clrE;
//写命令,P0
voidwriteCom(unsignedcharCom)
clrRS;
P0=Com;
//清屏函数
voidclear_scr(void)
{
writeCom(0x01);
delayms(5);
}
//写一个字符串在(X,Y)位置
voiddisStr(unsignedcharx,unsignedchary,unsignedchar*str)
if(y==0)writeCom(0x80+x);
//第一行
elsewriteCom(0xc0+x);
//第二行
while(*str)
writeData(*str);
str++;
}
//LCD1602初始化
voidlcdInitial()
writeCom(0x38);
//显示模式设置
writeCom(0x08);
//显示关闭
clear_scr();
//清屏
writeCom(0x06);
//显示光标移动设置
writeCom(0x0C);
//显示开及光标设置
voidstart()
SDA_SET;
SCL_SET;
SDA_CLR;
voidstop()
voidack()
SCL_CLR;
voidnoAck()
voidsend(unsignedcharData)
unsignedchari=0;
unsignedchartemp=0;
temp=Data;
8;
if(temp&
0x80)SDA_SET;
elseSDA_CLR;
temp<
<
=1;
unsignedcharrecive()
SDA_SET;
//必须设置
//拉低允许数据改变
//拉高保持数据,等待读走
delay
(2);
if(SDA)temp|=0x01;
elsetemp&
=0xfe;
if(i<
7)temp<
//最低位发送完成不能移位,否则出错
returntemp;
unsignedcharread(unsignedcharch)
start();
send(AddWr);
//确认芯片
ack();
send(adCon|ch);
//确认通道
//读出数据,放进temp
start();
send(AddRd);
temp=recive();
noAck();
stop();
voidDAC(unsignedcharlight)
send(0x40);
//写入控制位,使能DAC输出
send(light);
voiddis(unsignedchar*date)
floatj;
unsignedintk;
unsignedcharch1,ch2,ch3;
for(i=0;
4;
j=date[i]*10/51;
k=(int)j;
ch1=i+48;
str[1]=ch1;
ch2=k/10+48;
str[3]=ch2;
ch3=k%10+48;
str[5]=ch3;
if(i>
1)disStr(i*8-16,1,str);
elsedisStr(i*8,0,str);
voidmain()
unsignedcharvot[4];
lcdInitial();
while
(1)
vot[3]=read(0);
vot[0]=read
(1);
vot[1]=read
(2);
vot[2]=read(3);
DAC(vot[0]);
//DA转换函数,A0的模拟量值送到DA输出
dis(vot);
delayms(5);
参考文献:
[1]彭伟.单片机C语言程序设计实训――基于8051+Protues仿真[M].电子工业出版社.2010
[2]徐玮,徐富军,沈建良.C51单片机高效入门[M].机械工业出版社.2010