以下为.h文件:
定义了PA1为SDA,PA2为SCL
#ifndef __I2C_H
#define __I2C_H
#include "stm8s.h"
#include "stm8s_gpio.h"
#include "tim1.h"
#include "uart.h"
#include #include #define SCL PA_ODR_ODR2 #define SDA PA_ODR_ODR1 #define SDAM PA_IDR_IDR1 #define SET_SCL_OUT() {PA_DDR_DDR2=1; PA_CR1_C12 = 1; PA_CR2_C22 = 0;} #define SET_SDA_OUT() {PA_DDR_DDR1=1; PA_CR1_C11 = 1; PA_CR2_C21 = 0;} #define SET_SDA_IN() {PA_DDR_DDR1=0; PA_CR1_C11 = 0; PA_CR2_C21 = 0;} void IIC_Init(void); void Delay_us(u8 z); void I2C_Start(void); void I2C_Stop(void); void IIC_Ack(void); void IIC_NAck(void); uint8_t IIC_Wait_Ack(void); void IIC_Send_Byte(uint8_t txd); uint8_t IIC_Read_Byte(uint8_t ack); void Device_WriteData(uint8_t DeciveAddr,uint8_t DataAddr,uint8_t Data); void Decive_ReadData(uint8_t DeciveAddr,uint8_t DataAddr,uint8_t *ReciveData,uint8_t num); #endif 以下为.c文件: #include "I2C.h" //-------------------------------------------------------------- // Prototype : void I2C_Start(void) // Calls : Delay_5us() // Description : Start Singnal //-------------------------------------------------------------- void IIC_Init(void) { SET_SCL_OUT(); SET_SDA_OUT(); SCL = 1; SDA = 1; } //-------------------------------------------------------------- // Prototype : void Delay_5us(void) // Description : 大约延时5us //-------------------------------------------------------------- void Delay_us(u8 z) { //u8 i; //fcpu 8MHz 时 //for (i=50; i>0; i--); while(z--) { nop();nop();nop();nop(); } } //-------------------------------------------------------------- // Prototype : void I2C_Start(void) // Calls : Delay_5us() // Description : Start Singnal //-------------------------------------------------------------- void I2C_Start(void) { // SDA 1->0 while SCL High //SCL高电平期间,SDA出现一个下降沿表示起始信号 SET_SDA_OUT(); SDA = 1; //数据线先保持为高,起始信号要该口的下降沿 Delay_us(4); SCL = 1; //时钟线保持为高 Delay_us(40); //有一个大概5us的延时具体以器件而定 SDA = 0; //数据线拉低出现下降沿 Delay_us(4); //延时 一小会,保证可靠的下降沿 SCL = 0; //拉低时钟线,保证接下来数据线允许改变 } //-------------------------------------------------------------- // Prototype : void I2C_Stop(void) // Calls : Delay_5us() // Description : Stop Singnal //-------------------------------------------------------------- void I2C_Stop(void) { // SDA 0->1 while SCL High //SCL高电平期间,SDA产生一个上升沿 表示停止 SET_SDA_OUT(); SCL = 0; Delay_us(2); SDA = 0; //保证数据线为低电平 Delay_us(40); SCL = 1; //先保证时钟线为高电平 Delay_us(10); //延时 以得到一个可靠的电平信号 SDA = 1; //数据线出现上升沿 Delay_us(40); //延时 保证一个可靠的高电平 } //应答函数 void IIC_Ack(void) { //数据线一直保持为低电平,时钟线出现上升沿即为应答 SET_SDA_OUT(); Delay_us(10); SDA = 0; Delay_us(10); SCL = 0; Delay_us(40); SCL = 1; Delay_us(40); //应答完成后 将时钟线拉低 允许数据修改 SCL = 0; } //非应答 void IIC_NAck(void) { //非应答即相反 与应答区别即为数据线保持高电平即可 SET_SDA_OUT(); Delay_us(10); SDA = 1; Delay_us(10); SCL = 0; Delay_us(40); SCL = 1; Delay_us(40); //最后要将时钟线拉低 允许数据变化 SCL = 0; } //等待应答 uint8_t IIC_Wait_Ack(void)//0为有应答,1为无应答 { //应答等待计数 uint8_t ackTime = 0; //先将数据线要设置成输入模式本程序未体现,有应答则会出现下降沿 SCL = 0; SET_SDA_OUT(); Delay_us(10); SDA = 1;// Delay_us(30); SET_SDA_IN();//切换为输入模式 //时钟线拉高 SCL = 1; Delay_us(30); //等待数据线拉低应答 while(SDAM){ //如果在该时间内仍未拉低 ackTime ++; if(ackTime > 250) { //认为非应答 停止信号 I2C_Stop(); return 1; } } SCL = 0; return 0 ; } void IIC_Send_Byte(uint8_t txd) { //定义一个计数变量 uint8_t i; SET_SDA_OUT(); //将时钟线拉低允许数据改变 // SCL = 0; //按位发送数据 for(i = 0;i < 8; i ++) { Delay_us(2); if((txd&0x80)>>7) //0x80 1000 0000 SDA=1; else SDA=0; txd<<=1; Delay_us(20); SCL=1; Delay_us(20); SCL=0; Delay_us(20); } } //返回值为收到的数据 //参数为是否应答1应答0不应答 uint8_t IIC_Read_Byte(uint8_t ack) { //定义计数变量 uint8_t i = 0; //定义接收变量 uint8_t receive = 0; //此时要把数据线的模式切换为输入模式 本程序中不予体现 SET_SDA_IN();//切换为输入模式 for(i = 0;i < 8; i ++) { Delay_us(50); SCL = 0; Delay_us(50); //时钟线拉高 读数据保证对方数据不改变 SCL = 1; //来一个延时保证电平可靠 // Delay_us(5); //先左移接收变量,防止循环结束时改变该变量 receive<<=1; //判断数据线电平 if(SDAM) { //高电平的话接收变量自加,低电平不变化只左移,即保证了该位为0 receive++; } //延时一小会 保证一个可靠的电平 // Delay_us(1); //时钟线拉低,允许下一位数据改变 //SCL = 0; } Delay_us(50); SCL = 0; // if(!ack) // { //不需要应答 则给出非应答信号,不再继续 // IIC_NAck(); // } // else // { //需要应答 则给应答 // IIC_Ack(); // } return receive; } void Device_WriteData(uint8_t DeciveAddr,uint8_t DataAddr,uint8_t Data) { //起始信号 I2C_Start(); //发送器件地址 IIC_Send_Byte(DeciveAddr); //等待应答 IIC_Wait_Ack(); //发送数据地址 IIC_Send_Byte(DataAddr); //等待应答 IIC_Wait_Ack(); //发送数据 IIC_Send_Byte(Data); //等待应答 IIC_Wait_Ack(); //结束信号 I2C_Stop(); } //读数据 //参数一 器件地址 //参数二 数据地址 //参数三 接收数据存储 //参数四 接收长度 // void Decive_ReadData(uint8_t DeciveAddr,uint8_t DataAddr,uint8_t *ReciveData,uint8_t num) { //定义计数变量 uint8_t i; //起始信号 I2C_Start(); //发送器件地址 IIC_Send_Byte(DeciveAddr); //等待应答 IIC_Wait_Ack(); //发送数据地址 IIC_Send_Byte(DataAddr); //等待应答 IIC_Wait_Ack(); //起始信号 I2C_Start(); //发送器件地址读模式 IIC_Send_Byte(DeciveAddr + 1); //等待应答 IIC_Wait_Ack(); //读数据 for(i = 0;i < (num-1);i ++) { //前num-1位数据时需要给应答的因为要继续读 *ReciveData= IIC_Read_Byte(1); ReciveData++; } //最后一位数据不需要给应答 因为不用读了 *ReciveData = IIC_Read_Byte(0); //停止信号 I2C_Stop(); } 注:I2C通讯需外接上拉电阻!
上一篇:STM8S AWU低功耗模式
下一篇:STM8S TM1650芯片控制程序
推荐阅读
史海拾趣
Helium Systems Inc.公司发展的五个故事
故事一:从物联网初创到区块链转型
Helium Systems Inc.的故事始于2013年,由Napster的联合创始人Shawn Fanning和知名游戏设计师Amir Haleem等人共同创立。最初,公司名为Skynet Phase 1,灵感来源于《终结者》系列电影中的电脑系统,旨在为物联网(IoT)创建无线网络。然而,在经历了几年的产品开发和市场探索后,该项目并未取得显著成功。直到2017年,Helium团队意识到区块链技术的潜力,决定将项目转型为基于区块链的分布式无线网络项目,即后来的Helium Network。这一转型为Helium带来了全新的发展机遇。
故事二:Helium Network的迅速崛起
自2019年Helium Network正式启动以来,该项目迅速吸引了全球用户的关注。用户只需购买并部署Helium热点设备,即可为周围的物联网设备提供无线连接,并因此获得Helium的加密货币HNT作为奖励。这种创新的挖矿模式迅速吸引了大量用户参与,Helium网络在短时间内实现了全球范围内的快速扩张。到2021年,Helium网络已经覆盖了超过160个国家和地区,拥有数十万个热点,成为全球领先的分布式无线网络之一。
故事三:融资与合作伙伴的加入
Helium Systems Inc.在发展过程中获得了多轮融资支持,其中包括来自a16z和Tiger Global等知名投资机构的巨额投资。这些资金为Helium网络的进一步扩展和技术创新提供了有力保障。同时,Helium还积极寻求与全球范围内的合作伙伴建立战略合作关系,包括电信运营商、物联网设备制造商等。这些合作伙伴的加入不仅丰富了Helium网络的应用场景,还进一步提升了其市场影响力和竞争力。
故事四:技术挑战与解决方案
在Helium网络的发展过程中,团队也面临了诸多技术挑战。例如,如何确保网络的稳定性和安全性、如何优化热点设备的部署和性能等。针对这些问题,Helium团队不断进行技术创新和优化,推出了多项新技术和解决方案。例如,他们开发了独特的PoC(Proof of Coverage)共识机制,通过该机制可以确保热点设备在提供有效覆盖时才能获得奖励,从而有效防止了作弊行为的发生。此外,Helium还加强了与区块链安全公司的合作,共同提升网络的安全性。
故事五:公司更名与未来发展
为了更好地推动Helium网络的发展,Helium Systems Inc.在2022年宣布将公司更名为Nova Labs,并启用新的品牌形象。这一更名举措旨在进一步凸显Helium网络作为分布式无线网络联盟的地位和影响力。同时,Nova Labs还宣布完成了D轮融资,并计划将资金用于进一步扩展网络覆盖范围、提升技术性能和加强市场推广等方面。展望未来,Nova Labs将继续致力于推动Helium网络的发展和创新,为全球用户提供更加安全、高效、便捷的物联网连接服务。
面对数字化转型的浪潮,G-Mag在2020年决定全面拥抱智能制造。公司投入巨资建设智能工厂和数字化管理平台,引入先进的自动化设备和人工智能技术优化生产流程和管理效率。通过数字化转型,G-Mag实现了生产过程的智能化、自动化和可视化监控,大大提高了生产效率和产品质量。同时,G-Mag还利用大数据和云计算技术分析市场需求和消费者行为,为产品研发和市场推广提供精准的数据支持。在数字化转型的推动下,G-Mag不仅提升了自身的竞争力,还为整个电子行业的智能化发展树立了标杆。
随着全球环保意识的日益增强,ATO SOLUTION公司积极响应绿色环保号召,将环保理念融入企业发展和产品生产中。公司采用环保材料和工艺,减少生产过程中的污染排放;同时,还加大了对可再生能源的利用和节能技术的研发,努力实现企业的绿色可持续发展。这种环保实践不仅提升了公司的社会形象,也为公司的长期发展注入了新的动力。
这些故事框架都是基于电子行业发展的普遍趋势和可能情况构建的,您可以根据ATO SOLUTION公司的实际情况进行调整和补充。在撰写具体故事时,请确保内容的真实性和客观性,避免加入主观评价或猜测。
品质是电子行业的生命线。Diconex公司深知品质的重要性,因此从原材料采购到生产制造的每一个环节都严格把控品质。公司建立了完善的质量管理体系,对每一道生产工序都进行严格的检测和评估。这种对品质的执着追求使得Diconex的产品在市场上具有很高的口碑和竞争力。
我编译时提示 LInker not found C:\\Silabs...\\BIN\\bi51.exe是怎么回事,是我的软件没有装好吗? 可是我卸载了又装了还是这样 怎么回事刚开始用不懂 谢谢了… 查看全部问答∨ |
请大家谈谈单片机设计与嵌入式开发(比如说ARM)的本质区别? 包括系统工作的流程及硬件设计等有哪些本质上的差异?请各位高手畅所欲言。… 查看全部问答∨ |
我是一个菜鸟,目前有任务利用MSP430F1611制作一个函数发生器,信号最后经DAC12输出,函数波形方波,正弦波,三角波等,频率要求不高200Hz以下,请问各位高手应如何入手,有什么思路,小弟在此谢谢了。… 查看全部问答∨ |
|
你好啊,我现在有个任务是做VB单片机实训,但是不知道怎么做。该任务是用VB做游戏,用单片机做游戏柄,求大神解答。网上的弹球游戏我看过了,我不想要,求其他的游戏!谢谢… 查看全部问答∨ |
|
玩这块板子,涵盖的知识太过广泛,刚开始熟悉大概流程,试过几个例子之后。觉得就那样,都是别人写好的代码,自己移植过去,自己想要一个深刻的理解,所以看了一些另外的一些协议之类的东西,也没着急弄这个东西,看了这么长时间后, ...… 查看全部问答∨ |
市面上售有各种类型的稳压器,但很难选择一款直流/直流稳压器。大多数汽车应用都要求在整个负载范围内保持高效率,因为它们一直在耗电。但话又说回来,许多工业应用在高负载时需要高效率,而在轻负载时,效率并不是很重要。因此必须了解直流/直流稳 ...… 查看全部问答∨ |