1、嵌入式系统应用技术,三、C8051F310+C51应用实例赵玉昆,实例,实例1 通用I/O端口 实例2 A/D转换 实例3 温度测量 实例4 定时器及中断 实例5 UART应用 实例6 SMBus应用(24C0X) 实例7 I2C应用(ZLG7290) 实例8 I2C应用(PCF8563T),实例1 通用I/O端口,1.1 C8051F310端口的特殊性 1.2 通用I/O端口实例 1.3 提高题,1.1 C8051F310端口的特殊性,C8051F310有29个 I/O 引脚(P0、P1、P2、P3-5脚) 通过交叉开关可以使引脚分配给数字外设、模拟外设 未分配给的管脚作为通用 I/O(GP
2、IO) (1)端口相关寄存器 (2)I/O 端口初始化 (3)I/O 端口初始化举例,(1)端口相关寄存器,Pn: 端口寄存器 PnMDIN: 输入方式 1=数字输入,0=模拟输入 PnMDOUT: 输出方式 0=开漏输出,1=推挽输出 PnSKIP: 端口跳过 0=不跳过, 1=跳过 XBR0、XBR1: 交叉开关 0=不分配, 1=分配数字外设其中n=03 为复位值,(2)交叉开关,P0.0P2.3管脚,通过交叉开关,分配给GPIO或数字外设 P2.4P3.4管脚,不通过交叉开关,不分配给数字外设。,UART SMBus 等,P0.07 P1.07 P2.03,交叉 开关,P0.0脚,P2
3、.4脚,P3.4脚,P2.47 P3.04,。,P2.3脚,.,XBR0,XBR1,PnSKIP,(3)I/O 端口初始化,端口 I/O 初始化(教科书P47) 1 输入方式(PnMDIN),端口引脚的输入方式(模拟或数字)。 2 输出方式(PnMDOUT),端口引脚的输出方式(开漏或推挽)。 3 端口跳过寄存器(PnSKIP),交叉开关跳过的引脚。 4 将引脚分配给要使用的外设。(XBR0、XBR1) 5 使能交叉开关(XBARE =1)。 说明:通用I/O端口(P0.0-P2.3)的初始化要做第1、2、5步。通用I/O端口(P2.4-P3.4)的初始化只要做第1、2步。,(3)I/O 端口
4、初始化举例,例如:C8051F310目标板上的发光管D2接到了P3.3脚,按钮S2接到了P0.7脚,模拟量接到了P2.4脚。P3.3做数字输出、 P0.7做数字输入、 P2.4做模拟输入P3MDIN = 0xff; /P3.3做数字输入(默认)P3MDOUT = 0x08; /P3.3推挽输出P0MDIN = 0xff; /P0.7做数字输入(默认)P2MDIN = 0xef; /P2.4做模拟输入,1.2 通用 I/O 端口应用实例,例题:C8051F310目标板上的发光管D2接到了P3.3脚,按钮S2接到了P0.7脚,模拟量接到了P2.4脚。要求:松开S2则D2慢闪,按住S2则D2快闪。,
5、1.2 通用 I/O 端口应用实例(续),#include / C8051F310的SFR定义 sbit LED =P33; / LED位定义 sbit SW =P07; / SW位定义 /- 延时 - void delay(unsigned long v) while(-v); /- 主程序 - void main(void) PCA0MD /SW按下则快闪,否则慢闪 ,1.3 提高题,(1)按一下S2,D2亮,再按一下S2,D2灭,依此类推。 (2)按下S2,D2闪亮3次,松开S2,D2闪亮2次,依此类推。 (3)用C8051F310带动DP-51实验箱,使8个LED左向、右向流水点亮。,
6、实例2 A/D转换,2.1 C8051F310的AD转换器简介 2.2 左右对齐的例子 2.3 ADC相关寄存器 2.4 ADC 输入引脚配置 2.5 A/D转换实例 2.6 提高题,10位ADC原理框图,除P0口,2.1 C8051F310的AD转换器简介,10 位逐次逼近型 ADC, 最高采样率200ksps AMX0P:正输入:23 选 1:P1.0P3.4、温度传感 器、VDD AMX0N:负输入:22 选 1:P1.0P3.4、GND 单端方式:GND作为负输入,其余为差分方式 (略)。 ADC0H、ADC0L:转换结果 AD0LJST 位:决定转换结果左对齐或右对齐Justifie
7、d 输入范围: 0 VREF*1023/1024 AD值与输入电压( VIN)的关系:,AD值 = ( ) * 1024,2.2 左右对齐的例子,单端方式时左、右对齐的例子,2.3 电压基准VREF,REF0CN: 电压基准控制寄存器REFSL:0=选择外部电压基准(来自P0.0脚)1=或内部电压基准(VDD) TEMPE:1=允许内部温度传感器工作 BIASE:1=内部偏压发生器工作(使用 ADC 时该位必须为1),2.3 ADC相关寄存器,AMUX0P:ADC 正输入通道选择寄存器AMX0P(正端选择):可选P1.0P3.4、温度传感 器、VDDAMUX0N:ADC 负输入通道选择寄存器A
8、MX0N(负端选择):可选P1.0P3.4、GND,2.3 ADC相关寄存器(续1),ADC0CF:配置寄存器每次AD转换约需11个AD时钟脉冲 AD0SC(选择AD时钟):复位后,AD时钟=系统时钟/32 AD0LJST(左对齐) :0=右对齐最低采样率 = 24.5MHz / 32 / 11 = 70ksps 最高采样率200ksps,此时AD0SC = ?11,AD时钟频率=,2.3 ADC相关寄存器(续2),ADC0CN:控制寄存器 地址=0xE8,可位寻址AD0EN(ADC允许):1=允许ADC AD0TM(跟踪方式) :0=正常方式,一直跟踪 AD0INT(结束标志) :1=AD转
9、换结束 AD0BUSY(忙标志):若 AD0CM000,AD0BUSY置1则启动AD转换 AD0CM(启动方式):000=向AD0BUSY 写1时启动AD转换,2.4 ADC 输入引脚配置,注意: 作为 ADC 输入的引脚应: 配置为模拟输入( PnMDIN对应位置 0 ), 使交叉开关跳过(如果是P0.0-P2.3,PnSKIP对应位置 1 ) 。,2.5 A/D转换实例,例题:按图在C8051F310目标板的J6上接一个电位器,要求:向P2.5输出高电平(=VDD),从P2.4读入模拟电压。当输入电压小于VDD一半时,发光管D2慢闪,否则快闪。,2.5 A/D转换实例(续1),#inclu
10、de / C8051F310的SFR定义 sbit LED=P33; / LED位定义 sbit P25=P25; / P2.5位定义 bit bKuai; / 快慢标志 /- 延时 - void delay(unsigned long v) while(-v); /- 初始化 - void First(void) PCA0MD / 允许 ADC0 ,2.5 A/D转换实例(续2),/- 主程序 - void main(void) unsigned int ad; / AD转换结果First (); / 初始化P25 = 1; / 向电位器送出+3.3V电压while(1)AD0BUSY =
11、1; / 启动 ADC0while(!AD0INT); / 等待AD转换结束AD0INT = 0; / 清除AD转换结束标志LED = !LED; / LED闪烁delay(bKuai ? 5000 : 20000); / 快慢闪ad = ADC0H*256 + ADC0L; / 读取AD值bKuai = (ad 512); / 决定快慢 ,2.6 提高题,(1)用电位器改变输入电压,电压越高,D2闪烁越快,直至全亮;电压越低,D2闪烁越慢,直至全暗。 (2)用C8051F310带动DP-51实验箱,使8个LED流水点亮。当电压大于2/3满量程,LED左向流动,当电压1/32/3满量程,LED
12、闪烁,当电压小于1/3满量程,LED右向流动。,实例3 温度测量,3.1 片内温度传感器简介 3.2 温度测量实例 3.3 提高题,3.1 片内温度传感器简介,要使用内部温度传感器,REF0CN.2(TEMPE)必须置1。 正端输入 AMX0P=0x1E,选择温度传感器 负端输入 AMX0N=0x1F,选择GND 温度传感器的传输函数 :mV温度=3.35*(温度)+897mV,AD值 = ( ) * 1024,当Vref = VDD = 3.3V时, 1 - 3.35mV - 3.35/3300*1024=1.04 AD值,3.2 温度测量实例,例题:利用C8051F310目标板,编程测量环
13、境温度。当温度较低(如低于20)时,发光管D2慢闪,否则快闪。 解:Vref = VDD = 3.3V20的mV温度=3.35*20+897=964mV20的AD值=964/3300*1024=351,3.2 温度测量实例(续1),#include / C8051F310的SFR定义 sbit LED=P33; / LED位定义 bit bKuai; / 快慢标志 /- 延时 - void delay(unsigned long v) while(-v); /- 初始化 - void First(void) PCA0MD / 允许 ADC0 ,3.2 温度测量实例(续2),/- 主程序 - v
14、oid main(void) unsigned int ad; / AD转换结果First (); / 初始化while(1)AD0BUSY = 1; / 启动 ADC0while(!AD0INT); / 等待AD转换结束AD0INT = 0; / 清除AD转换结束标志LED = !LED; / LED闪烁delay(bKuai ? 5000 : 20000); / 快慢闪ad = ADC0H*256 + ADC0L; / 读取AD值bKuai = (ad 351); / 决定快慢,根据实际情况修改 ,3.3 提高题,(1)用手指给C8051F310加温,温度越高D2闪烁越快。 (2)用C80
15、51F310带动DP-51实验箱,使8个LED流水点亮。温度越高,流动越快。,实例4 定时器及中断,4.1 定时器的时钟 4.2 定时器的相关寄存器 4.3 定时器的初值 4.4 定时器中断实例 4.5 提高题,4.1定时器的时钟,内部振荡频率=24.5MHz, 系统时钟=24.5MHz / 振荡器分频 T0时钟=系统时钟 / 定时器分频,4.2 定时器的相关寄存器,内部振荡频率=24.5MHz, 系统时钟=24.5MHz / 振荡器分频 OSCICN:内部振荡器控制寄存器IOSCEN:1=内部振荡器使能。 IFRDY:内部振荡器就绪标志。1=就绪 IFCN :内部振荡器到SYSCLK的分频位
16、缺省分频数为8。 系统时钟=24.5/8=3.0625MHz,4.2 定时器相关的寄存器(续1),T0时钟=系统时钟 / 定时器分频 CKCON :时钟控制寄存器T1M:类似于T0M。 T0M:0=T0时钟由分频位(SCA)决定。1=T0时钟为系统时钟 SCA:T0、T1 分频位,4.3定时器的初值,例如:振荡器分频=1,T0分频=12,求定时10ms的初值=?振荡器分频=1:OSCICN |= 0x03; SYSCLK=24.5MHzT0分频=12(默认):CKCON = 0x00; T0时钟=24.5/12=2.0417MHz10ms计数=10000(us) * 2.0417(次/us)=
17、 20417T0初值=65536 - 20417,4.4 定时器中断实例,例题:用定时器及中断功能,构造C8051F310应用程序框架,具有1ms、10ms、100ms、1s函数调用。利用程序框架,编制发光管D2每秒亮100ms的程序。,4.4 定时器中断实例(续1),#include / C8051F310的SFR定义 / T0时钟=24.5/12=2.0417MHz,10ms计数=10000(us)*2.0417(次/us)=20417 #define T0_VAL (65536-20417) / T0初值 sbit LED=P33; / LED位定义 bit b10ms; / 10ms标
18、志 unsigned char Cnt10ms; /- 初始化 - void First(void) PCA0MD ,4.4 定时器中断实例(续2),/- 10ms处理 - void do_10ms(void) /- 100ms处理 - void do_100ms(void) /- 1s处理 - void do_1s(void) LED = !LED; / LED 亮1秒、暗1秒 ,4.4 定时器中断实例(续3),/- 主程序 - void main(void) First (); / 初始化while(1) if(b10ms) b10ms = 0;do_10ms();if(Cnt10ms %
19、 10 = 0) do_100ms();if(+Cnt10ms = 100) Cnt10ms=0;do_1s(); ,4.4 定时器中断实例(续4),/- 定时中断 10ms - void T0_Int(void) interrupt 1 TH0 = T0_VAL / 256;TL0 = T0_VAL % 256;b10ms = 1; 注意: 中断函数定义 函数名任意, 加上 interrpt n修饰,n为中断号,T0中断为1号中断。 中断函数的入口参数、出口参数均为void。,4.4 定时器中断实例(续5),要实现LED每秒亮100ms的效果,只要每秒点亮LED,每100ms熄灭LED即可。
20、 /- 100ms处理 - void do_100ms(void) LED = 0; / 熄灭LED /- 1s处理 - void do_1s(void) LED = 1; / 点亮LED ,4.5 提高题,(1)用DP-51实验箱,使LED1以1秒闪烁, LED2以2秒闪烁, LED2LED8流水点亮。,实例5 UART应用,5.1 交叉开关 5.2 交叉开关相关的寄存器 5.3 波特率 5.4 UART应用实例 5.5 UART应用实例b 5.6 提高题,数字交叉开关原理框图,5.1 交叉开关,P0.0P2.3管脚,通过交叉开关,分配给GPIO或数字外设,UART SMBus 等,P0.0
21、7 P1.07 P2.03,交叉 开关,P0.0脚,P2.4脚,P3.4脚,P2.47 P3.04,。,P2.3脚,.,XBR0,XBR1,PnSKIP,5.1 交叉开关(续1),交叉开关:优先权交叉开关译码器 某些数字资源(如UART、SMBus等)需要引脚,交叉开关为其分配引脚。 从P0.0到P2.3按顺序分配(UART0总是使用P0.4和P0.5)。 PnSKIP中被置1的那些位,将被跳过。如用于VREF、模拟输入、晶振或 GPIO 的引脚。,5.1 交叉开关(续2),没有引脚被跳过(PnSKIP=0x00)的交叉开关优先权译码表,5.1 交叉开关(续3),晶体引脚被跳过的交叉开关优先权
22、译码表,5.2 交叉开关相关的寄存器,XBR0:交叉开关寄存器0SMB0E :SMBus I/O 使能位,1=连到端口引脚。 URT0E :UART I/O 使能位,1=连到端口引脚。 其他省略位:其他数字外设使能。 XBR1:交叉开关寄存器1XBARE :交叉开关使能位。要使用交叉开关,应使XBARE=1。 其他省略位:其他数字外设使能。,5.3 波特率,使用内部振荡器时的波特率,内部振荡24.5MHz,OSCICN:IFCN,振荡器分频,定时器分频,CKCON :T1M、SCA,T1时钟,系统时钟,T1定时溢出,溢出,T1:方式2,波特率,2,T1时钟,5.3 波特率(续1),UART0
23、波特率公式:波特率 = 2例:振荡器分频=1,T1分频=12,波特率=9600,求T1的初值=? 解:振荡器分频=1:OSCICN |= 0x03; SYSCLK=24.5MHzT1分频=12 (默认) :CKCON = 0x00; T1时钟=24.5/12=2.0417MHz波特率 = 9600T1计数值 = 2041700 / 9600 / 2 = 106T1初值 = 256 106 = 150,RS-232,5.4 UART应用实例,例题:C8051F310通过串口发送一些信息。通过电脑运行的串口调试软件显示这些信息。,5.4 UART应用实例(续1),#include / C8051F
24、310的SFR定义 #include / 可以使用printf等函数 #define T0_VAL (65536-20417) / T0初值 sbit LED=P33; / LED位定义 bit b10ms; / 10ms标志 unsigned char Cnt10ms; /- 初始化 - void First(void) PCA0MD ,5.4 UART应用实例(续2),/- UART初始化 - void UART_init(void) OSCICN |= 0x03; / SYSCLK=24.5MhzXBR0 = 0x01; / 交叉开关0:允许UARTXBR1 = 0x40; / 交叉开关
25、1:允许XBARSCON0 = 0x10; / SCON0: 8位,允许接收,TH1 = (256-106); / 波特率=9600TL1 = TH1; TR1 = 1; / 启动 Timer1TI0 = 1; / TI 发送完成 ,5.4 UART应用实例(续3),/- 10ms处理 - void do_10ms(void) /- 100ms处理 - void do_100ms(void) /- 1s处理 - void do_1s(void) LED = !LED; / LED闪烁printf(“rnHello”); / 向串口输出字符串 ,5.4 UART应用实例(续4),/- 主程序 -
26、 void main(void) UART_init(); / UART初始化First (); / 初始化while(1) if(b10ms) b10ms = 0;do_10ms();if(Cnt10ms % 10 = 0) do_100ms();if(+Cnt10ms = 100) Cnt10ms=0;do_1s(); ,5.4 UART应用实例(续5),/- 定时中断 10ms - void T0_Int(void) interrupt 1 TH0 = T0_VAL / 256;TL0 = T0_VAL % 256;b10ms = 1; 由于系统函数printf()占用资源比较多, 建议
27、自己编写简单的字符串输出函数Fs_Str()。,5.5 UART应用实例b,不使用printf函数,自己构建Fs_Str函数: /- 串口发送1字节 - void Fs_1Byte(unsigned char v) SBUF0 = v;while(!TI0);TI0 = 0; /- 串口发送code字符串 - void Fs_Str(unsigned char code *Str) while(*Str) Fs_1Byte(*Str+); 去掉头文件 #include 在使用 printf(“rnHello“); 的地方,改为 Fs_Str(“rnHello“);,5.4 UART应用实例(续
28、5),无printf、Fs_Str函数时,资源占用:Program Size: data=20.1 xdata=0 code=125用printf函数时,资源占用:Program Size: data=41.2 xdata=0 code=1183 推算,printf需要资源:data=41.2-20.1=21.1,code=1183-125=1058用自建Fs_Str函数,资源占用:Program Size: data=23.1 xdata=0 code=194 推算, Fs_Str函数需要资源:data=23.1-20.1=3,code=194-125=69,5.6 提高题,(1)试将上述例
29、题中的波特率改为4800。 (2)通过串口,将温度值每秒一次发送到电脑。 (3)通过串口,发送以下信息:按一次S2,将C8051F310内部RAM的00H7FH单元的内容发送到电脑显示。,实例6 SMBus应用(24C0X),6.1 SMBus规范 6.2 24C0X简介 6.3 I2C底层程序 6.4 I2C测试程序(24C0X) 6.5 提高题(24C0X),6.1 SMBus规范,SMBus与I2C兼容 用2根导线传递双向信号:SDA:串行数据SCL:串行时钟 典型SMBus 连接:,6.1 SMBus规范(续1),SMBus规定:SCL=0时,SDA可以变化;SCL=1时,SDA的变化
30、有特殊定义。 开始位:SCL=1时,SDA的下跳变。 停止位:SCL=1时,SDA的上跳变。数据1:SCL=1时,SDA的1。 数据0:SCL=1时,SDA的0。应答ACK:即数据0。 应答NACK:即数据1。,6.1 SMBus规范(续2),主器件:发开始位、停止位,发SCL。通常由MCU担任。 从器件:听从主器件指挥。通常为各种外围功能芯片。可以有1个主器件,多个从器件。 每个从器件有从地址SLA,最低位为读写位,0=写,1=读。 例如:I2C接口E2PROM芯片24C0X的从地址为1010000X,(0xA0)I2C接口键盘及LED驱动ZLG7290的从地址为0111000X,(0x70
31、)I2C接口日历芯片PCF8563的从地址为1010001X,(0xA2)主、从器件都可以发送、接收。 接收者负责返回应答信号ACK或NACK 一次通讯过程由1个开始位、若干数据字节+应答、1个停止位组成,6.2 24C0X简介,24C01A/02A/04A 1K/2K/4K位的电擦除PROM。 使用标准2线串行接口I2C。 同一总线中最多可连接8个24C01/02或4个24C04。 有硬件写保护功能。,6.3 I2C底层程序,例题:以F310为主器件,24C02为从器件为例,编制I2C底层程序和测试程序。,6.3 I2C底层程序(续1),/-口位地址定义- sbit SDA = P00; s
32、bit SCK = P01; /-发送1个开始位- void Start(void) SDA=1; SCK=1;SDA=0;SCK=0;SDA=1; / 释放SDA /-发送1个停止位- void Stop(void) SDA=0;SCK=1;SDA=1; ,6.3 I2C底层程序(续2),bit bACK; /-发出1个NACK,也用于读入ACK - bit TestACK() SDA=1;SCK=1;bACK=SDA;SCK=0;return(bACK); /-发出1个ACK- void I2C_ACK(void) SDA=0;SCK=1;SCK=0;SDA=1; ,6.3 I2C底层程序
33、(续3),/-输出8位。入口 v=发送的数据- void Out8Bit(uchar v) uchar i;for(i=0;i8;i+) SDA=(bit)(v / 发送SDA=1,以接收ACK ,6.3 I2C底层程序(续4),/- 输入8位。入口:fACK=发送的ACK,返回:接收的数据 - uchar In8Bit(bit fACK) uchar i,v=0;for(i=0;i8;i+) SCK=1; / 发1个时钟v=v1;v=v | (uchar)(SDA); / 读SDASCK=0;if(fACK) I2C_ACK(); / 发ACKelse TestACK(); / 发NACKr
34、eturn(v); ,6.3 I2C底层程序(续5),MCU写出1字节到E2PROM:,6.3 I2C底层程序(续6),/-写出1个字节。入口 Addr=8位地址,v=数据 - void I2C_Wr1By(uchar Addr,uchar v) Start(); / 发送1个开始位Out8Bit(0xa0); / 发出器件slave地址,24系列为1010XXX0写Out8Bit(Addr); / 发送存储单元地址Out8Bit(v); / 发送写数据Stop(); / 发送1个停止位ACKPol(); / ACK轮询,检查写完成 /- ACK轮询,等待写完成。- void ACKPol(v
35、oid) bACK=1;while(bACK) / 取EE的ACK Start(); / 发送1个开始位Out8Bit(0xa0); / 发写命令,如果器件忙,bACK=1 Stop(); / 发送1个停止位 ,6.3 I2C底层程序(续7),MCU从E2PROM读入1字节:,6.3 I2C底层程序(续8),/-读入1个字节。入口 Addr=8位地址,返回读入数据- uchar I2C_Rd1By(uchar Addr) uchar v;Start(); / 发送1个开始位Out8Bit(0xa0); /发出器件slave地址,24系列为1010XXX0写Out8Bit(Addr); / 发送
36、存储单元地址Start(); / 再发送1个重启动命令Out8Bit(0xa1); / 发出器件slave地址,24系列为1010XXX1读v=In8Bit(0); / 读入1字节数据,发NACK,告诉器件要结束了Stop(); / 发送1个停止位return(v); ,6.4 I2C测试程序(24C0X),#include / C8051F310的SFR定义 /- 初始化 - void First(void) PCA0MD ,6.5 提高题(24C0X),(1)通过串口读取24C0X:键入“D0”,显示24C0X的00H0FH单元的内容,键入“D1”,显示24C0X的10H1FH单元的内容,
37、依此类推。 (2)通过串口读写24C0X:键入一个字符串,以回车结束,保存到24C0X。断电重新启动后,显示一次24C0X中保存的字符串。,实例7 I2C应用(ZLG7290),7.1 ZLG7290简介 7.2 F310与ZLG7290的连接 7.3 ZLG7290的驱动 7.4 ZLG7290测试程序 7.5 提高题(ZLG7290),7.1 ZLG7290简介,特点 LED/键盘驱动芯片 I2C串行接口,写:0x70;读:0x71 可驱动8位共阴数码管和64个按键。 可控扫描位数,可控任一数码管闪烁。 无需外接元件驱动LED。 提供键盘中断。 可检测键的连击次数。,7.2 F310与ZL
38、G7290的连接,C8051F310与ZLG7290连接示意图,7.3 ZLG7290的驱动,ZLG7290速度较慢,I2C驱动中要加延时 例如: void nop(uchar n) for( ;n!=-1;n-); /*发送1个启动命令*/ void Start(void) SDA=1; nop(1);SCK=1; nop(1);SDA=0; nop(1);SCK=0; nop(1);SDA=1; nop(1); ,7.3 ZLG7290的驱动(续1),ZLG7290显示通讯接口: 从地址=0x70 内部有寄存器0x000x17,7、8号是命令接口 在第w个位置处显示v的方法是,连续向7、8
39、号寄存器写入:DP=1:小数点亮 Flash=1:闪烁 最右边数码管的位置w=0 显示值v=0F 例如:在第7个位置处显示3:向7、8号送0x67、0x03,7.3 ZLG7290的驱动(续2),连续写出n个字节的函数: / 入口 sla=从地址,Addr=8位地址,*s=指向数据,n=数据个数 void I2C_WrnBy(uchar sla,uchar Addr,uchar data *s,uchar n) uchar i;Start(); / 发送1个开始位Out8Bit(sla); / 发出器件slave地址,ZLG7290为0x70Out8Bit(Addr); / 发送存储单元地址f
40、or(i=0;in;i+) / 连续n次 Out8Bit(*s+); / 发送写数据 Stop(); / 发送1个停止位 ,7.3 ZLG7290的驱动(续3),zlg7290 显示命令(在第w位,显示v): #define ZLG7290_sla 0x70 /ZLG7290的从地址=0x70 void ZLG7290_Disp(uchar w,uchar v) uchar Data2;Data0=0x60+w;Data1=v;I2C_WrnBy(ZLG7290_sla,0x07,Data,2);Delay(10); 例如:在第7个位置处显示3: ZLG7290_Disp(7, 3);,7.3
41、 ZLG7290的驱动(续4),ZLG7290键盘通讯接口: 当有按键时,ZLG7290发出INT=0 1号寄存器为键值寄存器,0=无键,116=键值。 读键程序: sbit KEY_INT =P12; uchar key; if(KEY_INT=0) key=I2C_Rd1By(ZLG7290_sla,1); / 从1号寄存器读入键值ZLG7290_Disp(0,key); / 在第0位处,显示键值 ,7.3 ZLG7290的驱动(续4),ZLG7290的复位: 初始化时做一次, 向RST发出一个负脉冲, 延时一段时间,等待ZLG7290完成复位。 复位函数: sbit ZLG_RST =P
42、13; / ZLG_RST管脚要上拉1K电阻,抗干扰 /- zlg7290 复位 - void ZLG7290_reset(void) ZLG_RST=0;Delay(1);ZLG_RST=1;Delay(200); ,7.4 ZLG7290测试程序,先在数码管上显示“76543210”, 然后,每按一键,在第0位置处显示键值。 void main(void) uchar i,key;First (); / 初始化ZLG7290_reset();for(i=0;i8;i+) ZLG7290_Disp(i,i); / 在第i位处,显示i值while(1) if(KEY_INT=0) key=I2
43、C_Rd1By(ZLG7290_sla,1); / 从1号寄存器读入键值ZLG7290_Disp(0,key); / 在第0位处,显示键值,7.5 提高题(ZLG7290),(1)在右边3个数码管上显示一个0255的计数值,每0.1秒增1。 (2)在上题基础上,增加以下功能:当按过1号键,每0.1秒增1 ;按过2号键,每0.1秒减1 。,实例8 I2C应用(PCF8563T),8.1 PCF8563T简介 8.2 F310与PCF8563T的连接 8.3 PCF8563T的驱动 8.4 PCF8563T测试程序 8.5 提高题(PCF8563T),8.1 PCF8563T简介,特点 实时时钟日
44、历芯片, I2C串行接口,写:0xA2;读:0xA3 可编程时钟输出, 报警和定时器.,8.2 F310与PCF8563T的连接,C8051F310与PCF8563T连接示意图,8.3 PCF8563T的驱动,PCF8563T显示通讯接口: 从地址=0xA2 内部有16个寄存器0x000x0F 0、1号是控制寄存器,初始化为0即可 第28号是日历时间,BCD码格式例如:10秒=0x10,8.3 PCF8563T的驱动(续1),连续读入n个字节的函数: / 入口 sla=从地址,Addr=8位地址,buf=数据指针,n=数据个数 void I2C_RdnBy(uchar sla,uchar Addr,uchar *buf,uchar n) uchar i;Start(); / 发送1个启动命令Out8Bit(sla); / 发出器件写地址,PCF8563T为0xa2Out8Bit(Addr); / 发送存储单元地址Start(); / 再发送1个重启动命令Out8Bit(sla|1); / 发出器件读地址,PCF8563T为0xa3for(i=0;in-1;i+) / 前n-1个字节*buf+=In8Bit(1); / 读入1字节数据,有ACK,告诉器件还要读*buf=In8Bit(0); / 读入最后1字节数据,无ACK,告诉器件不读了Stop(); / 发1个停止 ,