当前位置:文档之家› 单片机课程设计--定时插座

单片机课程设计--定时插座

课程设计报告题 目 定时插座课 程 名 称 单片机原理及接口技术院 部 名 称 机电工程学院专 业 自动化班 级 09自动化学 生 姓 名 吴程剑学 号 0904105003课程设计地点 C314课程设计学时 一周指 导 教 师 高峰金陵科技学院教务处制 成绩目录一:概述二:设计要求和设计思路及方案2.1设计要求2.2设计思路2.3设计方案三:硬件电路设计3.1按键设计电路3.2数码管显示电路3.3 DS1302电路和AT24C02电路3.4继电器电路四:软件设计五:系统调试及软件仿真六:总结一、概述随着科学技术特别是微型计算机技术的高速发展,单片机微机技术也获得了飞速发展。

目前,单片机已经在日常生活和控制领域等方面得到了广泛的应用,它正为我国经济的快速发展发挥着举足轻重的作用。

作为自动化专业的一名工科学生应该牢牢掌握这一重要技术。

而课程设计这一环节是我们提高单片机应用能力的很好机会,也是我们学好这一课程的必经环节。

通过课程设计可以进一步巩固我们前面所学的理论知识,使我们对单片机理论知识有一个深刻的认识和全面的掌握。

另外通过这一真正意义上的实践活动,我们可以从中发现自己的不足之处并能够在自己的深思下和老师的指导下得到及时的解决。

再次,它能使我们的应用能力和科技创新能力得到较大的提高。

单片机作为嵌入式微控制器在工业测控系统,智能仪器和家用电器中得到广泛应用。

虽然单片机的品种很多,但MCS-51系列单片机仍不失为单片机中的主流机型。

本课程一MCS-51系列以及派生系列单片机芯片为主介绍单片机的原理及应用,其特点是由浅入深,注重接口技术和应用。

二、设计要求和设计思路及方案2.1 设计要求本次课程设计用STC89C52作为主控器做一个定时插座。

实现一个具有定时、按键设置及控制、定时时间显示等功能的定时开关插座,具体要求和指标如下:(1)可以设定三组定时时间值。

(2)设定的定时可调整的时间范围。

(3)具有开始/停止操作按键。

(4)具有定时时间显示和时钟显示。

2.2设计思路为了确定其设计方案,首先必须构思好初步的设计思路。

根据设计要求和实验仿真条件,初步的设计思路可以总结如下:(1)用DS1302芯片处理当前时间并用8位数码管显示。

(2)用AT24C02芯片存储预先设定好的密码。

(3)设置模式:常开模式、常闭模式、定时模式(4)设置开关时间:先按设置键出现01 on,再按小时和分钟键调节时间,调节好后再按设置键出现01 off,再调节时间,按确认键,这样就设置好一组定时时间。

设置其他组方法相同。

2.3设计方案根据设计要求和设计思路,可以确定系统的设计方案,图1为该系统设计的硬件电路图设计框图。

硬件主要由6部分组成,即单片机,键盘,数码管显示,DS1302芯片,AT24C02芯片,继电器。

STC89C52介绍VCC:供电电压。

GND:接地。

P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8个TTL门电流。

当P0口的管脚第一次写“1”时,被定义为高阻输入。

P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。

在FIASH编程时,P0 口作为原码输入口,当FIASH 进行校验时,P0输出原码,此时P0外部必须被拉高。

P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4个TTL门电流。

P1口管脚写入“1”后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。

在FLASH编程和校验时,P1口作为第八位地址接收。

P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。

并因此作为输入时,P2口的管脚被外部拉低,将输出电流。

这是由于内部上拉的缘故。

P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。

在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。

P2口在FLASH编程和校验时接收高八位地址信号和控制信号。

P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。

当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。

作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。

P3口作为AT89C51的一些特殊功能口,管脚备选功能P3.0 RXD(串行输入口)P3.1 TXD(串行输出口)P3.2 /INT0(外部中断0)P3.3 /INT1(外部中断1)P3.4 T0(计时器0外部输入)P3.5 T1(计时器1外部输入)P3.6 /WR(外部数据存储器写选通)P3.7 /RD(外部数据存储器读选通)RST:复位输入。

当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。

ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。

在FLASH编程期间,此引脚用于输入编程脉冲。

在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。

因此它可用作对外部输出的脉冲或用于定时目的。

然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。

如想禁止ALE的输出可在SFR8EH地址上置0。

此时,ALE只有在执行MOVX,MOVC指令是ALE才起用。

另外,该引脚被略微拉高。

如果微处理器在外部执行状态ALE禁止,置位无效。

/PSEN:外部程序存储器的选通信号。

在由外部程序存储器取指期间,每个机器周期两/PSEN有效。

但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。

/EA / VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。

注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。

在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。

XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。

XTAL2:来自反向振荡器的输出。

在单片机中,定时功能既可以由硬件(定时/计数器)实现,也可通过软件定时实现。

硬件定时是利用单片机内定时器定时,启动以后定时器可与CPU 并行工作,不占用CPU 时间,CPU 有较高的工作效率。

采用硬件定时和软件定时比用的方式,即用T0溢出中断功能实现50ms 定时,通过软件延时程序实现5s 定时。

定时器的TMOD 用于设置定时器/计数器的工作方式,并确定用于定时还是计数。

TCON 只要功能是为定时器在溢出时设定标志位,并控制定时器运行或停止。

图1:硬件电路设计三、硬件电路设计3.1按键设计电路 MCU 继电器按键 DS1302AT24C02数码管显示对于按键电路的设计可以有2种方式:一种方式是独立按键设计,这种设计电路适用于按键较少的控制,具有按键电路简单,编程方便等优点;另一种方式是矩阵方式键盘的设计,它适用于对控制按键较多的电路控制,占用较少的I/O接口,但是按键电路复杂,编程比较复杂。

本课题总共需要6个按键,所以采用矩阵式键盘,如图2图2:按键电路3.2数码管显示电路本课题所采用的是数码管作为显示电路,用来显示当前的时间及密码门时输入的密码。

硬件电路连接是单片机P0口接2片74hc573锁存芯片,两片芯片的输出端分别接数码管的段选端跟位选端。

这样P0口不断送出位码跟断码锁存可以实现数码管的动态显示。

连接方法如图3所示。

图3:数码管显示电路3.3 DS1302电路和AT24C02电路24C02的SCK,SDA,WP引脚分别接单片机的P2.0,P2.1引脚和地。

DS1302的RST,SCLK,I/O引脚分别接单片机的P1.3,P1.7和P2.3引脚。

电路图如图4所示。

图4:DS1302和24C02连接电路3.4继电器电路继电器的线圈一端接电源vcc一端接ULN2003的12脚。

ULN2003是8个非门,可以耐高压等,用来驱动继电器。

电路连接图如图5所示。

图5:继电器连接电路四、软件设计主程序流程图 NY开始读取当前时间并显示是否有键按下?设置键模式调节时间模式循环按确认键五、系统调试和软件仿真5.1程序调试部分:uVsion3先新建一个工程,选择芯片为AT89C52然后点击是,然后弹出来是否加入标准启动文件,点击否,然后新建一个文件,保存为“main.c”。

然后双击工程窗口的Target选择添加文件到工程,选刚才新建的文件然后点击OK,输入程序,点击工程选择,选中Output 中的Creat Hex File,然后编译,连接生成Hex文件,有错误修改后再编译连接。

当编译结果中不出现错误时说明已经没有语法错误,但是否能完成课题所需要的功能则需要进行仿真。

5.2软件仿真部分:运行proteus的ISIS后进入仿真界面将所需元件选择好,根据原理图画出仿真图,待仿真图画好后双击AT89C52导入Keil所产生的后缀名为.HEX文件。

按开始键进行仿真。

实验程序:#include<reg52.h>#include<intrins.h>#include"display.h"#include"ds1302.h"#include"key.h"#include"24c02.h"#include"uln2003.h"sbit buzz=P0^6;sbit relay=P0^4;#define uchar unsigned char#define uint unsigned inttypedef struct SYSTEMTIME{uchar min;uchar hour;uchar sec;};struct SYSTEMTIME clock,time;uchar tempdata[8],temp[8],disTime[8];uchar keynum,n,setflag,modeflag,hour_temp,min_temp; bit flag,onflag,offflag;void read_time(struct SYSTEMTIME *p) //结构体形参{p->hour = read_DS1302(0x85);p->min = read_DS1302(0x83);p->sec = read_DS1302(0x81);}{uchar i,j;buzz=0;relay=0;ULN2003_Latch();buzz=0;relay=0;ULN2003_Latch();DS1302_init(); //初始化,第一次下载后将其屏蔽while(1){read_time(&clock);disTime[0] = clock.hour>>4; //时十位disTime[1] = clock.hour&0x0f; //时个位disTime[2] = 10;disTime[3] = clock.min>>4; //分十位disTime[4] = clock.min&0x0f; //分个位disTime[5] = 10;disTime[6] = clock.sec>>4; //秒十位disTime[7] = clock.sec&0x0f; //秒个位hour_temp=disTime[0]*10+disTime[1]; //转换成十进制小时min_temp=disTime[3]*10+disTime[4]; //转换成十进制keynum=KeyPro();switch(keynum){case 0:{setflag++;if(setflag==2){wrbyte_24c02(n*2,time.hour);wrbyte_24c02(n*2+1,time.min);n++;}time.hour=0;time.min=0;flag=0;break;}case 1:{time.hour++;if(time.hour==24)time.hour=0;flag=1;break;}case 2:{time.min++;if(time.min==60)time.min=0;flag=1;break;}case 3:{wrbyte_24c02(n*2,time.hour);wrbyte_24c02(n*2+1,time.min);flag=0;setflag=0;n++;break;}case 4:{modeflag++;if(modeflag==3)modeflag=0;break;}case 5:{flag=0;setflag=0;modeflag=0;onflag=0;offflag=0;while(n!=0){wrbyte_24c02((n-1)*2,0);wrbyte_24c02((n-1)*2+1,0);n--;}break;}default:break;}switch(setflag){case 1:{temp[0]=(n/2+1)/10;temp[1]=(n/2+1)%10;temp[2]=11;temp[3]=0;temp[4]=13;temp[5]=11;temp[6]=11;temp[7]=11;break;}case 2:{temp[0]=(n/2+1)/10;temp[1]=(n/2+1)%10;temp[2]=11;temp[3]=0;temp[4]=14;temp[5]=14;temp[6]=11;temp[7]=11;break;}default:break;}switch(modeflag){case 0:{buzz=0;relay=0;ULN2003_Latch();break;}case 1:{buzz=0;relay=1;ULN2003_Latch();break;}case 2:{for(j=0;j<n/2;j++){if(hour_temp==read(4*j)&&min_temp==read(4*j+1)){onflag=1;offflag=0;}if(hour_temp==read(4*j+2)&&min_temp==read(4*j+3)){onflag=0;offflag=1;}}if(onflag){buzz=0;relay=1;ULN2003_Latch();}if(offflag){buzz=0;relay=0;ULN2003_Latch();}if(!offflag&&!onflag){buzz=0;relay=0;ULN2003_Latch();}break;}default:break;}if(!setflag&&!flag){for(i=0;i<8;i++)tempdata[i]=disTime[i];}if(setflag&&!flag){for(i=0;i<8;i++)tempdata[i]=temp[i];}if(setflag&&flag){tempdata[0]=time.hour/10;tempdata[1]=time.hour%10;tempdata[2]=10;tempdata[3]=time.min/10;tempdata[4]=time.min%10;tempdata[5]=10;tempdata[6]=0;tempdata[7]=0;}display(tempdata);}REG52.HHeader file for generic 80C52 and 80C32 microcontroller. Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.All rights reserved.--------------------------------------------------------------------------*/#ifndef __REG52_H__#define __REG52_H__/* BYTE Registers */sfr P0 = 0x80;sfr P1 = 0x90;sfr P2 = 0xA0;sfr P3 = 0xB0;sfr PSW = 0xD0;sfr ACC = 0xE0;sfr B = 0xF0;sfr SP = 0x81;sfr DPL = 0x82;sfr DPH = 0x83;sfr PCON = 0x87;sfr TCON = 0x88;sfr TMOD = 0x89;sfr TL0 = 0x8A;sfr TL1 = 0x8B;sfr TH0 = 0x8C;sfr TH1 = 0x8D;sfr IE = 0xA8;sfr IP = 0xB8;sfr SCON = 0x98;sfr SBUF = 0x99;/* 8052 Extensions */ sfr T2CON = 0xC8;sfr RCAP2L = 0xCA;sfr RCAP2H = 0xCB; sfr TL2 = 0xCC;sfr TH2 = 0xCD;/* BIT Registers *//* PSW */sbit CY = PSW^7;sbit AC = PSW^6;sbit F0 = PSW^5;sbit RS1 = PSW^4;sbit RS0 = PSW^3;sbit OV = PSW^2;sbit P = PSW^0; //8052 only/* TCON */sbit TF1 = TCON^7;sbit TR1 = TCON^6;sbit TF0 = TCON^5;sbit TR0 = TCON^4;sbit IE1 = TCON^3;sbit IT1 = TCON^2;sbit IE0 = TCON^1;sbit IT0 = TCON^0;/* IE */sbit ET2 = IE^5; //8052 only sbit ES = IE^4;sbit ET1 = IE^3;sbit EX1 = IE^2;sbit ET0 = IE^1;sbit EX0 = IE^0;/* IP */sbit PT2 = IP^5;sbit PS = IP^4;sbit PT1 = IP^3;sbit PX1 = IP^2;sbit PT0 = IP^1;sbit PX0 = IP^0;/* P3 */sbit RD = P3^7;sbit WR = P3^6;sbit T1 = P3^5;sbit T0 = P3^4;sbit INT1 = P3^3;sbit TXD = P3^1;sbit RXD = P3^0;/* SCON */sbit SM0 = SCON^7;sbit SM1 = SCON^6;sbit SM2 = SCON^5;sbit REN = SCON^4;sbit TB8 = SCON^3;sbit RB8 = SCON^2;sbit TI = SCON^1;sbit RI = SCON^0;/* P1 */sbit T2EX = P1^1; // 8052 only sbit T2 = P1^0; // 8052 only/* T2CON */sbit TF2 = T2CON^7;sbit EXF2 = T2CON^6;sbit RCLK = T2CON^5;sbit TCLK = T2CON^4;sbit EXEN2 = T2CON^3;sbit TR2 = T2CON^2;sbit C_T2 = T2CON^1;sbit CP_RL2 = T2CON^0;#endifINTRINS.HIntrinsic functions for C51.Copyright (c) 1988-2004 Keil Elektronik GmbH and Keil Software, Inc.All rights reserved.--------------------------------------------------------------------------*/#ifndef __INTRINS_H__#define __INTRINS_H__extern void _nop_ (void);extern bit _testbit_ (bit);extern unsigned char _cror_ (unsigned char, unsigned char); extern unsigned int _iror_ (unsigned int, unsigned char);extern unsigned long _lror_ (unsigned long, unsigned char); extern unsigned char _crol_ (unsigned char, unsigned char); extern unsigned int _irol_ (unsigned int, unsigned char); extern unsigned long _lrol_ (unsigned long, unsigned char); extern unsigned char _chkfloat_(float);extern void _push_ (unsigned char _sfr);extern void _pop_ (unsigned char _sfr);#endif#ifndef __DISPLAY_H__#define __DISPLAY_H__#define uchar unsigned char#define uint unsigned int//0 1 2 3 4 5 67 8 9 - 灭_unsigned char codeDuanMa[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0 xbf,0xff,0xf7,0xab,0x8e}; //共阳unsigned char codeWeiMa[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//分别对应相应的数码管点亮,即位码#define DataPort P0 //定义数据端口程序中遇到DataPort 则用P0替换void SEG_Latch(void) //段码锁存子程序{P2 |= 0xe0;//P2.7~P2.5=111,Y7=0,Y7C=1,即U7的LE=1,段码数据选通_nop_();P2 &= 0x1f;//P2.7~P2.5=000,Y7=1,Y7C=0,即U7的LE=0,段码数据被锁存}void BIT_Latch(void) //位码锁存子程序{P2 |= 0xC0; //P2.7~P2.5=110,Y6=0,Y6C=1,即U8的LE=1,位码数据选通_nop_();P2 &= 0x1f; //P2.7~P2.5=000,Y6=1,Y6C=0,即U8的LE=0,位码数据被锁存}void delay_50us(uint t) //50us 延时{uchar j;for(;t>0;t--)for(j=19;j>0;j--);}void display(uchar *point){unsigned char i=0;for(i=0;i<8;i++){DataPort=WeiMa[i]; //取位码BIT_Latch(); //数据锁存DataPort=DuanMa[*(point+i)]; //取显示数据,段码SEG_Latch(); //数据锁存delay_50us(30); // 扫描间隙延时,时间太长会闪烁,太短不亮DataPort=0xff; //关显示,消除重影SEG_Latch(); //数据锁存}}#endif#ifndef __DS1302_H__#define __DS1302_H__#include <intrins.h>#define uint unsigned int#define uchar unsigned char#define nop _nop_()sbit DS1302_CLK = P1^7;sbit DS1302_IO = P2^3;sbit DS1302_RST = P1^3;uchar NowTime[8]={0x12,0x5,0x26,0x6,0x00,0x00,0x00};//年,月,日,星期,时,分,秒/*************************************************************************** **函数功能:写DS1302一个字节子程序入口参数:出口参数:**************************************************************************** */void sendbyte(uchar a){uchar i;for(i=8;i>0;i--){DS1302_CLK=0;nop;DS1302_IO = a & 0x01;a >>= 1;DS1302_CLK=1;nop;}}/*************************************************************************** **函数功能:读DS1302一个字节子程序入口参数:出口参数:**************************************************************************** */uchar readbyte(void){uchar i,dat=0;for(i=8;i>0;i--){DS1302_CLK=1;nop;DS1302_CLK=0;dat>>=1;if(DS1302_IO)dat|=0x80;}DS1302_IO=0;return dat;}/*************************************************************************** **函数功能:写DS1302地址子程序入口参数:add入口数据:dat**************************************************************************** */void write_DS1302(uchar address,uchar dat){DS1302_RST=0;nop;DS1302_CLK=0;nop;DS1302_RST=1;nop;sendbyte(address);nop;sendbyte(dat);nop;DS1302_RST=0;nop;DS1302_CLK=0;}/*************************************************************************** **函数功能:读DS1302地址子程序入口参数:add出口参数:readtimeR[]**************************************************************************** */uchar read_DS1302(uchar address){uchar timer;DS1302_RST=0;nop;DS1302_CLK=0;nop;DS1302_RST=1;nop;sendbyte(address);timer=readbyte();DS1302_RST=0;nop;DS1302_CLK=0;return timer;}/*************************************************************************** **函数功能:初始化DS1302子程序入口参数:wr_data[](全局变量)出口参数:**************************************************************************** */void DS1302_init(){write_DS1302(0x8e,0x00); //关闭保护,若写0x80,则开启保护write_DS1302(0x8c,NowTime[0]); //年write_DS1302(0x88,NowTime[1]); //月write_DS1302(0x86,NowTime[2]); //日write_DS1302(0x8A,NowTime[3]); //星期write_DS1302(0x84,NowTime[4]); //时write_DS1302(0x82,NowTime[5]); //分write_DS1302(0x80,NowTime[6]); //秒write_DS1302(0x8e,0x80); //开写保护}//=======================时钟开启,可省略==================================void clock_start(void){uchar val;val = read_DS1302(0x81); //读秒寄存器val &= 0x7f; //最高位CH,振荡器工作允许write_DS1302(0x8e,0x00); //关写保护write_DS1302(0x80,val);write_DS1302(0x90,0xa5);//使能涓电流充电,DS=01:选择一个二极管,RS=01:R1=2kwrite_DS1302(0x8e,0x80);//开写保护}#endif#ifndef __KEY_H__#define __KEY_H__#define KeyPort P3/*------------------------------------------------将跳线帽套在J5的BIN针上独立按键扫描函数,返回扫描键值左边一列从上向下对应P30,P31,P32,P33分别是0,1,2,3号键------------------------------------------------*/void delay50us(unsigned int t) //50us 延时{unsigned char j;for(;t>0;t--)for(j=19;j>0;j--);}unsigned char KeyScan(void) //键盘扫描函数,使用行列逐级扫描法{unsigned char Val;KeyPort=0xf0;//高四位置高,低四位拉低if(KeyPort!=0xf0)//表示有按键按下{delay50us(200); //去抖if(KeyPort!=0xf0){ //表示有按键按下KeyPort=0xfe; //检测第一行if(KeyPort!=0xfe){Val=KeyPort&0xf0;Val+=0x0e;while(KeyPort!=0xfe);delay50us(200); //去抖while(KeyPort!=0xfe);return Val;}KeyPort=0xfd; //检测第二行if(KeyPort!=0xfd){Val=KeyPort&0xf0;Val+=0x0d;while(KeyPort!=0xfd);delay50us(200); //去抖while(KeyPort!=0xfd);return Val;}KeyPort=0xfb; //检测第三行if(KeyPort!=0xfb){Val=KeyPort&0xf0;Val+=0x0b;while(KeyPort!=0xfb);delay50us(200); //去抖while(KeyPort!=0xfb);return Val;}KeyPort=0xf7; //检测第四行if(KeyPort!=0xf7){Val=KeyPort&0xf0;Val+=0x07;while(KeyPort!=0xf7);delay50us(200); //去抖while(KeyPort!=0xf7);return Val;}}}return 0xff;}unsigned char KeyPro(void){switch(KeyScan()){case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值case 0x7d:return 1;break;//1case 0x7b:return 2;break;//2case 0x77:return 3;break;//3case 0xbe:return 4;break;//4case 0xbd:return 5;break;//5case 0xbb:return 6;break;//6case 0xb7:return 7;break;//7case 0xde:return 8;break;//8case 0xdd:return 9;break;//9case 0xdb:return 10;break;//acase 0xd7:return 11;break;//bcase 0xee:return 12;break;//ccase 0xed:return 13;break;//dcase 0xeb:return 14;break;//ecase 0xe7:return 15;break;//fdefault:return 0xff;break;}}#endif#ifndef _24c02_H#define _24c02_H#include "reg52.h"#include "intrins.h"#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}sbit SDA = P2^1;sbit SCL = P2^0;void iic_start(void){SDA = 1;_nop_();SCL = 1;somenop;SDA = 0;somenop;SCL = 0;}void iic_stop(void){SDA = 0;_nop_();SCL = 1;somenop;SDA = 1;}void iic_ack(bit ackbit) {if(ackbit)SDA = 0;elseSDA = 1;somenop;SCL = 1;somenop;SCL = 0;SDA = 1;somenop;}bit iic_waitack(void) {SDA = 1;somenop;SCL = 1;somenop;if(SDA){SCL = 0;iic_stop();return 0;}else{SCL = 0;return 1;}}void iic_sendbyte(unsigned char byt) {unsigned char i;for(i=0;i<8;i++){if(byt&0x80)SDA = 1;elseSDA = 0;somenop;SCL = 1;byt <<= 1;somenop;SCL = 0;}}unsigned char iic_recbyte(void) {unsigned char da;unsigned char i;for(i=0;i<8;i++){SCL = 1;somenop;da <<= 1;if(SDA)da |= 0x01;SCL = 0;somenop;}return da;}/* void delay_50us(unsigned int t){unsigned char j;for(;t>0;t--)for(j=19;j>0;j--);} */bit ISendStr(unsigned char add1,unsigned char add2,unsigned char *s,unsigned char no){unsigned char i;iic_start();iic_sendbyte(add1);if(iic_waitack()==0)return 0;iic_sendbyte(add2);if(iic_waitack()==0)return 0;for(i=0;i<no;i++){iic_sendbyte(*s);if(iic_waitack()==0)return 0;delay_50us(10);s++;}iic_stop();return 1;}bit IRcvStr(unsigned char add1,unsigned char add2,unsigned char *s,unsigned char no){unsigned char i;iic_start();iic_sendbyte(add1);if(iic_waitack()==0)return 0;iic_sendbyte(add2);if(iic_waitack()==0)return 0;iic_start();iic_sendbyte(add1+1);if(iic_waitack()==0)return 0;for(i=0;i<no-1;i++){*s=iic_recbyte();iic_ack(1);s++;delay_50us(10);}*s=iic_recbyte();iic_ack(0);iic_stop();return(1);}unsigned char read(unsigned char add) {unsigned char temp;iic_start();。

相关主题