求解STM8L硬件I2C

eq2001k   2010-7-20 11:36 楼主
STM8L的I2C设置时是否需要设置GPIO(PC0,PC1),我在初始化时设置如下:
  CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);
  I2C_Cmd(I2C1, ENABLE);
  I2C_Init(I2C1, 100000, 0xA0, I2C_Mode_I2C, I2C_DutyCycle_2,
           I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit);

初始化完成后
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
结果死在while循环中,是不是我的I2C没有使能啊?

回复评论 (13)

                                 STM8L的I2C设置也需要设置GPIO(PC0,PC1)为OD输出,这跟STM8S、STM32F是类似的。
点赞  2010-7-20 13:25
                                 设置为OD输出了,系统时钟为CLK_SYSCLKDiv_4,电阻上拉,但是未连接其他I2C的设备,程序运行到这里不知道有没有影响
点赞  2010-7-20 13:43
                                 未连接其他I2C的设备,程序运行到发送 START位 应该没有影响
点赞  2010-7-20 13:56
                                 那就应该是I2C没有使能,我查了stm8l1526开发板的代码,发现没什么特别之处啊,而且他并没有初始化IO为OD输出
点赞  2010-7-20 14:04
                                 难道大家都不用硬件I2C,谁共享一段I2C初始化的代码啊?
点赞  2010-7-20 17:10
我的初始化代码大约是这样,供参考:
CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);
  GPIO_Init(GPIOC, GPIO_Pin_1 | GPIO_Pin_0, GPIO_Mode_Out_OD_HiZ_Fast);
  I2C_DeInit();
  I2C_Init(I2C1, 50000, 0xA0, I2C_Mode_I2C, I2C_DutyCycle_2,
           I2C_Ack_Disable, I2C_AcknowledgedAddress_7bit);
  I2C_Cmd(I2C1, ENABLE);
点赞  2010-7-20 17:13
                                 stm8的硬件I2C不好用,我宁愿用模拟的,不就两端口嘛
点赞  2010-7-20 19:05
                                 我也比较赞成用模拟的,感觉楼主I2C初始化程序没什么问题
点赞  2010-7-20 20:19
供参考....

/**
  ******************************************************************************
  * @file Dev_I2C.c
  * @brief I2C共用的C文件..
  * @author WuHan P&S 电力电子组.
  * @version V 0.0.1
        * @Target STM8L
  * @date 11/10/2009
  ******************************************************************************
  */

#include "dev_i2c.h"

void I2C_Delay(u32 nCount)
{
    /* Decrement nCount value */
    while (nCount != 0)
    {
        nCount--;
    }
}

// 释放I2C总线.
void I2C_BusRelease(void)
{
        GPIO_Init(I2C_PORT, (I2C_SDA_PIN | I2C_SCL_PIN), GPIO_Mode_Out_PP_High_Fast);

        I2C_Delay(500);
        GPIO_WriteBit( I2C_PORT, I2C_SCL_PIN, RESET );                // SCL为低
        GPIO_WriteBit( I2C_PORT, I2C_SDA_PIN, RESET );                // SDA为低
        I2C_Delay( 500 );
        GPIO_WriteBit( I2C_PORT, I2C_SCL_PIN, SET );        // SCL 为高
        I2C_Delay( 500 );
        GPIO_WriteBit( I2C_PORT, I2C_SDA_PIN, SET );        // SDA 为高
        I2C_Delay( 500 );
}

/**
  * @brief Initializes the I2C peripheral registers to communicate the EEPROM
  * @par Parameters:
  * None
  * @retval None
  * @par Required preconditions:
  * None
  */

I2C_Op_TypeDef I2C_BusInit(void)
{  
        u32 lu32TimeOut;
       
        I2C_BusRelease();
        I2C_BusRelease();
        I2C_BusRelease();

        /* Optional: put here as example only */
        I2C_DeInit( I2C1);

        /*Enable I2C1 clock */
        CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);

        /* I2C Peripheral Enable */
        I2C_Cmd(I2C1, ENABLE);
        /* Apply I2C configuration after enabling it */
        I2C_Init(I2C1, I2C_Speed, I2C_OWN_ADDRESS7, I2C_Mode_I2C, I2C_DutyCycle_2, I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit );
        I2C_Delay( 100 );

        while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY ))
        {
                if( lu32TimeOut ++ >= CNT_I2C_DELAY_COUNT )
                {
                        return CNT_I2C_FAIL;
                }
        }
       
        return CNT_I2C_SUCCESS;

}


/**
  ******************************************************************************
  * @file Dev_I2C.h
  * @brief I2C共用的头文件..
  * @author WuHan P&S 电力电子组.
  * @version V 0.0.1
        * @Target STM8L
  * @date 11/10/2009
  ******************************************************************************
  */
#ifndef __DEV_I2C__H
#define __DEV_I2C_H

/* Includes ------------------------------------------------------------------*/
#include "stm8l15x.h"

#define I2C_Speed              100000  
#define I2C_OWN_ADDRESS7             0x88
// 若是STM8S2XX时,I2C的SCL--PE1, SDA--PE2.
#define I2C_PORT                        GPIOC
#define I2C_SDA_PIN           GPIO_Pin_0
#define I2C_SCL_PIN                GPIO_Pin_1

#define CNT_I2C_DELAY_COUNT        1000

typedef enum
{
        CNT_I2C_SUCCESS = (u8) 1,                // 操作成功
        CNT_I2C_FAIL    = (u8) 0                        // 操作失败
} I2C_Op_TypeDef;                                                        // E2操作类.

void I2C_Delay(u32 u32Count);
// 释放I2C总线.
void I2C_BusRelease(void);
// I2C 初始化.
I2C_Op_TypeDef I2C_BusInit(void);

#endif // _DEV_I2C_H
点赞  2010-7-21 17:17
// I2C_BusInit调用完后可做如下工作,
    I2C_GenerateSTART(I2C1, ENABLE);
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
// 不过最好是在while语句中加入超时控制.
点赞  2010-7-21 17:20
已经解决,谢谢大家,现分享下我的问题:
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));
点赞  2010-7-21 17:45
                                 怎么没有R/W呢。。。
点赞  2011-1-25 19:06
                                 发现了。I2C direction
点赞  2011-1-25 19:30
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复