历史上的今天
返回首页

历史上的今天

今天是:2025年04月15日(星期二)

正在发生

2018年04月15日 | STM32自带的IIC配置

2018-04-15 来源:eefocus

以下是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个地址里写入0X89  

    data = 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;           //最高输出速度50Hz  

    GPIO_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的占空比,低电平除以高电平值为2  

    I2C_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;                  //时钟频率,必须小于等于400KHz  

      

    I2C_Cmd( I2C2, ENABLE );                                    //使能IIC2  

    I2C_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 );                                                    //使能IIC2  

    I2C_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接收的数据,赋给temp  

    I2C_AcknowledgeConfig( I2C2, ENABLE );                                      //再一次使能IIC2的应答状态  

  

    return data;                                                                //返回接收到的数据  

}  


以下是iic.h中的内容:

#ifndef _IIC_H  

#define _IIC_H  

  

#include "sys.h"  

  

/*EEPROM芯片AT24C02的芯片地址*/  

#define AT24C02_ADDRESS 0XA0  

  

  

void I2C2_Init(void);  

void I2C2_WriteByte( u8 id, u8 write_address, u8 data );  

u8 I2C2_ReadByte( u8 id, u8 read_address );  

  

#endif  


推荐阅读

史海拾趣

杰力(EMC)公司的发展小趣事

杰力(EMC)公司成立于XXXX年,由一群具有丰富电子行业经验的专业人士创立。公司初期专注于功率组件和集成电路(IC)的设计与开发,以满足不断增长的电子市场需求。通过引进先进的生产设备和工艺,杰力迅速建立起一条高效的生产线,并开始为一些小型电子厂商提供定制化的产品。随着产品质量的不断提升和客户口碑的积累,杰力逐渐在市场中树立了良好的品牌形象。

Benchmarq Microelectronics Inc公司的发展小趣事

随着半导体技术的不断进步,Benchmarq Microelectronics Inc始终保持着对技术创新的追求。公司加大研发投入,引进先进的生产设备和技术人才,不断推出具有创新性的半导体产品。其中,一款具有高性能、低功耗特点的芯片是公司技术创新的代表作。这款芯片采用了先进的工艺和材料,实现了更高的集成度和更低的功耗,满足了客户对高性能、长续航的需求。同时,公司还不断优化产品设计和生产流程,提高产品质量和生产效率,为客户提供了更加优质、可靠的产品。

福斯特(FIRST)公司的发展小趣事
使用压电或电容等技术。
DART(英国达特)公司的发展小趣事

DART公司成立于英国的一个小城市,最初只有几名工程师和少量的资金。然而,他们凭借着对电子技术的热爱和对创新的不懈追求,逐渐在行业中崭露头角。公司的创始人是一位资深的电子工程师,他带领团队开发了一款具有革命性的新型传感器,这款传感器在精度和稳定性上远超当时的同类产品。这一技术突破为DART公司赢得了第一个重要的客户,也为公司的未来发展奠定了坚实的基础。

安信可(Ai)公司的发展小趣事

2012年4月,深圳市安信可科技有限公司正式成立,标志着这家公司在电子行业的起点。成立之初,安信可便专注于物联网领域,致力于为客户提供高质量的模组产品。通过引入先进的科技和创新理念,安信可逐渐在物联网市场中崭露头角,为后续的发展奠定了坚实的基础。

Chips And Technologies Inc公司的发展小趣事

随着公司规模的扩大和市场份额的提升,C&T开始积极拓展海外市场。通过设立分支机构、参加国际展会等方式,C&T的产品逐渐打入国际市场,赢得了全球客户的认可。同时,C&T还积极与海外企业开展合作,共同推动半导体技术的发展和应用。

问答坊 | AI 解惑

2440 wince 5.0移植到wince6.0

谁做过2440的wince 5.0的bsp移植到wince6.0? 我有个2440的板子,想把5.0换成6.0。该怎么移植,大家给点意见…

查看全部问答>

求助:vxworks启动盘 总是不成功

                各位大侠帮帮忙啊! 我把启动盘插入后,显示器上显示:v1.6+++++++++++++++。几行加号以后就停在那里不动了。 我的目标机处理器是p3的,网卡类型是Intel 8255x ethernet interface. ...…

查看全部问答>

verilog -- inout 测试问题

verilog 的代码: module bi4b(q,dout,din,ctr1); parameter wide = 3; inout[wide:0] q; input ctr1; input[wide:0] din; output[wide:0] dout; wire[3:0] q,dout; assign dout = (!ctr1) ? q : 4\'bz; assign q = (ctr1) ? din : 4\'bz; ...…

查看全部问答>

模电知识

1.为什么当D1开路是T1、T2管会因功耗过大而损坏? 2.为什么当T1管集电极开路T2管会因功耗过大而损坏? 麻烦各位大侠帮忙讲解一下,谢谢喽 …

查看全部问答>

CCS 5装好不能用,求各位大虾帮帮忙啊

装好之后打开选途径,该了下就出现第二幅图,打不开,不能用…

查看全部问答>

小弟准备升大三,想搞嵌入式,纠结考研呢,大家帮我,对编程有兴趣,想搞嵌入式 LINUX

请教前辈们 小弟准备升大三,想搞嵌入式,纠结考研呢,大家帮我,对编程有兴趣,想搞嵌入式 LINUX,这些偏软的工作, 现在经常参加竞赛,明年有个全国电子设计大赛,如果考研就没时间参加了。还有就是,很多人说考研对以后长远发展还是很有好处的 ...…

查看全部问答>

Beaglebone学习之外围电路设计参考资料最全汇总贴

我把外围电路设计过程中的参考资料全部汇总了放上来,欢迎大家下载,有商业板的资料,有开源的资料,有原厂的资料,有我们坛子里网友分享的资料,下一步准备把全部原件库和封装库发上来,这个我还在整理,等我画完了就上传,希望大家都更贴补充 ...…

查看全部问答>

LPC1500体验+Hello EEWorld!

本帖最后由 ddllxxrr 于 2014-7-30 09:58 编辑 这个我认为是选择mbed的好处啦。为什么呢,不用看手册,不用去构思,拿来主义,只两句话两板线就可实现串口通讯。 少费话,上程序! #include \"mbed.h\" DigitalOut myled(LED1); Serial pc( ...…

查看全部问答>

低级bug耗费12小时Fix

本帖最后由 lzwml 于 2016-5-4 16:34 编辑 调试某程序非常简单的程序,简单到认为不可能存在缺陷,但该BUG处理时间超过12小时: 程序属于后台进程,监控系统每隔15秒检查外设IO状态,IO异常后发出报警或复位外设,外设都在linux下有/sys/class等 ...…

查看全部问答>