i2c简易时序图
I2C存储器读写(计数器,并能断电存储)
任务二:I2C存储器读写(计数器,并能断电存储)之阿布丰王创作实验原理1)I2C总线概述I2C总线是PHLIPS公司推出的一种串行总线,是具备多主机系统所需的包括总线判决和高低速器件同步功能的高性能串行总线.2)I2C信号线I2C总线只有两根双向信号线.一根是数据线SDA,另一根是时钟线SCL.I2C总线通过上拉电阻接正电源.当总线空闲时,两根线均为高电平.连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA及SCL都是线“与”关系.图 1 I2C总线框图3)I2C总线的数据传送a)数据位的有效性规定I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必需坚持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变动.图 2 SDA与SCL的工作时序图b) 起始和终止信号SCL线为高电平期间,SDA线由高电平向低电平的变动暗示起始信号SCL线为高电平期间,SDA线由低电平向高电平的变动暗示终止信号.起始和终止信号都是由主机发出的,在起始信号发生后,总线就处于被占用的状态;在终止信号发生后,总线就处于空闲状态.c) I2C总线的数据传送速率I2C总线的通信速率受主机控制,能快能慢,最高速率限制为100Kb/sd) I2C总线的数据传送格式主机向从机发送数据从机向主机发送数据图 3 I2C总线的数据传送格式S:起始位 SA: 从机地址,7位W/:写标识表记标帜位,1位 R:读标识表记标帜位,1位A:应答位,1位 A/:非应答位,1位D:数据,8位 P:停止位阴影:主机发生的信号无阴影:从机发生的信号4)总线的寻址I2C总线协议有明确的规定:采纳7位的寻址字节(寻址字节是起始信号后的第一个字节).寻址字节的位界说D7~D1位组成从机的地址.D0位是数据传送方向位,为“0”时暗示主机向从机写数据,为“1”时暗示主机由从机读数据.主机发送地址时,总线上的每个从机都将这7位地址码与自己的地址进行比力,如果相同,则认为自己正被主机寻址,根据R/位将自己确定为发送器或接收器.从机的地址由固定部份和可编程部份组成.在一个系统中可能希望接入多个相同的从机,从机地址中可编程部份决定了可接入总线该类器件的最年夜数目.如一个从机的7位寻址位有4位是固定位,3位是可编程位,这时仅能寻址8个同样的器件,即可以有8个同样的器件接入到该I2C总线系统中.任务三:要求:设计一个简单系统,每10S进行温度收集(结合电路与法式,分析指标),在液晶屏上显示以后温度和前一状态的温度,并将结果存入存储器,具备可将温度的存储结果与PC机通讯和数据发送功能,可以使用键盘设定温度高低限制值,到达限制值时报警.一、实验设计思路二、实验内容1、蜂鸣器工作原理蜂鸣器发声原理是电流通过电磁线圈,使电磁线圈发生磁场来驱动振动膜发声的,因此需要一定的电流才华驱动它,单片机IO引脚输出的电流较小,单片机输出的TTL电平基本上驱动不了蜂鸣器,因此需要增加一个电流放年夜的电路.原理图见图:如图所示,蜂鸣器的负极经电阻R3接地,蜂鸣器的正极接到三极管的集电极C,三极管的基级B经过限流电阻R2后由单片机的P1.3引脚控制,当P1.3输出高电平时,三极管Q1截止,没有电流流过线圈,蜂鸣器不发声;当P1.3输出低电平时,三极管导通,这样蜂鸣器的电流形成回路,发作声音.因此,我们可以通过法式控制P1.3脚的电平来使蜂鸣器发作声音和关闭.法式中改变单片机P1.3引脚输出波形的频率,就可以调整控制蜂鸣器音调,发生各种分歧音色、音调的声音.另外,改变P1.3输出电平的高低电平占空比,则可以控制蜂鸣器的声音年夜小.2、SP2键盘控制数据格式数据发送时序一个键盘发送值的例子:通码和断码是以什么样的序列发送到你的计算机从而使得字符G 呈现在你的字处置软件里的呢?因为这是一个年夜写字母,需要发生这样的事件次第:按下Shift 键-按下G键-释放G 键-释放Shift 键.与这些时间相关的扫描码如下:Shift 键的通码12h,G 键的通码34h ,G 键的断码F0h 34h ,Shift 键的断码F0h 12h .因此发送到你的计算机的数据应该是:12h 34h F0h 34h F0h 12h3、DS18B20温度传感器DS18B20工作原理及应用:DS18B20的温度检测与数字数据输出全集成于一个芯片之上,从而抗干扰力更强.其一个工作周期可分为两个部份,即温度检测和数据处置.在讲解其工作流程之前我们有需要了解18B20的内部存储器资源.18B20共有三种形态的存储器资源,它们分别是:ROM 只读存储器,用于寄存DS18B20ID编码,其前8位是单线系列编码(DS18B20的编码是19H),后面48位是芯片唯一的序列号,最后8位是以上56的位的CRC码(冗余校验).数据在生产时设置不由用户更改.DS18B20共64位ROM.RAM 数据暂存器,用于内部计算和数据存取,数据在失落电后丧失,DS18B20共9个字节RAM,每个字节为8位.第1、2个字节是温度转换后的数据值信息,第3、4个字节是用户EEPROM(经常使用于温度报警值贮存)的镜像.在上电复位时其值将被刷新.第5个字节则是用户第3个EEPROM的镜像.第6、7、8个字节为计数寄存器,是为了让用户获得更高的温度分辨率而设计的,同样也是内部温度转换、计算的暂存单位.第9个字节为前8个字节的CRC 码.EEPROM 非易失性记忆体,用于寄存长期需要保管的数据,上下限温度报警值和校验数据,DS18B20共3位EEPROM,并在RAM都存在镜像,以方便用户把持.4、LCD1602液晶显示读写把持时序如图所示图三:读把持时序图四:写把持时序附录一:(任务二法式)#include <p18f452.h>#include <i2c.h>#define uint unsigned int#define uchar unsigned char#define e PORTBbits.RB3//液晶屏e端接RB3#define rw PORTBbits.RB4//液晶屏rw端接RB4#define rs PORTBbits.RB5//液晶屏rs端接RB5void disp(uchar num1,uchar num2,uchar num3);void delay(uint z);void disp_init(void); //液晶屏初始化void write_com(uchar com);//对液晶屏写指令void write_data(uchar dat);//写数据void main(void){unsigned int lednum=0,x,tt=0; //lednum 显示的数据,x 24c02读到的数据,tt时间累加unsigned int a1=0,a2=0,a3=0; //显示位数个十百 disp_init();//1602的初始化OpenI2C(MASTER, SLEW_ON);//I2C 的初始化SSPADD = 9; //频率为400KHZT0CONbits.TMR0ON=0;//关闭TIMER0 T0CONbits.T08BIT=0;//配置为16位计数模式T0CONbits.T0CS=0;//选择内部时钟源即按时模式TMR0H=(65536-10000)/256;//按时5us TMR0L=(65536-10000)%256;INTCONbits.TMR0IF=0;//清TIMER0溢出中断标识表记标帜位T0CONbits.TMR0ON=1;//使能TIMER0 while(1){x = EERandomRead(0xA0,0x03);//读数据,0XA0为器件地址 0X03为存储地址 if(INTCONbits.TMR0IF==1)//TIMER0溢出中断标识表记标帜位为1 {INTCONbits.TMR0IF=0;//清TIMER0溢出中断标识表记标帜位TMR0H=(65536-10000)/256;//5us*10000=50msTMR0L=(65536-10000)%256;tt++;if(tt==20)//1s{tt=0;x++;if(x==256){x=0;}EEByteWrite(0xA0, 0x03,x); //写数据EEAckPolling(0xA0);//应答}}lednum = EERandomRead(0xA0,0x03);//防止断电遗失a1=lednum/100;//百位上的数字a2=lednum%100/10;//十位上的数字a3=lednum%10;//个位上的数字disp(a1,a2,a3);//显示}}void write_com(uchar com)//LED1602控制字输入{TRISB=0b000000000;//TRISB=0b00010000;TRISD=0;e=0;rw=0;rs=0; //写指令:RS=L,RW=L,D0~D7=指令码,E=高脉冲PORTD=com; //写指令到液晶delay(5);e=1;delay(5);e=0;}void write_data(uchar dat)//LCD1602数据输入{ TRISD=0;e=0;rw=0;rs=1;//写数据:RS=H,RW=L,D0~D7=指令码,E=高脉冲PORTD=dat;//写数据到液晶delay(5);e=1;delay(5);e=0;}void disp_init(){TRISD=0;//选择D端口为液晶屏数据的输入口write_com(0x38);//液晶开显示write_com(0x0c);//显示光标,光标闪烁write_com(0x06);//读或写一个字符后地址指针加一,光标加一write_com(0x01);//显示清屏:1、数据指针清零;2、所有显示清零write_com(0x80);//第一行首位}void disp(uchar num1,uchar num2,uchar num3){write_com(0x80+0x40);write_data(num1+0x30);//液晶第二行第一位数delay(1);write_com(0x80+0x41);write_data(num2+0x30);//液晶第二行第二位数delay(1);write_com(0x80+0x42);write_data(num3+0x30);//液晶第二行第三位数delay(1);}void delay(uint z)//z毫秒延时子法式{uint x,y;for(x=110;x>0;x--)for(y=z;y>0;y--);}附录二(任务三法式)#include <pic18.h> //调用头文件,可以去PICC18软件下去查找PIC18FXX2.H__CONFIG(1,XT) ; //晶振为外部4M__CONFIG(2,WDTDIS) ; //看门狗关闭__CONFIG(4,LVPDIS) ; //禁止低电压编程#define RSPIN RB5 //Data or Instrument Select LCD1602#define RWPIN RB4 //Write or Read#define EPIN RB3 //6800 mode Enable singleunsigned char temp1=0,temp1_1=0; //收集到的温度高8位上一次的unsigned char temp2=0,temp2_2=0; //收集到的温度低8位unsigned int a,b,c=0;#define beep RC2 //界说蜂鸣器接口/****************************************/#define sda RC4 //AT24C02#define scl RC3bit eepromdi;bit eepromdo;unsigned char addressbuf;unsigned char buf_24C02;/****************************************/bit clrbit; //USARTunsigned char recebuf;/****************************************///转换后的温度值小数点部份查表const unsigned char tablexiao[16]={0,0,1,2,2,3,4,4,5,6,6,7,8,8,9,9};/***************************************************************************** ***********/#define Key_Data RB1#define Key_CLK RB0unsigned char IntNum; //中断次数计数unsigned char KeyV; //键值unsigned char Key_UP=0, Shift = 0;//Key_UP是键松开标识,Shift是Shift键按下标识unsigned char keybuf;unsigned char disbuf;//84unsigned char shu1=0,shu2=0,tem1=0,tem2=0,tem3=0; //温度上限bit bf; //标识是否有字符被收到bit disbit;//0x66为backspace键//0x5a为Enter键const unsigned char UnShifted[59][2] = {0x1C, 'a',0x32, 'b',0x21, 'c',0x23, 'd',0x24, 'e',0x2B, 'f',0x34, 'g',0x33, 'h',0x43, 'i',0x3B, 'j',0x42, 'k',0x4B, 'l',0x3A, 'm',0x31, 'n',0x44, 'o',0x4D, 'p',0x15, 'q',0x2D, 'r',0x1B, 's',0x2C, 't',0x3C, 'u',0x2A, 'v',0x1D, 'w',0x22, 'x',0x35, 'y',0x1A, 'z',0x45, '0',0x16, '1',0x1E, '2',0x26, '3',0x25, '4',0x2E, '5',0x36, '6',0x3D, '7',0x3E, '8',0x46, '9',0x0E, '`',0x4E, '-',0x55, '=',0x5D, '\\',0x29, ' ',0x54, '[',0x5B, ']',0x4C, ';',0x52, '\'',0x41, ',',0x49, '.',0x4A, '/',0x71, '.',0x70, '0',0x69, '1',0x72, '2',0x7A, '3',0x6B, '4',0x73, '5',0x74, '6',0x6C, '7',0x75, '8',0x7D, '9',};const unsigned char Shifted[59][2] = { 0x1C, 'A',0x32, 'B',0x21, 'C',0x23, 'D',0x24, 'E',0x2B, 'F',0x34, 'G',0x33, 'H',0x43, 'I',0x3B, 'J',0x42, 'K',0x4B, 'L',0x3A, 'M',0x31, 'N',0x44, 'O',0x4D, 'P',0x15, 'Q',0x2D, 'R',0x1B, 'S',0x2C, 'T',0x3C, 'U',0x2A, 'V',0x1D, 'W',0x22, 'X',0x35, 'Y',0x1A, 'Z',0x45, '0',0x16, '1',0x1E, '2',0x26, '3',0x25, '4',0x2E, '5',0x36, '6',0x3D, '7',0x3E, '8',0x46, '9',0x0E, '~',0x4E, '_',0x55, '+',0x5D, '|',0x29, ' ',0x54, '{',0x5B, '}',0x4C, ':',0x52, '"',0x41, '<',0x49, '>',0x4A, '?',0x71, '.',0x70, '0',0x69, '1',0x72, '2',0x7A, '3',0x6B, '4',0x73, '5',0x74, '6',0x6C, '7',0x75, '8',0x7D, '9',};//******************************************************************/ //6x8.h文件:/*-----------------------------------------------6 x 8 font1 pixel space at left and bottomindex = ASCII - 32-----------------------------------------------*/const unsigned char font6x8[][6] ={{ 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 },// ! { 0x00, 0x00, 0x07, 0x00, 0x07, 0x00 },// " { 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14 },// # { 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12 },// $ { 0x00, 0x62, 0x64, 0x08, 0x13, 0x23 },// %5 { 0x00, 0x36, 0x49, 0x55, 0x22, 0x50 },// & { 0x00, 0x00, 0x05, 0x03, 0x00, 0x00 },// ' { 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 },// ( { 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 },// ) { 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14 },// * { 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08 },// + { 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 },// , { 0x00, 0x08, 0x08, 0x08, 0x08, 0x08 },// - { 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 },// . { 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 },// / { 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E },// 0 16 { 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 },// 1 { 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 },// 2 { 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 },// 3 { 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 },// 4 { 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 },// 5 { 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 },// 6 { 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 },// 7 { 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 },// 8 { 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E },// 9 { 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 },// : 26 { 0x00, 0x00, 0x56, 0x36, 0x00, 0x00 },// ; { 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 },// < { 0x00, 0x14, 0x14, 0x14, 0x14, 0x14 },// = { 0x00, 0x00, 0x41, 0x22, 0x14, 0x08 },// > { 0x00, 0x02, 0x01, 0x51, 0x09, 0x06 },// ? { 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E },// @ { 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C },// A33 { 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36 },// B { 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22 },// C { 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C },// D { 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41 },// E { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01 },// F { 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A },// G { 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F },// H { 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00 },// I { 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01 },// J { 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41 },// K { 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40 },// L { 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F },// M { 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F },// N { 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E },// O { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06 },// P { 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E },// Q { 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46 },// R { 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 },// S { 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 },// T { 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F },// U { 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F },// V { 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F },// W { 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 },// X{ 0x00, 0x61, 0x51, 0x49, 0x45, 0x43 },// Z{ 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00 },// [59{ 0x00, 0x02, 0x04, 0x08, 0x10, 0x20 },// '\'{ 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00 },// ]{ 0x00, 0x04, 0x02, 0x01, 0x02, 0x04 },// ^{ 0x00, 0x40, 0x40, 0x40, 0x40, 0x40 },// _{ 0x00, 0x00, 0x01, 0x02, 0x04, 0x00 },// '{ 0x00, 0x20, 0x54, 0x54, 0x54, 0x78 },// a 65{ 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38 },// b{ 0x00, 0x38, 0x44, 0x44, 0x44, 0x20 },// c{ 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F },// d{ 0x00, 0x38, 0x54, 0x54, 0x54, 0x18 },// e{ 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02 },// f{ 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C },// g{ 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78 },// h{ 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00 },// i{ 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00 },// j{ 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00 },// k{ 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00 },// l{ 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78 },// m{ 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78 },// n{ 0x00, 0x38, 0x44, 0x44, 0x44, 0x38 },// o{ 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18 },// p{ 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC },// q{ 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08 },// r{ 0x00, 0x48, 0x54, 0x54, 0x54, 0x20 },// s{ 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20 },// t{ 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C },// u{ 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C },// v{ 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C },// w{ 0x00, 0x44, 0x28, 0x10, 0x28, 0x44 },// x{ 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C },// y{ 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44 },// z 90{ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00 },// | 91{ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 }// horiz lines};/***************************************************************************** **************************/void delay(unsigned char x,unsigned char y){unsigned char z;do{z=y;do{;}while(--z);}while(--x);}//名称: 复位DS18B20函数unsigned char reset(void){unsigned char outbit;TRISA4=0;//设置RA4位输出口RA4=0; //设置RA4=0;delay(2,70); //延时503usTRISA4=1; //设置RA4为输入口,以释放总线等电阻拉高总线delay(2,8); //延时70usif(RA4==1) outbit=0; //没有接收到应答信号,继续复位else outbit=1; //接收到应答信号delay(2,60); //延时430usreturn outbit; //带参数返回,如果接收到应答,返回1,否则返回0 }//名称: 写字节函数void write_byte(unsigned char val){unsigned char i;unsigned char temp;for(i=8;i>0;i--){temp=val&0x01; //最低位移出TRISA4=0;//设置RA4位输出口RA4=0; //设置RA4=0;NOP();NOP();NOP();NOP();NOP(); //从高拉至低电平,发生写时间隙if(temp==1) TRISA4=1; //如果写1,拉高电平delay(2,7); //延时63usTRISA4=1; //设置RA4为输入口,以释放总线等电阻拉高总线NOP();NOP();val=val>>1; //右移一位}}//名称: 读字节函数unsigned char read_byte(void){unsigned char i;unsigned char value=0; //读出温度for(i=8;i>0;i--){value>>=1;TRISA4=0;//设置RA4位输出口RA4=0; //设置RA4=0;NOP();NOP();NOP();NOP();NOP();NOP(); //6usTRISA4=1; //设置RA4为输入口NOP();NOP();NOP();NOP(); //4usif(RA4==1) value|=0x80; //如果接收到数据为1,从最高位往右移delay(2,7); //63us}return(value);}//名称: 启动读温度函数void convert_T(void){if(reset()==1) //如果复位胜利{write_byte(0xcc); // 跳过多器件识别write_byte(0x44); // 启动温度转换}}//名称: 读温度函数void read_T(void){unsigned char Lsb,Msb;if(reset()==1){write_byte(0xcc); // 跳过多器件识别write_byte(0xbe); // 读暂存器Lsb=read_byte(); // 低字节Msb=read_byte(); // 高字节temp2=Lsb&0x0f; //LSB的低4位为小数部份temp1=(Lsb>>4)|(Msb<<4);//LSB的高4位和MSB拼成整数部份 }}//名称: 延时函数void delay1(unsigned int t){unsigned int i,j;for(i=0;i<t;i++){for(j=0;j<10;j++);}}//名称: 1602忙检测函数void lcd_wait_busy(void){TRISD7=1; //为读状态做准备,把RD7设为输入RSPIN=0; //选择指令寄存器RWPIN=1; //选择读EPIN=1; //使能线电平变动while(RD7==1); //读忙状态,不忙时退出EPIN=0; //恢复使能线电平TRISD7=0; //把RD7设置为输出}//名称: 1602写命令函数void lcd_write_com(unsigned char combuf){RSPIN=0; //选择指令寄存器RWPIN=0; //选择写PORTD=combuf; //把命令字送入RDEPIN=1; //使能线电平变动,命令送入1602的8位数据口asm("NOP"); //来一个空把持,以延时片刻EPIN=0; //恢复使能线电平}//1602写命令函数(带忙检测)void lcd_write_com_busy(unsigned char combuf){lcd_wait_busy();//调用忙检测函数lcd_write_com(combuf); //调用写命令函数}//1602写数据函数(带忙检测)void lcd_write_data(unsigned char databuf){lcd_wait_busy();//调用忙检测函数RSPIN=1; //选择数据寄存器RWPIN=0; //选择写PORTD=databuf; //把数据字送入RD口EPIN=1; //使能线电平变动,命令送入1602的8位数据口asm("NOP");EPIN=0; //恢复使能线电平}//名称: 1602显示地址写函数void lcd_write_address(unsigned char x,unsigned char y){x&=0x0f;//列地址限制在0-15y&=0x01;//行地址限制在0-1if(y==0x00)lcd_write_com_busy(x|0x80); //第一行的列地址写入elselcd_write_com_busy((x+0x40)|0x80); //第二行的列地址写入}//名称: 1602初始化函数void lcdreset(void){delay1(150);lcd_write_com(0x38);delay1(50);lcd_write_com(0x38);delay1(50);lcd_write_com(0x38);lcd_write_com_busy(0x38); //8位数据,双列,5*7字形lcd_write_com_busy(0x08);//显示功能关,无光标lcd_write_com_busy(0x01);//清屏指令lcd_write_com_busy(0x06);//写入新的数据后,光标右移,显示屏不移动lcd_write_com_busy(0x0c);//显示功能开,无光标,}//指定地址写入函数void lcd_write_char(unsigned char x,unsigned char y,unsigned char buf){lcd_write_address(x,y); //写入地址lcd_write_data(buf);//写入显示数据}/*********************************************************************/ //T0初始化函数void timer0init(void){T0CS=0; //TMR0工作于按时器方式PSA=1; //TMR0不分频TMR0IF=0; //清除TMR0中断标识表记标帜TMR0IE=1; //TMR0中断允许T0CON=0x88; //16bit按时方式,预分频关闭,TMR0H=(65536-50000)/256; //0.05;TMR0L=(65536-50000)%256;//GIE=1;}//T0中断函数 //外部中断INT处置函数 //PIC单片机和51单片机纷歧样,它只能有一个中断服务函数.void interrupt ISR(void){if(TMR0IF==1) //250us{//TMR0=0xff13; //晶振4.0M,按时250usTMR0H=(65536-50000)/256; //0.05;TMR0L=(65536-50000)%256;TMR0IF=0;a++;if(a==20){a=0;b++;if(b==999){b=0;}c++;}}if(INT0IF==1) //如果是外部中断{INT0IF=0; //清中断标识表记标帜位if(IntNum==0) KeyV=0; //接收开始,将缓冲区清零if((IntNum>0)&&(IntNum<9)) //接收8位有效码{KeyV=KeyV>>1; //因键盘数据是低>>高,结合上一句所以右移一位if (Key_Data) KeyV=KeyV|0x80; //当键盘数据线为1时为1到最高位}IntNum++; //中断次数计次if (IntNum > 10){IntNum = 0; //傍边断11次后暗示一帧数据收完,清变量准备下一次接收bf = 1; //接收完成标识表记标帜位,写1后,暗示接收OKkeybuf=KeyV; //把接收缓冲区的数据移植keybufKeyV=0; //接收缓冲区清0}}}/****************************************************************************/ /***************************************************************************/ //PS2解码处置函数unsigned char Decode(unsigned char ScanCode)//注意:如SHIFT+G为12H 34H F0H 34H F0H 12H?//也就是说shift的通码+G的通码+shift的断码+G的断码{unsigned char TempCyc;unsigned char KeyChar=0; if (!Key_UP) //当键盘松开时。
实验八 IIC通信协议
实验八I2C通信协议一、实验目的:1、培养学生阅读资料的能力;2、加深学生对I2C总线通信协议的理解;3、加强学生对模块化编程的理解;二、实验环境:1、硬件环境:PC机一台、单片机实验板一块、母头串口交叉线、USB电源线;2、软件环境:keil uVision2集成开发环境;STC-ISP下载上位机软件;三、实验原理:要学会I2C通信协议的编程,关键是要看懂并掌握其时序图,理解对I2C通信协议相关子程序的实验编写。
I2C通信协议的总线时序图如下所示:I2C总线时序图I2C相关子程序的详细介绍1、起始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
2、结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
起始信号和结束信号的时序图如下所示:起始信号和结束信号的时序图起始信号的流程如下:1、SCL和SDA拉高,保持时间约为0.6us-4us;2、拉低SDA,保持时间为约为0.6us-4us;3、拉低时钟线结束信号的流程如下:1、SCL置高电平,SDA置低电平,保持时间约为0.6us-4us2、SDA拉高,保持时间约为1.2-4us;应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。
CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。
若未收到应答信号,由判断为受控单元出现故障。
应答信号的时序图如下所示:应答时序图发送时的应答信号;**********应答信号**********ACK: SETB SDA ;数据线置高SETB SCL ;时钟线置高ACALL DELAYJB SDA,$ ;等待数据线变低ACALL DELAYCLR SCL ;时钟线置低RET注意:这里如果数据线一直为高将进入死循环,所以一般我们都会在这做一个容错的处理。
具体的程序如下:ACK: MOV R4,#00HSETB SDASETB SCLLOP0: JNB SDA,LOPDJNZ R4,LOP0 ;循环255次LOP: ACALL DELCLR SCLRET接收时的应答信号ACK1: CLR SDA ;数据线置低SETB SCL ;时钟线置高NOPNOPCLR SCL ;时钟线置低SETB SDA ;数据线置高RET3、字节的发送和接收写周期时序图一字节数据发送子程序,流程如下:图6-22 发送子程序流程图(2)一字节数据接收子程序,流程如下:图6-23 接收子程序流程图7、写操作(1)字节写图6-24 字节写时序图流程如下:图6-25 字节写的流程图(2)页写图6-26 页写时序图页写流程如下:8、读操作(1)选择读图6-28 选择读时序图图6-29 NO ACK时序图(2)连续读图6-30 连续读时序图四、实验原理图:I2C总线电路图五、实验例题:例题一编写一程序,实现I2C的指定字节读写,用24C08来记录单片机复位或者开机的次数,并将复位或者开机的次数显示在数码管上。
I2C_24C02总线通信协议实例详解(附详细示波器实测波形图)
I2C详解I2C总线是PHLIPS公司推出的一种串行总线,是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串行总线。
I2C总线只有两根双向信号线:一根是数据线SDA,另一根是时钟线SCL。
I2C总线通过上拉电阻接正电源。
当总线空闲时,两根线均为高电平。
连到总线上的任一器件输出的低电平都将使总线的信号变低,即各器件的SDA及SCL都是线“与”关系。
在有些情况下,可能没接上拉电阻I2C也能正常通信,但是建议读者最好接上拉电阻。
本文最后将给出有接上拉电阻和没接两种情况下的I2C通信波形,可以明显的看出来,接了上拉电阻波形更漂亮,通信也更稳定。
本文将以24C02来详细讲解I2C 协议。
因为本文的重点是讲解I2C,所以这里只简单的介绍24C02,有关24C02的更为详细的资料,读者可以查阅其数据手册,在这里就其必需的部分进行简单的讲解。
一、 AT24C02简介AT24C02是美国ATMEL公司的低功耗CMOS串行EEPROM,它是内含256×8位(2K)存储空间,具有工作电压宽(2.5~5.5V)、擦写次数多(大于10000次)、写入速度快(小于10ms)等特点。
它的典型应用电路如图1:图1 AT24C02典型应用电路图1中AT24C02的1、2、3脚是三条地址线,用于确定芯片的硬件地址。
在本文都将其接地,表示其地址为000。
第5脚SDA为串行数据输入/输出,数据通过这条双向I2C总线串行传送,第6脚SCL为串行时钟输入线。
当用单片机I/O 口模拟I2C通信时,这两个引脚可以接任意的I/O口。
SDA和SCL都需要接一个上拉电阻,其阻值一般为4.7K~10K。
第7脚是写保护引脚,可以接IO口也可以直接接地,接地就不再具有保护功能。
这里将其直接接地。
二、 I2C总线的构成及信号类型I2C总线是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。
I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
常用数据传输接口
RST
命令和控制逻辑 地址总线 31X8bit RAM
图12.6.2 DS1302结构图
❖ DS1302的控制字节
RST
SCLK I/O
1 A0 A1 A2 A3 A4 R/C 1
LSB
MSB
(a)单字节数据读时序
RST
SCLK I/O
1 A0 LSB
A1 A2 A3 A4 R/C 1 MSB
D0 D1 D2 D3 D4 D5 D6 D7
❖ DS1302的结构及工作原理
❖ DS1302工作电压为2.5V~5.5V,采用三线 接口与CPU进行同步通信,并可采用突发 方式一次传送多个字节的时钟信号或RAM 数据。DS1302内部有一个31×8的用于临 时性存放数据的RAM寄存器。DS1302是 DS1202的升级产品,与DS1202兼容,但 增加了主电源/后背电源双电源引脚,同时 提供了对后背电源进行涓细电流充电的能 力。
传输,这就需要一定的协议来对读/写数据提 出严格的时序要求,而AT89系列单片机并不 支持单线传输。因此,必须采用软件的方法 来模拟单线的协议时序。
图12.9.1 DS18B20应用原理图
12.10 小结
❖ 本章详细介绍了I2C,SPI和1-wire三种总线 的传输协议和传输过程,本章中所设计的三 个应用实例也十分实用,在很多场合都能使 用得上,比如DS1302电子表和DS18B20温 度计。若是同学们能掌握它们的设计方法, 自己设计一个简易的电子表或温度计都不再 有问题。
SCLK SS (CS)
功能 主器件数据输出,从器件数据输入 主器件数据输入,从器件数据输出
时钟信号,由主器件产生 从器件使能信号,由主器件控制
表12.5.1 SPI 的4根信号线功能表
I2C通信时序图解析
I2C通信时序图解析⼀、I2C协议简介 I2C 通讯协议(Inter-Integrated Circuit)是由 Phiilps 公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要 USART、CAN 等通讯协议的外部收发设备,现在被⼴泛地使⽤在系统内多个集成电路(IC)间的通讯。
关于I2C协议的更多内容,可阅读《I2C总线协议》,本博⽂主要分析I2C波形图,对于I2C的基础知识不在做介绍。
⼆、I2C协议标准代码2.1 起始信号&停⽌信号 起始信号:当 SCL 线是⾼电平时 SDA 线从⾼电平向低电平切换。
停⽌信号:当 SCL 线是⾼电平时 SDA 线由低电平向⾼电平切换。
2.1.1 起始信号代码void I2C_Start(void){I2C_SDA_High(); //SDA=1I2C_SCL_High(); //SCL=1I2C_Delay();I2C_SDA_Low();I2C_Delay();I2C_SCL_Low();I2C_Delay();}2.1.2 停⽌信号代码void I2C_Stop(void){I2C_SDA_Low();I2C_SCL_High();I2C_Delay();I2C_SDA_High();I2C_Delay();}2.2 发送⼀个字节 CPU向I2C总线设备发送⼀个字节(8bit)数据u8 I2C_SendByte(uint8_t Byte){uint8_t i;/* 先发送⾼位字节 */for(i = 0 ; i < 8 ; i++){if(Byte & 0x80){I2C_SDA_High();}else{I2C_SDA_Low();}I2C_Delay();I2C_SCL_High();I2C_Delay();I2C_SCL_Low();I2C_Delay();if(i == 7){I2C_SDA_High(); /* 释放SDA总线 */}Byte <<= 1; /* 左移⼀位 */I2C_Delay();}} 2.3 读取⼀个字节 CPU从I2C总线设备上读取⼀个字节(8bit数据)u8 I2C_ReadByte(void){uint8_t i;uint8_t value;/* 先读取最⾼位即bit7 */value = 0;for(i = 0 ; i < 8 ; i++){value <<= 1;I2C_SCL_High();I2C_Delay();if(I2C_SDA_READ()){value++;}I2C_SCL_Low();I2C_Delay();}return value;}2.4 应答2.4.1 CPU产⽣⼀个ACK信号void I2C_Ack(void){I2C_SDA_Low();I2C_Delay();I2C_SCL_High();I2C_Delay();I2C_SCL_Low();I2C_Delay();I2C_SDA_High();}2.4.2 CPU产⽣⼀个⾮ACK信号void I2C_NoAck(void){I2C_SDA_High();I2C_Delay();I2C_SCL_High();I2C_Delay();I2C_SCL_Low();I2C_Delay();}2.4.3 CPU产⽣⼀个时钟,并读取器件的ACK应答信号uint8_t I2C_WaitToAck(void){uint8_t redata;I2C_SDA_High();I2C_Delay();I2C_SCL_High();I2C_Delay();if(I2C_SDA_READ()){redata = 1;}else{redata = 0;}I2C_SCL_Low();I2C_Delay();return redata;}三、I2C通信时序图解析 有了上边的I2C总线标准代码的基础,下⾯我们进⼊本博⽂所要讲解的内容,怎么分析I2C的时序图,以O2Micro的OZ9350为例,OZ9350是⼀款模拟前端(AFE)的IC器件。
I2C操作时序问题总结(内附大量实用代码和详解)
I2C 总线在单片机操作中用到的很多。
特别是以I2C总线进行数据和命令传输的器件,比如AT24C02存储芯片等。
特此做了相关操作过程中经常用到的操作和一些操作的解释。
相信看完之后,肯定会对I2C总线有深刻的理解。
I2C总线操作(从高位开始进行读写操作)写操作时序启动之后先进行一个字节的指令写入操作,然后进行应答;在进行字节数据的传送;然后再进行应答;I2C读操作时序基本上与写操作相同,不同的是读操作只需进行指令的写入,不写数据(应该不绝对),最后主机产生非应答信号,结束数据的读取;在对E2PROM(24C02)进行操作时,写入写操作指令后,然后写入需要操作的存储器地址号,最后写入数据。
且每个存储器地址只能赋值一次,重复对该存储器地址赋值会使前一个数据丢失。
读操作过程中需对将指令改写为读指令,在读取数据时需要写入指令指明需要读出数据时的存储器地址号下面是对24C02的写操作和读操作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();stop();start();write_byte(0xa1); //写入指令,进行读操作respons();date=read_byte(); //进行读取数据norespons();stop();return date;}void main(){init();write_add(23,0xcc); //写入存储器地址号为23中,数据为0xcc delay1(100);P1=read_add(23); //读入存储器地址号为23中的数据,并将数据赋值给P1口,通过数码管显示while(1); //停留在此处}I2C串行总线的操作程序起始信号(时钟线为高,数据线由高变低):void AT24C04_Start(){SDA = 1; //拉高数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时SDA = 0; //产生下降沿 Delay5us(); //延时SCL = 0; //拉低时钟线}结束信号:(时钟线为高,数据线由低变高)void AT24C04_Stop(){SDA = 0; //拉低数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时SDA = 1; //产生上升沿 Delay5us(); //延时}字节传输:(每个字节为8位,一个字节带一个相应位)发送数据:void AT24C04_SendByte(BYTE dat){BYTE i;for (i=0; i<8; i++) //8位计数器{dat <<= 1; //移出数据的最高位SDA = CY; //送数据口SCL = 1; //拉高时钟线Delay5us(); //延时SCL = 0; //拉低时钟线,以便下一次传送数据 Delay5us(); //延时}AT24C04_RecvACK();}接收数据:BYTE AT24C04_RecvByte(){BYTE i;BYTE dat = 0;SDA = 1; //使能内部上拉,准备读取数据for (i=0; i<8; i++) //8位计数器{dat <<= 1;SCL = 1; //拉高时钟线Delay5us(); //延时dat |= SDA; //读数据SCL = 0; //拉低时钟线以便下一个数据传送 Delay5us(); //延时}return dat;数据响应:每次数据传输成功后,接收器件发送一个应答信号,当第九个信号产生时,产生应答信号的器件将SDA拉低。
I2C总线入门(很详细,很经典)
I2C总线入门1)最近学习51单片机,学到A/DQ/A转换的时候发现我板子上的转换芯片不是书上所讲的ADC0804和DAC0832而是PCF859仃,看了一下它的数据手册, 发现它并不是书上所说的并行传输数据,是使用I2C总线传输的。
搞了两天才搞懂,写出来给大家分享一下,不足之处请务必不吝指出。
! ≡tt f Itiief II R J Ih PHiLlPSt j ΓC bFC 口対由⅞⅛⅞κΓt r SDA IUB L f W r■I. SeiL閃離找L#參G [⅛总蠻H件嗣时Mtfl ι⅛X⅛ttStM'QUIA ft/i CPU 1√ Kf?IC ZlHh IC J J Ie Z糾幣町遊i;I^I ILW*s4t∣ιIkh i P"⅛.BtflK硏是Jl伯的内评.iaiT IT K以上是I2C总线的简单介绍。
就比如说AT24C02存储芯片,和PCF8591数模模数转换芯片都支持I2C端口(如下图)2)接下来看如何使用I2C总线进行通信3. I S C总线通信格式图8,i+2 ⅛ PC总统上进彳J -次数撫传输的通信格式HJ. λ5WuJΓ IMPuJT λWλ√[T+ *1⅛∕'f ⅛ff融戟代答ftK >⅛祎:J*j*hrn⅛释止他号图S.I .2 I3C总纽上遊打谀散据传输的JfflG⅛A 以上是I2C 总线通信的格式。
由上图可以看出进行通信需要以下几个步骤S-Iead PDlPAOL1 8□ VCCAl匚⅛WPA2匚3GND匚4£AJNOITU迴VDDAINlI 2ISj AOUTAIN2 3]回” RE FAIN3 I 41^I3] AGNDPCF8591PAO ^5∏^↑2∖ EXTAt叵TrlOSCA2 T/JO)SeL^kVSS叵(VJ SDAIH2引脚图(Dlla.初始化I2C总线就是把SDA和SCL都变成高电平。
Void in it() 〃初始化{SDA=1;delay();SCL=1;delay();}delay ()为延时函数void delay() 〃延时4-5个微秒{;;}b.发送起始信号就是保持SCL为高电平,而SDA从高电平降为低电平(这是I2C总线的规定, 别问我为什么)void Start()// 起始信号{SDA=1;delay();SCL=1;delay();SDA=0;delay();}C.发送地址字(芯片的硬件地址)74地址12C总线象统中的每一片PCF859J通过发送有效地址封该黠件来激活。
第11章 I2C总线图文图文课件
编号;
位 为1,表示要对器
01
3.数据传输 在数据传送过程中,SCL为高电平时,SDA必须是一稳定的高或低电平,此时
数据有效。SDA线的改变只能发生在SCL为低电平。 4.传输应答
所有数据都是按字节发送的,每次发送的字节数不限,但每发完每一个字节 要释放SDA线(呈高电平),然后由接收器下拉SDA线(呈低电平)产生应答位,表 示传输成功,此时主控器必须产生一个与此位相应的额外时钟脉冲。I2C 总线 数据传送时,每成功地传送一个字节数据后接收器都必须产生一个应答信号, 应答的器件在第9 个时钟周期时将SDA 线拉低,表示其已收到一个8 位数, 24C04在接收到起始信号和从器件地址之后响应一个应答信号,如果器件已选择 了写操作,则在每接收一个8 位字节之后响应一个应答信号。当24C04 工作于
主机发送地址时,总线上的每一个从机都将这7位地址码与自已的器件地址 进行比较,如果相同则认为自已正被主机寻址,根据读写位将自已确定为发送 器或接收器。
从机的地址由一个固定部分和一个可编程部分组成。固定部分为器件的编号
02 例如24C02的地址格式如下:
其中高四位1010为器件标识类型。 A2~A0:引脚地址,对应于该芯片引脚A2~A0的取值,当A2-A0引脚均接低电 平时,该器件的地址为A0H或A1H,如果为A0H表示写数据到该器件,A1H表示从 该器件读数据。 说明:从机地址只表明选择挂在总线的哪一个器件及传送方向,而器件内 部的地址是由编程者传送的第一数据中指定的,即第一个数据为器件内的子地 址。
功能:该函数与rcvbyte() 不同,它包含了从启动总线、 发送从器件地址、读数据到结 束总线的全过程。
如其果中返:回1表示操作成功, 否则s操la作:有从错器。件地址
IIC串口(精)
②在总线上挂接的I2C接口器件,有标志本器件类别的器件类型码(内臵4bit)和器件片选地址(引脚设定,P196)。
③在单主控器的IIC总线中,无论发送还是接收,SCL均由主控方提供,单向,由主控器传送给从器件;而SDA是双向的。
挂接在总线上的集成电路总数仅受总线总电容≤400pF的限制。
⑤I2C总线协议支持三种工作模式:标准S(100Kbit/s)、快速F(400Kbit/s)、高速Hs(3.4Mbit/s)。
我们这一讲从以下三个方面来初步认识I2C总线协议,并以具有I2C接口的EEPROM存储器芯片24CWxx的应用为例来具体理解和认识基于IIC总线的系统扩展。
⒈ I2C接口的电原理结构:①凡具有I2C接口的器件,其内部双向口线均为漏极(或集电极)开路输出电路/带缓冲的输入电路。
所有器件,包括主控器的输出口线均以“线与方式”挂接在I2C 总线上,总线上有上拉电阻(5~10kΩ)。
双向口线和“线与”方式,便于总线双向数据传输和控制权转移。
某器件要在SDA线上输出1,或要放弃对SDA线的控制,均应向SDA线输出1。
②在具有I2C总线接口的器件内,均有实现I2C通信协议的控制逻辑;51单片机基本型89C51没有这种控制逻辑,但可以用编程方式来模拟这种控制逻辑;51系列中的8XC550/552/752等增强性机种内就预构了具备I2C控制逻辑的I2C通信模块。
⒉信息结构:①I2C串行通信基于“位传输”,即通信传输中的底层单位是“位”。
但“位”不独立存在,必须由多个“位”组成一定格式的“基本单位”,并以这个基本单位进行I2C通信。
所谓“基本单位”与异步串行通信中的“帧”相当(不完全相同),我们就借用“帧”这个概念了。
通信中,主从双方有序组织多个“帧”进行“交互式通信”,以完成信息传送。
②“帧”组成格式:由8bit数据位(高位在前,低位在后)、应答位ACK(或非应答位NACK)构成,根据通信开始或结束的需要,在“帧”的前后拼装开始信号S或停止信号P。
i2c 连续读 时序
i2c 连续读时序
I2C(Inter-Integrated Circuit)是一种串行通信协议,它允
许多个设备通过两根线进行通信。
在I2C连续读取时,首先需要发
送一个起始条件,然后发送设备的地址和读取位(R/W = 1),接着
设备会发送一个ACK信号,表示已经准备好接收数据。
接下来,主
设备可以连续读取从设备的数据,每次读取完数据后,主设备会发
送一个ACK信号以继续读取下一个字节的数据,直到主设备发送一
个NACK信号为止,表示读取结束,最后发送一个停止条件。
在I2C连续读取过程中,时序非常重要。
首先是起始条件的产生,主设备发送起始信号后,从设备准备好之后发送应答信号。
接
下来是设备地址和读取位的发送,主设备发送完地址后,从设备再
次发送应答信号。
接着是连续读取数据的过程,每次读取完数据后,主设备发送ACK信号,从设备再次发送数据,直到读取结束。
最后
是停止条件的产生,主设备发送停止信号后,通信结束。
除了时序外,还需要考虑通信过程中的时钟频率、数据传输的
稳定性等因素。
在实际应用中,需要根据具体的I2C设备和控制器
的规格书来确定正确的时序,以确保通信的稳定和可靠性。
总的来说,I2C连续读取的时序包括起始条件、设备地址和读取位发送、数据读取和停止条件,时序的准确性对于通信的成功非常重要。
希望这个回答能够满足你的需求。
i2c协议时序
I2C协议时序一、概述I2C(Inter-Integrated Circuit)是一种串行通信协议,由飞利浦公司(现在的恩智浦)在1980年代开发。
它被广泛应用于各种电子设备之间的通信,如传感器、存储器、扩展IO等。
I2C协议采用两根线(SDA和SCL)进行通信,支持多主机和多从机的连接。
I2C协议具有以下特点: - 两根线进行全双工通信。
- 支持多主机和多从机的连接。
- 速率可调,常见的速率有100Kbps、400Kbps和1Mbps。
- 使用地址寻址方式,每个设备都有唯一的7位或10位地址。
二、时序图I2C协议的时序图如下所示:_______SDA: |_______| SDA _______|_______SCL: _______| |___________|在I2C协议中,SDA线是数据线,SCL线是时钟线。
数据传输分为两种类型:写操作和读操作。
1. 写操作写操作由主机发起,并包含以下步骤: 1. 主机发送起始条件:将SDA从高电平拉到低电平时,SCL保持高电平。
2. 主机发送器件地址和写命令:主机发送器件地址和写命令,从机通过检测地址匹配来响应。
3. 主机发送数据:主机将要发送的数据传输到SDA线上,并在每个数据位的传输之前拉低SCL线,然后释放SCL线,从而使从机可以读取数据。
4. 主机发送停止条件:当所有数据传输完毕后,主机将SDA从低电平拉到高电平时,再将SCL保持高电平。
2. 读操作读操作由主机发起,并包含以下步骤: 1. 主机发送起始条件:与写操作相同。
2. 主机发送器件地址和读命令:与写操作相同。
3. 从机发送应答信号:当从机接收到地址和命令后,会向主机发送一个应答信号。
4. 主机接收数据:主机在每个数据位的传输之前拉低SCL线,然后释放SCL线,从而使从机可以将数据传输到SDA线上。
主机在每个数据位的传输之后需要向从机发送一个应答信号来确认是否继续传输下一个数据位。
i2c 读写时序
i2c 读写时序I2C(Inter-Integrated Circuit)是一种通信协议,用于在集成电路之间进行短距离的串行数据传输。
在许多电子设备中,I2C被广泛应用于连接各种芯片和传感器。
I2C通信的核心是传输数据的主设备(Master)和接收数据的从设备(Slave)。
主设备负责控制总线并发送读写指令,从设备则响应这些指令并返回数据。
在I2C通信中,主设备和从设备之间的数据传输需要遵循一定的时序规则。
1. I2C 读取时序在I2C的读取过程中,主设备发送读取请求,从设备返回数据。
以下是一个典型的I2C读取时序示意图:___ ___ ____________| S | |AD+W| | A | | A | | . . . | | NACK | | P ||____|---|____|---|_____|____|---|_____|____|---|________|---|_______|---|____|--注释:- S:启动信号(Start),主设备发送一个低电平信号来启动通信。
- AD+W:从设备地址和写入位(Address + Write),主设备发送从设备地址和一个写入位来指定要进行数据传输的从设备。
- A:应答位(Acknowledge),每个字节的传输结束后,接收器返回一个应答位,表示已成功接收数据。
- NACK:非应答位(Not Acknowledge),主设备在读取数据时,如果从设备不再发送数据,将发送一个非应答位。
- P:停止信号(Stop),主设备发送一个高电平信号来结束通信。
在I2C读取时序中,主设备首先发送启动信号(S),然后发送从设备地址和写入位(AD+W)。
接下来,从设备返回应答位(A)。
主设备接着发送内部寄存器地址(A),再次收到从设备的应答位(A)。
随后,主设备发送读取请求,从设备返回数据,并以应答位(A)响应。
若后续还有数据需要读取,主设备持续发送读取请求,直到不再需要数据时,主设备发送非应答位并发送停止信号(P)来结束通信。
IIC总线的串行扩展
(1)控制字节 在起始条件之后,必须是器件的控制字节,其中,高四位
为器件类型识别符(不同的芯片类型有不同的定义,如E2PROM 为1010),接着三位为片选,最低位为读写控制位,为“1”时 为读操作,为“0”时为写操作。如下图所示。
6
(2)写操作 写操作分为字节写和页面写两种操作,对于页面写,根据
1
3. I2C总线协议 I2C总线在传送数据过程中共有三种类型信号:开始信号、
停止信号和应答信号。
开始信号:SCL保持高电平的状态下,SDA出现下降沿。出现 开始信号以后,总线被认为“忙”。
停止信号:SCL保持高电平的状态下,SDA出现上升沿。停止 信号过后,总线被认为“空闲”。
应答信号:接收数据的器件在接收到8位数据后,向发送数据的 器件发出特定的低电平脉冲,表示已收到数据。
总线空闲:SCL和SDA都保持高电平。
总线忙:在数据传送开始以后,SCL为高电平的时候,SDA的 数据必须保持稳定,只有当SCL为低电平的时候才允许SDA上 的数据改变。
2
4. I2C总线的传送格式
I2C总线的传送格式为主从式,对系统中的某一器件来说有 四种工作方式:主发送方式、从发送方式、主接收方式、从接 收方式。 (1)主发送从接收
2. I2C总线系统结构 一个典型的I2C总线结构如下图所示。系统中所有的器件均
有I2C总线接口,所有器件通过两根线SDA(串行数据线)和 SCL(串行时钟线)连接到I2C总线上,并通过寻址识别。
I2C总线中的器件既可以作为主控器,也可以作为被控器, 系统中每个器件均具有惟一的地址,各器件之间通过寻址确定 数据交换方。任何时刻总线只能由一个主控制器,数据的传输 只能在主、从器件间进行。
4.串行外设总线SPI
基于高云FPGA的I2C读写EEPROM
基于高云 FPGA的 I2C读写 EEPROM摘要:无线通信设备设计中,需要对功率平坦度进行调试,所以需要将每个频点的数控衰减值存储于EEPROM,以便设备在正常工作中,使用该衰减值,达到功率输出一致的要求。
同时由于无线通信设备的硬件差异性和环境影响,使得无线通信设备的正反向功率等参数不一致,所以需要EEPROM存储每个设备的基准值,已达到无线通信设备的一致性。
本文主要选用国产芯片使用VHDL语言实现EEPROM的读写,来实现数控衰减值和基准值的存储和读出,广东高云半导体FPGA芯片GW2A-LV55PBGA484C8/I7作为主机,成都华微电子EEPROm芯片HWD24C512作为为从机。
关键词:FPGA;I2C;EEPROM1 引言I2C总线(I2C bus,Inter-IC bus)是一个双向的两线连续总线,提供集成电路之间的通信线路,它是一种串行扩展技术,即就是完成集成电路或功能单元之间的信息交换的规范或者协议[1]。
I2C总线采用一条数据(SDA:串行数据线Serial data line),加一条时钟线(SCL:串行时钟线Serial clock line)来完成数据的传输及外围器件的扩展。
I2C在芯片的配置中应用很广泛,比如摄像头、VGA转HDMI转换芯片[2]。
无线通信设备设计中,需要对功率平坦度进行调试。
即就是对其所有工作频点进行功率校准,使设备处于发射状态时,所有工作频点下输出功率基本一致并且在特定的范围内,否则会出现状态不一致甚至烧坏其他部件的情况。
本文通过改变每个频点下的数控衰减值,以达到功率一致,并将每个频点的数控衰减值存储于EEPROM,以便设备在正常工作中,使用该衰减值,达到功率输出一致的要求。
无线通信设备设计中,由于硬件差异性和环境影响,使得无线通信设备的一致性不同,为了使得控制一致,所以需要EEPROM存储每个设备的基准值,已达到无线通信设备的一致性。
本文以实际项目中用于存储参数的EEPROM的读写设计为实例。
i2c信号
图14-3 I2C通信流程解析起始信号:UART通信是从一直持续的高电平出现一个低电平标志起始位;而I2C通信的起始信号的定义是SCL为高电平期间,SDA由高电平向低电平变化产生一个下降沿,表示起始信号,如图14-3中的start部分所示。
前几章我们学了一种通信协议叫做UART异步串口通信,这节课我们要来学习第二种常用的通信协议I2C。
I2C总线是由PHILIPS公司开发的两线式串行总线,多用于连接微处理器及其外围设备。
I2C总线的主要特点是接口方式简单,两条线可以挂多个参与通信的器件,即多机模式,而且任何一个器件都可以作为主机,当然同一时刻只能一个主机。
从原理上来讲,UART属于异步通信,比如电脑发送给单片机,电脑只负责把数据通过TXD发送出来即可,接收数据是单片机自己的事情。
而I2C属于同步通信,SCL时钟线负责收发双方的时钟节拍,SDA数据线负责传输数据。
I2C的发送方和接收方都以SCL这个时钟节拍为基准进行数据的发送和接收。
从应用上来讲,UART通信多用于板间通信,比如单片机和电脑,这个设备和另外一个设备之间的通信。
而I2C多用于板内通信,比如单片机和我们本章要学的EEPROM之间的通信。
14.1 I2C时序初步认识在硬件上,I2C总线是由时钟总线SCL和数据总线SDA两条线构成,连接到总线上的所有的器件的SCL都连到一起,所有的SDA都连到一起。
I2C总线是开漏引脚并联的结构,因此我们外部要添加上拉电阻。
对于开漏电路外部加上拉电阻的话,那就组成了线“与”的关系。
总线上线“与”的关系,那所有接入的器件保持高电平,这条线才是高电平。
而任意一个器件输出一个低电平,那这条线就会保持低电平,因此可以做到任何一个器件都可以拉低电平,也就是任何一个器件都可以作为主机,如图14-1所示,我们添加了R63和R64两个上拉电阻。
图14-1 I2C总线的上拉电阻虽然说任何一个设备都可以作为主机,但绝大多数情况下我们都是用微处理器,也就是我们的单片机来做主机,而总线上挂的多个器件,每一个都像电话机一样有自己唯一的地址,在信息传输的过程中,通过这唯一的地址可以正常识别到属于自己的信息,在我们的KST-51开发板上,就挂接了2个I2C设备,一个是24C02,一个是PCF8591。
I2C总线时序详解
I2C总线时序详解I2C总线位传输由于连接到I2C 总线的器件有不同种类的工艺(CMOS、NMOS、双极性),逻辑0(低)和逻辑1(高)的电平不是固定的,它由电源VCC的相关电平决定,每传输一个数据位就产生一个时钟脉冲。
数据的有效性SDA 线上的数据必须在时钟的高电平周期保持稳定。
数据线的高或低电平状态只有在SCL 线的时钟信号是低电平时才能改变。
I2C位传输数据有效性起始和停止条件SCL 线是高电平时,SDA 线从高电平向低电平切换,这个情况表示起始条件;SCL 线是高电平时,SDA 线由低电平向高电平切换,这个情况表示停止条件。
起始和停止条件一般由主机产生,总线在起始条件后被认为处于忙的状态起始和停止条件,在停止条件的某段时间后总线被认为再次处于空闲状态。
如果产生重复起始条件而不产生停止条件,总线会一直处于忙的状态,此时的起始条件(S)和重复起始条件(Sr)在功能上是一样的。
I2C总线数据传输字节格式发送到SDA 线上的每个字节必须为8 位,每次传输可以发送的字节数量不受限制。
每个字节后必须跟一个响应位。
首先传输的是数据的最高位(MSB),如果从机要完成一些其他功能后(例如一个内部中断服务程序)才能接收或发送下一个完整的数据字节,可以使时钟线SCL 保持低电平,迫使主机进入等待状态,当从机准备好接收下一个数据字节并释放时钟线SCL 后数据传输继续。
应答响应数据传输必须带响应,相关的响应时钟脉冲由主机产生。
在响应的时钟脉冲期间发送器释放SDA 线(高)。
在响应的时钟脉冲期间,接收器必须将SDA 线拉低,使它在这个时钟脉冲的高电平期间保持稳定的低电平。
通常被寻址的接收器在接收到的每个字节后,除了用CBUS 地址开头的数。
I2C总线数据传输和应答据,必须产生一个响应。
当从机不能响应从机地址时(例如它正在执行一些实时函数不能接收或发送),从机必须使数据线保持高电平,主机然后产生一个停止条件终止传输或者产生重复起始条件开始新的传输。
I2C总线原理及应用实例
I2C总线原理及应用实例I2C(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。
I2C总线产生于在80年代,最初为音频和视频设备开发,如今主要在服务器管理中使用,其中包括单个组件状态的通信。
例如管理员可对各个组件进行查询,以管理系统的配置或掌握组件的功能状态,如电源和系统风扇。
可随时监控内存、硬盘、网络、系统温度等多个参数,增加了系统的安全性,方便了管理。
一、I2C总线特点I2C总线最主要的优点是其简单性和有效性。
由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。
总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件。
I2C总线的另一个优点是,它支持多主控(multimastering),其中任何能够进行发送和接收的设备都可以成为主总线。
一个主控能够控制信号的传输和时钟频率。
当然,在任何时间点上只能有一个主控。
二、I2C总线工作原理1.总线的构成及信号类型I2C总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。
在CPU与被控IC 之间、IC与IC之间进行双向传送,最高传送速率100kbps。
各种被控制电路均并联在这条总线上,但就像电话机一样只有拨通各自的号码才能工作,所以每个电路和模块都有唯一的地址,在信息的传输过程中,I2C总线上并接的每一模块电路既是主控器(或被控器),又是发送器(或接收器),这取决于它所要完成的功能。
CPU发出的控制信号分为地址码和控制量两部分,地址码用来选址,即接通需要控制的电路,确定控制的种类;控制量决定该调整的类别(如对比度、亮度等)及需要调整的量。
这样,各控制电路虽然挂在同一条总线上,却彼此独立,互不相关。
I2C总线在传送数据过程中共有三种类型信号,它们分别是:开始信号、结束信号和应答信号。
I2C总线协议
I2C总线定义I2C(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。
I2C总线产生于在80年代,最初为音频和视频设备开发,如今主要在服务器管理中使用,其中包括单个组件状态的通信。
例如管理员可对各个组件进行查询,以管理系统的配置或掌握组件的功能状态,如电源和系统风扇。
可随时监控内存、硬盘、网络、系统温度等多个参数,增加了系统的安全性,方便了管理。
I2C总线特点I2C总线最主要的优点是其简单性和有效性。
由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。
总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件。
I2C总线的另一个优点是,它支持多主控(multimastering),其中任何能够进行发送和接收的设备都可以成为主总线。
一个主控能够控制信号的传输和时钟频率。
当然,在任何时间点上只能有一个主控。
I2C总线工作原理总线的构成及信号类型I2C总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。
在CPU与被控IC之间、IC与IC之间进行双向传送,最高传送速率100kbps。
各种被控制电路均并联在这条总线上,但就像电话机一样只有拨通各自的号码才能工作,所以每个电路和模块都有唯一的地址,在信息的传输过程中,I2C总线上并接的每一模块电路既是主控器(或被控器),又是发送器(或接收器),这取决于它所要完成的功能。
CPU发出的控制信号分为地址码和控制量两部分,地址码用来选址,即接通需要控制的电路,确定控制的种类;控制量决定该调整的类别(如对比度、亮度等)及需要调整的量。
这样,各控制电路虽然挂在同一条总线上,却彼此独立,互不相关。
I2C总线在传送数据过程中共有三种类型信号,它们分别是:开始信号、结束信号和应答信号。
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
I2C接口的EEPROM 24C64芯片的驱动方法
I2C接口的EEPROM24C64芯片的驱动方法与93C46类似的,24C64也是EEPROM,但不同的是24C64是I2C接口的,容量也要更大些,用来存储较大容量的数据,甚至在某些单片机中可以用作程序存储器。
24C64提供65536个位,它们是以字节方式进行组织的。
通过设置不同的地址,可以实现多达8个芯片共享两线总线。
它被广泛应用于工业、化工等需要低功耗与低电压的领域。
同时,它还提供诸如4.5V~5.5V、2.7V~5.5V、2.5V~5.5V与1.8V~5.5V各种工作电压范围的芯片,从而使其应用更加通用。
24C64的引脚定义:引脚功能详细描述:24C64的功能框图:引脚功能描述:串行时钟(SCL):在SCL的上升沿数据写入芯片中,在下降沿从芯片中读出数据。
串行数据(SDA):SDA用作双向数据传输。
这个引脚是漏极开路驱动,需要加上拉电阻。
设备地址(A2,A1,A0):A2~A0是设备地址设置引脚,可以通过接高或接低来设置不同的地址,也可以直接悬空。
设置为不同地址时最多可以在同一总线上存在多达8个芯片。
当这些引脚悬空时,默认地址为0。
写保护(WP):当此引脚接到GND上时,允许正常的写操作。
当WP接到V CC时,所有的写操作都是被禁止的。
如果悬空,则WP在内部被拉到GND。
24C64的组织方式:24C64在内部被组织为256个页,每个页32个字节。
可以按字节来进行操作,地址为13位。
24C64的操作方法:24C64是采用I2C接口来进行数据传输的,在这里不再介绍I2C接口数据传输的相关内容,具体的I2C总线协议在相关章节有详细讲解,敬请翻阅。
下面只针对于24C64的操作方法进行讲解。
1)设备寻址在开始条件使芯片使能后,需要给其写入一个8位的设备地址码,以使某一芯片被命中。
在地址码的开头有两个“10”序列,共4位,然后是3位的地址,最后是1位的读写标识位。
具体的地址码结构如下:24C64使用3个设备地址位A2、A1、A0使多达8个芯片同时存在于一条总线上。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
启动信号:
SCL为高电平的时候,SDA由高电平向低电平跳变。
结束信号:
SCL为高电平的时候,SDA由低电平向高电平跳变。
应答信号:
I2C总线上的所有数据都是以8位字节传送的,发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。
应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接收了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功,对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。
如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信号P。
写时序:
开始信号:主机+从设备地址+写命令,从机应答,应答成功,表示有这个设备,然后主机+设备内部寄存器地址,此时不用再加写命令控制字,从机应答,应答成功,表示设备内有这个地址,主机写入数据,从机应答,是否继续发送,不发送的话,发送停止信号P。
读时序:
要想读设备,首先要知道将要所读取设备的地址告诉从设备,从设备才能将数据放到(发送)SDA上使主设备读取,从设备将数据放入SDA上的过程,由硬件主动完成,不用人为的写入。
所以首先先写入从机地址,然后+写控制命令,从机应答,应答成功,表示有这个设备,然后写入内部寄存器地址,此时不用再加写命令控制字,从机应答,应答成功,表示设备内有这个地址。
然后主机继续发出:写入从机地址,然后+读命令,从机应答,应答成功,此时便可以读取数据了,从设备已经将数据放入到SDA上了。
地址跟设备已经验证了,不用再进行验证。
启动信号与停止信号的时序图如下图所示:
数据位发送:
在I2C总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。
进行数据传送时,在SCL呈现高电平期间,SDA上的电平必须保持稳定,低电平为数据0,高电平为数据1。
只有在SCL为低电平期间,才允许SDA上的电平改变状态。
逻辑0的电平为低电压,而逻辑1则为高电平。
时序如下图所示:
应答信号时序图如下图所示:
当进行一次写时序的时候,SDA上的数据变化的时序图如下:
当进行一次读的时候,SDA上的数据变化的时序图如下:
i2c协议中的数据传输时序图如下:。