|
发表于 2012-4-24 10:46:33
|
显示全部楼层
你好,能否抽空帮我看下这个程序,我在两块STM32板子间做I2C通信,主发从收,因为没有两个主机两个仿真器 ,我就是先将主机的程序固化到主机中,然后在从机上调试运行,结果是跑了N多次,只有两次收到数据,都是正确的。其他时候就一直停在
1. while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); //Bus busy flag 0x00020000 -- SR2 BUSY位
或者停在 /*接收地址*/
2. I2C_Send7bitAddress(I2C1,0x60,I2C_Direction_Receiver); //从机地址 传输方向
while(!I2C_CheckEvent(I2C1, I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED));/*EV1 ADDR*/
你能否帮我看下,到底是哪里出错了。。。俺琢磨了好久,都是按照STM32手册写的,怎么就错了呢。。。。。。
////////////////////////////////////主STM32板 设置地址为0x90////////////////////////////////
#define N 8
int main(void)
{
I2C_Configuration();
I2C_Master_Send();
}
void I2C_Configuration(void)
{
I2C_InitTypeDef I2C_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); //I2C时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //I2C对应GPIO管脚时钟
/* PB6,7 I2C1 PB10.11 I2C2 SCL and SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //设置管脚为复用功能开漏输出
GPIO_Init(GPIOB, &GPIO_InitStructure); //I2C接口使用的GPIO管脚初始化
I2C_DeInit(I2C1); //0x40005400恢复到默认值
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //设置I2C接口模式
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //设置I2C接口的高低电平周期
I2C_InitStructure.I2C_OwnAddress1 = 0x90; //设置I2C接口的主机地址
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //设置是否开启ACK响应
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000; //100K速度
I2C_Cmd(I2C1, ENABLE); //使能I2C接口
I2C_Init(I2C1, &I2C_InitStructure); //I2C接口初始化
/*允许1字节1应答模式*/
I2C_AcknowledgeConfig(I2C1, ENABLE); //使能I2C接口响应--应答功能
}
void I2C_Master_Send(void)
{
u8 i,data_send[N],data_receive[N];
for(i=0;i<N;i++)
{
data_send[i] = i+9;
data_receive[i] = 0;
}
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); //Bus busy flag 0x00020000 -- SR2 BUSY位
/*起始位*/
I2C_GenerateSTART(I2C1, ENABLE); //CR1_START_Set 0x0100 -- CR1 START
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* EV5 0x00030001 BUSY, MSL and SB flag */
/*写器件地址*/
I2C_Send7bitAddress(I2C1,0x60,I2C_Direction_Transmitter); //从机地址 传输方向
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* EV6.8 BUSY, MSL, ADDR, TXE and TRA flags */
/*写地址值*/
// I2C_SendData(I2C1, 0);
// while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* TRA, BUSY, MSL, TXE and BTF flags */
for(i=0;i<N;i++)
{
I2C_SendData(I2C1,data_send[i]);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* EV8 TRA, BUSY, MSL, TXE and BTF flags */
}
/*停止位*/
I2C_GenerateSTOP(I2C1, ENABLE);
}
////////////////////////////////////从STM32板 设置地址为0x60////////////////////////////////
#define N 8
int main(void)
{
I2C_Configuration();
I2C_Slave_Receive();
}
void I2C_Configuration(void)
{
I2C_InitTypeDef I2C_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); //I2C时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //I2C对应GPIO管脚时钟
/* PB6,7 I2C1 PB10.11 I2C2 SCL and SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //设置管脚为复用功能开漏输出
GPIO_Init(GPIOB, &GPIO_InitStructure); //I2C接口使用的GPIO管脚初始化
I2C_DeInit(I2C1); //0x40005400恢复到默认值
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //设置I2C接口模式
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //设置I2C接口的高低电平周期
I2C_InitStructure.I2C_OwnAddress1 = 0x60; //设置I2C接口的主机地址
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //设置是否开启ACK响应
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000; //100K速度
I2C_Cmd(I2C1, ENABLE); //使能I2C接口
I2C_Init(I2C1, &I2C_InitStructure); //I2C接口初始化
/*允许1字节1应答模式*/
I2C_AcknowledgeConfig(I2C1, ENABLE); //使能I2C接口响应--应答功能
}
void I2C_Slave_Receive(void)
{
u8 i,data_receive[N];
for(i=0;i<N;i++)
{
data_receive[i] = 0;
}
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); //Bus busy flag 0x00020000 -- SR2 BUSY位
/*允许1字节1应答模式*/
I2C_AcknowledgeConfig(I2C1, ENABLE); //CR1_ACK_Set 0x0400 -- CR1 ACK位
/* 发送起始位 */
I2C_GenerateSTART(I2C1, ENABLE); //CR1_START_Set 0x0100 -- CR1 START
/*接收地址*/
I2C_Send7bitAddress(I2C1,0x60,I2C_Direction_Receiver); //从机地址 传输方向
while(!I2C_CheckEvent(I2C1, I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED));/*EV1 ADDR*/
for(i=0;i<N;i++)
{
if(7==i)
{
I2C_AcknowledgeConfig(I2C1, DISABLE); //最后一位后要关闭应答的
I2C_GenerateSTOP(I2C1, ENABLE); //发送停止位
}
while(!I2C_CheckEvent(I2C1, I2C_EVENT_SLAVE_BYTE_RECEIVED)); /* EV2 */
data_receive[i] = I2C_ReceiveData(I2C1);
}
//再次允许应答模式
I2C_AcknowledgeConfig(I2C1, ENABLE);
}
|
|