STM32的硬件I2C實現及問題

雖然軟件可實現I2C讀取三軸傳感器數據,但I2C作爲一種重要的通信協議是一定要搞清楚問題所在的,SO繼續研究之前的問題。(網上傳言STM32硬件I2C有問題,但仍然有人實現出來)

再次啓動程序,依舊是停在原來的位置

等待EV6,網上搜索相關問題好多人都停在了等待EV5上。分析EV5等待問題,主機發送起始信號,沒能接受從設備發送的應答,

或者可能都沒有發送。此問題應該是接線或IIC初始化代碼的問題。

而我此時停在等待EV6,說明已檢測到該設備。換句話說從設備已經知道了主設備的存在。卻在主設備發送設備地址之後,接受不到從設備的應答信號,自己分析有兩種可能,一是設備地址錯誤,從設備接受到不是自身的設備而地址自然不會應答。二是從設備已應答,而並接受到。在設備地址正確的前提下(前面已經通過例程驗證過,前面的文章),思索第二種問題。

網上類似問題網友迴應也是繁多,如RCC時鐘初始化的問題,檢查代碼RCC_APB1Periph_I2C1,RCC_APB2Periph_GPIOB均已使能。又如可能i2c1默認引腳被複用,或該引腳沒接上拉電阻,而不能開漏輸出。將默認PIN6.PIN7重映射後依舊老樣子排除該問題。

(重映射函數

GPIO_PinRemapConfig(u32 GPIO_Remap, FunctionalState NewState)


再一次想到時鐘問題,將IIC初始化結構體中的速率該低

原來是400000,也不行

直到在某論壇看到據說可以直接用的程序,打開發現代碼並無差別,唯一不同的是,RCC初始化,其代碼在主函數開始就初始化了所有的需要用到的時鐘包括

,只是初始化位置不同。。。。

終於豁然開朗。

數據讀取準確無誤。

之後又將初始化程序恢復到原位置發現,程序仍可正確運行,不知何解。

嘗試恢復速率發現,恢復成400000後不能讀取,程序停滯在等待EV6

2000000等待EV5,1000000等待EV5

只能還設爲100000,可以正常工作。

至此可確定STM32硬件I2C真的有問題!!!!

程序只能在10000輸出,僅供參考

.h

#ifndef __I2C_H__
#define __I2C_H__

#include "stm32f10x.h"

void I2C_GPIO_Config(void);
void I2C1_Init(void);
void I2C1_Write(u8 addr, u8 data);
u8 I2C1_Read(u8 nAddr);
#endif

.c

#include "tb_delay.h"
#include "i2c.h"
void I2C_GPIO_Config()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
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);
}

void I2C1_Init()
{
I2C_InitTypeDef I2C_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
I2C_DeInit(I2C1);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x77;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 10000;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}

void I2C1_Write(u8 addr, u8 data)
{
I2C_AcknowledgeConfig(I2C1,ENABLE); 
I2C_GenerateSTART(I2C1,ENABLE); 
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){;}//EV5
I2C_Send7bitAddress(I2C1,0x3a,I2C_Direction_Transmitter); 
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){;} //EV6
I2C_SendData(I2C1,addr); 
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){;} //EV8
I2C_SendData(I2C1,data);
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){;} 
I2C_GenerateSTOP(I2C1,ENABLE); 
}

u8 I2C1_Read(u8 nAddr)
{
I2C_AcknowledgeConfig(I2C1,ENABLE); //????
I2C_GenerateSTART(I2C1,ENABLE); //???????
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){;} //??EV5
I2C_Send7bitAddress(I2C1,0x3a,I2C_Direction_Transmitter); //????????
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){;}//??EV6
I2C_SendData(I2C1,nAddr);//?????
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){;} //??EV8

I2C_GenerateSTART(I2C1,ENABLE); //???????
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){;} //??EV5
I2C_Send7bitAddress(I2C1,0x3a,I2C_Direction_Receiver); //???????
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){;} //??EV6
I2C_AcknowledgeConfig(I2C1,DISABLE); //??????
I2C_GenerateSTOP(I2C1,ENABLE); //???????
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)){;} //??EV7
return I2C_ReceiveData(I2C1); //???????
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章