datasheet

STM8S105S4 I2C

2016-10-08来源: eefocus关键字:STM8S105S4  I2C
STM8S105S4 I2C这样配置可以从机发数据,从机接数据就不行,是什么问题 
//I2C端口初始化 
GPIO_Init(GPIOE,GPIO_PIN_1|GPIO_PIN_2, GPIO_MODE_OUT_OD_HIZ_SLOW); 
void I2C_init(void) 

I2C_CCRH   = 0;    //标准I2C接口 
I2C_CCRL    = 80 ; 
I2C_FREQR = 16; 
I2C_OARL   = (I2CAddr<<1); 
I2C_OARH  = 0x40; 
I2C_ITR      =  0x06; 
I2C_CR1     =  0x01; 
I2C_CR2   |=  0x04; 

@far @interrupt void I2C_Handler (void) 

u8 state1,state2,state3; 
state1 = I2C_SR1; 
state2 = I2C_SR2; 
state3 = I2C_SR3; 
//地址匹配 
if((state1&0x02)!=0){I2C_CR2 |= 0x04;} 
        //接收到数据,需要处理 
if( (state1& 0x40) != 0) 
     { 
     I2C_CR2  |= 0x04; 
     temp1  = I2C_DR; 
SetOutput(temp1); 
     } 
//从机需要发送数据 
if((state1 & 0x80) != 0)   
     { 
     I2C_DR = num++; 
     } 
if((state2 & 0x04) != 0)I2C_SR2 &= ~0x04; //应答失败,清除该位 
if((state1 & 0x10) != 0) 

I2C_CR2 = 0x02; 


我写成这样子,发现现在是从机发数据是没问题,从机接收数据不行,没有进入中断。

成功传输一次正确的数据后就进不去了。程序还正常运行

 

 

 

 

 

 

 

 

#define I2CAddr 0x01
在主机
  //主机写数据,从机接,这个不行
   Soft_I2C_Start();
    Soft_I2C_Write(0x02);
    Soft_I2C_Write(0xAA);
    Soft_I2C_Stop();
    //主机接收数据。没有运行上一段程序,主机可以接收数据,运行上段,主机接收数据都是255
    Soft_I2C_Start();
    Soft_I2C_Write(0x03);
    var0=Soft_I2C_Read(1);
    Soft_I2C_Stop();
    这个软I2C在控制其它设备是没有问题的,主机用的芯片是STM32。应该是没有问题的

 

 

 

 

 
 

 

 解决问题:

这就是了,你第一次成功后了,你把应答给关掉了,还怎么接收啊。。。以后配寄存器要多一个心眼才是。

问题就在这里I2C_CR2 = 0x02; 修改为I2C_CR2 |= 0x02;  原因是修改了,第一次成功后,没有再回复

 

 

 

 

1.PC0,PC1初始化,GPIO_Init(GPIOC, GPIO_Pin_1 | GPIO_Pin_0, GPIO_Mode_Out_OD_HiZ_Fast);
2.必须连接硬件
3.总线不能busy,一定要空闲
初始化代码如下:
GPIO_Init(GPIOC, GPIO_Pin_0, GPIO_Mode_Out_OD_HiZ_Slow);
                GPIO_Init(GPIOC, GPIO_Pin_1, GPIO_Mode_Out_OD_HiZ_Slow);
                CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);
                I2C_Init(I2C1, 50000, 0xA5, I2C_Mode_I2C, I2C_DutyCycle_2,
           I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit);
//注:I2C_Init()里已经使能了I2C,所以可以不用I2C_Cmd(I2C1, ENABLE);
                while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

 
 

 

 

stm8 自带I2C终于调试成功。

1,此次调试I2C受益多多,首先证明官方的那个写EEPROM的程序是对的。
2,这次调试TW8816开始调不通的原因是误以为寄存器地址是16位的(芯片公司的业务也是这么说的,我相信了),才让我看到的数据不同,但我想,有数据了,而且用WHILE等待的方法,程序跑通了,说明连上了从机。
3, I2C的GPIO不要配置,我看到有些同仁把GPIO配置了。
4,为了大家用好STM8的I2C,我把程序烤下来。

void IIC_Init(void)
{
        UCHAR temp;
        
        CLK_PCKENR1 |= 0x01;

        I2C_FREQR |= 0x10;                  //输入外设时钟频率为1MHz
        I2C_CR1    = 0x00;                  //禁止I2C外设
        I2C_CCRH  &= ~0xcf;
        I2C_CCRL  &= ~0xff;  
  I2C_TRISER = 0x11;
        I2C_CCRL   = 0x10;
        I2C_CCRH   = 0x00;
        I2C_CR1   |= 0x01;                  //开启I2C外设
        I2C_CR2   |= 0x04;                  //当前接收字节返回应答
        I2C_CR2   &= 0x08;
        I2C_OARL   = 0x86;                  //自身地址
        I2C_OARH   = 0x40;
}

void Read_8816(UCHAR *pBuffer, UCHAR index, UCHAR NumByteToRead)
{
        UCHAR temp;

        while(I2C_SR3 & 0x02);             //等待总线空闲
        I2C_CR2 |= 0x01;                                //产生起始位
        while(!(I2C_SR1 & 0x01));          //等待START发送完
        I2C_DR = 0x8a;                     //发送8816器件地址
        while(!(I2C_SR1 & 0x02));          //等特7位器件地址发送完
        temp = I2C_SR1;
        temp = I2C_SR3;
        I2C_DR = (UCHAR)(index);
        while(!(I2C_SR1 & 0x84));
        
        I2C_CR2 |= 0x01;                                      //产生重复起始位
        while(!(I2C_SR1 & 0x01));          //等待START发送完
        I2C_DR = 0x8b;                     //读
        while(!(I2C_SR1 & 0x02));          //等特7位器件地址发送完
        temp = I2C_SR1;
        temp = I2C_SR3;
        while(NumByteToRead)                      //要读几个字节
        {
                if(NumByteToRead == 1)
                {
                        I2C_CR2 &= ~0x04;              //不返回应答
                        I2C_CR2 |= 0x02;               //产生停止位
                }
                if(I2C_SR1 & 0x40)
                {
                        temp = I2C_SR1;
                        Buff[8-NumByteToRead]=I2C_DR;
                        *pBuffer = Buff[8-NumByteToRead];
                        pBuffer++;
                        NumByteToRead--;
                }
        }
        I2C_CR2 |= 0x04;
        I2C_CR2 &= ~0x08;                  //为下一次接收使能应答
}

关键字:STM8S105S4  I2C

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

上一篇:STM8S中断优先级设置
下一篇:STM8S-Discovery第三个程序 - DS18B20

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

推荐阅读

stm8s 独立看门狗和窗口看门狗的代码

void WWDG_INI(void){       WWDG_WR = 0x60; //看门狗窗口值,窗口值必须在0x3F以上,但必须小于计数值,否则无法喂狗   WWDG_CR      = 0x7F; //看门狗计数值   WWDG_CR |= 0x80; //使能窗口看门狗}void Free_WWDG(void){    if ((WWDG_CR & 0x7F) < WWDG_WR) //小于窗口值才能喂狗      WWDG_CR = 0x
发表于 2019-04-12

STM8S 窗口看门狗

.h文件如下: #ifndef __WWDG_H#define __WWDG_H#include "stm8s.h"void Delay(); void WWDG_Configuration(void) ; void Refresh_WWDG_Window(void);#endif.c文件如下:#include "wwdg.h"#include "stm8s_wwdg.h" #define CounterInit 0x7f#define window      0x77 void Delay
发表于 2019-04-12

STM8S 三种时钟源的配置HSE\HSI\LSI的配置

1. 关于HSE的时钟配置为主时钟static void CLK_Config(void){    CLK_DeInit();  // 初始化    CLK_HSECmd(ENABLE); //使能HSE   CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE,                               
发表于 2019-04-12
STM8S 三种时钟源的配置HSE\HSI\LSI的配置

stm8s编译器查看代码量大小的软件

\STMicroelectronics\st_toolset\stvd中  2. 用stvd打开你的工程文件,在工程上点右键选settings...  3. 右侧的选项卡选择Linker,将category的下拉框选成output,然后在Generate Map file前打勾  4. 再将选项卡上选择到Post-Build,在下方文本框中新粘贴一行内容 mapinfo $(OutputPath)$(TargetSName).map  5. 点OK按键确定,菜单File->save workspace,保存工程  6. 重新编译下,你就能看到flash,ram,eeprom占用
发表于 2019-03-06

STM8S 三种时钟源的配置HSE\HSI\LSI的配置

1. 关于HSE的时钟配置为主时钟static void CLK_Config(void){    CLK_DeInit();  // 初始化    CLK_HSECmd(ENABLE); //使能HSE   CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE,                               
发表于 2019-02-15
STM8S 三种时钟源的配置HSE\HSI\LSI的配置

小广播

何立民专栏

单片机及嵌入式宝典

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

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