版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第6章 单片机单总线、I2C和SPI应用 总线就是一个公共的连接线,所有外围设备都可以通过它与单片机相连接,是信息传递的通道。总线的种类很多,常用的有单总线(1-wire)、集成电路总线I2C(也称IC、IIC,Inter-Integrated Circuit)和串行外设接口SPI(Serial Peripheral Interface),分别需要1、2、3条线的连接。(1)单总线需要1条线:一条数据线通信。(2)I2C需要2条线:一条时钟线,一条数据线。(3)SPI需要3条线:一条时钟线,一条数据接收线,一条数据发送线。 这些总线传输,结构简单、传输速度快、传输距离远,被越来越多的系统应用。
2、 6.1 单总线单总线DS18B20测温项目设计测温项目设计项目单总线单总线概述单总线概述 近年来,美国的达拉斯半导体公司(近年来,美国的达拉斯半导体公司(DALLAS SEMICONDUCTOR)推出了一项特有的单总线()推出了一项特有的单总线(1Wire Bus)技术。它采用单根信号线,既可传输时钟,又能传输)技术。它采用单根信号线,既可传输时钟,又能传输数据,而且数据传输是双向的,因而这种单总线技术具有线数据,而且数据传输是双向的,因而这种单总线技术具有线路简单,硬件开销少,成本低廉,便于总线扩展和维护等优路简单,硬件开销少,成本低廉,便于总线扩展和维护等优点。点。 序列号序列号 产品型
3、号:产品类别(例如产品型号:产品类别(例如18B20为为0 x28) 产品序列号:产品序列号:48位的身份证,可寻址。位的身份证,可寻址。 CRC校验码:校验码:CRC(Cyclic Redundancy Check)在)在使用时使用时,将前将前56位按位按CRC多项式计算出多项式计算出CRC值值,然后与然后与ROM中高中高8位的位的CRC值比较值比较,若相同则表明数据传送正确若相同则表明数据传送正确,否则要否则要求重传。求重传。 DS-18B20 数字温度传感器 DS18B20是美国DALLAS公司生产的1-wire式单总线的数字温度传感器。具有耐磨耐碰,体积小,线路简单,使用方便,大大提高
4、了系统的抗干扰性。适合于恶劣环境的现场温度测量。例如:冷冻库,粮仓,储罐,电讯机房,电力机房,电缆线槽等测温,汽车空调、冰箱、冷柜、以及中低温干燥箱等。 27.0DQ2VCC3GND1U3DS18B20一、主要特点 1. 1. 1-wire1-wire式式 单总线有单总线有4.7K10K 4.7K10K 的上拉电阻,这样,当的上拉电阻,这样,当总线闲置时其状态为高电平。总线闲置时其状态为高电平。 2.2.分辨率可以在分辨率可以在9-129-12位位选择(温度转换后的数字信号是选择(温度转换后的数字信号是9-9-1212位位: :0.5 0.0625 0.5 0.0625 ) 3. 3. 测温范
5、围测温范围 5555125,125,在在 -10+ 85-10+ 85C C 范围内,范围内,精度为精度为 0.5 0.5C C 。 4.4.每个器件都有每个器件都有唯一的序列号。唯一的序列号。 5.5.内部有内部有温度上限、下限的报警温度上限、下限的报警设置,有报警功能设置,有报警功能 6. 6. 支持支持多点组网多点组网功能,多个功能,多个DS18B20DS18B20可以并联在唯一的总可以并联在唯一的总线上,实现多点测温线上,实现多点测温 7.7.供电方式灵活供电方式灵活 , ,可以外接电源,也可以通过内部寄生电可以外接电源,也可以通过内部寄生电路从数据线上获取电源路从数据线上获取电源二、
6、DS18B20管脚排列DS18B20DS18B20的管脚排列的管脚排列1. GND1. GND为电源为电源 地;地;2. DQ2. DQ(I/OI/O)为数字信号输入输出端;)为数字信号输入输出端;3. VDD3. VDD为外接供电电源输入端为外接供电电源输入端(在寄生电源接线方式时接地)(在寄生电源接线方式时接地)两种供电方式:两种供电方式: 通常为了给通常为了给 1-WIRE 设备提供足够的电源,设备提供足够的电源, 1. 外部电源:需要一个上拉电阻,将外部电源:需要一个上拉电阻,将 1-WIRE 总线上拉至总线上拉至 +5V 电电源。源。 2. 寄生电源:再需要一个寄生电源:再需要一个
7、MOSFET 管将管将 1-WIRE 总线上拉至总线上拉至 +5V 电源。电源。三、三、DS18B20内部结构内部结构 如图所示,主要由如图所示,主要由4部分组成:部分组成: 64 64 位光刻位光刻 ROMROM 、温度传感器、温度报警触发器、温度传感器、温度报警触发器TH和和TL、配、配置寄存器。置寄存器。 温度传感器温度传感器 DS18B20DS18B20中的温度传感器完成对温度的测量,中的温度传感器完成对温度的测量,把温度转换为对应的数字量(把温度转换为对应的数字量(9 9位或位或1212位,出位,出厂时默认厂时默认1212位,最高位是符号位)。位,最高位是符号位)。该数字量和温度之间
8、的对应转换格式,见下图,该数字量和温度之间的对应转换格式,见下图,其中其中S S为符号位,即数据格式以为符号位,即数据格式以0.0625/LSB0.0625/LSB形式表达。高形式表达。高5 5位为符号位:位为符号位:0 0为正,为正,1 1为负。为负。正:正:* *0.06250.0625;负:(取反加;负:(取反加1 1)* *0.06250.0625 配置寄存器配置寄存器最高位用于设置最高位用于设置DS18B20DS18B20在工作模式还是在测试模式。在在工作模式还是在测试模式。在DS18B20DS18B20出厂时该位被设置为出厂时该位被设置为0 0,用户不要去改动。,用户不要去改动。R
9、1R1和和R0R0用来设置分辨率,(用来设置分辨率,(DS18B20DS18B20出厂时被设置为出厂时被设置为1212位)位)低五位一直都是低五位一直都是“1”1” 高速暂存存储器高速暂存存储器RAMRAM 高速暂存存储器由9个字节组成,见下图.四、DS18B20的工作时序(单线接口访问(单线接口访问DS18B20DS18B20的协议的协议 ) 单片机对单片机对DS18B20DS18B20操作:温度转换、读取温度、存操作:温度转换、读取温度、存取报警上下限等。取报警上下限等。根据根据DS18B20DS18B20的通讯协议,单片机每次访问的通讯协议,单片机每次访问DS18B20DS18B20都必
10、须遵循以下顺序:都必须遵循以下顺序: 初始化初始化18B20 18B20 ; 发发ROMROM操作命令;操作命令; 发发RAMRAM操作命令:操作命令: 相应操作。相应操作。 1. 1. ROM操作命令操作命令2. RAMRAM操作命令操作命令五、DS18B20的基本操作 在以上的工作流程中,首先要初始化18B20,然后发各种命令以及数据传输都涉及到对DS18B20的读写操作,所以共涉及到以下3个工作时序:1.初始化操作2.写操作 (发命令)3.读操作 (读温度)1.初始化时序对应时序图,实现初始化的程序设计如下。对应时序图,实现初始化的程序设计如下。uchar DS18B20_init(vo
11、id) /DS18B20初始化初始化uchar i,s=0;DQ=0; i=250; while(i0) i-;/500us,范围范围:480-960DQ=1; i=20; while(i0) i-;/40us,范围范围:15-60s=DQ; /读存在脉冲,如果读存在脉冲,如果DQ为为0,说明初始化成功;说明初始化成功;为为1,说明损坏或不存在,说明损坏或不存在while(!DQ); /DQ恢复恢复1return s; /函数值为函数值为0或或12. 2. 写时序写时序主机要产生一个写0时隙,就必须把数据线拉低并保持60us。主机要产生一个写1时隙,就必须把数据线拉低,在写时隙开始后的15us
12、内允许数据线拉高。实现的程序代码如下所示。uchar i;DQ=1; i=2; while(i0) i-;/6us,间隔至少1usDQ=0; i=2; while(i0) i-;/6us,间隔至少1usDQ=x; i=45; while(i0) i-;/90us,写一位时间范围:60-120usDQ=1;3.3.读时序读时序完成一个读时序过程,至少需要60us才能完成DQ=1;i=2;while(i0) i-;/6us,间隔至少间隔至少1usDQ=0;i=2;while(i0) i-;/6us,间隔至少间隔至少1usDQ=1;i=2;while(i0) i-;/6us,间隔至少间隔至少1usx
13、=DQ;i=40;while(i0) i-;/80us,读一位时间范围:读一位时间范围:60-90usDQ=1;动手做动手做画出硬件电路图画出硬件电路图 启动温度转换、读取温度值并显示在LCD的完整程序如下:#include #define uchar unsigned char#define uint unsigned intuint DS18B20(void); /读DS18B20双字节函数声明uchar DS18B20_init(void); /DS18B20初始化void Write(uchar ); /写DS18B20一个字节函数声明uchar Read(void); /读DS18B
14、20一个字节函数声明 void start(void); /启动DS18B20函数声明bit LCD_Busy(); /忙函数声明void LCD_write_command(uchar ); /写命令函数声明void LCD_write_data(uchar ) ; /写数据函数声明void LCD_init( ) ; /初始化函数声明void LCD_1_line(uchar pos1,uchar*LCDline1); /第一行显示函数声明void LCD_2_line(uchar pos2,uchar*LCDline2); /第二行显示函数声明void delay(uchar); sbi
15、t DQ=P22; /单总线sbit LCD_RS=P30; /将P3.0引脚取名为LCD_RS,控制寄存器选择sbit LCD_E=P32; /将P3.2引脚取名为LCD_E,使能端sbit LCD_RW=P31; /将P3.1引脚取名为LCD_RW,控制读写选择bit ERROR=0;/*主程序*/void main(void) uchar LCDline1=TEMP:; /定义第一行要显示的字符串uchar LCDline216= ; /定义第二行要显示的字符串unsigned int temp12,temp;LCD_init();LCD_1_line(0 x00,LCDline1);w
16、hile(1)temp=DS18B20();if(temp0 xF800) /高5位为11111,温度为负temp=temp+1; /负数要有补码:取反加1LCDline20= ; /负百位不显示LCDline21=-; /显示温度的负temp12=(long int)temp*625/1000;/十进制数温度,计小数点一位,放大10倍LCDline22=(temp12%1000)/100+0 x30;/十位if (LCDline22=0 x30) LCDline21= ; /首位为0,不显示LCDline22=-; /显示负elseLCDline20= ;temp12=(long int)t
17、emp*625/1000; /十进制数温度,计小数点一位,放大10倍 LCDline21=(temp12%10000)/1000+0 x30; /温度百位,并+0 x30,形成LCD字符码if (LCDline21=0 x30) LCDline21= ; /首位为0,不显示LCDline22=(temp12%1000)/100+0 x30;/温度十位if (LCDline21= &LCDline22=0 x30) LCDline22= ; /首位为0,不显示temp=(long int)temp*625/1000; /十进制数温度,计小数点一位,放大10倍 LCDline23=(tem
18、p%100)/10+0 x30; /温度个位LCDline24=.; /温度小数点LCDline25=(temp%10)/1+0 x30; /温度小数位LCDline26=0 xdf; /6位显示温度符号的oLCDline27=0 x43; /7位显示温度符号的CLCD_2_line(0 x00,LCDline2);/*DS18B20初始化*/uchar DS18B20_init(void)uchar i,s=0;DQ=0; i=250;while(i0) i-; /500us,范围:480-960DQ=1; i=20;while(i0) i-; /40us,范围:15-60s=DQ; /存在
19、脉冲为0,初始化成功;为1,损坏或不存在while(!DQ); /DQ恢复1return s; /函数值为0或1/*温度传感器写一字节*/void Write(uchar date) uchar i,j;for(j=0;j0) i-; /6us,间隔至少1usDQ=0;i=2;while(i0) i-; /6us,间隔至少1usDQ=date&0 x01; /先写最低位i=45;while(i0) i-; /90us,写一位时间范围:60-120usdate=date1; /右移一位,再写,循环8次DQ=1;/*温度传感器读出一字节数据*/uchar Read(void)uchar i
20、,j,date=0;for(j=0;j0) i-; /6us,间隔至少1usdate=1; /右移1位DQ=0;i=2;while(i0) i-; /6us,间隔至少1usDQ=1;i=2;while(i0) i-; /6us,间隔至少1usif(DQ=1) date=date|0 x80; /若DQ=1, 最高位置1i=40;while(i0) i-; /80us,读一位时间范围:60-90usDQ=1;return(date); /返回一字节数据/*启动DS18B20的一次温度转换*/void start(void)if(DS18B20_init()=1) ERROR=1; /无法初始化,
21、出错elseWrite(0 xcc); /单个传感器,可以跳过ROM,即跳过多传感器识别Write(0 x44); /启动温度转换while(!DQ); /DQ由0转为1,则温度转换结束 /*温度传感器读温度双字节*/ uint DS18B20(void) unsigned int Temp=0;start();if(DS18B20_init()=1) ERROR=1; elseWrite(0 xcc); /跳过ROM,即跳过多传感器识别Write(0 xbe); /读取DS18B20寄存器指令Temp=Read(); /读取温度值低位字节Temp=(Read()8)|Temp; /读取温度值
22、高位字节,并合成16位字节return(Temp); /返回温度值/* LCD显示程序 */*忙检测函数*/bit LCD_Busy() bit LCD_Busy;LCD_RS=0; LCD_RW=1; LCD_E=1; delay(1); LCD_Busy=(bit)(P0&0 x80); /取LCD数据首位,即忙信号位LCD_E=0;return LCD_Busy;/*写命令函数*/void LCD_write_command(uchar cmd) while(LCD_Busy(); /等待显示器忙检测完毕delay(1); LCD_RS=0; LCD_RW=0; P0=cmd;d
23、elay(1); LCD_E=1; delay(1); LCD_E=0;/*写数据函数*/void LCD_write_data(uchar dat) while(LCD_Busy(); delay(1); LCD_RS=1; LCD_RW=0; P0=dat;delay(1); LCD_E=1; delay(1);LCD_E=0;/*初始化函数*/void LCD_init( ) LCD_write_command(0 x38); / 162显示,57点阵,8位数据接口 delay(1);LCD_write_command(0 x01); /清屏delay(1);LCD_write_comm
24、and(0 x06); /光标右移,字符不移 delay(1);LCD_write_command(0 x0C); /显示开,无光标,光标不闪烁delay(1);/*显示第一行字符*/void LCD_1_line(uchar pos1,uchar*LCDline1) uchar i=0;LCD_write_command(0 x80+pos1); /在第一行pos1位显示while(LCDline1i!=0) /显示首行字符串LCD_write_data(LCDline1i);i+;delay(1);/*显示第二行字符*/void LCD_2_line(uchar pos2,uchar*LC
25、Dline2) uchar i=0;LCD_write_command(0 x80+0 x40+pos2); /在第二行pos2位显示while(LCDline2i!=0) /显示第二行字符串LCD_write_data(LCDline2i);i+;delay(1);/*延时函数t(ms)*/void delay(uchar t ) uchar j,k; for(j=0;jt;j+) for(k=0;k255;k+) 仿真运行图 6.2 I2C总线总线AT24C02 项目项目设计设计项目I2C串行总线概述串行总线概述 I2C总线是总线是PHLIPS公司推出的一种串行总线,是高性能公司推出的一种
26、串行总线,是高性能串行总线。串行总线。 I2C总线只有两根双向信号线。总线只有两根双向信号线。 一根是数据线一根是数据线SDA(Serial Data), 另一根是时钟线另一根是时钟线SCL(Serial Clock)。)。 I2C总线通过上拉电阻总线通过上拉电阻(4.7K或或10K)接正电源。当总线空闲接正电源。当总线空闲时,两根线均为高电平。连到总线上的任一器件输出的低电时,两根线均为高电平。连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的平,都将使总线的信号变低,即各器件的SDA及及SCL都是线都是线“与与”关系关系。种类种类型号型号寻址地址寻址地址(设备号设备号+引脚
27、配置引脚配置+读读写位写位)256x8/128x8静态静态RAM PCF8570/711010 A2A1A0 R/W 256x8静态静态RAM PCF8570C1011 A2A1A0 R/W 256B E2PROM PCF8582 1010 A2A1A0 R/W 256B E2PROM AT24C02 1010 A2A1A0 R/W 512B E2PROMAT24C041010 A2A1P0 R/W 1024B E2PROMAT24C081010 A2P1P0 R/W 2048B E2PROMAT24C161010 P2P1P0 R/W 日历时钟日历时钟PCF85911010 0 0 A0 R
28、/W8位位I/O口口PCF85740100 A2A1A0 R/W 4位位LED驱动控制器驱动控制器SAA10640111 0 A1A0 R/W 4通道通道8位位A/D、1路路D/A转换转换器器PCF85911001 A2A1A0 R/W 每个接到每个接到I2C总线上的器件都有唯一的地总线上的器件都有唯一的地址。(例如:址。(例如:1010A2A1A0) 由总线上传送数据的器件为发送器。由总线上传送数据的器件为发送器。 由总线上接收数据的器件则为接收器由总线上接收数据的器件则为接收器。 在在80C51单片机应用系统的串行总线扩单片机应用系统的串行总线扩展中,我们经常遇到的是以展中,我们经常遇到的
29、是以80C51单片机单片机为主机,其它接口器件为从机的单主机情为主机,其它接口器件为从机的单主机情况。况。 一、起始和终止信号一、起始和终止信号 SCL线为高电平期间,线为高电平期间,SDA线由高电平向低电线由高电平向低电平的变化表示起始信号;平的变化表示起始信号; SCL线为高电平期间,线为高电平期间,SDA线由低电平向高电线由低电平向高电平的变化表示终止信号。平的变化表示终止信号。 I2C总线的数据传送总线的数据传送起始信号为:当起始信号为:当SCL为高期间,为高期间,SDA由高到低的跳变。该信号是一种电平由高到低的跳变。该信号是一种电平跳变时序信号。跳变时序信号。起始信号程序模拟如下。起
30、始信号程序模拟如下。void delay_6us(void) /6微秒延时微秒延时 _nop_();_nop_(); _nop_(); _nop_();_nop_();_nop_(); void start() /开始数据传送,开始位开始数据传送,开始位 SDA=1; /SDA初始化为高电平初始化为高电平“1” SCL=1; /开始数据传送时,开始数据传送时,SCL为高电平为高电平“1” delay_6us(); /按时序大于按时序大于4.7微秒微秒 SDA=0; /SDA的下降沿的下降沿:开始信号开始信号 delay_6us(); /按时序大于按时序大于4微秒微秒 SCL=0; /SCL为低
31、电平时,为低电平时,SDA上数据才允许变化上数据才允许变化 停止信号为:当停止信号为:当SCL为高期间,为高期间,SDA由低到高的跳变;停止信号也是一种由低到高的跳变;停止信号也是一种电平跳变时序信号电平跳变时序信号(边沿边沿),而不是一个电平信号。,而不是一个电平信号。停止信号程序模拟如下。停止信号程序模拟如下。void stop() /结束数据传递结束数据传递 SDA=0; /SDA初始化为低电平初始化为低电平“0” SCL=1; /结束数据传送时,结束数据传送时,SCL为高电平为高电平“1” delay_6us();/按时序大于按时序大于4微秒微秒 SDA=1; /SDA的上升沿的上升沿
32、:结束信号结束信号 delay_6us();/按时序大于按时序大于4微秒微秒 SCL=0; /SCL为低电平时,为低电平时,SDA上数据才允许变化上数据才允许变化数据传送的应答与非应答应答信号应答信号ACK:主机读写,主机读写,接收设备接收设备产生,数产生,数据传输正确,产生应答。据传输正确,产生应答。非应答信号非应答信号NO ACK:主机读,:主机读,主机主机接收后接收后不产生应答,产生非应答,表示数据接收结不产生应答,产生非应答,表示数据接收结束。束。发送应答信号程序模拟如下。发送应答信号程序模拟如下。void ack()/应答应答 SDA=0; SCL=1; delay_6us();/按
33、时序大于按时序大于4微秒微秒 SCL=0; SDA=1; 发送非应答信号程序模拟如下。发送非应答信号程序模拟如下。void noack()/非应答非应答 SDA=1; SCL=1; delay_6us();/按时序大于按时序大于4微秒微秒 SCL=0; SDA=0; 检测检测I2C设备应答信号程序模拟如下。设备应答信号程序模拟如下。bit detect_ack()/检测应答检测应答 bit detect_ack; SDA=1; SCL=1; delay_6us();/按时序大于按时序大于4微秒微秒 detect_ack=SDA; SCL=0; return detect_ack; 在传输期间,
34、如果从设备没有应答意味着将没有更多的数据要传送在传输期间,如果从设备没有应答意味着将没有更多的数据要传送或者设备没有准备好传送。这时,主设备要么产生停止信号,要么重新或者设备没有准备好传送。这时,主设备要么产生停止信号,要么重新发出起始信号。发出起始信号。二、数据位的有效性规定二、数据位的有效性规定 I2C总线进行数据传送时,总线进行数据传送时, (1)时钟信号为高电平期间)时钟信号为高电平期间,数据线上的数据,数据线上的数据必须保持稳定,必须保持稳定, (2)时钟线上的信号为低电平期间)时钟线上的信号为低电平期间,数据线上,数据线上的高电平或低电平状态才允许变化。的高电平或低电平状态才允许变
35、化。三、总线的寻址三、总线的寻址 I2C总线协议有明确的规定:采用总线协议有明确的规定:采用7位的寻址字位的寻址字节(寻址字节是起始信号后的第一个字节)。节(寻址字节是起始信号后的第一个字节)。 D7D1位组成从机的地址。位组成从机的地址。D0位是数据位是数据传送方向位,为传送方向位,为“0”时表示主机向从机写数时表示主机向从机写数据,为据,为“1”时表示主机由从机读数据。时表示主机由从机读数据。主机发送地址主机发送地址时,总线上的每个从机都将这时,总线上的每个从机都将这7位地址码与自己的地址进行比较,如果相同,位地址码与自己的地址进行比较,如果相同,则认为自己正被主机寻址,根据则认为自己正被
36、主机寻址,根据R/W位将自己位将自己确定为发送器或接收器确定为发送器或接收器。从机的地址从机的地址由固定部分和可编程部分组成。由固定部分和可编程部分组成。在一个系统中可能希望接入多个相同的从机,在一个系统中可能希望接入多个相同的从机,从机地址中可编程部分决定了可接入总线该类从机地址中可编程部分决定了可接入总线该类器件的最大数目。如一个从机的器件的最大数目。如一个从机的7位寻址位有位寻址位有4位是固定位,位是固定位,3位是可编程位,这时仅能寻位是可编程位,这时仅能寻址址8个同样的器件,即可以有个同样的器件,即可以有8个同样的器件个同样的器件接入到该接入到该I2C总线系统中总线系统中。四、数据传送
37、格式四、数据传送格式(1)字节传送)字节传送 每一个字节必须保证是每一个字节必须保证是8位长度。数据传送时,先传位长度。数据传送时,先传送最高位(送最高位(MSB)。)。 (2)数据帧格式)数据帧格式 I2C总线上传送的数据信号是广义的,既包括总线上传送的数据信号是广义的,既包括地址地址信号信号,又包括真正的,又包括真正的数据信号数据信号。 在起始信号后必须传送一个从机的地址(在起始信号后必须传送一个从机的地址(7位),位),第第8位是数据的传送方向位(位是数据的传送方向位(R/W),), 用用“0”表示主机发送数据(表示主机发送数据(W),), “1”表示主机接收数据(表示主机接收数据(R)
38、。)。 每次数据传送总是由主机产生的终止信号结束。每次数据传送总是由主机产生的终止信号结束。但是,若主机希望继续占用总线进行新的数据传送,但是,若主机希望继续占用总线进行新的数据传送,则可以不产生终止信号,马上再次发出起始信号对则可以不产生终止信号,马上再次发出起始信号对另一从机进行寻址。另一从机进行寻址。 数据传输格式起始起始-地址地址-读写读写-应答应答-数据数据-应答应答-停止停止I2C器件: AT24C02芯片AT24C02是一个2K位串行CMOS E2PROM程序存储器, 内部含有256个8位字节,掉电保护,并可以多次电擦写管脚名称管脚名称功能功能A2、A1、A0设备地址选择SDAI
39、2C数据线SCLI2C时钟线WP写保护VCC+1.8V5.5V工作电压VSS地存储结构与寻址芯片寻址:1010 (固定) A2A1A0(三位)R/W(读1写0)片内寻址:256(8位)动手做动手做画出硬件电路图画出硬件电路图 项目使用了二个按钮开关BUTTON1和BUTTON2,作为计件,分别将计件数存放到二个AT24C02中,随后,单片机分别取出二个AT24C02中的存放数,显示在液晶显示器LCD的第一行和第二行项目使用了二个AT24C02,U2器件的地址为0 xa0即为10100000B,其中1010为AT24C02,000为U2选择器件,0为写。U3器件的地址为0 xa2即为101000
40、10B,其中1010为AT24C02,001为U3选择器件,0为写。程序设计如下。#include#include /包含_nop_()函数定义的头文件#define uchar unsigned charsbit LCD_RS=P30; /将P3.0引脚取名为LCD_RS,控制寄存器选择sbit LCD_E=P32; /将P3.2引脚取名为LCD_E,使能端sbit LCD_RW=P31; /将P3.1引脚取名为LCD_RW,控制读写选择sbit button1=P10; /将第一按钮开关位定义为P1.0引脚sbit button2=P11; /将第二按钮开关位定义为P1.1引脚sbit S
41、DA=P34; /将串行数据总线SDA位定义在为P3.4引脚sbit SCL=P33; /将串行时钟总线SCL位定义在为P3.3引脚uchar num=;bit LCD_Busy(); /忙函数声明void LCD_write_command(uchar ); /写命令函数声明void LCD_write_data(uchar ) ; /写数据函数声明void LCD_init( ) ; /初始化函数声明void delay(uchar); /延时函数声明void delay_6us(); /延时6微秒函数声明 void LCD(uchar,uchar); /LCD显示函数声明void sta
42、rt() ; /开始函数声明void stop(); /停止函数声明void ack(); /应答函数声明void no_ack(); /非应答函数声明bit detect_ack(); /检测应答函数声明uchar Read24c02_byte(); /读24C02函数声明void Write24c02_byte(uchar); /写数据函数声明void Write24c02_addr_byte(uchar ,uchar,uchar) ; /写地址函数声明uchar Read24c02_addr_byte(uchar,uchar); /读地址函数声明/*主程序*/void main(void
43、)uchar num1,num2; uchar DATA_24C02; /存储从AT24C02读出的值LCD_init(); /调用LCD初始化函数while(1) /无限循环if(button1=0) /如果该键被按下delay(10); /软件消抖,延时10msif(button1=0) /确实该键被按下 num1+; /计数值加1if(num1=100) /如果计满99 num1=0; /清0,重新开始计数while(button1=0); /等待按键松开Write24c02_addr_byte(0 xa0,0 x01,num1); /0 xa0即为1010 0000B:1010为AT2
44、4C02,000为选择器件,0为写.将计件值写入第一片AT24C02中的指定地址“0 x01”DATA_24C02=Read24c02_addr_byte(0 xa0,0 x01);/从AT24C02中0 x01地址读出计件值LCD(0 x5,DATA_24C02); /将计件值用1602LCD显示在第一行第五位if(button2=0) /如果该键被按下delay(10); /软件消抖,延时10msif(button2=0) /确实该键被按下 num2+; /计数值加1if(num2=100) /如果计满99 num2=0; /清0,重新开始计数while(button2=0); /等待按键
45、松开Write24c02_addr_byte(0 xa2,0 x01,num2); /0 xa2即为1010 0010B:1010为AT24C02,001为选择器件,0为写,将计件值写入第二片AT24C02中的指定地址“0 x01”DATA_24C02=Read24c02_addr_byte(0 xa2,0 x01); /从AT24C02中0 x01地址读出计件值LCD(0 x5+0 x40,DATA_24C02); /将计件值用1602LCD显示在第一行第五位/*开始数据传送,开始位*/void start() SDA=1; /SDA初始化为高电平“1”SCL=1; /开始数据传送时,SCL
46、为高电平“1”delay_6us(); /按时序大于4.7微秒SDA=0; /SDA的下降沿:开始信号delay_6us(); /按时序大于4微秒SCL=0; /SCL为低电平时,SDA上数据才允许变化/*结束数据传递*/void stop() SDA=0; /SDA初始化为低电平“0”SCL=1; /结束数据传送时,SCL为高电平“1”delay_6us(); /按时序大于4微秒SDA=1; /SDA的上升沿:结束信号delay_6us(); /按时序大于4微秒SCL=0; /SCL为低电平时,SDA上数据才允许变化/*应答*/void ack()SDA=0;SCL=1;delay_6us(
47、); SCL=0;SDA=1; /*非应答*/void no_ack()SDA=1;SCL=1;delay_6us(); SCL=0;SDA=0; /*检测应答*/bit detect_ack()bit detect_ack;SDA=1;SCL=1;delay_6us(); detect_ack=SDA;SCL=0;return detect_ack; /*从AT24C02读取数据字节到单片机*/uchar Read24c02_byte() uchar i;uchar read_byte; SDA=1; /读方式:数据线为输入方式for(i=0;i8;i+) read_byte=1; /左移一
48、位,补0read_byte|=(uchar)SDA; /将SDA上的数据通过按位“或”运算存入字节SCL=1; delay_6us(); /按时序大于4.7微秒 SCL=0; return(read_byte); /返还读取的AT24C02字节数据/*向AT24C02的当前地址写入数据*/void Write24c02_byte(uchar write_byte) uchar i;for(i=0;i8;i+) /循环移入8个位SDA=(bit)(write_byte&0 x80); /传送时高位在前,低位在后SCL=1; delay_6us(); /按时序大于4.7微秒SCL=0; d
49、elay_6us(); /按时序大于4.7微秒write_byte=1; /左移一位,传送下一位/*向AT24C02中的指定单个地址add写入数据dat*/void Write24c02_addr_byte(uchar I2C,uchar addr,uchar byte) start(); /开始送数据Write24c02_byte(I2C); while(detect_ack(); /等待应答Write24c02_byte(addr); /写入指定地址while(detect_ack(); /等待应答Write24c02_byte(byte); /向这个地址写入数据while(detect_
50、ack(); /等待应答stop(); /停止数据传递delay(4); /一字节的写入周期为1ms,延时1ms以上/*从指定AT24C02中的指定地址读取数据*/uchar Read24c02_addr_byte(uchar I2C,uchar addr) uchar read_addr_byte; start(); /开始数据传递Write24c02_byte(I2C); while(detect_ack(); /等待应答Write24c02_byte(addr); /写入指定地址while(detect_ack(); /等待应答start(); /开始数据传递Write24c02_byt
51、e(I2C+0 x01); /+0 x01为读while(detect_ack(); /等待应答read_addr_byte=Read24c02_byte(); no_ack();stop(); /停止数据传递return read_addr_byte; /返回读取的数据/* LCD显示程序 */*忙检测函数*/bit LCD_Busy() bit LCD_Busy;LCD_RS=0; LCD_RW=1; LCD_E=1; delay(1); LCD_Busy=(bit)(P0&0 x80); /取LCD数据首位,即忙信号位LCD_E=0;return LCD_Busy;/*写命令函数
52、*/void LCD_write_command(uchar cmd) while(LCD_Busy();delay(1); LCD_RS=0; LCD_RW=0; P0=cmd;delay(1); LCD_E=1; delay(1); LCD_E=0;/*写数据函数*/void LCD_write_data(uchar dat) while(LCD_Busy(); delay(1); LCD_RS=1; LCD_RW=0; P0=dat;delay(1); LCD_E=1; delay(1);LCD_E=0;/*初始化函数*/void LCD_init( ) LCD_write_comman
53、d(0 x38); /162显示,57点阵,8位数据接口 delay(1);LCD_write_command(0 x01); /清屏 delay(1);LCD_write_command(0 x06); /光标右移,字符不移 delay(1);LCD_write_command(0 x0C); /显示开,无光标,光标不闪烁delay(1);/*计件数x显示在第一行pos位数*/void LCD(uchar pos,uchar x )num1=x/10+0; /取整运算,求得十位数字ASCII码num2=x%10+0; /取余运算,求得个位数字ASCII码LCD_write_command(0
54、 x80+pos); /在第一行pos1位显示LCD_write_data(num1); /将十位数字的字符常量写入LCDLCD_write_data(num2); /将个位数字的字符常量写入LCD/*延时函数t(ms)*/void delay(uchar t ) uchar j,k; for(j=0;jt;j+) for(k=0;k255;k+) /*延时函数6微秒*/ void delay_6us(void)_nop_();_nop_(); _nop_(); _nop_();_nop_(); _nop_(); 仿真运行图 6.3 SPI总线总线25AA040 项目项目设计设计项目SPI总线
55、概述总线概述 SPI是是Serial Peripheral Interface的缩写,的缩写,就是串行外围设备接口。它是就是串行外围设备接口。它是Motorola公司推出公司推出的一种同步串行接口技术。的一种同步串行接口技术。SPI主要应用在主要应用在EEPROM、Flash、实时时钟、实时时钟RTC、数模转换器、数模转换器ADC、数字信号处理器、数字信号处理器DSP以及数字信号解码器以及数字信号解码器的数据通信。的数据通信。SPI总线引脚总线引脚 (1)MOSI:主器件数据输出,从器件数据输入:主器件数据输出,从器件数据输入(2)MISO:主器件数据输入,从器件数据输出:主器件数据输入,从器
56、件数据输出(3)SCLK:时钟信号,由主器件产生:时钟信号,由主器件产生(4)/SS (/CS):从器件使能信号,由主器件控制:从器件使能信号,由主器件控制SPI一主多从连接图一主多从连接图 主设备通过发出片选信号主设备通过发出片选信号/SS (/CS)有效,来选择有效,来选择某个从设备进行通信,而未被选中的从设备不进行某个从设备进行通信,而未被选中的从设备不进行通信。通信。25AA040芯片引脚 Microchip公司的公司的25AA040为为4k串行电可擦除可编串行电可擦除可编程只读存储器程只读存储器EEPROM引脚引脚功能说明功能说明/CS片选输入端,低电平时选中该芯片SO串行数据输出端
57、,在读周期,数据在SCK的下降沿输出,输出E2PROM存储器的数据/WP 写保护端,该脚接地,写操作被禁止,接高电平,所有功能正常VSS电源地SI串行数据输入端,数据在SCK的上升沿写入,接受来自单片机的命令、地址和数据SCK串行时钟端/HOLD保持输入脚,低电平有效,用于在数据传送中途暂停向25AA040传送VCC电源25AA040芯片指令集 单片机必须通过相应的指令实现对单片机必须通过相应的指令实现对25AA040的读的读写操作写操作指令名称指令名称指令格式指令格式描述描述READ读读0000A8011在选定的地址读25AA040的数据WRITE写写0000A8010在选定的地址将数据写入
58、25AA040WRDI0000 x100禁止写操作WREN0000 x110允许写操作RDSR0000 x101读状态寄存器WRSR0000 x001写状态寄存器动手做动手做画出硬件电路图画出硬件电路图 项目将一字节数据项目将一字节数据0 x33写入写入25AA040,再读出,再读出,然后送然后送P3口,用口,用LED显示。显示。/*将一字节数据写入25AA040,再读出,然后送P3口显示*/#include #include #define uchar unsigned char/*SPI引脚定义*/sbit SCK=P10; /将SCK位定义为P1.0引脚sbit MOSI=P11; /将
59、SI位定义为P1.1引脚sbit MISO=P12; /将SO位定义为P1.2引脚sbit CS=P13; /将SCK位定义为P1.3引脚/*功能变量定义*/#define WREN 0 x06 /写允许#define WRDI 0 x04 /写禁止#define WRSR 0 x01 /写状态寄存器#define READ 0 x03 /读操作#define WRITE 0 x02 /写操作void Write25AA040_addr_byte(uchar ,uchar );/写数据到指定地址函数声明uchar Read25AA040_addr_byte(uchar);/读指定地址数据函数声
60、明void Write25AA040_byte(uchar ); /写数据函数声明uchar Read25AA040_byte(void); /读数据函数声明void delay(uchar); /*主程序*/void main(void) Write25AA040_addr_byte(0 x33,0 x80);/将数据“0 x33”写入指定地址“0 x80”delay(10); /写入周期约为10msP3=Read25AA040_addr_byte(0 x80);/将数据读出送P3口显示/*读25AA040数据*/uchar Read25AA040_byte(void)uchar i;uchar dat_SO=0 x00; SCK=1
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026新疆乌鲁木齐市乌鲁木齐县南郊供排水有限公司及子公司招聘14人考试参考试题及答案解析
- 2026重庆市铜梁区发展和改革委员会招聘2人笔试备考试题及答案解析
- 2025年江苏省徐州市高职单招职业适应性测试考试题库及答案解析
- 2026新疆双河国投运营集团有限公司本部及权属企业财务人员招聘4人笔试模拟试题及答案解析
- 2026广西南宁市青秀区凤岭北路中学教师招聘1人考试参考试题及答案解析
- 铜川爱国主题古诗词校本课程案例
- 2026广东深圳市宝安区西乡街道中心幼儿园招聘短期教师1人考试备考试题及答案解析
- 2026浙江金华市武义县人民法院招聘1人考试备考题库及答案解析
- 2026年芜湖市急救中心公开招聘编外工作人员2名考试备考试题及答案解析
- 2026广西百色市德保县公安局招聘警务辅助人员15人考试备考题库及答案解析
- 湖南省长沙市长郡双语学校2023-2024学年九年级下学期入学物理试卷
- 郴州职业技术学院单招《语文》考试复习题库(含答案)
- 化妆品工厂培训课件
- 【内蒙古乳制品出口贸易发展现状及优化建议分析8900字(论文)】
- 翻译研究论文的写作
- 配电类“两种人”安全规程考试题库
- 《小丑鱼的奇妙世界》大班美术活动
- 医疗质量与安全管理委员会会议专家讲座
- 川2020J146-TJ 建筑用轻质隔墙条板构造图集
- 外研版中考英语复习课件
- GB/T 7762-2003硫化橡胶或热塑性橡胶耐臭氧龟裂静态拉伸试验
评论
0/150
提交评论