鲁东大学毕业设计
LCALL STOP SETB SCL SETB SDA CLR SDA
//开始
MOV A,#40H //写方式 LCALL SBU1 MOV A,30H LCALL SBU1 ACALL DDD LCALL STOP LJMP START DDD:MOV R4,#01H //延时
LL3:MOV R6,#00H LL2:MOV R5,#00H LL1:DJNZ R5,LL1 DJNZ R6,LL2 DJNZ R4,LL3
RET
STOP:CLR SCL //停止
CLR SDA SETB SDA SETB SCL
RET
SBU1:MOV R7,#08H //传一个字 CLR SDA L1:CLR SCL RLC A MOV SDA,C SETB SCL DJNZ R7,L1 CLR SCL
SETB SDA
19
鲁东大学毕业设计
SETB SCL
WAIT:JB SDA,WAIT //发送一个字应答 RET
END
PCF8591A/D,D/A转换程序:
#include
sbit SDA=P3^4; //定义总线连接端口 sbit SCL=P3^3;
bit ADFlag; //定义AD采样标志位
unsigned char code Datatab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//7段数共阴码管段码表
data unsigned char Display[2];//定义临时存放数码管数值 void mDelay(unsigned char j) // 延时程序 {
unsigned int i; for(;j>0;j--) {
for(i=0;i<125;i++) {;} } }
void Init_Timer1(void) //初始化定时器1 {
TMOD=0x10; TH1=0xff; TL1=0x00;
EA=1; //中断允许
ET1=1; //定时器1允许中断 TR1=1; //定时器1启动 }
void Start(void) //启动IIC总线 {
SDA=1; _nop_(); SCL=1; _nop_(); SDA=0; _nop_(); SCL=0; }
void Stop(void) //停止IIC总线 {
SDA=0; _nop_();
20
鲁东大学毕业设计
SCL=1; _nop_(); SDA=1; _nop_(); SCL=0; }
void Ack(void) //应答IIC总线 {
SDA=0; _nop_(); SCL=1; _nop_(); SCL=0; _nop_(); }
void NoAck(void) // {
SDA=1; _nop_(); SCL=1; _nop_(); SCL=0; _nop_(); }
void Send(unsigned char Data) // {
unsigned char BitCounter=8; unsigned char temp; do {
temp=Data; SCL=0; _nop_();
if((temp&0x80)==0x80) SDA=1; else
SDA=0; SCL=1;
temp=Data<<1; Data=temp; BitCounter--; }
while(BitCounter); SCL=0; }
unsigned char Read(void) // {
unsigned char temp=0; unsigned char temp1=0;
unsigned char BitCounter=8;
非应答IIC总线 发送一个字节 读入一个字节并返回21
鲁东大学毕业设计
SDA=1; do {
SCL=0; _nop_(); SCL=1; _nop_(); if(SDA)
temp=temp|0x01; else
temp=temp&0xfe; if(BitCounter-1) {
temp1=temp<<1; temp=temp1; }
BitCounter--; }
while(BitCounter); return(temp); }
void DAC(unsigned char Data) //写入DA数模转换值 {
Start();
Send(AddWr); //写入芯片地址 Ack();
Send(0x40); //写入控制位,使能DAC输出 Ack();
Send(Data); //写数据 Ack(); Stop(); }
unsigned char ReadADC(unsigned char Chl) //读取AD模数转换的值,有返回值 {
unsigned char Data;
Start(); //写入芯片地址 Send(AddWr); Ack();
Send(0x40|Chl);//写入选择的通道,本程序只用单端输入,差分部分需要自行添加 //Chl的值分别为0、1、2、3,分别代表1-4通道 Ack(); Start();
Send(AddRd); //读入地址 Ack();
Data=Read(); //读数据 SCL=0; NoAck(); Stop();
return Data; //返回值
22
鲁东大学毕业设计
}
void main() //主程序 {
unsigned char num; //DA数模输出变量 unsigned char ADtemp; //定义中间变量 Init_Timer1(); //定时器初始化开中断 while(1) {
DAC(num); //DA输出,可以用LED模拟电压变化
num++; //累加,到256后溢出变为0,往复循环。 mDelay(25); //延时用于清晰看出变化 if(ADFlag) //定时采集输入模拟量 {
ADFlag=0;
ADtemp=ReadADC(0);
Display[0]=Datatab[((ReadADC(0))/51)]|0x80;//处理0通道电压显示 Display[1]=Datatab[((ReadADC(0))Q)/5]; } } }
void Timer1_isr(void) interrupt 3 using 1 //定时器中断程序 {
static unsigned int count,j; TH1=0xff; //重新赋值 TL1=0x00; j++;
if(j==30)
{j=0;ADFlag=1;
} //定时置位AD采样标志位
P2=count; //用于动态扫描数码管 P0=Display[count]; count++;
if(count==2) //表示扫描2个数码管 count=0; }
23
鲁东大学毕业设计
参考文献
[1] 杨居义 计算机科学与技术《单片机原理与工程应用》 清华大学出版社 2009.114-116
[2] 谢维成 《单片机原理与应用及C51程序设计》第二版 北京清华大学 2010. 228-233 [3] 何立民 《单片机高级教程》I2C总线的串行扩充技术 2000.9.19
[4] 朱明荣 汪立森 I2C总线I/O器件PCF8574的原理与应用 中船总公司扬州723所 1994
[5] 周剑利 郭建 波崔涛 具有I2C总线接口的A/D芯片PCF8591及其应用 The used of A/D chip PCF8591 which has I2C interface 唐山学院网络教育中心 [6] Coolbor Xie PCF8591中文数据手册 8位A/D,D/A转换器 [7] 陈柱峰 沈治国 基于PCF85591的I2C总线A/D D/AN转换《企业技术开发》 2009.5 [8] 周润景 《基于Proteus的电路及单片机系统设计与仿真》北京航空航天大学出版社 2006.5
[9] 周润景 《Proteus在MCS-51&ARM7系统中的应用百例》电子工业出版社 2006.10 311-318
[10] 谭浩强 《C语言程序设计》第三版 2009.10
致 谢
[致谢词] 四年的读书生活转眼即逝,在这段大学时光里,通过老师和同学们的帮助,我学到了很多宝贵的知识,这将是我人生的重要财富。这篇毕业论文是大学四年学习经验和技巧的总结,是一次专业能力的锻炼与提升。在论文的选题,构思,收集资料,设计,编辑完善过程中,都给老师添了不少麻烦。特别是李老师拿出宝贵的时间,给予了细心指导和鼓励,使我能够及时的发现问题把设计进行下去,最后成功的完成论文,在此过程中我积累了很多宝贵经验,对他们的帮助表示深深的感激。
24