- int main(void)
- {
- u8 i = 0;
- u16 temp = 0;
- RCC_Configuration(); //時鐘配置
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級
-
- IIC_Configuration1();
- I2C_Configuration2();
-
- gpio_init();
- // TIM2_Int_Init(719,999); // 配置定時器TIM1每10ms產生中斷,定時器計數頻率為1kHz=72M/72000。
-
- //GPIO_SetBits(GPIOB,GPIO_Pin_0);
- while(1)
- {
- temp++;
- I2C_Master_BufferWrite(I2C1, I2C1_Buffer_Tx, 8, 0x20);
- __nop();
- for(i=0;i<8;i++)
- {
- I2C1_Buffer_Tx[i] = 0;
-
- }
- I2C_Master_BufferRead( I2C1, I2C1_Buffer_Tx,8, 0x20);
- for(i=0;i<8;i++)
- {
- I2C1_Buffer_Tx[i] = temp+i;
-
- }
-
- }
-
- }
- #include "i2c1.h"
- #include "delay.h"
- #include"stm32f10x.h"
- u8 Tx_Idx1 = 0;
- u8 Rx_Idx1 = 0;
- u8 I2C1_Buffer_Tx[8] = {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55};
- u8 I2C1_Buffer_Rx[8] = {0};
- u8 ReadingFlag = 0;
- /*IIC1從機模式*/
- void gpio_init()
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- //配置IO接口
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_5; //READY1/READY2
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //Waring
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- //void I2C_Configuration1(void)
- //{
- // GPIO_InitTypeDef GPIO_InitStructure;
- // I2C_InitTypeDef I2C_InitStructure;
- // NVIC_InitTypeDef NVIC_InitStructure;
- // //使能時鐘
- // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- // RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
- //
- // //配置IO接口
- // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //PB6/PB7
- // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //
- // GPIO_Init(GPIOB, &GPIO_InitStructure);
- //
- // I2C_InitStructure.I2C_ClockSpeed=400000; //I2C數據傳輸速度
- // I2C_InitStructure.I2C_Mode=I2C_Mode_I2C; //I2C模式設置 ,I2C模式,SMBus主模式,SMBus從模式
- // I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
- // I2C_InitStructure.I2C_OwnAddress1 =0x20; //設備地址
- // I2C_InitStructure.I2C_Ack =I2C_Ack_Enable;
- // I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit ; //尋址模式,7bit或者10bit
- // I2C_Init(I2C1,&I2C_InitStructure);
- // NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;//事件中斷
- // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- // NVIC_Init(&NVIC_InitStructure);
- // NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;//錯誤中斷
- // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- // NVIC_Init(&NVIC_InitStructure);
- // I2C_ITConfig(I2C1, I2C_IT_BUF | I2C_IT_EVT |I2C_IT_ERR, ENABLE);
- // I2C_Cmd(I2C1, ENABLE);
- //
- //}
- //void I2C1_EV_IRQHandler(void) //I2C1事件中斷響應函數 ,主要完成對上位機指令的響應
- //{
- // switch(I2C_GetLastEvent(I2C1))
- // {
- // case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
- // {
- //// I2C_GenerateSTOP(I2C2, DISABLE);
- // I2C_ClearFlag(I2C1,I2C_FLAG_ADDR);
- // I2C_ClearFlag(I2C1,I2C_FLAG_BTF);
- // break;
- // }
- // case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
- // I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx1++]);
- // break;
- // case I2C_EVENT_SLAVE_BYTE_TRANSMITTING: //EV3
- // I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx1++]);
- // break;
- // case I2C_EVENT_SLAVE_BYTE_RECEIVED:
- // I2C_ClearFlag(I2C1,I2C_FLAG_BTF);
- // I2C1_Buffer_Rx[Rx_Idx1++] = I2C_ReceiveData(I2C1);
- // break;
- // case I2C_EVENT_SLAVE_STOP_DETECTED:
- // I2C_ClearFlag(I2C1,I2C_FLAG_STOPF);
- // I2C_GenerateSTOP(I2C1, DISABLE);
- // Rx_Idx1=0;
- // //i2c_event = EVENT_OPCOD_NOTYET_READ;
- // break;
- // default:
- // break;
- // }
- //}
- //
- //void I2C1_ER_IRQHandler(void) //I2C2錯誤事件中斷響應函數
- //{
- // if (I2C_GetITStatus(I2C1, I2C_IT_AF))
- // {
- // I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
- //
- // Tx_Idx1 = 0;
- // //i2c_event = EVENT_OPCOD_NOTYET_READ;
- //
- // }
- //
- // if (I2C_GetITStatus(I2C1, I2C_IT_BERR))
- // {
- // I2C_ClearITPendingBit(I2C1, I2C_IT_BERR);
- // }
- //}
- /*IIC1主機模式*/
- #define DEVICE_ADDRESS 0x20
- /*******************************************************************************
- * Function Name : IIC_Configuration
- * Description : 初始化IIC2外設
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void IIC_Configuration1(void)
- {
- //先定義結構體
- GPIO_InitTypeDef GPIO_InitStructure;
- I2C_InitTypeDef I2C_InitStructure;
-
- //要開了對應的gpio的時鐘還有其他的外設的時鐘,然后你配置寄存器才可以,軟件仿真里面開時鐘先后沒有影響,但是實物里面,要先開時鐘
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能APB2外設的GPIOB的時鐘,I2C2是PB_10 SCL,PB_11 SDA上面的復用
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 ,ENABLE); //開啟時鐘
-
- //要對上面定義的兩個結構體進行定義,首先PB要定義為復用的才行,而且是開漏復用
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //選擇PB_6是SCL引腳
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管腳頻率為50MHZ
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //輸出模式為復用開漏輸出
- GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化GPIOB寄存器
-
- //配置I2C
- I2C_DeInit(I2C1);//I2C1寄存器復位
- I2C_InitStructure.I2C_ClockSpeed = 400000; /*I2C的時鐘頻率100kHz ,不是I2C輸入時鐘的頻率*/
- I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
- I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; /*設置CCR寄存器的,占空比 快速模式下0:Tlow/Thigh = 2;1:Tlow/Thigh = 16/9 */
- I2C_InitStructure.I2C_OwnAddress1 = 0x20 ; /*這句話說的是stm32作為從機的時候它的地址,如果沒有做從機不用理會這個值*/
- I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; /*應答使能 */
- I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /* */
- I2C_Init(I2C1,&I2C_InitStructure);
-
- //使能I2C
- I2C_Cmd(I2C1, ENABLE);
- }
- /*******************************************************************************
- 主機發送數據的流程:
- 1) 主機在檢測到總線為“空閑狀態”(即 SDA、SCL 線均為高電平)時,發送一個啟動信號“S”,開始一次通信的開始
- 2) 主機接著發送一個命令字節。該字節由 7 位的外圍器件地址和 1 位讀寫控制位 R/W組成(此時 R/W=0)
- 3) 相對應的從機收到命令字節后向主機回饋應答信號 ACK(ACK=0)
- 4) 主機收到從機的應答信號后開始發送第一個字節的數據
- 5) 從機收到數據后返回一個應答信號 ACK
- 6) 主機收到應答信號后再發送下一個數據字節
- 7) 當主機發送最后一個數據字節并收到從機的 ACK 后,通過向從機發送一個停止信號P結束本次通信并釋放總線。從機收到P信號后也退出與主機之間的通信。
- 主機發送數據的程序
- *******************************************************************************//**/
- uint8_t I2C_Master_BufferWrite(I2C_TypeDef * I2Cx, uint8_t* pBuffer, uint32_t NumByteToWrite, uint8_t SlaveAddress)
- {
- if(NumByteToWrite==0)
- return 1;
- /* 1.開始,發送一個s,也就是起始信號*/
- I2C_GenerateSTART(I2Cx, ENABLE);
- ///判斷EV5,看下函數定義可以發現,該事件是SB=1,MSL=1,BUSY=1 意思是起始條件已經發送了,然后是主模式,總線在通訊
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
- /* 2.設備地址·/寫 */
- I2C_Send7bitAddress(I2Cx, SlaveAddress, I2C_Direction_Transmitter);
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
- /* 3.連續寫數據 */
- while(NumByteToWrite--)
- {
- I2C_SendData(I2Cx, *pBuffer);
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
- pBuffer++;
- }
- /* 4.停止 */
- I2C_GenerateSTOP(I2Cx, ENABLE);//產生停止信號P,結束本次通訊釋放總線
- while ((I2Cx->CR1&0x200) == 0x200);//完成當前字節傳輸后釋放 SCL 和 SDA 線
-
- return 0;
- }
- /*******************************************************************************
- IIC主機讀取數據的具體流程:
- 1) 主機發送啟動信號后,接著發送命令字節(其中 R/W=1)
- 2) 對應的從機收到地址字節后,返回一個應答信號并向主機發送數據
- 3) 主機收到數據后向從機反饋一個應答信號
- 4) 從機收到應答信號后再向主機發送下一個數據
- 5) 當主機完成接收數據后,向從機發送一個“非應答信號(ACK=1)”,從機收到ACK=1 的非應答信號后便停止發送
- 6) 主機發送非應答信號后,再發送一個停止信號,釋放總線結束通信.
- *******************************************************************************/
- uint8_t I2C_Master_BufferRead(I2C_TypeDef * I2Cx, uint8_t* pBuffer, uint32_t NumByteToRead, uint8_t SlaveAddress)
- {
- if(NumByteToRead==0)
- return 1;
- ///等待總線空閑
- while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
- ///在接受一個字節(匹配地址或數據)之后返回應答
- I2C_AcknowledgeConfig(I2Cx, ENABLE);
-
- /* 1.開始 */
- I2C_GenerateSTART(I2Cx, ENABLE);
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
-
- /* 2.設備地址·/寫 */
- I2C_Send7bitAddress(I2Cx, SlaveAddress, I2C_Direction_Transmitter);
- while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
- /* 3.開始*/
- I2C_GenerateSTART(I2Cx, ENABLE);
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
-
- /* 4.設備地址·/讀 */
- I2C_Send7bitAddress(I2Cx, SlaveAddress, I2C_Direction_Receiver);
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
- /* 5.連續寫數據 */
- while (NumByteToRead)
- {
- if(NumByteToRead==1)
- {
- I2C_AcknowledgeConfig(I2Cx, DISABLE);
- I2C_GenerateSTOP(I2Cx, ENABLE);//6.停止,非應答
- }
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */
- *pBuffer++ = I2C_ReceiveData(I2Cx);
- NumByteToRead--;
- }
- I2C_AcknowledgeConfig(I2Cx, ENABLE);
- return 0;
- }
復制代碼
全部資料51hei下載地址:
stm32 IIC2.7z
(190.48 KB, 下載次數: 44)
2019-7-26 22:46 上傳
點擊文件名下載附件
|