STM8S103K3 I2C

2019-11-08来源: 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_A

[1] [2]
关键字:STM8S103K3  I2C  h文件 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic479400.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

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

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

stm8s003k3加数码管做的定时小板,继电器以及MOS管输出
最近刚做的用stm8s003k3加三位数码管做的定时小板,继电器以及MOS管输出,四个按键进行设置,代码可以根据自己需求更改单片机:stm8s003k3输入:四路按键输出:继电器、MOS管电路原理图如下: 单片机源程序如下:#include "main.h"#include "display.h"SysTime_t PollTestTime;void main(void){  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);  disableInterrupts();   
发表于 2019-10-15
stm8s003k3加数码管做的定时小板,继电器以及MOS管输出
STM8S105K4 SPI相关代码
/* 初始化函数 */void SPI_FLASH_Init(void){   SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_2, SPI_MODE_MASTER,            SPI_CLOCKPOLARITY_HIGH, SPI_CLOCKPHASE_2EDGE,            SPI_DATADIRECTION_2LINES_FULLDUPLEX, SPI_NSS_SOFT, 0x07);   SPI
发表于 2019-04-25
STM8L驱动I2C类型的12864
原理之前没有操作过12864这种类型的屏,但是,操作过其他类型的,原理都是相通的。12864是拥有128x64像素点这类屏幕的称号吧。屏幕有64行,128列;每个汉字是16x16,所以一个这样的屏,最多可以显示4x8的汉字或者8x16的字符。我使用的是不带字库的I2C接口的屏幕,主芯片是ST7656。这样的屏,只能写,不能读。先配置屏幕,然后通过字模制作软件制作出待显示内容的像素数字,最后,通过数据线传送给屏幕显示。了解了原理后,接下来就根据主芯片的数据手册进行配置屏幕就好了。硬件连线CS:片选RST: 复位RS:数据或命令选择SDA:I2C数据线SCL:I2C时钟线I2C采用的是软件模拟的底层写操作#define
发表于 2019-11-11
STM8S003的GPIO模拟I2C切换输入输出的解决办法
刚开始学STM8,很多东西刚了解,正在做一个温湿度显示小板,就是使用I2C驱动SHT20传感器,并显示到数码管,数码管用的四位一体共阴数码管,STM8管脚有限,添加了一片TM1650做驱动,不过SHT20和TM1650都是用的I2C接口,由于对STM8硬件I2C还不了解,先打算用软件模拟,这就涉及到需要对GPIO做输入输出切换处理来检测ACK响应,刚开始,直接操作DDR寄存器,但是出现从输出切换到输入就会出现单片机死机,不解,查资料,得到一个解决办法,在输出状态时,可以不用切换到输入,我使用管脚D4,D5这两个管脚,这两个管脚比较特殊,就是真正开漏,在管脚描述为T,其它描述为HS(高吸收电流)。解决办法,将IO设置为开漏输出,外部
发表于 2019-11-11
STM8 I2C从机
宏定义#define SLAVE_ADDR 0x51#define I2CSPEED 400000 //i2c速度stm8l051 i2c从机初始化    /* I2C  clock Enable*/    CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);    I2C_DeInit(I2C1);    I2C_Init(I2C1, I2CSPEED, SLAVE_ADDR ,        I2C_Mode_I2C
发表于 2019-11-11
STM8 I/O口模拟I2C
STM8I/O口模拟I2C所读数据不正确  STM8 I/O口模拟I2C      #define I2C_ERR   0    #define I2C_CRR   1    #define  I2CDataIn  1    #define  I2CDataOut 0    #define I2C_PORT  (GPIOC)    #define I
发表于 2019-11-11
小广播
何立民专栏 单片机及嵌入式宝典

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

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