首先我们要分清通信协议和通讯协议中的信和讯的含义
“通信”仅指数据通信,即通过计算机网络系统和数据通信系统实现数据的端到端传输。
“通信”重在传输手段或使用方式,从这个角度,“通信”的概念包括了信息“传输”。
因此通信协议主要集中在ISO七层协议中的物理层、数据链路层、网络层和传输层。
先简单的说明以下I2C总线, I2C总线是一种串行数据总线,只有二根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。
处理器和芯片间的通信可以形象的比喻成两个人讲话:1、你说的别人得能听懂:双方约定信号的协议。2、你的语速别人得能接受:双方满足时序要求。
I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
起始和终止信号 :SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。
数据传送格式(1)字节传送与应答
每一个字节必须保证是8位长度。数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。如果一段时间内没有收到从机的应答信号,则自动认为从机已正确接收到数据。
AT24C02的芯片地址如下图,
AT24C02的芯片地址(0xa0为写,0xa1为读)
1010为固定,A0,A1,A2正好与芯片的1,2,3引角对应,为当前电路中的地址选择线,三根线可选择8个芯片同时连接在电路中,当要与哪个芯片通信时传送相应的地址即可与该芯片建立连接,TX-1B实验板上三根地址线都为0。最后一位R/W为告诉从机下一字节数据是要读还是写,0为写入,1为读出.
模拟i2c的功能的代码块
void init() //初始化 { SCL=1; delay(); SDA=1; delay(); } void start() //启动信号 { SDA=1; delay(); SCL=1; delay(); SDA=0; delay(); } void stop() //停止信号 { SDA=0; delay(); SCL=1; delay(); SDA=1; delay(); } Void write_add(uchar address, uchar info) //指定地址写一个字节数据 { start(); writebyte(0xa0); respons(); writebyte(address); respons(); writebyte(info); respons(); stop(); } void respons() //回应信号 { uchari=0;SCL=1;delay(); while((SDA==1)&&(i<255))i++; SCL=0;delay();} void writebyte(uchar date)// 写一个字节 { uchari,temp; temp=date; for(i=0;i<8;i++) { temp=temp<<1; SCL=0; delay(); SDA=CY; delay(); SCL=1; delay(); } SCL=0; delay(); SDA=1; delay(); } uchar readbyte() //读一个字节 { uchari,j,k; SCL=0; delay(); SDA=1; for(i=0;i<8;i++) { SCL=1; delay(); if(SDA==1) j=1; else j=0; k=(k<<1)|j; SCL=0; delay(); } delay(); return k; } Void write_add(uchar address, uchar info) //指定地址写一个字节数据 { start(); writebyte(0xa0); respons(); writebyte(address); respons(); writebyte(info); respons(); stop(); } uchar read_add(uchar address) //指定地址读一个字节数据 { uchar dd; start(); writebyte(0xa0); respons(); writebyte(address); respons(); start(); writebyte(0xa1); respons(); dd=readbyte(); stop(); return dd; }
|
实例:0-99秒的自动计时器,随机关断电源,在通电以后计时器接着断电时的状态继续计时
这里是C51单片机与AT24C02相连的原理图
#include <reg52.h> #define uchar unsigned char #define uint unsigned int bit write=0; sbit sda=P2^0; sbit scl=P2^1; sbit dula=P2^6; sbit wela=P2^7; uchar sec,tcnt; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f}; void delay() {;;} void delay1ms(uint z) { uint i,j; for(i=z;i>0;i--) for(j=110;j>0;j--); } void start() { sda=1; delay(); scl=1; delay(); sda=0; delay(); } void stop() { sda=0; delay(); scl=1; delay(); sda=1; delay(); } void respons() { uchar i; scl=1; delay(); while((sda==1)&&(i<250)) i++; scl=0; delay(); } void init() { sda=1; delay(); scl=1; delay(); } void write_byte(uchar date) { uchar i,temp; temp=date; for(i=0;i<8;i++) { temp=temp<<1; scl=0; delay(); sda=CY; delay(); scl=1; delay(); } scl=0; delay(); sda=1; delay(); } uchar read_byte() { uchar i,k; scl=0; delay(); sda=1; delay(); for(i=0;i<8;i++) { scl=1; delay(); k=(k<<1)|sda; scl=0; delay(); } return k; } void write_add(uchar address,uchar date) { start(); write_byte(0xa0); respons(); write_byte(address); respons(); write_byte(date); respons(); stop(); } uchar read_add(uchar address) { uchar date; start(); write_byte(0xa0); respons(); write_byte(address); respons(); start(); write_byte(0xa1); respons(); date=read_byte(); stop(); return date; } void display(uchar bai_c,uchar sh_c) { dula=0; P0=table[bai_c]; dula=1; dula=0; wela=0; P0=0x7e; wela=1; wela=0; delay1ms(5); dula=0; P0=table[sh_c]; dula=1; dula=0; wela=0; P0=0x7d; wela=1; wela=0; delay1ms(5); /* dula=1; P0=table[bai_c]; dula=0; P0=0xff; wela=1; P0=0x7e; wela=0; delay1ms(5); dula=1; P0=table[sh_c]; dula=0; P0=0xff; wela=1; P0=0x7d; wela=0; delay1ms(5); */} void main() { init(); sec=read_add(2); if(sec>100) sec=0; TMOD=0x01; ET0=1; EA=1; TH0=(65536-50000)/256; TL0=(65536-50000)%256; TR0=1; while(1) { display(sec/10,sec%10); if(write==1) { write=0; write_add(2,sec); } } } void t0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; tcnt++; if(tcnt==20) { tcnt=0; sec++; write=1; if(sec==100) sec=0; }
}