最近用HK的32畫了一塊板子想測試一下芯片功能,用到了硬件IIC,因為我之前一直都是用的模擬IIC,沒接觸過硬件IIC,就花了點時間研究了一下網上的案例。測試的時候用的是正點的stm32f407探索者板子,依手冊PB6,7 或者PB8,9都可復用為I2C1,我就隨便挑了一組。寫完IIC幾個關鍵函數以后試著跑了一下中景園那個OLED的例程,屏的代碼是絕對沒問題的,大家用過都知道。硬件IIC運行成功,然后代碼里有一步是scroll刷屏顯示漢字,速度奇慢無比,與軟件IIC比起來差了三四倍,但是我的硬件IIC已經都配置成400KHZ了,照樣沒用。現在有兩個疑惑:
1.依原子的原理圖該I2C1 4.7K上拉,除了我自己掛載的OLED外,連接了器件24C02,MPU6050,WM8978,只啟動了I2C1總線,在沒有對這些器件使能編寫驅動的時候,他們是否也屬于掛在I2C1總線上,這樣的話,會不會是驅動能力不足的問題?(沒接觸過多個從機不太了解忘指教)
2.懷疑是IIC實現代碼出了問題,檢查ev5,ev6,ev8-2等事件時,需要重復進行檢測讀取,造成了巨大的卡頓。問一下各位大佬是因為這部分函數的問題嗎,如果是的話,我該怎么優化呢。
下附我參考別人修改的I2C程序。- //PB6 PB7復用為SCL和SDA
- void I2C1_GPIO_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//開漏,實現IIC線與
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_I2C1);
- GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_I2C1);
- }
- //I2C配置
- void I2C1_Configuration(void)
- {
- I2C_InitTypeDef I2C_InitStructure;
- I2C_DeInit(I2C1);
- I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//I2C模式
- I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//SCL占空比
- I2C_InitStructure.I2C_OwnAddress1 = 0XA0;//主機地址
- I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
- I2C_InitStructure.I2C_AcknowledgedAddress= I2C_AcknowledgedAddress_7bit;//七位地址
- I2C_InitStructure.I2C_ClockSpeed = 400000;//400KHZ
- I2C_Init(I2C1, &I2C_InitStructure);
- I2C_Cmd(I2C1, ENABLE);
- }
- //I2C初始化
- void I2C1_Init(void)
- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);//I2C時鐘使能
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//GPIO時鐘使能
- I2C1_GPIO_Configuration();
- I2C1_Configuration();
- }
- //起始信號 0成功 1失敗
- u8 I2C_Start(void)
- {
- u16 time=0;
- I2C_GenerateSTART(I2C1,ENABLE);
- //檢查ev5事件
- while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)!=SUCCESS)
- {
- time++;
- if(time>1000)
- {
- return 1;
- }
- }
- return 0;
- }
- //結束信號
- void I2C_Stop(void)
- {
- I2C_GenerateSTOP(I2C1,ENABLE);
- }
- //發送從設備地址
- u8 I2C_SendAddr(u8 addr)
- {
- u32 event=I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED;//發送模式
- u16 time=0;
- I2C_Send7bitAddress(I2C1,addr,addr&0x01);
-
- if(addr&0x01)//判斷末位
- event=I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED;//接收模式
- //檢查ev6事件
- while(I2C_CheckEvent(I2C1,event)!=SUCCESS)
- {
- time++;
- if(time>1000)
- {
- return 1;
- }
- }
- return 0;
- }
- //發送數據
- void I2C_SendDat(u8 data)
- {
- I2C_SendData(I2C1,data);
- }
- //獲取應答信號
- u8 I2C_get_Ack(void)
- {
- u16 time=0;
- //檢查ev8-2
- while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)!=SUCCESS)
- {
- time++;
- if(time>1000)
- {
- return 1;
- }
- }
- return 0;
- }
復制代碼
|