STM32自带的IIC配置

来源:互联网 发布:jquery导出表格数据 编辑:程序博客网 时间:2024/05/16 14:15

以下是main.c中的内容:

//**********************************************************// 使用STM32F103自带的IIC,利用IIC2实现STM32与EEPROM芯片// AT24C02间的数据传输。传输成功在LCD上显示。// 试验平台为正点原子的ALIENTEK战舰开发板//**********************************************************#include "sys.h"#include "delay.h"#include "usart.h"#include "lcd.h"#include "iic.h"int main(void){u8 data = 0;//测试的数据变量delay_init();//延时函数初始化uart_init(9600);//通用异步首发传输器初始化LCD_Init();//TFTLCD液晶初始化I2C2_Init();//STM32硬件自带IIC2初始化NVIC_Configuration();  //设置NVIC中断分组2:2位抢占优先级,2位响应优先级I2C2_WriteByte( AT24C02_ADDRESS, 1, 0x89 );//往EEPROM的第1个地址里写入0X89data = I2C2_ReadByte( AT24C02_ADDRESS, 1 ); //读取EEPROM第1个地址里的数据,赋给data      if (data==0x89)//如果data = 0X89,证明EEPROM写、读成功,STM32的IIC2写、读成功{POINT_COLOR = RED;//设置字体为红色 LCD_ShowString(35,50,200,16,16,"STM32 IIC2 READ/WRITE");LCD_ShowString(70,70,200,16,16,"SUCCESSFULLY");}while (1);}

以下是iic.c中的内容:

#include "iic.h"//*****************************************************// IIC2初始化函数:初始化STM32硬件自带的IIC2//                 IIC2_SCL对应GPIO.B10//                 IIC2_SDA对应GPIO.B11//*****************************************************void I2C2_Init(void){/*GPIO与IIC初始化结构体*/GPIO_InitTypeDef GPIO_InitStructure;I2C_InitTypeDef I2C_InitStructure;/*GPIO与IIC时钟使能*/RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//GPIOB时钟使能RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C2, ENABLE );//IIC2时钟使能/*初始化GPIO*/GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11;//初始化GPIO.B10(IIC2_SCL),GPIO.B11(IIC2_SDA)GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//最高输出速度50HzGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//输入输出模式为复用功能开漏输出GPIO_Init( GPIOB, &GPIO_InitStructure );//根据GPIO初始化结构体初始化GPIOB/*初始化IIC2*/I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//设置为IIC模式I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//设置IIC的占空比,低电平除以高电平值为2I2C_InitStructure.I2C_OwnAddress1 = AT24C02_ADDRESS;//指定第一个设备的地址为7位地址I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//使能ACK信号I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//指定7位地址I2C_InitStructure.I2C_ClockSpeed = 400000;//时钟频率,必须小于等于400KHzI2C_Cmd( I2C2, ENABLE );   //使能IIC2I2C_Init( I2C2, &I2C_InitStructure );//根据IIC初始化结构体初始化IIC2/*允许一字节一应答模式*/I2C_AcknowledgeConfig( I2C2, ENABLE );  //使能IIC2应答状态  }//*****************************************************// IIC2写函数   :往IIC设备写入一个BYTE的data// id           :IIC设备的id// write_address:数据要写入IIC设备的地址// data         :需要写入的数据//*****************************************************void I2C2_WriteByte( u8 id, u8 write_address, u8 data ){while (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));//当IIC2状态为BUSY时,一直停在这里死循环/*发送START之后要等待,意味着START条件被正确释放,此时IIC总线上没有其它外设*/I2C_GenerateSTART( I2C2, ENABLE );//一旦不为BUSY,跳出循环,产生START条件while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));//如果主机被选中(死循环等待ACK信号) /*主机发送地址联系从机后,主机要等待从机的ACK,如果主机设置为发射,*//*则收到ACK信号时 I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED 被置1 */I2C_Send7bitAddress( I2C2, id, I2C_Direction_Transmitter );//发送从机地址以选择从机,主机为发送模式while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//如果主机发射模式被选中(死循环等待ACK信号)/*通讯建立(生成START过程与从机地址被承认)以后,主机发送数据,*//*如果数据被转移并输出IIC总线,则 I2C_EVENT_MASTER_BYTE_TRANSMITTED 被置1*/I2C_SendData( I2C2, write_address );//将write_address,即要写的地址通过IIC2发送出去while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//如果地址已经从IIC2成功发射出去(死循环等待ACK信号)/*往寄存器发送数据data*/I2C_SendData( I2C2, data );while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_GenerateSTOP( I2C2, ENABLE );//IIC2产生STOP条件/*循环确保IIC设备与主机的通讯建立*/do{                I2C_GenerateSTART( I2C2, ENABLE );//IIC2产生START条件I2C_Send7bitAddress( I2C2, AT24C02_ADDRESS, I2C_Direction_Transmitter );//发送EEPROM地址0XA0}while (!(I2C_ReadRegister(I2C2,I2C_Register_SR1)&0x0002));//读取IIC2->SR1的值,当IIC2->SR1[1] = 1时跳出循环//此时地址发送结束I2C_ClearFlag( I2C2, I2C_FLAG_AF );//IIC2清除应答错误标志位   I2C_GenerateSTOP( I2C2, ENABLE );  //IIC2产生STOP条件}//*****************************************************// IIC2读函数   :从IIC设备的指定地址中读出一个BYTE的数据// id           :IIC设备的id// read_address :需要读取IIC数据的设备的地址// 返回值       :读出的数据//*****************************************************u8 I2C2_ReadByte( u8 id, u8 read_address ){  u8 data;  /***主机发送地址***/while (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));//当IIC2状态为BUSY时,一直停在这里死循环/*发送START之后要等待,意味着START条件被正确释放,此时IIC总线上没有其它外设*/I2C_GenerateSTART( I2C2, ENABLE );//一旦不为BUSY,跳出循环,产生START条件while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));//如果主机被选中(死循环等待ACK信号)/*主机发送地址联系从机后,主机要等待从机的ACK,如果主机设置为发射,*//*则收到ACK信号时 I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED 被置1 */I2C_Send7bitAddress( I2C2, id, I2C_Direction_Transmitter );//发送从机地址以选择从机,主机为发送模式while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//如果主机发射模式被选中(死循环等待ACK信号)/*通讯建立(生成START过程与从机地址被承认)以后,主机发送数据,*//*如果数据被转移并输出IIC总线,则 I2C_EVENT_MASTER_BYTE_TRANSMITTED 被置1*/I2C_Cmd( I2C2, ENABLE );//使能IIC2I2C_SendData( I2C2, read_address );  //将write_address,即要读的地址通过IIC2发送出去while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//如果地址已经从IIC2成功发射出去(死循环等待ACK信号?  I2C_GenerateSTART( I2C2, ENABLE );//产生START条件while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));//如果主机被选中(死循环等待ACK信号)/***主机接收数据***/I2C_Send7bitAddress( I2C2, id, I2C_Direction_Receiver );//主机设置为接收模式while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//如果主机接收模式被选中(死循环等待ACK信号)I2C_AcknowledgeConfig( I2C2, DISABLE );//失能IIC2的应答状态I2C_GenerateSTOP( I2C2, ENABLE );//产生STOP条件while (!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)));//如果主机接收数据成功(死循环等待ACK信号)  data = I2C_ReceiveData(I2C2);//返回IIC2接收的数据,赋给tempI2C_AcknowledgeConfig( I2C2, ENABLE );//再一次使能IIC2的应答状态return data;//返回接收到的数据}

以下是iic.h中的内容:

#ifndef _IIC_H#define _IIC_H#include "sys.h"/*EEPROM芯片AT24C02的芯片地址*/#define AT24C02_ADDRESS 0XA0void I2C2_Init(void);void I2C2_WriteByte( u8 id, u8 write_address, u8 data );u8 I2C2_ReadByte( u8 id, u8 read_address );#endif

以上iic部分代码参考了:http://www.amobbs.com/thread-5492914-1-1.html

0 0
原创粉丝点击