实验八 51系列单片机IIC

合集下载

单片机IIC程序设计用c8051f单片机

单片机IIC程序设计用c8051f单片机

#include <c8051f020.h> // SFR declarations//------------------------------------------------------------------------------------// Global CONSTANTS//------------------------------------------------------------------------------------#define WRITE 0x00 // SMBus WRITE command#define READ 0x01 // SMBus READ command// Device addresses (7 bits, lsb is a don't care)#define CLOCK3530_ADDRESS_RESET 0x60 //1 ack#define CLOCK3530_ADDRESS_STATUS 0x62 //2 ack#define CLOCK3530_ADDRESS_DATEHOUR 0x64 //8 ack year month day week hour minute second#define CLOCK3530_ADDRESS_HOUR 0x66 //4 ack hour minute second#define CLOCK3530_ADDRESS_INT1 0x68 //3 ack#define CLOCK3530_ADDRESS_INT2 0x6A //3 ackunion{unsigned char ClockString[7];struct RealClock{unsigned char Year,Month,Day,Week,Hour,Minute,Second;} RT;} RealTime;// SMBus states:// MT = Master Transmitter// MR = Master Receiver#define SMB_BUS_ERROR 0x00 // (all modes) BUS ERROR#define SMB_START 0x08 // (MT & MR) START transmitted#define SMB_RP_START 0x10 // (MT & MR) repeated START#define SMB_MTADDACK 0x18 // (MT) Slave address + W transmitted;// ACK received#define SMB_MTADDNACK 0x20 // (MT) Slave address + W transmitted;// NACK received#define SMB_MTDBACK 0x28 // (MT) data byte transmitted; ACK rec'vd #define SMB_MTDBNACK 0x30 // (MT) data byte transmitted; NACK rec'vd#define SMB_MTARBLOST 0x38 // (MT) arbitration lost#define SMB_MRADDACK 0x40 // (MR) Slave address + R transmitted;// ACK received#define SMB_MRADDNACK 0x48 // (MR) Slave address + R transmitted;// NACK received#define SMB_MRDBACK 0x50 // (MR) data byte rec'vd; ACK transmitted #define SMB_MRDBNACK 0x58 // (MR) data byte rec'vd; NACK transmitted//-----------------------------------------------------------------------------------//Global V ARIABLES//-----------------------------------------------------------------------------------char COMMAND; // Holds the slave address + R/W bit for use in the SMBus ISR. unsigned char *I2CDataBuff;char BYTE_NUMBER; // Used by ISR to check what data has just been// sent - High address byte, Low byte, or data byteunsigned char HIGH_ADD, LOW_ADD; // High & Low byte for EEPROM memory addressbit SM_BUSY; // This bit is set when a send or receive// is started. It is cleared by the// ISR when the operation is finished.//------------------------------------------------------------------------------------// Function PROTOTYPES//------------------------------------------------------------------------------------void SMBus_ISR (void);//------------------------------------------------------------------------------------// MAIN Routine//------------------------------------------------------------------------------------//// Main routine configures the crossbar and SMBus, and tests// the SMBus interface between the three EEPROMsvoid ResetRealClock(void){while (SM_BUSY); // Wait for SMBus to be free.SM_BUSY = 1; // Occupy SMBus (set to busy)SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycleBYTE_NUMBER = 0; // 2 address bytes.COMMAND = (CLOCK3530_ADDRESS_RESET | READ); // Chip select + READ STA = 1; // Start transferwhile (SM_BUSY); // Wait for transfer to finish }//======================写S-3530A内部实时数据寄存器程序=====================//功能:将设定年、月、日、星期、时、分、秒数据写入S-3530A |//入口:发送数据放在年、月、日、星期、时、分、秒各寄存器|//出口:NONE |//===================================================================== =====void SetRealClock(void){while (SM_BUSY); // Wait for SMBus to be free.SM_BUSY = 1; // Occupy SMBus (set to busy)SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycleBYTE_NUMBER = 7; // 2 address bytes.COMMAND = (CLOCK3530_ADDRESS_DATEHOUR | WRITE); // Chip select + WRITEI2CDataBuff = &RealTime.ClockString[0]; // Data to be writenSTA = 1; // Start transfer}//==================读S-3530A实时数据寄存器子程序===========================//功能:从S-3530A读入当前时间数据|//入口:NONE |//出口:接收数据放在年、月、日、星期、时、分、秒各寄存器|//===================================================================== =====void GetRealClock(void){while (SM_BUSY); // Wait for SMBus to befree.SM_BUSY = 1; // Occupy SMBus (set to busy)SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycleBYTE_NUMBER = 7; // 2 address bytes.COMMAND = (CLOCK3530_ADDRESS_DATEHOUR | READ); // Chip select + READI2CDataBuff = &RealTime.ClockString[0]; // Data to be writenSTA = 1; // Start transferwhile (SM_BUSY); // Wait for transfer to finish }//============================写状态寄存器程序==============================//功能:读/写S-3530A状态寄存器,对S-3530A进行设置|//入口:NONE 出口:NONE | //===================================================================== =====unsigned char GetRealClockStatus(void){unsigned char result;while (SM_BUSY); // Wait for SMBus to be free.SM_BUSY = 1; // Occupy SMBus (set to busy)SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycleBYTE_NUMBER = 1;COMMAND = (CLOCK3530_ADDRESS_STATUS | READ);I2CDataBuff = &result;STA = 1; // Start transferwhile (SM_BUSY); // Wait for transfer to finish return result;}void SetRealClockStatus(unsigned char status){while (SM_BUSY); // Wait for SMBus to be free.SM_BUSY = 1; // Occupy SMBus (set to busy)SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycleBYTE_NUMBER = 1;COMMAND = (CLOCK3530_ADDRESS_STA TUS | WRITE);I2CDataBuff = &status;STA = 1; // Start transfer}/*void SetRealClockINT1(unsigned int Int1){while (SM_BUSY); // Wait for SMBus to be free.SM_BUSY = 1; // Occupy SMBus (set to busy)SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycleBYTE_NUMBER = 2;COMMAND = (CLOCK3530_ADDRESS_INT1 | WRITE);I2CDataBuff = (unsigned char*)&Int1;STA = 1; // Start transfer}*/#include "INTRINS.H"unsigned char revolve(unsigned char val){char i;unsigned char val1=0;for (i=0;i<8;i++){if (val&0x1)val1++;val1=_crol_(val1,1);val=_cror_(val,1);}val1=_cror_(val1,1);return val1;}/*-- 文字: 时--*/char code Shi[]={0x00,0x00,0xFC,0x44,0x44,0xFC,0x00,0x08,0x48,0x88,0x08,0xFF,0x08,0x08,0x08,0x00, 0x00,0x00,0x1F,0x04,0x04,0x0F,0x00,0x00,0x00,0x11,0x20,0x1F,0x00,0x00,0x00,0x00, };/*-- 文字: 钟--*/char code Zhong[]={0x00,0x60,0x38,0xE7,0x24,0x24,0x04,0x00,0xF8,0x88,0x88,0xFF,0x88,0x88,0xF8,0x00, 0x00,0x01,0x01,0x3F,0x11,0x09,0x01,0x00,0x01,0x00,0x00,0x3F,0x00,0x00,0x01,0x00, };void LCD_WriteHZ(char x,char y,char *Dot);void LCD_DispChar(char x,char y,char ch); //128*64 取值x=0-128 y=0-8void InitLCD(void);void Delay1ms(unsigned char T);void TestI2C (void){unsigned char var ;WDTCN = 0xde; // disable watchdog timerWDTCN = 0xad;OSCICN |= 0x03; // Set internal oscillator to highest setting// (16 MHz)XBR0 |= 0x07; // Route SMBus to GPIO pins through crossbarXBR2 |= 0x44; // Enable crossbar and weak pull-upsP0MDOUT |= 0x1D;P1MDOUT |= 0x01;SMB0CN = 0x44; // Enable SMBus with ACKs on acknowledge cycleSMB0CR = -80; // SMBus clock rate = 100kHz.EIE1 |= 2; // SMBus interrupt enableEA = 1; // Global interrupt enableSM_BUSY = 0; // Free SMBus for first transfer.// SetRealClockINT1(0x8000);var = GetRealClockStatus();ResetRealClock();var = GetRealClockStatus();SetRealClockStatus(0xc2);var = GetRealClockStatus();GetRealClock();RealTime.RT.Year=0x02;RealTime.RT.Month=0x12;RealTime.RT.Day=0x010;RealTime.RT.Week=0x05;RealTime.RT.Hour=0x11;RealTime.RT.Minute=0x59;RealTime.RT.Second=0x57;SetRealClock();GetRealClock();InitLCD();LCD_WriteHZ(0,0,Shi);LCD_WriteHZ(16,0,Zhong);//在0,2处显示00:00:00LCD_DispChar(0,2,0); //128*64 取值x=0-128 y=0-8LCD_DispChar(8,2,0);LCD_DispChar(16,2,10);LCD_DispChar(24,2,0);LCD_DispChar(32,2,0);LCD_DispChar(40,2,0xa);LCD_DispChar(48,2,0);LCD_DispChar(56,2,0);//在0,4处显示02/01/01LCD_DispChar(0,4,0); //128*64 取值x=0-128 y=0-8LCD_DispChar(8,4,2);LCD_DispChar(16,4,0xb);LCD_DispChar(24,4,0);LCD_DispChar(32,4,1);LCD_DispChar(40,4,0xb);LCD_DispChar(48,4,0);LCD_DispChar(56,4,1);for (;;){GetRealClock();LCD_DispChar(0,2,(RealTime.RT.Hour>>4)&0x03);//(RealTime.RT.Hour>>4)&0x0f); //128*64 取值x=0-128 y=0-8LCD_DispChar(8,2,RealTime.RT.Hour&0x0f);LCD_DispChar(24,2,(RealTime.RT.Minute>>4)&0x0f);LCD_DispChar(32,2,RealTime.RT.Minute&0x0f);LCD_DispChar(48,2,(RealTime.RT.Second>>4)&0x0f);LCD_DispChar(56,2,RealTime.RT.Second&0x0f);//在0,4处显示02/01/01LCD_DispChar(0,4,(RealTime.RT.Year>>4)&0x0f);LCD_DispChar(8,4,RealTime.RT.Year&0x0f);LCD_DispChar(24,4,(RealTime.RT.Month>>4)&0x0f);LCD_DispChar(32,4,RealTime.RT.Month&0x0f);LCD_DispChar(48,4,(RealTime.RT.Day>>4)&0x0f);LCD_DispChar(56,4,RealTime.RT.Day&0x0f);Delay1ms(100);}}//------------------------------------------------------------------------------------// Interrupt Service Routine//------------------------------------------------------------------------------------void SMBUS_ISR (void) interrupt 7{switch (SMB0STA){ // SMBus 状态码SMB0STA 寄存器// 主发送器/接收器起始条件已发送case SMB_START:SMB0DAT = COMMAND ; // 装入要访问的从器件的地址STA = 0; // 手动清除START 位break;//主发送器/接收器重复起始条件已发送// 该状态只应在读操作期间出现在存储器地址已发送并得到确认之后?case SMB_RP_START:SMB0DAT = COMMAND; // COMMAND 中应保持从地址+ R.STA = 0;break;// 主发送器从地址+ WRITE 已发送收到ACKcase SMB_MTADDACK:// 主发送器数据字节已发送收到ACKcase SMB_MTDBACK:if (BYTE_NUMBER){SMB0DAT = revolve(*I2CDataBuff); // If R/W=WRITE, load byte to write.I2CDataBuff++;BYTE_NUMBER--;}else{STO = 1; SM_BUSY = 0; // Free SMBus}break;// 主发送器从地址+ WRITE 已发送收到NACK// 从器件不应答发送STOP + START 重试case SMB_MTADDNACK:STO = 1; STA = 1;break;// 主发送器数据字节已发送收到NACK// 从器件不应答发送STOP + START 重试case SMB_MTDBNACK:STO = 1; STA = 1;break;// 主发送器竞争失败// 不应出现如果出现重新开始传输过程case SMB_MTARBLOST:STO = 1; STA = 1;break;// 主接收器从地址+ READ 已发送,收到ACKcase SMB_MRADDACK:AA = 1; // 在应答周期ACKif (!BYTE_NUMBER){STO = 1; SM_BUSY = 0; // 释放SMBus}break;// 主接收器从地址+ READ 已发送收到NACK// 从器件不应答发送重复起始条件重试case SMB_MRADDNACK:STA = 1;break;// 收到数据字节ACK 已发送// 该状态不应出现因为AA 已在前一状态被清0 如果出现发送停止条件case SMB_MRDBACK:if (BYTE_NUMBER){*I2CDataBuff=revolve(SMB0DA T);I2CDataBuff++;BYTE_NUMBER--;}if (!BYTE_NUMBER) AA= 0;break;// 收到数据字节NACK 已发送// 读操作已完成读数据寄存器后发送停止条件case SMB_MRDBNACK:STO = 1;SM_BUSY = 0; // 释放SMBusbreak;// 在本应用中所有其它状态码没有意义通信复位default:STO = 1; // 通信复位SM_BUSY = 0;break;}SI=0; // 清除中断标志}/*{switch (SMB0STA){ // Status code for the SMBus (SMB0STA register) case SMB_START:SMB0DAT = COMMAND; // COMMAND should hold slave address + R.break;case SMB_MTADDNACK:STO = 1;STA = 1;break;case SMB_RP_START:// SMB0DAT = COMMAND; // COMMAND should hold slave address + R.// STA = 0;// break;case SMB_MTADDACK:case SMB_MTDBACK:if (BYTE_NUMBER){if (COMMAND & 0x01) // If R/W=READ,{STA = 1;}else{SMB0DAT = *I2CDataBuff; // If R/W=WRITE, load byte to write.I2CDataBuff++;BYTE_NUMBER--;}}else{STO = 1;SM_BUSY = 0; // Free SMBus}break;// Master Transmitter: Data byte transmitted. NACK received.// Slave not responding. Send STOP followed by START to try again.case SMB_MTDBNACK:STO = 1;STA = 1;break;// Master Transmitter: Arbitration lost.// Should not occur. If so, restart transfer.case SMB_MTARBLOST:STO = 1;STA = 1;break;// Master Receiver: Slave address + READ transmitted. NACK received.// Slave not responding. Send repeated start to try again.case SMB_MRADDNACK:STA = 1;break;// Data byte received. ACK transmitted.// State should not occur because AA is set to zero in previous state.// Send STOP if state does occur.case SMB_MRDBACK:STO = 1;SM_BUSY = 0;break;// Master Receiver: Slave address + READ transmitted. ACK received.// Set to transmit NACK after next transfer since it will be the last (only) byte.case SMB_MRADDACK:// AA = 0; // NACK sent on acknowledge cycle.// break;// Data byte received. NACK transmitted.// Read operation has completed. Read data register and send STOP.case SMB_MRDBNACK:if (BYTE_NUMBER){if (COMMAND & 0x01) // If R/W=READ,{*I2CDataBuff=SMB0DA T;I2CDataBuff++;}BYTE_NUMBER--;}else{STO = 1;SM_BUSY = 0; // Free SMBus}break;// All other status codes meaningless in this application. Reset communication.default:STO = 1; // Reset communication.SM_BUSY = 0;break;}SI=0; // clear interrupt flag }*/。

实验八 IIC通信协议

实验八 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来记录单片机复位或者开机的次数,并将复位或者开机的次数显示在数码管上。

51单片机综合学习系统之 IIC总线学习篇.

51单片机综合学习系统之 IIC总线学习篇.

大家好,通过以前的学习,我们已经对51单片机综合学习系统的使用方法及学习方式有所了解与熟悉,学会了使用无线遥控模块的基本知识,体会到了综合学习系统的易用性与易学性,这一期我们将一起学习IIC总线的基本原理与应用实例。

先看一下我们将要使用的51单片机综合学习系统能完成哪些实验与产品开发工作:分别有流水灯,数码管显示,液晶显示,按键开关,蜂鸣器奏乐,继电器控制,IIC 总线,SPI总线,PS/2实验,AD模数转换,光耦实验,串口通信,红外线遥控,无线遥控,温度传感,步进电机控制等等。

上图是我们将要使用的51单片机综合学习系统硬件平台,如图1所示,本期实验我们用到了综合系统主机、板载的AT24C02芯片,综合系统其它功能模块原理与使用详见前几期《电子制作》杂志及后期连载教程介绍。

在很多电子设备中都有要随时存取数据作为历史记录或标志位。

目前常用的存储器有24CXX系列和93CXX系列,前者是I2C总线结构,后者是SPI总线结构,本小节先介绍I2C结构的EEPROM(24CXX)作用方法,在后面小节中再介绍SPI结构的EEPROM(93CXX)使用方法。

I2C总线基本概念I2C总线,是INTERINTEGRATEDCIRCUITBUS的缩写,即“内部集成电路总线”。

I2C总线是Philips公司推出的一种双向二线制总线。

目前Philips公司和其它集成电路制造商推出了很多基于I2C总线的外围器件。

I2C总线包括一条数据线(SDA)和一条时钟线(SCL)。

协议允许总线接入多个器件,并支持多主工作。

总线中的器件既可以作为主控器也可以作为被控器,既可以是发送器也可以是接收器。

总线按照一定的通信协议进行数据交换。

在每次数据交换开始,作为主控器的器件需要通过总线竞争获得主控权,并启动一次数据交换。

系统中各个器件都具有唯一的地址,各器件之间通过寻址确定数据接收方。

I2C总线的系统结构一个典型的I2C总线标准的IC器件,其内部不仅有I2C接口电路,还可将内部各单元电路划分成若干相对独立的模块,它只有二根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。

北京工业大学8051单片机实验报告

北京工业大学8051单片机实验报告

8051单片机实验报告专业:电子科学与技术姓名:学号: 120231指导教师:金冬月第一单元单片机程序调试环境使用及并行数据传送操作训练1-1修改例程一的源程序:将A寄存器的初值改为80H(正逻辑,数据位为1表示发光二极管点亮),再对源程序进行简单修改,使程序运行后发光二极管点亮情况与修改前相同。

$include (C8051F020.inc) ;C8051F02x系列单片机信息头文件包含伪指令LCALL Init_Device ;调用初始设置子程序MOV A,#080H ;赋初始值并在发光二极管上显示该数值 CPL AMOV P3,ALOOP: CALL DELAYCALL DELAYCALL DELAYCALL DELAYCALL DELAYRR A ;A寄存器内容右移1位并送发光二极管显示 MOV P3,AAJMP LOOP ;无限循环DELAY: MOV R5,#0H ;延时子程序D1: MOV R6,#0HDJNZ R6,$DJNZ R5,D1RET$include (Init_Device.inc) ;初始设置子程序文件包含伪指令 END将LED向左循环移位点亮改为向右循环移位点亮。

$include (C8051F020.inc) ;C8051F02x系列单片机信息头文件包含伪指令LCALL Init_Device ;调用初始设置子程序MOV A,#07FH ;赋初始值并在发光二极管上显示该数值 MOV P3,ALOOP: CALL DELAYCALL DELAYCALL DELAYCALL DELAYCALL DELAYRL A ;A寄存器内容右移1位并送发光二极管显示 MOV P3,AAJMP LOOP ;无限循环DELAY: MOV R5,#0H ;延时子程序D1: MOV R6,#0HDJNZ R6,$DJNZ R5,D1RET$include (Init_Device.inc) ;初始设置子程序文件包含伪指令END加快LED循环移位点亮的速度。

C8051F021单片机实验指导

C8051F021单片机实验指导

提要:实验项目1、单片机的IO编程实验1 IO开关量输入实验实验2 IO输出驱动继电器(或光电隔离器)实验实验3 IO输入/输出------半导体温度传感器DS18B20实验2、单片机的中断系统实验1 外部外部中断----脉冲计数实验3、单片机的定时器/计数器实验1 计数器实验实验2 秒时钟发生器实验4、单片机的串口特点和编程实验1 P C机串口通讯实验实验2 R S485通讯实验5、存储器实验1 RAM存储器读写实验6、PWM发生器实验1 PWM发生器(模拟)实验实验1 PWM发生器(内部)实验7、WDG看门狗实验1 外扩WDG(MAX813)实验实验2 WDG(内部)实验8、SPI总线实验1 SPI(模拟)实验-----TLC2543 AD转换实验实验2 SPI(模拟)实验-----TLV5616 DA转换实验9、I2C总线实验1 I2C(模拟)实验-----AT24C01读写实验实验2 I2C(内部)实验-----AT24C01读写实验10、综合实验实验1 HD7279LED数码管显示实验实验2 HD7279键盘实验实验3 外部中断---电机转速显示实验11、步进电机正反转实验12、TFT液晶显示彩色条纹实验13、16X16LED点阵显示汉字实验一、单片机的IO编程实验1 IO开关量输入实验目的:学习单片机读取IO引脚状态的的方法。

内容:编程读取IO引脚状态。

设备:EL-EMCU-I试验箱、EXP-C8051F021 CPU板。

编程:首先要把相关的引脚设置在IO的输入状态,然后写一个循环,不停地检测引脚的状态。

步骤:1、将CPU板正确安放在CPU接口插座上,2、连线:用导线将试验箱上MCU部分的IO1--- IO8分别连接到SWITCH 的8个拨码开关的K1---K8的输出端子K1---K8上,连接好仿真器。

3、试验箱上电,在PC机上打开Keil C环境,打开试验程序文件夹IO_INPUT 下的工程文件IO_INPUT.Uv2编译程序,上电,在函数main()的最后一句设置断点,进入调试状态,打开窗口Peripherals-->IO-Port-->P3,改变开关状态,运行程序到断点处,观察窗口的数值与开关的对应关系。

如何用51单片机实现IIC通信

如何用51单片机实现IIC通信

如何用51单片机实现IIC通信在之前的MCS-51系列单片机中内部没有IIC通信资源,所如果要想用51单片机实现IIC通信,就只能通过软件模拟其时序,这样也能实现IIC通信的功能。

这个是IIC的头文件,便于使用调用:#ifndef _IIC_H_#define _IIC_H_/***ucahr和uint 的宏定义很重要,否则下面的函数无法正常运行******/#define uchar unsigned char //定义uchar型数据为无符号型#define uint unsigned int //定义uint型数据为无符号型sbit SCL = P2 ;sbit SDA = P2 ;/***申明外部函数****/extern void delay_1ms(void);extern void IIC_Init(void);//IIC初始化extern void Signal_Start(void);//IIC停止信号extern void Signal_Stop(void);//IIC停止信号extern void Write_Byte(uchar wdata);//写一个字节数据函数extern uchar Read_Byte();//读一个字节数据函数extern void Write_Add(uchar add,uchar wdata,uchar comd);//向某个IIC器件写指令,地址和数据extern uchar Read_Add(uchar add,uchar comd);//向某个IIC器件写指令读某个地址里面的数据#endif以下是IIC通信的C语言源代码:#include#include。

51单片机模拟I2C总线的C语言实现

51单片机模拟I2C总线的C语言实现

51单⽚机模拟I2C总线的C语⾔实现I2C(Inter-Integrated Circuit)总线是⼀种由PHILIPS公司开发的两线式串⾏总线,⽤于连接微控制器及其外围设备。

I2C总线产⽣于在80年代,最初为⾳频和视频设备开发,如今主要在服务器管理中使⽤,其中包括单个组件状态的通信。

例如管理员可对各个组件进⾏查询,以管理系统的配置或掌握组件的功能状态,如电源和系统风扇。

可随时监控内存、硬盘、⽹络、系统温度等多个参数,增加了系统的安全性,⽅便了管理。

⼀、I2C总线特点 I2C总线最主要的优点是其简单性和有效性。

由于接⼝直接在组件之上,因此I2C总线占⽤的空间⾮常⼩,减少了电路板的空间和芯⽚管脚的数量,降低了互联成本。

总线的长度可⾼达25英尺,并且能够以10Kbps的最⼤传输速率⽀持40个组件。

I2C总线的另⼀个优点是,它⽀持多主控 (multimastering), 其中任何能够进⾏发送和接收的设备都可以成为主总线。

⼀个主控能够控制信号的传输和时钟频率。

当然,在任何时间点上只能有⼀个主控。

⼆、I2C总线⼯作原理2.1、总线的构成及信号类型I2C 总线是⼀种串⾏数据总线,只有⼆根信号线,⼀根是双向的数据线SDA,另⼀根是时钟线SCL。

在CPU与被控IC之间、IC与IC之间进⾏双向传送,最⾼传送速率100kbps。

各种被控制电路均并联在这条总线上,但就像电话机⼀样只有拨通各⾃的号码才能⼯作,所以每个电路和模块都有唯⼀的地址,在信息的传输过程中,I2C总线上并接的每⼀模块电路既是主控器(或被控器),⼜是发送器(或接收器),这取决于它所要完成的功能。

CPU发出的控制信号分为地址码和控制量两部分,地址码⽤来选址,即接通需要控制的电路,确定控制的种类;控制量决定该调整的类别(如对⽐度、亮度等)及需要调整的量。

这样,各控制电路虽然挂在同⼀条总线上,却彼此独⽴,互不相关。

2.2、位的传输SDA 线上的数据必须在时钟的⾼电平周期保持稳定数据线的⾼或低电平状态只有在SCL 线的时钟信号是低电平时才能改变。

片机教程51系列单片机读写IIC总线

片机教程51系列单片机读写IIC总线

测试步骤和注意事项
测试步骤和注意事项
01
3. 发送IIC总线读写命令,检查数据传输是否正确。
02
4. 重复测试,验证稳定性。
注意事项
03
1. 确保电源稳定,避免因电源波动导致IIC总线不稳定。
2. 确保连接线缆质量良好,避免因线缆问题导致信号传输错误。
3. 在测试过程中,避免频繁开关电源或拔插线缆。
51系列单片机读写IIC总线调试与测试
软件工具
串口调试助手、IIC调试器等。
调试方法
通过观察IIC总线的信号波形、电压值等参数,判断IIC总线是否正常工作。
硬件工具
万用表、示波器、逻辑分析仪等。
调试工具和方法
1
2
3
测试步骤
1. 连接IIC总线,确保单片机、传感器等设备正确连接。
2. 配置单片机IIC总线参数,如地址、速率等。
是8051的改进版,增加了一些功能,如更多的I/O端口、定时器等。
是8051的增强版,具有更高的处理速度和更大的内存。0302源自0151系列单片机介绍
SDA(串行数据):用于传输数据。
SCL(串行时钟):用于同步数据传输。
双向数据线:SDA线是双向的,可以用于发送和接收数据。
IIC总线硬件接口
为单片机提供稳定的电源。
工业控制实例
在医疗设备中,以血压计为例,通过51单片机读写IIC总线,实现血压数据的采集、处理和显示,同时可将数据传输至云平台进行分析。
医疗设备实例
应用实例解析
应用前景展望
随着物联网技术的不断发展,51系列单片机读写IIC总线的应用将更加广泛,特别是在智能家居、工业控制等领域,具有广阔的市场前景。
IIC总线具有寻址能力,可以通过地址码识别目标设备。

IIC总线原理及其在51单片机中的简单应用

IIC总线原理及其在51单片机中的简单应用

IIC 总线原理及其在51 单片机中的简单应用
1. IIC 总线基本概念
1.1 总线概述
IIC 总线是PHLIPS 公司推出的一种串行总线,是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串行总线。

1.2 总线结构
IIC 总线是由数据线SDA 和时钟线SCL 构成的串行总线,可发送和接收数据。

在CPU 与被控IC 之间、IC 与IC 之间可以进行双向传送,最高传送速率100kbps。

各种被控制电路均并联在这两条总线上。

2. IIC 总线协议
2.1 数据传输中的主/从机
在多主机系统中,可能同时有几个主机企图启动总线传送数据。

为了避免混乱,IIC 总线要通过总线仲裁,以决定由哪一台主机控制总线。

连在每一个总线上的电路和模块都有一个唯一地址,它们彼此之间只有简单的。

实验二 8051单片机IO口输出操作实验

实验二 8051单片机IO口输出操作实验

实验二8051单片机I/O口输出操作实验一实验目的:通过实验了解和学习8051单片机I/O口作为输出方式使用时,CPU对I/O口的操作方法。

二实验原理:8051单片机有4个8位的并行口,记作P0、P1、P2和P3,共32根I/O线。

每个口主要由四部分组成:端口锁存器、输入缓冲器、输出驱动器和引至芯片外的端口引脚。

它们都是双向通道,每一条I/O线都能独立地用作输入或输出。

作为输出口用时,内部带锁存器,故可以直接和外设相连,不必加锁存器。

这四个接口特性上的差别主要是P0、P2和P3都还有第二功能,而P1口只能用作I/O 口。

三实验内容:实验中P1.0脚上连一个发光二极管和一个限流电阻。

端口送低电位时,发光二极管点亮,送高电位时,发光二极管熄灭。

编写程序控制发光二极管,使之每隔大约0.5秒钟点亮一次。

四实验电路图:图2-1五实验方法:1.根据如上电路图连接好实验电路。

在实验板中将P1.0的管脚和LED的管脚相连。

也可以照这个电路图用实验面包板自己搭一个电路,VCC用直流5V,也可以用三节碱性电池串联。

2.按照实验要求编写实验程序,建立新工程,保存为OUTPUT。

图2-23.调试程序,根据调试结果,调整软件延时的时间。

图2-34.图2-2是软件编译成功的窗口;图2-3是软件仿真窗口,可以拉开外设菜单观察P1口状态。

5.将keilC51产生的output.hex文件通过在线下载ISP或商用编程器写入芯片中,将芯片插入实验板(如果是在线下载就可以省略这步,因为芯片就在实验板上),复位后运行程序观察结果。

六参考程序:1.汇编源程序ORG 0000HSTART: SETB P1.0 ;P1.0口置位ACALL DLAY ;调用延时子程序DLY0.5S CLR P1.0 ;P1.0口清位ACALL DLAYSJMP START ;程序循环执行DLAY: MOV R0,#0FFH ;延时子程序,延时约0.5S D1: MOV R1,#0FFHD2: MOV R2,#6HDJNZ R2,$DJNZ R1,D2DJNZ R0,D1RETEND2.C语言源程序/*************************************************** 文件名: output.c* 描述: P1口输出,点亮发光二极管**************************************************/#include <reg51.h>sbit LED=P1^0; //引脚定义void main(void){int i;while(1){LED=1;for(i=0;i<=30000;i++); //空循环延时LED=0;for(i=0;i<=30000;i++);}}思考题:观察汇编语言和C语言控制单片机的过程,有哪些相同和不同的地方。

51单片机的模拟IIC总线程序

51单片机的模拟IIC总线程序

#include <reg764.h> /*头文件的包含*/#include <intrins.h>#define uchar unsigned char /*宏定义*/#define uint unsigned int#define _Nop() _nop_() /*定义空指令*//* 常,变量定义区 *//*端口位定义*/ sbit SDA=P1^3; /*模拟I2C数据传送位*/sbit SCL=P1^2; /*模拟I2C时钟控制位*//*状态标志*/ bit ack; /*应答标志位*/void Start_I2c(){SDA=1; /*发送起始条件的数据信号*/_Nop();SCL=1;_Nop(); /*起始条件建立时间大于4.7us,延时*/_Nop();_Nop();_Nop();_Nop();SDA=0; /*发送起始信号*/_Nop(); /* 起始条件锁定时间大于4μs*/_Nop();_Nop();_Nop();_Nop();SCL=0; /*钳住I2C总线,准备发送或接收数据 */_Nop();_Nop();}void Stop_I2c(){SDA=0; /*发送结束条件的数据信号*/_Nop(); /*发送结束条件的时钟信号*/SCL=1; /*结束条件建立时间大于4μs*/_Nop();_Nop();_Nop();_Nop();_Nop();SDA=1; /*发送I2C总线结束信号*/_Nop();_Nop();_Nop();_Nop();}void SendByte(uchar c){uchar BitCnt;for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8位*/{if((c<<BitCnt)&0x80)SDA=1; /*判断发送位*/else SDA=0;_Nop();SCL=1; /*置时钟线为高,通知被控器开始接收数据位*/ _Nop();_Nop(); /*保证时钟高电平周期大于4μs*/_Nop();_Nop();_Nop();SCL=0;}_Nop();_Nop();SDA=1; /*8位发送完后释放数据线,准备接收应答位*/ _Nop();_Nop();SCL=1;_Nop();_Nop();_Nop();if(SDA==1)ack=0;else ack=1; /*判断是否接收到应答信号*/SCL=0;_Nop();_Nop();}/*******************************************************************字节数据传送函数函数原型: uchar RcvByte();功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后请用应答函数。

用Proteus学习51单片机之I2C

用Proteus学习51单片机之I2C

在学习单片机的过程中,我常有这样的烦恼:随随便便一个芯片,少则占用三五个IO口,一般的就占用8个,稍微想用多一点芯片吧,老觉得IO口不够用。

学串口的时候觉得串口是个好东西,连两条线就够了,现在学到I2C,觉得这也是一个非常好的东西,也是两条线,还能给每个总线上的设备设立地址,简直就是一个小网络了。

I2C总线使用两条线,一条是时钟线,称为SCL,一条是数据线,称为SDA,各个设备就并在总线上,每一个总线上的设备都有一个自己的地址,主机在操作设备的时候,都会先发送一个地址码,告诉被操作机,接下来的命令由它接收。

接下来说一下I2C总线的数据有效性。

I2C总线进行数据传送时,要求SCL为高电平时,SDA上的数据必需保持稳定,换言之,当SCL为高电平时,SDA的电平不能变换,只有当SCL为低电平时,SDA的电平才能变。

I2C总线通信时,需要遵照一定的协议,以下为一次通信过程:1.由主机发送起始信号,启动I2C总线。

时序为,在SCL为高电平期间,SDA出现一个下降沿。

2.主机发送寻址信号,即告诉特定的设备,接下来的命令是发给它的。

地址分为7位和10位,以7位为例,高7位为设备地址,最低位表示读或写,1表示读,0表示写。

3.应答信号,I2C协议规定,每传送一个字节数据(包括地址及命令)后,都要有一个接收设备返回的应答信号,以确定信号是否被接收设备正确接收到了。

其时序为,在SCL信号为高电平期间,接收设备把SDA电平拉低。

4.数据传输,当主机发送发址并收到应答后,就可以发送数据了,但是发送数据只能每次发送一位,并且每发送一位后都需要收到接收机的应答。

或主机为接收设备时,主机对最后一个字节不应答,表示向发送设备说,数据传送结束。

5.发送停止信号,在全部数据传送完毕后,主机发送停止信号,时序为,在SCL为高电平期间,SDA上产生一个上升沿。

前面讲到,I2C协议要求数据的发送,要求SCL为低电平时,SDA才能变换,看一下上面的时序,可以看到,命令都是SCL为高电平时对SDA的操作,而发送数据则是SCL为低电平时对SDA操作。

MCS51-IIC

MCS51-IIC

总线仲裁
总线仲裁发生在两个主IIC设备中。如果一个 主设备欲使用总线,而测得SDA为低电平,则 该主设备仲裁不能够使用总线启动传输。这个 仲裁过程会延长,直到信号线SDA变为高电平 每次操作都要进行仲裁
MCS-51模拟IIC总线
SCL
>4.7μS > 4μ S
SC L
> 4μ S
>4.7μS
IIC总线数据传输格式
一般操作格式
S 从IIC地址(7位) R/W A
主控制器写操作格式
传输数据 …… A P
S 从IIC地址 W A 数据1 A 数据2 A …… 数据n A/A P 红色起始信号S、地址信号、控制信号W、各个数据、结束信号 P,均为主IIC设备发送、从IIC设备接收;黑色的应答信号A/A 为从IIC设备发送、主IIC设备接收
IIC总线的工作原理
数据位信号 数据位
SDA SCL
起始信号
结束信号
IIC总线的工作原理
IIC总线对数据线上信号的定义
数据位信号:时钟信号线是低电平时,可以改变数 据信号线电平;时钟信号线是高电平时,应保持数 据信号线上电平不变,即时钟是高电平时数据有效 应答信号:占1位,数据接收者接收1字节数据后, 应向数据发出者发送一应答信号。低电平为应答, 继续发送;高电平为非应答,结束发送 控制位信号:占1位,主IIC设备发出的读写控制信 号,高为读、低为写(对主IIC设备而言)。控制 位在寻址字节中
IIC总线系统组成
SDA SCL SCL SDA SCL SDA SCL 单片机 A 单片机 B SDA SCL SDA SCL 日历 时钟 SDA SCL SDA
SRAM或 E2PROM
A/D或 D/A

51单片机模拟IIC

51单片机模拟IIC

#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbit SDA=P2^0;sbit SCL=P2^1;uchar code table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; void Delay(){_nop_();_nop_();_nop_();_nop_();_nop_();}void delay(uint x){uint y,z;for(y=x;y>0;y--)for(z=110;z>0;z--);}void start(){SDA=1;SCL=1;Delay();SDA=0;Delay();SCL=0;_nop_();}void stop(){SDA=0;SCL=1;Delay();SDA=1;Delay();SDA=0;SCL=0;}void init(){SCL=1;_nop_();SDA=1;_nop_();}void response() //回应信号{uchar i=0;SCL=1;_nop_();while((SDA==1)&&(i<255))i++;SCL=0;_nop_();}void writebyte(uchar dat) // 写一个字节{uchar i,temp;temp=dat;for(i=0;i<8;i++){temp=temp<<1;SCL=0;_nop_();SDA=CY;_nop_();SCL=1;_nop_();}SCL=0;_nop_();SDA=1;_nop_();_nop_();}uchar readbyte() //读一个字节{uchar i,j,dat;SCL=0;_nop_();_nop_();SDA=1;for(i=0;i<8;i++){SCL=1;_nop_();if(SDA==1)j=1;elsej=0;dat=(dat<<1)|j;SCL=0;_nop_();_nop_();}_nop_();_nop_();return dat;}void write24c02(uchar address,uchar dat)//指定地址写一个字节数据{start();writebyte(0xa0);response();writebyte(address);response();writebyte(dat);response();stop();}uchar read24c02(uchar address)//指定地址读一个字节数据{uchar dat;start();writebyte(0xa0);response();writebyte(address);response();start();writebyte(0xa1);response();dat=readbyte();stop();return dat;}void main(){uchar i=0;init();P1=0xff;delay(50);while(1){for(i=0;i<8;i++){write24c02(i+1,table[i]);response();delay(40);}// stop();delay(10);for(i=0;i<8;i++){P1=read24c02(i+1);response();delay(200);}// stop();}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
• I2C总线是很简单方便的芯片间串行扩展总线。使用I2C总线 可以直接和具有I2C总线接口的单片机通信,也可以和各种 类型的外围器件进行通信,如存储器、A/D、D/A、键盘、 LCD等。目前Philips、Atmel、Maxim以及其他集成电路制 造商推出了很多基于I2C总线的单片机和外围器件,如24系 列E2PROM、串行实时时钟芯片DS1302、USB2.0芯片 CY7C68013A等。

I_Delay(100);

SCL=HIGH;

I_Delay(100);

S);

SCL=LOW;

I_Delay(100);
•}
8.3.3 应答信号
• 应答信号用于表明数据传输的结束。I2C总线数据传送时,每传送一个字节 数据后都必须有应答信号。应答信号从主器件产生。主器件在第9个时钟 位上释放数据总线,使其处于高电平状态,此时从器件输出低电平拉低数 据总线为应答信号。
• 如果采用C语言进行程序设计,则发送应答位子程序示例如下:
• void I_Ack()
•{

SDA=LOW;

I_Delay(100);

SCL=HIGH;

I_Delay(100);

SCL=LOW;

I_Delay(100);

SDA=HIGH;

I_Delay(100);
•}
8.3.4 非应答信号
• 非应答信号用于数据传输出现异常而无法完成时。 在传送完一个字节数据后,在第9个时钟位上从器 件输出高电平为非应答信号。非应答信号的产生 有两种情况。
• 当从器件正在进行其他处理而无法接收总线上的 数据时,从器件不产生应答,此时从器件释放总 线,将数据线置为高电平。这样,主器件可产生 一个停止信号来终止总线数据传输。
• I2C总线的传输速率可以支持100kHz和400kHz两种,对于 100kHz的速率一般采用10KΩ 的上拉电阻,对于400kHz的速 率一般采用2KΩ 的上拉电阻。
• I2C总线上的外围扩展器件都是属于电压型负载的CMOS器件, 因此总线上的器件数量不是由电流负载能力决定,而是由 电容负载能力确定。I2C总线上每一个节点器件的接口都有 一定的等效电容,这会造成信号传输的延迟。通常I2C总线 的负载能力为400pF(通过驱动扩展可达4000pF),据此可 计算出总线长度及连接器件的数量。
8.0 I2C总线工作原理
• 典型的I2C总线系统结构,如图28.1所示。其采用 两线制,由数据线SDA和时钟线SCL构成。总线上 挂接的单片机(主器件)或外围器件(从器件), 其接口电路都应具有I2C总线通信能力。
8.1 I2C总线的电气结构和负载能力
• I2C总线的SCL和SDA端口输出为漏极开路,因此使用时上必 须连接上拉电阻。不同型号的器件对上拉电阻的要求不同, 可参考具体器件的数据手册。上拉电阻的大小与电源电压、 传输速率等有关系。
8.3 I2C总线器件的寻址方式
• I2C总线上的所有器件连接在一个公共的总线上,因此,主 器件在进行数据传输前选择需要通信的从器件,即进行总 线寻址。
• I2C总线上所有外围器件都需要有惟一的地址,由器件地址 和引脚地址两部分组成,共7位。器件地址是I2C器件固有的 地址编码,器件出厂时就已经给定,不可更改。引脚地址 是由I2C总线外围器件的地址引脚(A2,A1,A0)决定,根 据其在电路中接电源正极、接地或悬空的不同,形成不同 的地址代码。引脚地址数也决定了同一种器件可接入总线 的最大数目。
• 地址位与一个方向位共同构成I2C总线器件寻址字节。寻址 字节的格式如表所示。方向位(R/)规定了总线上的主器 件与外围器件(从器件)的数据传输送方向。当方向位 R/=1,表示主器件读取从器件中的数据;R/=0,表示主器 件向从器件发送数据。
8.3 I2C总线数据传输协议及其程序详解
• I2C总线规定了严格的数据通信格式,所有具有 I2C总线接口的器件都必须遵守。另外,对于应用 最广的51系列单片机,却没有提供I2C总线接口。 实际上,利用这些单片机的普通I/O口,采用软件 模拟I2C总线SCL和SDA上的数据传送时序,完全可 以实现对I2C总线器件的读、写操作。
• 本章主要介绍了I2C总线的工作原理、结构以及寻址方式, 并重点介绍了数据传输协议以及程序实现。这些程序均以 子程序的形式提供,便于读者调用。最后通过具体的实例, 介绍如何使用单片机读写具有I2C总线接口的E2PROM。
I2C总线概述
• I2C总线对数据通信进行了严格的定义,要进行 I2C总线的接口设计,就需要首先了解I2C总线的 工作原理图、寻址方式和数据传输协议等。
• 如果采用C语言进行程序设计,则其程序示例如下:
• void I_Start()
•{

SDA=HIGH;

I_Delay(100);

SCL=HIGH;

I_Delay(100);

SDA=LOW;

I_Delay(100);

SCL=LOW;

I_Delay(100);
•}
8.3.2 终止信号
• 终止信号用于终止I2C总线通信。在时钟线SCL为高电平期间,数 据线SDA上出现由低电平到高电平变化的上升沿时,被认为是终止 信号。终止信号一出现,所有总线操作都结束,主从器件释放总 线控制权。
• 如果采用C语言进行程序设计,则其程序示例如下:
• void I_Stop()
•{

SDA=LOW;
• 下面就分别介绍数据传输过程中的格式以及如何 使用8051单片机来实现。这里假设51系列单片机 的外接晶振频率为6MHz,单片机的机器周期为2µs, 采用P1.0作为时钟线SCL,P1.1作为数据线SDA。
8.3.1 起始信号
• 起始信号用于开始I2C总线通信。在时钟线SCL为高电平期间,数 据线SDA上出现由高电平向低电平变化的下降沿时,被认为是起始 信号。起始信号出现以后,才可以进行寻址或数据传输等。
实验八 51系列单片机读写I2C总线
• I2C总线是Philips公司推出的一种双向二线制总线,全称为 芯片间总线(Inter Integrate Circuit BUS)。其在芯片 间使用两根连线实现全双工同步数据传送,一条数据线 (SDA)和一条串行时钟线(SCL),可以很方便地构成外 围器件扩展系统。
相关文档
最新文档