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没有使能啊?
STM8L的I2C设置也需要设置GPIO(PC0,PC1)为OD输出,这跟STM8S、STM32F是类似的。
设置为OD输出了,系统时钟为CLK_SYSCLKDiv_4,电阻上拉,但是未连接其他I2C的设备,程序运行到这里不知道有没有影响
未连接其他I2C的设备,程序运行到发送 START位 应该没有影响
那就应该是I2C没有使能,我查了stm8l1526开发板的代码,发现没什么特别之处啊,而且他并没有初始化IO为OD输出
难道大家都不用硬件I2C,谁共享一段I2C初始化的代码啊?
我的初始化代码大约是这样,供参考:
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);
stm8的硬件I2C不好用,我宁愿用模拟的,不就两端口嘛
我也比较赞成用模拟的,感觉楼主I2C初始化程序没什么问题
供参考....
/**
******************************************************************************
* @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
// I2C_BusInit调用完后可做如下工作,
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
// 不过最好是在while语句中加入超时控制.
已经解决,谢谢大家,现分享下我的问题:
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));