78K与MAX11068 IIC通讯C程序
- 格式:docx
- 大小:21.56 KB
- 文档页数:20
ATMEGA16 读写iic(24c02) C 语言程序测试通过nclude <iom16v.h>#i nclude "I2C.h"#in clude "1602.h"#in clude "delay.h"/*通过AVR往I IC写数据,并通过串口把数据读出显示出来*///===============================================================void UAR_i nit(void) //UART 初始化{ DDRD = 0x02;PORTD = 0x00;UCSRA = 0x02; /* 无倍速*/UCSRB = 0x18; /*允许接收和发送*/U(SRC= 0x06; 1*8位数据,1位停止位,无校验*/UBRRH = 0x00;UBRRL = 12; /*9600*/}//===============================================================void USART_TXD(float data) // 发送采用查询方式{while( !(UCSRA & BIT(UDRE)));UDR=data;while( !(UCSRA & BIT(TXC )));UCSRA|=BIT(TXC);}void mai n(void){un sig ned char i;// LCDinit();uart_i ni t();//TART 初始化SEI(); // 全局中断使能while(1){/*I2C_Write('n',0x00); I2C_Write('c',0x01); I2C_Write('e',0x02);I2C_Write('p',0x03); I2C_Write('u',0x04);*/ i=I2C_Read(0x00); //LCD_write_char(0,0,i); USART_TXD(i); i=I2C_Read(0x01);//LCD_write_data(i); USART_TXD(i); i=I2C_Read(0x02); //LCD_write_data(i); USART_TXD(i);i=I2C_Read(0x03); //LCD_write_data(i); USART_TXD(i); i=I2C_Read(0x04); //LCD_write_data(i); USART_TXD(i);}}/* 上面上主函数部分*/#include <macros.h>#include "delay.h"//I2C 状态定义//MT 主方式传输MR 主方式接受#define START 0x08#define RE_START 0x10#define MT_SLA_ACK 0x18 #define MT_SLA_NOACK 0x20 #define MT_DATA_ACK 0x28 #defineMT_DATA_NOACK 0x30 #define MR_SLA_ACK 0x40 #define MR_SLA_NOACK 0x48 #define MR_DATA_ACK 0x50 #define MR_DATA_NOACK 0x58#define RD_DEVICE_ADDR 0xA1 // 前4位器件固定,后三位看连线,最后1位是读写指令位#define WD_DEVICE_ADDR 0xA0//常用TWI操作(主模式写和读)#define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) // 启动I2C #define Stop()(TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) // 停止I2C #define Wait() {while(!(TWCR&(1<<TWINT)));} // 等待中断发生#define TestAck() (TWSR&0xf8) // 观察返回状态#define SetAck (TWCR|=(1<<TWEA)) // 做出ACK应答#define SetNoAck (TWCR&=~(1<<TWEA)) // 做出Not Ack 应答#define Twi() (TWCR=(1<<TWINT)|(1<<TWEN)) // 启动I2C#define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} // 写数据到TWDRunsigned char I2C_Write(unsigned char Wdata,unsigned char RegAddress); unsigned charI2C_Read(unsigned RegAddress);/*********************************************I2C 总线写一个字节返回0: 写成功返回1: 写失败**********************************************/unsigned char I2C_Write(unsigned char Wdata,unsigned char RegAddress){Start(); //I2C 启动Wait();if(TestAck()!=START)return 1; //ACKWrite8Bit(WD_DEVICE_ADDR); // 写I2C 从器件地址和写方式Wait(); if(TestAck()!=MT_SLA_ACK) return 1; //ACKWrite8Bit(RegAddress); // 写器件相应寄存器地址Wait();if(TestAck()!=MT_DATA_ACK)return 1; //ACKWrite8Bit(Wdata); // 写数据到器件相应寄存器Wait();if(TestAck()!=MT_DATA_ACK)return 1; //ACKStop(); //I2C 停止delay_nms(10); // 延时return 0;}/*********************************************I2C 总线读一个字节返回0: 读成功返回1: 读失败**********************************************/unsigned char I2C_Read(unsigned RegAddress){ unsigned char temp;Start();//I2C 启动Wait();if (TestAck()!=START) return 1; //ACKWrite8Bit(WD_DEVICE_ADDR); // 写I2C 从器件地址和写方式Wait(); if (TestAck()!=MT_SLA_ACK) return 1; //ACKWrite8Bit(RegAddress); // 写器件相应寄存器地址Wait();if (TestAck()!=MT_DATA_ACK) return 1;Start(); //I2C 重新启动Wait();if (TestAck()!=RE_START) return 1;Write8Bit(RD_DEVICE_ADDR); // 写I2C 从器件地址和读方式Wait(); if(TestAck()!=MR_SLA_ACK)return 1; //ACKTwi(); // 启动主I2C 读方式Wait(); if(TestAck()!=MR_DATA_NOACK) return 1; //ACKtemp=TWDR;// 读取I2C 接收数据Stop();//l2C 停止return temp;}/*以上是IlC.h头文件部分,需要对照技术文档好好研究*/延时函数编译器:I CC-AVR V6.31A 日期:2005-11-24 20:29:57 目标芯片:M16 时钟:8.0000M Hz作者:arche ng504------------------------------------------------- */#ifndef __delay_h#defi ne __delay_hvoid delay_ nus(un sig ned int n);void delay_ nms(un sig ned int n);void delay_1us(void);void delay_1ms(void);void delay_1us(void) //1us 延时函数{asm( "n op");}void delay_ nus(un sig ned int n) 〃N us 延时函数{un sig ned in t i=0;for (i=0;i <n ;i++)delay_1us();}void delay_1ms(void) //1ms 延时函数{un sig ned in t i;for (i=0;i<1140;i++);}void delay_ nms(un sig ned int n) //N ms 延时函数{un sig ned in t i=0;for (i=0;i <n ;i++)delay_1ms();}#en dif/*以上是delay.h 部分,再加上IIC中自带的iom16v.h和macros.h就可以编译通过*//*注意点:本程序在实验板ATMEGA1上测试通过,在示波器把SCL, SDA信号线有数据,移值到自己电路上可以放心使用,在ATMEGA3上一样使用,本人24C02的A2, A1, A0都是接地,若地址不一样,在程序相应位置改一下就可以,串口上调试单片机的基础,所以它一定要会用*//*本程序调试软件环境是ICC6.31*/。
i2c波形通过电平转换后异常【导言】I2C(Inter-Integrated Circuit)是一种常用的串行通信协议,用于在电子设备之间传输数据。
作为一种主从式通信协议,I2C使用两条线(称为SDA和SCL)实现多个设备通过总线相互通信。
然而,在实际应用中,由于各种原因,如电压不稳定、线缆质量差、接触不良等,i2c波形可能会出现异常。
特别是在电平转换过程中,异常情况更容易发生。
本文将探讨i2c波形通过电平转换后的异常情况,并提供解决方案。
【正文】1. 异常现象及原因通过电平转换将I2C信号从5V转换为3.3V或其他不同的电压级别时,可能会出现以下异常情况:1.1 压摆率减慢由于电平转换电路可能引入额外的电容负载,I2C波形在上升沿和下降沿的压摆率可能会减慢。
这可能导致信号的传输速率降低,甚至使其无法达到预期的速率要求。
1.2 信号失真如果电平转换电路的响应时间不足或电压变化不平稳,可能会导致I2C 信号的失真。
信号失真可能表现为波形的不规则变形,甚至是部分波形丢失。
这种情况会导致通信错误,数据传输的准确性受到损害。
1.3 电源噪声电平转换电路引入的电容和电阻可能会引起电源噪声。
这些噪声可能会干扰I2C信号的传输,导致数据的错误或丢失。
1.4 传输延迟由于电平转换电路的存在,I2C信号的传输可能会有一定的延迟。
这种延迟可能会导致在实时应用中出现问题,如数据同步不匹配或信号超时。
2. 解决方案要解决通过电平转换后的I2C波形异常问题,可以采取以下措施:2.1 选择合适的电平转换器根据实际应用需求,选择性能良好的电平转换器。
电平转换器应具备快速响应、低电压降和低功耗的特点,以确保信号的准确转换和传输。
2.2 优化线路设计优化I2C线路布局和连接方式,尽量减少电流回路长度,避免浪费功耗和信号损耗。
使用优质的线缆和连接器,保证信号的可靠传输。
2.3 添加滤波电路在电平转换器的输入和输出端添加恰当的滤波电路,以抑制电源噪声和信号干扰。
I2C读写流程范文I2C(Inter-Integrated Circuit)是一种串行通信协议,用于在集成电路之间进行短距离的通信。
这个协议由飞利浦公司(现在的恩智浦半导体)在20世纪80年代初引入。
I2C由两根线构成,分别是时钟线(SCL)和数据线(SDA),其中时钟线由主设备控制发送,数据线用于主设备和从设备之间的双向数据传输。
I2C协议支持多主设备和多从设备的并行连接。
1.初始化:a.设置I2C总线的时钟频率。
b.初始化GPIO端口,将SCL和SDA设置为输出模式,并将它们拉高。
2.发送设备地址:a.主设备发送起始信号,即在SCL线上拉低SDA线,表示数据的传输即将开始。
b.主设备发送设备地址和读写位(0表示写,1表示读)到SDA线。
设备地址是从设备的标识符,主设备用它来选择要通信的从设备。
c.主设备发送读写位确认信号,即主设备将SCL线拉低一段时间,然后释放,之后从设备根据读写位作出响应。
3.发送数据:a.主设备将要发送的数据写入到SDA线上。
b.主设备发送数据确认信号,即主设备将SCL线拉低一段时间,然后释放。
c.从设备接收数据,并根据接收情况作出响应。
4.接收数据:a.主设备发出重新起始信号,即在SCL线上拉低SDA线,然后释放。
b.主设备发送设备地址和读写位到SDA线,指示要读取数据的从设备。
c.主设备发送读写位确认信号,即主设备将SCL线拉低一段时间,然后释放。
d.从设备将要发送的数据写入到SDA线上。
e.主设备接收数据,并根据接收情况作出响应。
5.终止通信:a.主设备发出停止信号,即在SCL线上拉低SDA线,然后释放。
b.从设备根据停止信号作出响应。
以上就是I2C读写的基本流程。
需要注意的是,I2C是一种同步通信协议,所有的数据传输都是通过时钟线同步的。
主设备控制时钟信号的频率,从设备负责根据时钟信号的变化作出响应。
通过这种方式,可以实现多个设备在同一总线上进行通信。
I2C总线编程实例(k1-k4:写⼊、读取、加+、清零)【EEPROM-AT24C02】(1)AT24C02是⼀种EEPROM元器件,是⼀种只读寄存器,断电保持,可保存数据100年, 是⼀种可擦除读写的芯⽚,相当于ROM硬盘,在下⾯实验中充当从机⾓⾊;(2)51在下⾯实验中充当主机⾓⾊;(3)在IIC总线标准协议上,进⾏51单⽚机(主机)和AT24C02(从机)的相互读写数据的操作。
⼩结:51单⽚机和各种EEPROM芯⽚之间可以通过IIC总线标准协议进⾏数据交互(通信)的。
实验:四个独⽴按键对应四个不同的功能,k1:将数据写⼊单⽚机,断电保存k2:读取上次保存的数据,断电后仍可读取上次保存的数据k3:当前数据+1k4:当前数据清零------------------------------------------------------------- 采⽤多⽂件的框架模式 -------------------------------------------------------------i2c.h:/*这个⽂件进⾏宏定义:定义I2C串⾏总线的相关数据端⼝、⽅法函数,以及定义⼀些使⽤频率较⾼的元素*/#ifndef _I2C_H_ // 如果没有定义宏#define _I2C_H_ // 定义⼀个宏// 需要⽤到51单⽚机的管脚,所以需要引⼊库⽂件#include <reg52.h>// 查单⽚机原理图可知(其中,SCL是时钟线,SDA是数据线)sbit SCL=P2^1;sbit SDA=P2^0;/* 相关函数 */// I2C的起始信号函数void I2cStart();// I2C的终⽌信号函数void I2cStop();// I2C发送(写⼊)字节函数,成功返回1,失败返回0unsigned char I2cSendByte(unsigned char dat);// I2C接收(读取)字节函数,返回读取的数据unsigned char I2cReadByte();// AT24C02芯⽚的写⼊数据函数void At24c02Write(unsigned char addr, unsigned dat);// AT24C02芯⽚的读取数据函数,返回读取的数据unsigned char At24c02Read(unsigned char addr);#endif // 结束i2c.c:/* 这个⽂件专门针对I2C模块的编程,其他模块可以新建另外⼀个⽂件 */#include <i2c.h> // 引⼊I2C的库⽂件/******************************************************************************** 函数名 : Delay10us()* 函数功能 : 延时10us* 输⼊ : ⽆* 输出 : ⽆*******************************************************************************/void Delay10us() //误差 0usunsigned char a,b;for(b=1;b>0;b--)for(a=2;a>0;a--);}/******************************************************************************** 函数名 : I2cStart()* 函数功能 : 起始信号:在SCL时钟信号在⾼电平期间SDA信号产⽣⼀个下降沿* 输⼊ : ⽆* 输出 : ⽆* 备注 : 起始之后SDA和SCL都为0,表⽰总线被主机占⽤*******************************************************************************/void I2cStart(){// 根据各个单⽚机的时序图来写SDA=1;Delay10us();SCL=1;Delay10us(); // 建⽴时间是SDA保持时间>4.7usSDA=0;Delay10us(); // 保持时间是>4usSCL=0;Delay10us();}/******************************************************************************** 函数名 : I2cStop()* 函数功能 : 终⽌信号:在SCL时钟信号⾼电平期间SDA信号产⽣⼀个上升沿* 输⼊ : ⽆* 输出 : ⽆* 备注 : 结束之后保持SDA和SCL都为1;表⽰总线处于空闲状态*******************************************************************************/void I2cStop(){// 根据各个单⽚机的时序图来写SDA=0;Delay10us();SCL=1;Delay10us(); // 建⽴时间是SDA保持时间>4.7usSDA=1;Delay10us(); // 保持时间是>4us}/******************************************************************************** 函数名 : I2cSendByte(unsigned char dat)* 函数功能 : 通过I2C发送⼀个字节。
iic调试方法IIC调试方法IIC(Inter-Integrated Circuit)是一种常用的串行通信协议,用于在电路板之间传输数据。
在进行IIC调试时,我们需要遵循一定的方法和步骤来确保通信的稳定和可靠性。
本文将介绍一些常用的IIC 调试方法,并对其原理和步骤进行详细说明。
一、IIC调试的基本原理IIC是一种基于硬件的串行通信协议,它由两根信号线组成:SDA (Serial Data Line)和SCL(Serial Clock Line)。
在IIC通信中,数据是通过SDA线传输的,而时钟信号则由SCL线提供。
调试过程中,我们需要确保这两根信号线的稳定性和正确性,以保证数据的准确传输。
二、IIC调试步骤1. 确认硬件连接:首先,我们需要确认IIC设备的硬件连接是否正确。
检查SDA和SCL线是否正确连接到目标设备的对应引脚,并确保电源和地线的连接正常。
2. 配置IIC设备地址:每个IIC设备都有一个唯一的地址,用于在总线上进行识别和通信。
在调试过程中,我们需要正确配置目标设备的地址。
通常可以通过读取设备的说明书或寄存器设置来获取正确的地址信息。
3. 设置IIC通信速率:IIC通信速率也称为波特率,决定了数据传输的速度。
根据目标设备的规格要求,我们需要设置适当的通信速率。
通常情况下,较低的通信速率可以提高通信的可靠性。
4. 编写测试代码:根据目标设备的功能和通信协议,我们需要编写相应的测试代码。
测试代码应包括初始化IIC设备、发送和接收数据等操作。
在编写代码时,我们可以使用现成的IIC库或驱动程序,以简化开发过程。
5. 运行调试代码:将编写好的测试代码烧录到目标设备上,并运行调试代码。
通过监测SDA和SCL线上的信号波形,我们可以判断通信是否正常。
如果出现通信错误或数据传输异常,我们可以通过调试工具或逐步调试的方法,逐个排查问题,找出并解决故障。
6. 数据验证和分析:在通信正常的情况下,我们可以通过发送特定的测试数据来验证目标设备的功能是否正常。
EEPROMI2C操作说明EEPROM (Electrically Erasable Programmable Read-Only Memory)是一种非易失性存储器,可以通过电子方式擦除和编程,同时可以通过I2C总线进行操作。
本文将详细介绍EEPROM的I2C操作说明。
I2C(Inter-Integrated Circuit)是一种串行通信接口协议,可以在多个设备之间进行通信。
在EEPROM的I2C操作中,需要了解以下几个重要的概念和步骤。
1.设备地址:每个通过I2C连接的设备都有一个唯一的设备地址。
在EEPROM的I2C操作中,需要使用设备地址来与EEPROM进行通信。
2.起始条件和停止条件:I2C通信中,起始条件表示通信的开始,停止条件表示通信的结束。
起始条件由一个高电平到低电平的SCL上升沿和一个低电平的SDA下降沿组成,停止条件由一个低电平到高电平的SCL上升沿和一个高电平的SDA上升沿组成。
3. 数据传输:I2C通信中,数据可以以字节的形式进行传输。
每个字节由8个bit组成,包括7个数据位和1个校验位。
在进行EEPROM的I2C操作时,通常需要经过以下几个步骤:1.发送起始条件:将SCL和SDA引脚拉高,然后将SDA引脚拉低,形成起始条件。
2.发送设备地址和写命令:根据EEPROM的设备地址,将设备地址和写命令(0)发送到SDA引脚。
3.发送要写入的地址:将要写入数据的地址发送到SDA引脚。
4.发送数据:将要写入的数据发送到SDA引脚。
5.发送停止条件:将SCL引脚拉高,然后将SDA引脚拉高,形成停止条件。
实际的EEPROM的I2C操作可能还包括以下一些操作:1.读操作:通过发送读命令(1)和读取数据的地址,可以从EEPROM 中读取数据。
读操作与写操作类似,只是需要在发送设备地址时,将写命令(0)改为读命令(1)。
2.擦除操作:EEPROM的主要特点之一是可以擦除数据。
通过发送擦除命令和要擦除的数据的地址,可以将指定数据段擦除为初始值。
To our customers,Old Company Name in Catalogs and Other DocumentsOn April 1st, 2010, NEC Electronics Corporation merged with Renesas Technology Corporation, and Renesas Electronics Corporation took over all the business of both companies. Therefore, although the old company name remains in this document, it is a valid Renesas Electronics document. We appreciate your understanding.Renesas Electronics website: April 1st, 2010Renesas Electronics CorporationIssued by: Renesas Electronics Corporation ()Send any inquiries to /inquiry.Notice1. All information included in this document is current as of the date this document is issued. Such information, however, issubject to change without any prior notice. Before purchasing or using any Renesas Electronics products listed herein, please confirm the latest product information with a Renesas Electronics sales office. Also, please pay regular and careful attention to additional and different information to be disclosed by Renesas Electronics such as that disclosed through our website.2. Renesas Electronics does not assume any liability for infringement of patents, copyrights, or other intellectual property rightsof third parties by or arising from the use of Renesas Electronics products or technical information described in this document.No license, express, implied or otherwise, is granted hereby under any patents, copyrights or other intellectual property rights of Renesas Electronics or others.3. You should not alter, modify, copy, or otherwise misappropriate any Renesas Electronics product, whether in whole or in part.4. Descriptions of circuits, software and other related information in this document are provided only to illustrate the operation ofsemiconductor products and application examples. You are fully responsible for the incorporation of these circuits, software, and information in the design of your equipment. Renesas Electronics assumes no responsibility for any losses incurred by you or third parties arising from the use of these circuits, software, or information.5. When exporting the products or technology described in this document, you should comply with the applicable export controllaws and regulations and follow the procedures required by such laws and regulations. You should not use RenesasElectronics products or the technology described in this document for any purpose relating to military applications or use by the military, including but not limited to the development of weapons of mass destruction. Renesas Electronics products and technology may not be used for or incorporated into any products or systems whose manufacture, use, or sale is prohibited under any applicable domestic or foreign laws or regulations.6. Renesas Electronics has used reasonable care in preparing the information included in this document, but Renesas Electronicsdoes not warrant that such information is error free. Renesas Electronics assumes no liability whatsoever for any damages incurred by you resulting from errors in or omissions from the information included herein.7. Renesas Electronics products are classified according to the following three quality grades: “Standard”, “High Quality”, and“Specific”. The recommended applications for each Renesas Electronics product depends on the product’s quality grade, as indicated below. You must check the quality grade of each Renesas Electronics product before using it in a particularapplication. You may not use any Renesas Electronics product for any application categorized as “Specific” without the prior written consent of Renesas Electronics. Further, you may not use any Renesas Electronics product for any application for which it is not intended without the prior written consent of Renesas Electronics. Renesas Electronics shall not be in any way liable for any damages or losses incurred by you or third parties arising from the use of any Renesas Electronics product for an application categorized as “Specific” or for which the product is not intended where you have failed to obtain the prior written consent of Renesas Electronics. The quality grade of each Renesas Electronics product is “Standard” unless otherwiseexpressly specified in a Renesas Electronics data sheets or data books, etc.“Standard”: Computers; office equipment; communications equipment; test and measurement equipment; audio and visual equipment; home electronic appliances; machine tools; personal electronic equipment; and industrial robots.“High Quality”: Transportation equipment (automobiles, trains, ships, etc.); traffic control systems; anti-disaster systems; anti-crime systems; safety equipment; and medical equipment not specifically designed for life support.“Specific”: Aircraft; aerospace equipment; submersible repeaters; nuclear reactor control systems; medical equipment or systems for life support (e.g. artificial life support devices or systems), surgical implantations, or healthcareintervention (e.g. excision, etc.), and any other applications or purposes that pose a direct threat to human life.8. You should use the Renesas Electronics products described in this document within the range specified by Renesas Electronics,especially with respect to the maximum rating, operating supply voltage range, movement power voltage range, heat radiation characteristics, installation and other product characteristics. Renesas Electronics shall have no liability for malfunctions or damages arising out of the use of Renesas Electronics products beyond such specified ranges.9. Although Renesas Electronics endeavors to improve the quality and reliability of its products, semiconductor products havespecific characteristics such as the occurrence of failure at a certain rate and malfunctions under certain use conditions. Further, Renesas Electronics products are not subject to radiation resistance design. Please be sure to implement safety measures to guard them against the possibility of physical injury, and injury or damage caused by fire in the event of the failure of aRenesas Electronics product, such as safety design for hardware and software including but not limited to redundancy, fire control and malfunction prevention, appropriate treatment for aging degradation or any other appropriate measures. Because the evaluation of microcomputer software alone is very difficult, please evaluate the safety of the final products or system manufactured by you.10. Please contact a Renesas Electronics sales office for details as to environmental matters such as the environmentalcompatibility of each Renesas Electronics product. Please use Renesas Electronics products in compliance with all applicable laws and regulations that regulate the inclusion or use of controlled substances, including without limitation, the EU RoHS Directive. Renesas Electronics assumes no liability for damages or losses occurring as a result of your noncompliance with applicable laws and regulations.11. This document may not be reproduced or duplicated, in any form, in whole or in part, without prior written consent of RenesasElectronics.12. Please contact a Renesas Electronics sales office if you have any questions regarding the information contained in thisdocument or Renesas Electronics products, or if you have any other inquiries.(Note 1) “Renesas Electronics” as used in this document means Renesas Electronics Corporation and also includes its majority-owned subsidiaries.(Note 2) “Renesas Electronics product(s)” means any product developed or manufactured by or for Renesas Electronics.用户手册适用于78K/0系列78K/0系列指令©NEC Electronics China 2007日本印制文档编号.U12326CA4V0UM00(第四版)发行日期2007年7月NCP(K)[备忘录]用户手册U12326CA4V0UM 2CMOS设备的注释①ESD防护措施如果MOS设备周围有强电场,将会击穿氧化栅极,从而影响设备的运行。
SCL BIT P1.0SDA BIT P1.1;----------------------------ORG 0RESET:SETB SCLSETB SDACALL I2C_WAITSTART ;等待起始信号CALL I2C_RXBYTE ;接收地址数据CLR CCALL I2C_TXACK ;回应ACKSETB C ;读/写 IDATA[80H - FFH] RRC A ;读/写位->CMOV R0,A ;地址送入R0JC READDATA ;C=1(读) C=0(写) WRITEDATA:CALL I2C_RXBYTE ;接收数据MOV @R0,A ;写入IDATAINC R0 ;地址+1CLR CCALL I2C_TXACK ;回应ACKCALL I2C_WAITSTOP ;等待停止信号JMP RESETREADDATA:MOV A,@R0INC R0CALL I2C_TXBYTE ;发送IDATA数据CALL I2C_RXACK ;接收ACKCALL I2C_WAITSTOP ;等待停止信号JMP RESET;----------------------------;等待起始信号;----------------------------I2C_WAITSTART:JNB SCL,$ ;等待时钟->高JB SDA,$ ;等待数据线下降沿JB SCL,$ ;等待时钟->低RET;----------------------------;等待结束信号;----------------------------I2C_WAITSTOP:JNB SCL,$ ;等待时钟->高JNB SDA,$ ;等待数据线上升沿RET;----------------------------;发送ACK/NAK信号;----------------------------第 1 页I2C_TXACK:MOV SDA,C ;送ACK数据JNB SCL,$ ;等待时钟->高JB SCL,$ ;等待时钟->低SETB SDA ;发送完成RET;----------------------------;接收ACK/NAK信号;----------------------------I2C_RXACK:SETB SDA ;准备读数据JNB SCL,$ ;等待时钟->高MOV C,SDA ;读取ACK信号JB SCL,$ ;等待时钟->低RET;----------------------------;接收一字节数据;----------------------------I2C_RXBYTE:MOV R7,#8 ;8位计数RXNEXT:JNB SCL,$ ;等待时钟->高MOV C,SDA ;读取数据口RLC A ;保存数据JB SCL,$ ;等待时钟->低DJNZ R7,RXNEXT ;收下一位RET;----------------------------;发送一字节数据;----------------------------I2C_TXBYTE:MOV R7,#8 ;8位计数TXNEXT:RLC A ;移出数据位MOV SDA,C ;数据送数据口JNB SCL,$ ;等待时钟->高JB SCL,$ ;等待时钟->低DJNZ R7,TXNEXT ;送下一位RET;----------------------------END第 2 页。
基于IIC总线控制ATMLH012芯片的读写操作ATMLH012芯片是一种IIC总线控制的非易失性存储器芯片,具备读写功能。
我们可以用IIC总线来控制它进行数据的读取和写入操作。
本篇文章将详细介绍基于IIC总线控制ATMLH012芯片的读写操作。
首先,我们需要了解一下IIC总线的基本原理。
IIC(Inter-Integrated Circuit)总线是一种串行通信协议,由两条线组成:SDA (串行数据线)和SCL(串行时钟线)。
在IIC总线中,每个设备都有一个唯一的地址,通过地址来与设备进行通信。
对于ATMLH012芯片,我们需要知道它的IIC地址。
通常,IIC设备的地址由7个比特位组成,其中最高位是固定的0或1,其余6位可由用户选择。
可以在芯片的数据手册中找到ATMLH012芯片的IIC地址。
一旦我们知道了芯片的IIC地址,就可以通过IIC总线来控制ATMLH012芯片进行读取和写入操作。
下面我们来介绍具体的步骤。
读取数据操作:1.启动IIC总线。
2.发送ATMLH012芯片的IIC地址和读取请求。
3.等待芯片的响应。
4.读取芯片返回的数据。
5.结束IIC总线。
写入数据操作:1.启动IIC总线。
2.发送ATMLH012芯片的IIC地址和写入请求。
3.发送要写入的数据。
4.结束IIC总线。
实际操作中,我们可以使用单片机或者其他IIC总线的主设备来控制ATMLH012芯片,以下是一个基于单片机的ATMLH012芯片读写操作的伪代码示例:```c#include <reg52.h>#define ADDR 0x50 // ATMLH012芯片的IIC地址void IIC_Star//启动IIC总线void IIC_Sto//结束IIC总线void IIC_SendByte(unsigned char dat)//发送一个字节的数据unsigned char IIC_ReceiveByt//接收一个字节的数据void ATMLH012_Write(unsigned char addr, unsigned char dat) IIC_Start(;IIC_SendByte(ADDR);IIC_SendByte(addr);IIC_SendByte(dat);IIC_Stop(;unsigned char ATMLH012_Read(unsigned char addr) unsigned char dat;IIC_Start(;IIC_SendByte(ADDR);IIC_SendByte(addr);IIC_Start(;IIC_SendByte(ADDR + 1);dat = IIC_ReceiveByte(;IIC_Stop(;return dat;void maiunsigned char data;//读取ATMLH012芯片的数据data = ATMLH012_Read(0x00);//将数据写入ATMLH012芯片ATMLH012_Write(0x00, data + 1);while (1)//无限循环}```以上是一个基于单片机的ATMLH012芯片读写操作的简单示例。
如何用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。
STM32 系统学习——I2C (读写EEPROM)
I2C 通讯协议(Inter-Integrated Circuit)引脚少,硬件实现简单,可扩展性强,不需要USART、CAN 等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路(IC)间的通讯。
在计算机科学里,大部分复杂的问题都可以通过分层来简化。
如芯片被分为
内核层和片上外设;STM32 标准库则是在寄存器与用户代码之间的软件层。
对于通讯协议,我们也以分层的方式来理解,最基本的是把它分为物理层和协
议层。
物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物
理媒体的传输。
协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。
简单来说物理层规定我们用嘴巴还是用肢体来交流,
协议层则规定我们用中文还是英文来交流。
一、I2C 物理层
它的物理层有如下特点:
(1) 它是一个支持设备的总线。
“总线”指多个设备共用的信号线。
在一个I2C 通讯总线中,可连接多个I2C 通讯设备,支持多个通讯主机及多个通讯从机。
(2) 一个I2C 总线只使用两条总线线路,一条双向串行数据线(SDA) ,一条串行时钟线(SCL)。
数据线即用来表示数据,时钟线用于数据收发同步。
(3) 每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问。
(4) 总线通过上拉电阻接到电源。
当I2C 设备空闲时,会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。
iic读写程序例程我们需要了解IIC总线的基本原理。
IIC总线由两根线组成,分别是时钟线(SCL)和数据线(SDA)。
SCL线由主设备控制,用于产生时钟信号,而SDA线用于数据的传输。
在IIC总线上,每个设备都具有一个唯一的地址,通过地址可以进行设备的选择和寻址。
数据的传输是通过主设备发送起始信号和停止信号来实现的。
在编写IIC读写程序之前,我们需要明确需要读写的设备的地址和寄存器的地址。
设备的地址是设备的唯一标识,寄存器的地址是设备内部的某个存储单元的地址。
通过寄存器地址,我们可以对设备进行相应的配置和控制。
接下来,我们开始编写IIC读写程序。
首先,我们需要初始化IIC总线,并设置主设备的地址。
初始化包括配置时钟频率、使能IIC总线等操作。
然后,我们可以通过写操作向设备发送相应的配置命令,例如设置传感器的工作模式、配置存储器的读写参数等。
写操作需要指定设备地址和寄存器地址,以及需要写入的数据。
接下来,我们可以进行读操作,从设备中读取相应的数据。
读操作同样需要指定设备地址和寄存器地址。
通过读操作,我们可以获取传感器的测量数据、读取存储器中的数据等。
读取到的数据可以进行进一步的处理和分析,例如显示在屏幕上、保存到文件中等。
在编写IIC读写程序时,我们需要注意以下几点。
首先,要保证程序的正确性和稳定性,可以通过添加错误处理机制和异常处理机制来增强程序的健壮性。
其次,要注意处理设备的响应和超时情况,避免程序陷入死循环或无响应的状态。
此外,要充分利用设备提供的文档和示例代码,以便更好地理解和使用设备。
IIC读写程序是嵌入式系统中常见的一种程序,通过使用IIC总线,我们可以方便地实现设备之间的数据传输和通信。
在编写IIC读写程序时,我们需要了解IIC总线的基本原理,并根据设备的地址和寄存器的地址进行相应的配置和操作。
通过合理设计和编写,可以实现稳定、高效的IIC读写程序,为嵌入式系统的开发和应用提供强大的支持。
iic的通信原理小伙伴,今天咱们来唠唠IIC通信原理呀。
这IIC呀,就像是两个小机灵鬼之间的独特对话方式呢。
IIC呢,它是一种串行通信协议。
你可以把它想象成两个人在传小纸条。
不过这小纸条上的信息可有讲究啦。
IIC总线上就两根线,一根叫SDA,一根叫SCL。
这SDA 就像是专门用来写消息内容的线,而SCL呢,就像是一个小指挥棒,指挥着什么时候开始传消息,什么时候传完了。
在这个小世界里呀,有主设备和从设备之分呢。
主设备就像是小团体里的小队长,可威风啦。
它能发起通信,告诉从设备:“小老弟,我要和你说话啦。
”从设备呢,就乖乖地等着主设备的召唤。
比如说,主设备就像一个爱发号施令的小班长,从设备就是听话的小同学。
那它们是怎么在这两根线上传递信息的呢?这就有趣啦。
SCL线会有规律地高低电平变化,就像小鼓在打节拍一样。
当SCL处于高电平的时候,SDA线上的数据就像是在舞台上表演的小演员,必须稳稳当当的,不能随便变来变去。
只有当SCL是低电平的时候,SDA才可以改变状态,就像演员在后台准备下一场表演一样。
再说说数据传输的格式呀。
就像是我们写信有一定的格式一样。
每次传输都是8位的数据,就像8个小士兵排成一队。
而且呢,在这8位数据前面还有一个起始位,就像是信件开头的“亲爱的”一样,告诉对方:“我要开始传消息喽。
”在8位数据后面呢,还有一个停止位,就像是信的结尾“此致,敬礼”,表示消息传完啦。
这里面还有个很有意思的东西叫应答信号呢。
主设备传完一个字节的数据后,就会等着从设备给个回应。
从设备如果说“嗯,我收到啦”,就会在SDA线上给出一个特定的电平信号,这就像是在点头一样。
要是没回应呢,那就可能是出问题啦,就像你和小伙伴说话,小伙伴却没反应,那肯定是哪里不对劲喽。
IIC还有个很贴心的地方呢,就是它可以在一条总线上连接多个设备。
这就像住在公寓里,大家共用一些设施一样。
不过每个设备都有自己的地址,就像每个住户都有自己的门牌号。
iic读写icm42670例程摘要:1.IIC 介绍2.ICM42670 传感器简介3.IIC 读写ICM42670 例程的实现a.硬件连接b.软件设计c.数据读取与写入d.结果分析正文:IIC,全称Inter-Integrated Circuit,是一种串行通信总线,常用于连接微处理器和外围设备。
它具有双总线结构,由两条信号线组成:SDA(串行数据线)和SCL(串行时钟线)。
IIC 通信速率最高可达400kbps,广泛应用于各种电子设备中。
ICM42670 是一款六轴惯性测量单元(IMU),包括三轴加速度传感器和三轴陀螺仪。
它具有低功耗、高精度、小尺寸等特点,适用于各种消费电子、工业控制等领域。
ICM42670 支持I2C 接口,可以通过IIC 总线与微处理器进行通信。
本文将详细介绍如何实现IIC 读写ICM42670 例程。
1.硬件连接首先,需要将ICM42670 与微处理器(如Arduino 或STM32)通过I2C 接口连接。
通常,ICM42670 的SDA 接到微处理器的SDA,SCL 接到微处理器的SCL。
此外,还需要为ICM42670 提供适当的电源(如3.3V 或5V)以及相应的复位信号。
2.软件设计为了实现IIC 读写ICM42670,需要编写相应的程序。
以下是Arduino 的示例代码:```c#include <Wire.h>#define ICM42670_ADDRESS 0x68void setup() {Wire.begin();Wire.setClock(100000); // I2C clock speed in Hz}void loop() {// Write data to ICM42670Wire.write(ICM42670_ADDRESS, 0x00, 1); // Write a single byte// Read data from ICM42670int16_t ax, ay, az;Wire.requestFrom(ICM42670_ADDRESS, 6); // Read 6 bytes (3 axes)ax = Wire.read() << 8 | Wire.read();ay = Wire.read() << 8 | Wire.read();az = Wire.read() << 8 | Wire.read();// Process the dataSerial.print("Accelerometer: X = ");Serial.print(ax);Serial.print(", Y = ");Serial.print(ay);Serial.print(", Z = ");Serial.print(az);Serial.println();delay(1000);}```3.数据读取与写入在上述代码中,首先通过`Wire.begin()`初始化I2C 总线。
I2C总线入门1)最近学习51单片机,学到A/D,D/A转换的时候发现我板子上的转换芯片不是书上所讲的ADC0804和DAC0832而是PCF8591T,看了一下它的数据手册,发现它并不是书上所说的并行传输数据,是使用 I2C 总线传输的。
搞了两天才搞懂,写出来给大家分享一下,不足之处请务必不吝指出。
以上是I2C总线的简单介绍。
就比如说AT24C02存储芯片,和PCF8591数模模数转换芯片都支持I2C端口。
(如下图)2)接下来看如何使用I2C总线进行通信以上是I2C总线通信的格式。
由上图可以看出进行通信需要以下几个步骤a.初始化I2C总线就是把SDA和SCL都变成高电平。
void init()//初始化{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.发送地址字(芯片的硬件地址)(8591的数据手册)前四位对同一种芯片来说是固定的,不同的芯片之间不同。
就像pcf8591是1001而at24c02是1010接下来三位A0,A1,A2是可编程的三个地址位,这里说说的编程并不是通过软件编程,而是把A0,A1,A2三个引脚接不同的电压来确定数值。
接VCC表示1,接GND表示0。
为什么要有这三个呢?因为有可能你在I2C总线上“并联”了不止一个相同的元件(比如说接了三个8591),那你如何来分辨你要操作的是哪一个芯片呢,就是通过设置A0,A1,A2的数值,来区别。
可编程的地址一个有三位,也就是说最多可以接8个相同的芯片在同一个I2C总线上。
最后一位是读/写位,1为读,0为写。
@如何写数据写数据只需要按照时序图1.先将SCL置0(只有它为0的时候SDA才允许变化)2.改变SDA是数值(就是你当前要穿的一位是0还是1)3.把SCL置1(此时芯片就会读取总线上的数据)下面是代码#define uchar unsigned char#define uint unsigned intvoid write_byte(uchar date)//写一字节数据{uchar i,temp;temp=date;for(i=0;i<8;i++){temp=temp<<1;//左移一位移出的一位在CY中SCL=0;//只有在scl=0时sda能变化值delay();SDA=CY;delay();SCL=1;delay();}SCL=0;delay();SDA=1;delay();}发送地址的时候只需把地址传给该函数即可。
IIC通信流程介绍IIC(Inter-Integrated Circuit)是一种串行通信协议,常用于连接微控制器、传感器和其他外设。
本文将详细介绍IIC通信的流程及其相关细节。
IIC通信基础IIC通信由两根线构成,分别是数据线(SDA)和时钟线(SCL)。
其中,SDA线用于传输数据,而SCL线则用于同步数据传输的时钟信号。
IIC通信流程IIC通信流程包括初始化、起始信号、地址传输、数据传输和停止信号等几个关键步骤。
下面将详细介绍每个步骤的具体内容。
初始化在进行IIC通信之前,需要对IIC总线进行初始化设置。
这包括设置SDA和SCL线的电平状态以及设置通信速率等参数。
起始信号IIC通信的起始信号由主设备(通常是微控制器)发送。
起始信号由一个高电平到低电平的跳变表示。
在发送起始信号之前,主设备需要检查总线是否空闲,以确保其他设备没有正在进行通信。
地址传输起始信号之后,主设备发送目标设备的地址信息。
地址信息包括设备地址和读/写位。
设备地址用于唯一标识目标设备,而读/写位用于指示主设备是要读取数据还是写入数据。
数据传输地址传输完成后,主设备和目标设备之间可以进行数据传输。
数据传输可以是单字节的,也可以是多字节的。
在每个字节传输之后,接收设备会发送一个应答信号来确认数据的接收情况。
停止信号数据传输完成后,主设备发送停止信号来结束通信。
停止信号由一个低电平到高电平的跳变表示。
发送停止信号后,总线将回到空闲状态,其他设备可以开始进行通信。
IIC通信的应用IIC通信广泛应用于各种领域,包括物联网、工业自动化、消费电子等。
以下是一些常见的应用场景:传感器接口许多传感器使用IIC通信与微控制器或其他主设备进行连接。
通过使用IIC通信,传感器可以将采集到的数据传输给主设备,实现实时监测和控制。
存储器接口一些存储器芯片(如EEPROM)也采用IIC通信协议。
通过使用IIC通信,微控制器可以读取和写入存储器中的数据,实现数据的存储和检索。
任务二: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 charvoid 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--);}附录二(任务三程序)__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, 0x00, 0x00, 0x00 },// sp{ 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, 0x07, 0x08, 0x70, 0x08, 0x07 },// Y{ 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) //当键盘松开时。
78K与MAX11068 IIC通讯C程序#include "MAX11068_CMD.h"/***-----------------------------------------------------------------------------**** Abstract:** This function stops the IIC11 operation.**** Parameters:** None**** Returns:** None****-----------------------------------------------------------------------------*/void IIC11_Stop(void){/* Stop transfer */ST1 |= _0002_SAU_CH1_STOP_TRG_ON; /* disable IIC11 */IICMK11 = 1U; /* disable INTIIC11 */}/***-----------------------------------------------------------------------------**** Abstract:** This function starts IIC11 condition.**** Parameters:** None**** Returns:** None****-----------------------------------------------------------------------------*/void IIC11_StartCondition(void){SO1 &= ~_0002_SAU_CH1_DATA_OUTPUT_1; /* clear IIC11 SDA */ NOP();NOP();SOE1 |= _0002_SAU_CH1_OUTPUT_ENABLE; /* enable IIC11 out */ SO1 &= ~_0200_SAU_CH1_CLOCK_OUTPUT_1; /* clear IIC11 SCL */ NOP();SS1 |= _0002_SAU_CH1_START_TRG_ON; /* enable IIC11 */}/***-----------------------------------------------------------------------------**** Abstract:** This function stops IIC11 condition.**** Parameters:** None**** Returns:** None****-----------------------------------------------------------------------------*/void IIC11_StopCondition(void){ST1 |= _0002_SAU_CH1_STOP_TRG_ON; /* disable IIC11 */SOE1 &= ~_0002_SAU_CH1_OUTPUT_ENABLE; /* disable IIC11 out */ NOP();SO1 &= ~_0002_SAU_CH1_DATA_OUTPUT_1; /* clear IIC11 SDA */ NOP();NOP();NOP();SO1 |= _0200_SAU_CH1_CLOCK_OUTPUT_1; /* set IIC11 SCL */NOP();NOP();NOP();SO1 |= _0002_SAU_CH1_DATA_OUTPUT_1; /* set IIC11 SDA */}UCHAR HELLOALL(void) /*set slave device address*/{UCHAR addr;UCHAR error_cnt = 0;addr = Address_HELLOALL & 0xFEU;/*** Change Communication mode to Tx*/Change_IIC_Communication_Mode(Transmission);retry:/**step 1. check IIC bus busy or free*///IIC11_StopCondition();/**step 2. send start signal*/IIC11_StartCondition();/**step 3. send data*/SDR11L = addr;/*** wait data transmite over!*/if(!Check_Interrupt_Status()){return 0;}/**step 4. check slave device ack*/if( !Check_ACK() ){//ACK_ERROR();//return 0;error_cnt ++;if(error_cnt > 10){return 0;}goto retry;}/**step 5. send stop signal*/IIC11_StopCondition();return 1;/************ END ***********/}UCHAR ROLLCALL(UCHAR *data_buff, UCHAR data_len) /*get slave device address and count slave device number*/{UINT i;UCHAR addr;addr = Address_Broadcast_W;/*** Change Communication mode to Tx*/Change_IIC_Communication_Mode(Transmission);/*** step 1. Check IIC busy or free*///IIC11_StopCondition();/*** step 2. Send start signal*/IIC11_StartCondition();/*** step 3. Send data (broadcast address)*/SDR11L = addr;/*** wait data transmite over!*/if(!Check_Interrupt_Status()){return 0;}/*** step 4. Check salve device ACK*/if(!Check_ACK()){//ACK_ERROR();return 0;}/*** step 5. Send data (slave device register address) */SDR11L = _01_MAX11068_ADDRESS_REGISTER;/*** wait data transmite over!*/if(!Check_Interrupt_Status()){return 0;}/*** step 6. Check slave device ACK*/if(!Check_ACK()){//ACK_ERROR();return 0;}/*** step 7. Send ReStart*/RESTART();/*** step 8. set new broadcast address and send data */addr = Address_Broadcast_R;SDR11L = addr;/*** wait data transmite over!*/if(!Check_Interrupt_Status()){return 0;}/*** step 9. Check slave device ACK*/if(!Check_ACK()){//ACK_ERROR();return 0;}/*** step 10. Change SCR to recieve mode*/Change_IIC_Communication_Mode(Reception);/*** step 11. Receive data from slave device*/i = 0;while(i < data_len){/*Writing dummy data to SDR 0xFF*/SDR11L = 0xff;/* Transfer end interrupt generated? */if(!Check_Interrupt_Status()) //when data is transmited over, there is a int happened {// interrupt errorreturn 0;}/* Reading SDR */data_buff[i] = SDR11L; //recieve datai ++;}/*** step 12. Send Stop*/IIC11_StopCondition();return data_buff[data_len - 2];}UCHAR SETLASTADDRESS(UCHAR last_device_adr) /*set last slave device address for lower device*/{UCHAR i;UCHAR buffer[8];buffer[0] = Address_Broadcast_W; /*Send broadcast address as write mode*/buffer[1] = 0x01; /*send ADDRESS Register address*/buffer[2] = 0xA0; /*lower 8 bit device address*/buffer[3] = last_device_adr; /*higher 8 bit: the number of device*/buffer[4] = PEC_Calculation(buffer,4);/*Send PEC byte*//*** Change Communication mode to Tx*/Change_IIC_Communication_Mode(Transmission);/*** step 1. Check IIC bus busy or free*///IIC11_StopCondition();/*** step 3. Send Start and delay*/IIC11_StartCondition();/*** step 3. Send Data : address+w, ADDRESS Register, LSB, MSB, PEC*/for(i=0;i<5;i++)SDR11L = buffer[i];/* Transfer end interrupt generated? */if(!Check_Interrupt_Status()) //when data is transmited over, there is a int happened{// interrupt errorreturn 0;}if(!Check_ACK()){//ACK_ERROR();return 0;}wait(delay_t);}/*** step 4. Send Stop*/IIC11_StopCondition();return 1;}UCHAR READALL(UCHAR Register_address, UCHAR *data_buff, UCHAR data_len)//NOTE: data_buff[0] not use{UINT i;UCHAR flag;UCHAR receive_over_flag;/*** Change Communication mode to Tx*/Change_IIC_Communication_Mode(Transmission);/*** step 1. Check IIC bus busy or free*///IIC11_StopCondition();/*** step 2. Send Start*/IIC11_StartCondition();/*** step 3. Send Data : broadcast address data */SDR11L = Address_Broadcast_W;/*** wait data transmite over!*/if(!Check_Interrupt_Status()){//Interrupt errorreturn 0;}/*** step 4. Check ACK and Wait*/if(!Check_ACK()){//ACK_ERROR();return 0;}/*** step 5. Send Data : register address data */SDR11L = Register_address;/*** wait data transmite over!*/if(!Check_Interrupt_Status()){//Interrupt errorreturn 0;}/*** step 6. Check ACK and Wait*/if(!Check_ACK()){//ACK_ERROR();return 0;}/*** step 7. Send ReStart*/RESTART();/*** step 9. Send Broadcast address*/SDR11L = Address_Broadcast_R;/*** wait data transmite over!*/if(!Check_Interrupt_Status()){//Interrupt errorreturn 0;}/*** step 10. Check ACK*/if(!Check_ACK()){//ACK_ERROR();return 0;}/*** step 11. Change communication as recive mode *//*** Change Communication mode to Rx*/Change_IIC_Communication_Mode(Reception);** step 12. Recive Data*/receive_over_flag = 0;i = 0;flag = 0;while(i <= data_len){/*RECEIVE SLAVE DATA UNTIL CONSECUTIVE 0xFF BYTES,THEN NACK THE SLAVE*/ if(i == data_len) /*last byte recieve ?*/{SOE1 &= ~_0002_SAU_CH1_OUTPUT_ENABLE; /* disable IIC11 out */SO1 &= ~_0002_SAU_CH1_DATA_OUTPUT_1; /* clear IIC11 SDA */NOP();NOP();NOP();SO1 &= ~_0200_SAU_CH1_CLOCK_OUTPUT_1; /* clear IIC11 SCL */NOP();NOP();NOP();SO1 |= _0002_SAU_CH1_DATA_OUTPUT_1; /* set IIC11 SDA */ST1 |= _0002_SAU_CH1_STOP_TRG_ON; /* disable IIC11 */NOP();break;}/*Writing dummy data to SDR 0xFF*/SDR11L = 0xff;/* Transfer end interrupt generated? */if(!Check_Interrupt_Status()) //when data is transmited over, there is a int happened {// interrupt errorreturn 0;}wait(delay_t);/* Reading SDR */data_buff[i] = SDR11L; //recieve datai ++;/*** step 13. Send stop*/IIC11_StopCondition();return data_buff[i -2];}//NOTE: data_buff only used bit 0,1;UCHAR WRITEALL(UCHAR register_address, UCHAR LSB, UCHAR MSB){UINT i;UCHAR buffer[5];buffer[0] = Address_Broadcast_W; /*Send broadcast address as write mode*/ buffer[1] = register_address; /*send Register address*/buffer[2] = LSB; /*lower 8 bit device address*/buffer[3] = MSB; /*higher 8 bit: the number of device*/buffer[4] = PEC_Calculation(buffer,4); /*Send PEC byte*//*** Change Communication mode to Tx*/Change_IIC_Communication_Mode(Transmission);/*** step 1. Check IIC bus busy or free*///IIC11_StopCondition();/*** step 2. Send Start*/IIC11_StartCondition();/*** step 3. Send Broadcast address*/SDR11L = Address_Broadcast_W; /*send MAX11068 broadcast address*//*** wait data transmite over!if(!Check_Interrupt_Status()){//Interrupt errorreturn 0;}if(!Check_ACK()){//ACK_ERROR();return 0;}/*** step 4. Send register address*/SDR11L = register_address;/*** wait data transmite over!*/if(!Check_Interrupt_Status()){//Interrupt errorreturn 0;}if(!Check_ACK()){//ACK_ERROR();return 0;}/*** step 4. Send data*/for(i=0; i<5; i++) /* 5 is datalength */{SDR11L = buffer[i];/* Transfer end interrupt generated? */if(!Check_Interrupt_Status()) //when data is transmited over, there is a int happened {// interrupt errorreturn 0;}if(!Check_ACK()){//ACK_ERROR();return 0;}wait(delay_t);}/*** step 8. Send stop*/IIC11_StopCondition();return 1;}UCHAR WRITEDEVICE(UCHAR cmd_device_address, UCHAR register_adr, UCHAR *data_buff)//NOTE: data_buff only bit 0,1,2 inuse{UCHAR i;UCHAR buffer[8];/*** Change Communication mode to Tx*/Change_IIC_Communication_Mode(Transmission);/*** step 1. Check IIC bus busy or free*///IIC11_StopCondition();/*** step 2. Send Start*/IIC11_StartCondition(); /*send a START*//*** step 4. Send buffer data*/buffer[0] = cmd_device_address; /*send WRITEDEVICE Command*/buffer[1] = register_adr; /*send Register address*/buffer[2] = data_buff[0]; /*lower 8 bit*/buffer[3] = data_buff[1]; /*higher 8 bit*/buffer[4] = PEC_Calculation(buffer,4);/*** step 5. Write Data to Device*/for(i=0;i<5;i++){SDR11L = buffer[i];/* Transfer end interrupt generated? */if(!Check_Interrupt_Status()) //when data is transmited over, there is a int happened{// interrupt errorreturn 0;}if(!Check_ACK()){//ACK_ERROR();return 0;}wait(delay_t);}/*** step 8. Send stop*/IIC11_StopCondition();return 1;}/******************************************************* Abstract:** This function**** Parameters:** None**** Returns:** None*******************************************************/void RESTART(void){ST1 |= _0002_SAU_CH1_STOP_TRG_ON; /* disable IIC11 */ SOE1 &= ~_0002_SAU_CH1_OUTPUT_ENABLE; /* disable IIC11 out *///SO1 &= ~_0002_SAU_CH1_DATA_OUTPUT_1; /* clear IIC11 SDA */SO1 |= _0200_SAU_CH1_CLOCK_OUTPUT_1; /* set IIC11 SCL */wait(delay_t);SO1 |= _0002_SAU_CH1_DATA_OUTPUT_1; /* set IIC11 SDA */IIC11_StartCondition();}/******************************************************* Abstract:** This function check the IIC busy or free**** Parameters:** USHORT Tx_or_Rx**** Returns:** None*******************************************************/UCHAR Check_Interrupt_Status(void){USHORT i = 0;while(!IICIF11) /*check interrupt flag*/{i++;if(i == 0xff) /*how long does it suitable ?*/{return 0; // interrupt error!}}IICIF11 = 0x0U;return 1; //interrupt OK!}/******************************************************* Abstract:** This function check the IIC busy or free**** Parameters:** USHORT Tx_or_Rx**** Returns:** None*******************************************************/void Change_IIC_Communication_Mode(USHORT Tx_or_Rx){if(Tx_or_Rx == Transmission){if((SCR11 & 0xC000) != Transmission){ST1 |= _0002_SAU_CH1_STOP_TRG_ON; /* disable IIC11 */NOP();SCR11 &= ~_C000_SAU_RECEPTION_TRANSMISSION;SCR11 |= _8000_SAU_TRANSMISSION;NOP();SS1 |= _0002_SAU_CH1_START_TRG_ON;}}if(Tx_or_Rx == Reception){if((SCR11 & 0xC000) != Reception){ST1 |= _0002_SAU_CH1_STOP_TRG_ON; /* disable IIC11 */NOP();SCR11 &= ~_C000_SAU_RECEPTION_TRANSMISSION;SCR11 |= _4000_SAU_RECEPTION;NOP();SS1 |= _0002_SAU_CH1_START_TRG_ON; /* enable IIC11 */ }}}/******************************************************* Abstract:** This function check the slave device ack signal**** Parameters:** None**** Returns:** None*******************************************************/UCHAR Check_ACK(void){/*when ACK is not detected during IIC transmission, PEF bit of SSR11 is set */ if(SSR11 & 0x0002){return 0; // check ACK ERROR!} elsereturn 1; // check SCK OK!}/******************************************************* Abstract:** This function check the IIC busy or free**** Parameters:** USHORT Tx_or_Rx**** Returns:** None*******************************************************/void wait(UINT number){while(number--){NOP();}}/******************************************************* Abstract:** This function PEC_Calculation**** Parameters:** ptr: point to databuffer** len: data length** Returns:** None*******************************************************/UCHAR PEC_Calculation(UCHAR * ptr,UCHAR len) // OK! 0x40,0x09,0xff,0x03 out CRC=0x7F {UCHAR crc;UCHAR i;crc = 0;while(len--){crc ^= *ptr++;for(i = 0;i < 8;i++){if(crc & 0x80 )crc = (crc << 1) ^ 0x07;elsecrc <<= 1;}}return crc;}。