- 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)
|