STM8S105S4 I2C

发布者:jingwen最新更新时间: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 引用地址:STM8S105S4 I2C

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

推荐阅读最新更新时间:2024-03-16 15:14

I2C总线协议及其应用
一、I2C总线介绍: 由于大规模集成电路技术的发展,在单个芯片集成CPU以及组成一个单独工作系统所必须的ROM、RAM、I/O端口、A/D、D/A等外围电路和已经实现,这就是常说的单片机或微控制器。目前,世界上许多公司生产单片机,品种很多:包括各种字长的CPU,各种容量和品种的ROM、RAM,以及功能各异的I/O等等。但是,单片机品种规格有限,所以只能选用某种单片机再进行扩展。扩展的方法有两种:一种是并行总线,另一种是串行总线。由于串行总线连线少,结构简单,往往不用专用的母板和插座而直接用导线连接各个设备即可。因此,采用串行总线大大简化了系统硬件设计。PHILIPS公司早在十几年就前推出了I2C串行总线,它是具备多主机系统所
[单片机]
<font color='red'>I2C</font>总线协议及其应用
KST-STM学习之I2C+SPI
只能说跟51的差不了多少,在这里仅仅记录下主要注意事项吧。 1、I 2 C 通信分为标准模式 100kbit/s、快速模式 400kbit/s 和高速模式 3.4Mbit/s。因为所有的I 2 C 器件都支持标准模式,但却未必支持另外两种速度。 所以作为通用的 I 2 C 程序我们选择100k 这个速率来实现,也就是说实际程序产生的时序必须小于等于 100k 的时序参数,有特殊速度需求的器件再针对性写高速通信程序。 2、I 2 C 引脚属于开漏并联结构,并且 STM32 的 GPIO 端口引脚设置为开漏输出时,可以直接从输入数据寄存器获取 I/O 电平状态,因此将 I 2 C 引脚配置为开漏输出模式。 3、由于 I
[单片机]
KST-STM学习之I2C+SPI
实用的单片机模拟I2C总线控制EEPROM读写程序
之前写的EEPROM程序虽然能够软仿成功,但烧到单片机里的时候却不能用,无疑是时序的问题,今天修正了时序,总算硬仿成功了。对照上次的程序可以发现就是添加了头函数: intrins.h ,这样就可以通过 _nop_() 指令较为准确的控制时序。 上次那个问题依然没有解决:就是接收缓冲区的数据是从readbuf 开始的,以这个程序为例: readbuf 中存放0x96 readbuf 中存放0x84 readbuf 中存放0xd5 readbuf 中存放0x63 readbuf 中存放0x7c readbuf 中存放0x8c 其实我是想把收到的数据存放在readbuf ~ 中的,我也不知道为什么结果会这样,有知道的麻烦指教
[单片机]
MCS-51单片机模拟I2C软件包
注意:普通M51单片机机器周期=12个时钟周期,f020机器周期=时钟周期 对于nop指令,F020是一个时钟周期,例如f020晶振为22.1184M, 约为45ns /*函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作 一定的修改....(本软件包是1us机器周期,即晶振频率要小于12MHZ)总线时序符合I2C标准模式,100Kbit/S。*/ #include reg51.h #include intrins.h #define uchar unsigned char /*宏定义*/ #define uint unsigned int #define _Nop() _nop_() /*定义空指令
[单片机]
MCS-51单片机模拟<font color='red'>I2C</font>软件包
详解嵌入式开发中的I2C总线
硬盘、U盘等这些设备中都有一个“掉电保存”的器件,他们的特点就是没电了之后,存在他们上面的信息不会丢失,就像人的大脑,有记忆功能。在工业领域也非常常见这种器件,一般有EEPROM和FLASH。它俩共同点是可读可写,断电保存。 不同点是EEPROM写之前不用擦除,而FLASH写之前一定要擦除,否则写不成功;EEPROM一般都使用I2C总线来通信,而FLASH一般是使用SPI总线。 EEPROM存储器系统架构图如下。 位传输 I2C总线是由飞利浦(Philips)公司开发的一种双向二线制同步串行总线,实现有效的IC间的控制,它只需要两根线(SDA和SCL)即可在连接于总线上的器件之间传送信息。 I2C总线在传输数据都是按照
[单片机]
i2c总线AT24C02存储器读写程序
#include reg52.h #define uint unsigned int //定义unsigned int 为uint #define uchar unsigned char //定义unsigned char 为uchar #define uchar unsigned char //定义unsigned char 为uchar #define uint unsigned int //定义unsigned int 为uint sbit sda=P3^3;//定义I2C数据线 sbit scl=P3^2;//定义I2C时钟线 void delay2()//延迟6us函数 {;;;} void start()//I2C开始
[单片机]
STM32F103利用模拟I2C驱动ADS1115
ADS1115通过模拟I2C驱动:(部分代码借鉴了网络上的几个,并且根据引脚进行了配置,都没有运行成功,今天调了一天,终于在晚上调了出来) 注意:本部分代码需要只是ADS1115的部分程序(一些用到的数组在此没有写),模拟II2C的各程序并未给出,大家根据需要进行裁剪,代码完全开源,希望能帮到大家,也希望大家乐于分享。 调试时需特别注意I2C的通信问题,特别是应答信号的使用需要特别关注,本人的程序之前出错全是因为从机的应答信号的未使用造成。 如有其它问题,欢迎指正批评,第一次写博客,感谢! 收获:对于I2C通信协议的理解更加深刻,对ADS1115也能进行单通道的使用。I2C的开始、发送/读写、应答、结束等一定要
[单片机]
奥地利微电子推出I2C 接口12位8通道低功耗A/D转换器
AS1538提供最低功耗,支持最高速I2C 接口 中国 —— 全球领先的通信、工业、医药、汽车领域模拟集成电路设计者和制造商奥地利微电子公司(瑞士苏黎士SWX 证券股票代码:AMS)新近推出带 I2C 接口的μA 级功耗A/D 转换器AS1538,以扩展其高性能ADC产品线。低功耗工作的AS1538采用16引脚 TSSOP封装,可以实现I2C的最高转换速度,其全差分或单端模拟输入模式可提供卓越的动态性能(THD -75dB)。上述特性加上其应用简便,使之成为了采用I2C 总线的 2.7 至 5.25V电池驱动应用和工业应用的理想解决方案。 AS1538 带有8个12 Bit的分辨率的输入通道。其在50ksps的转换速度下低于
[新品]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved