历史上的今天

今天是:2024年11月08日(星期五)

正在发生

2019年11月08日 | STM8S103K3 I2C

发布者:Bby1978 来源: eefocus关键字:STM8S103K3  I2C  h文件 手机看文章 扫描二维码
随时随地手机看文章

以下为.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通讯需外接上拉电阻

关键字:STM8S103K3  I2C  h文件 引用地址:STM8S103K3 I2C

上一篇:STM8S AWU低功耗模式
下一篇:STM8S TM1650芯片控制程序

推荐阅读

集微网消息,11月6日锤子在成都举行了新品会,会上发布了加湿器、行李箱和智能音效三款产品,而手机则成为了配角,当场发布会上没有新品发布,仅推出了坚果R1孔雀蓝特别版而已。        由此《财经》报道称,有多位熟悉锤子科技的行业人士透露,这款孔雀蓝坚果R1手机很可能是锤子的“最后一款手机”,而且有数据表明在过去四年,锤子科技推出的7款...
第二届中国国际进口博览会(以下简称“进博会”)于2019年11月5日-10日在上海国家会展中心盛大开启。罗德与施瓦茨公司(以下简称“R&S公司”)作为外资仪表厂商的代表参加了本次进博会,并现场演示了毫米波快速人体探测解决方案、航空航天与国防测试测量解决方案、无线电监测系统、全新的5G测试测量解决方案以及5G元器件测试解决方案。 在本次进博会上,R&...
进入第四季度之后,电视液晶面板市场形势一片大好,价格依然持续上涨。近日,韩国厂商纷纷延后产线关停时间,中国厂商不断提升产能,电视液晶面板价格何时会止涨? 面板还在涨价自6月开始,电视液晶面板全面涨价,截至目前仍没有停止上涨的步伐。中小尺寸电视液晶面板价格上涨幅度最为迅猛,32英寸至55英寸电视液晶面板价格上涨幅度皆超过40%,其中55英寸...
11月6日,芯瑞达在投资者互动平台表示,公司一直深耕新型显示领域,在研的Micro LED技术项目可应用于VR/AR显示终端,目前尚未转换为订单。在植物照明领域,自2017年取得相关发明专利以来,目前已售产品包括高光子通量效率在660、730nm等系列红光LED,营收较小,在公司收入结构中占比较低。资料显示,芯瑞达自设立以来,每年均有新增导入品牌厂商的供应链...

史海拾趣

问答坊 | AI 解惑

华为逻辑电平设计规范教材

华为逻辑电平设计规范教材…

查看全部问答∨

8051f单片机silicon ide编译请教

  我编译时提示 LInker not found C:\\Silabs...\\BIN\\bi51.exe是怎么回事,是我的软件没有装好吗? 可是我卸载了又装了还是这样 怎么回事刚开始用不懂 谢谢了…

查看全部问答∨

菜鸟提问:高手请进!单片机设计与嵌入式开发的本质区别?

请大家谈谈单片机设计与嵌入式开发(比如说ARM)的本质区别? 包括系统工作的流程及硬件设计等有哪些本质上的差异?请各位高手畅所欲言。…

查看全部问答∨

STM32串口控制寄存器疑问

准备采用中断法发送数据,看到datasheet描述USART_CR1位7(TXEIE)和位8(TCIE),不是太明白。采用那一种比较好?…

查看全部问答∨

求助:利用MSP430制作函数发生器

我是一个菜鸟,目前有任务利用MSP430F1611制作一个函数发生器,信号最后经DAC12输出,函数波形方波,正弦波,三角波等,频率要求不高200Hz以下,请问各位高手应如何入手,有什么思路,小弟在此谢谢了。…

查看全部问答∨

电子时钟控制程序

最近写了一个有关电子时钟控制的程序(我是初学者),程序调试时发现:当调节参数时,数码管显示不稳定。程序我修改了无数遍,就是不知道原因出在哪里!希望可以在各位大虾的帮助找出原因!!!!!   程序如下:   /*------ ...…

查看全部问答∨

VB单片机实训,求解

你好啊,我现在有个任务是做VB单片机实训,但是不知道怎么做。该任务是用VB做游戏,用单片机做游戏柄,求大神解答。网上的弹球游戏我看过了,我不想要,求其他的游戏!谢谢…

查看全部问答∨

MXCHIP open

    玩这块板子,涵盖的知识太过广泛,刚开始熟悉大概流程,试过几个例子之后。觉得就那样,都是别人写好的代码,自己移植过去,自己想要一个深刻的理解,所以看了一些另外的一些协议之类的东西,也没着急弄这个东西,看了这么长时间后, ...…

查看全部问答∨

直流/直流转换器数据表——系统效率揭秘

市面上售有各种类型的稳压器,但很难选择一款直流/直流稳压器。大多数汽车应用都要求在整个负载范围内保持高效率,因为它们一直在耗电。但话又说回来,许多工业应用在高负载时需要高效率,而在轻负载时,效率并不是很重要。因此必须了解直流/直流稳 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved