×
单片机 > 单片机程序设计 > 详情

STM32外设驱动篇——AT24C02(I2C接口)

发布时间:2020-08-31 发布时间:
|

SOC:STM32F103RCT6

软件平台:STM官方库V3.5.0

开发工具:Keil


1. 摘要

  本文章将给出STM32F103RCT6控制AT24C02的代码。如有疑问和错误,欢迎留言告之。


2.硬件连接


AT24C02使用I2C进行数据访问,板子上使用STM32的I2C控制器2和AT24C02进行连接。

具体来说,PB10作为SCL和AT24C02相连,PB11作为SDL和AT24C02相连。

这里就不给出硬件连接图了,比较简单。


3. AT24C022C访问代码(轮询)

I2C这里使用轮询方法,不是中断,请留意。

首先,给出I2C控制器的初始化代码,和读写代码,一共三个函数,对应三个功能。

注意:这里是使用I2C控制器2。


  1. #include "stm32f10x.h"  

  2. #include "stm32f10x_i2c.h"  

  3. #include   

  4.   

  5. void I2C2_Init(I2C_InitTypeDef* I2C_InitStruct)  

  6. {  

  7.     GPIO_InitTypeDef GPIO_InitStruct;   

  8.   

  9.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);      

  10.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);     

  11.       

  12.     /* 配置IO管脚 */  

  13.     GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11;         

  14.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;          

  15.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;  

  16.     GPIO_Init(GPIOB, &GPIO_InitStruct);   

  17.      

  18.     I2C_Init(I2C2, I2C_InitStruct);  

  19.     I2C_Cmd(I2C2, ENABLE);  

  20.       

  21.     // 配置NVIC  

  22. /*  NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQn   ;               //I2C事件中断 

  23.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;    //抢占优先级1  

  24.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;           //子优先级2  

  25.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //使能中断通道 

  26.     NVIC_Init(&NVIC_InitStructure);                             //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 */  

  27.   

  28.     //I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE); //打开事件中断  

  29. }  

  30.   

  31. /* i2c 写一个字节*/  

  32. /* Byte Write */  

  33. void I2C2_WriteByte(uint8_t DeviceAddress, uint8_t MemoryAddress, uint8_t Data)  

  34. {  

  35.     while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));      //等待I2C空闲   

  36.   

  37.     //start  

  38.     I2C_GenerateSTART(I2C2, ENABLE);  

  39.     while( I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS );   

  40.       

  41.     //device address  

  42.     I2C_Send7bitAddress(I2C2, DeviceAddress, I2C_Direction_Transmitter); //写模式  

  43.     while( I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS );     

  44.     //printf("address over ") ;   

  45.   

  46.     //memory address  

  47.     I2C_SendData(I2C2, MemoryAddress);  

  48.     while( I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS );   

  49.               

  50.     //data  

  51.     I2C_SendData(I2C2, Data);  

  52.     while( I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS );      

  53.   

  54.     //stop  

  55.     I2C_GenerateSTOP(I2C2, ENABLE);   

  56. }  

  57.   

  58. /* i2c 读一个字节*/  

  59. /* Random Read */  

  60. uint8_t I2C2_ReadByte(uint8_t DeviceAddress, uint8_t MemoryAddress)  

  61. {  

  62.     uint8_t Data;  

  63.       

  64.     while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));      //等待I2C空闲    

  65.     //start  

  66.     I2C_GenerateSTART(I2C2, ENABLE);  

  67.     while( I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS ); //ev5   

  68.   

  69.     //device address  

  70.     I2C_Send7bitAddress(I2C2, DeviceAddress, I2C_Direction_Transmitter);  //写模式  

  71.     while( I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS );   //ev6   

  72.        

  73.     //memory address  

  74.     I2C_SendData(I2C2,  MemoryAddress);  

  75.     while( I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS ) ;   

  76.                                                                             

  77.     //start  

  78.     I2C_GenerateSTART(I2C2, ENABLE);  

  79.     while( I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS ) ;      

  80.   

  81.     //device address  

  82.     I2C_Send7bitAddress(I2C2, DeviceAddress, I2C_Direction_Receiver); //读模式  

  83.     while( I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) != SUCCESS ) ;  

  84.       

  85.     /* 按照manual的图273,先读取数据,关闭ACK应答,最后发出STOP*/         

  86.     while( I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED) != SUCCESS );   /* 等待读取事件,再读取数据 */  

  87.     Data = I2C_ReceiveData(I2C2);   

  88.         I2C_AcknowledgeConfig(I2C2, DISABLE); //关闭应答和停止条件产生    

  89.     printf("received ");  

  90.     I2C_GenerateSTOP(I2C2, ENABLE);   

  91.       

  92.     I2C_AcknowledgeConfig(I2C2, ENABLE);   

  93.   

  94.     return Data;  

  95. }  


接着给出相应的AT24C02访问代码


  1. #include "stm32f10x.h"  

  2. #include "stm32f10x_i2c.h"  

  3. #include "i2c.h"  

  4. #include "delay.h"  

  5. #include   

  6.   

  7. /* 从AT24CXX的指定地址开始读出一个字节 */  

  8. uint8_t AT24CXX_ReadByte(uint8_t ReadAddr)  

  9. {  

  10.     return I2C2_ReadByte(0xA0, ReadAddr);  

  11. }    

  12.   

  13. /* 向AT24CXX的指定地址开始写入一个字节 */  

  14. void AT24CXX_WriteByte(uint8_t WriteAddr, uint8_t Data)  

  15. {  

  16.     I2C2_WriteByte(0xA0, WriteAddr, Data);  

  17. }  

  18.   

  19. void AT24CXX_test(void)  

  20. {  

  21.     uint8_t i;  

  22.     I2C_InitTypeDef I2C_InitStructure;   

  23.   

  24.     I2C_InitStructure.I2C_ClockSpeed    =  200000;     //200kHZ  

  25.     I2C_InitStructure.I2C_Mode          =  I2C_Mode_I2C;  

  26.     I2C_InitStructure.I2C_DutyCycle     =  I2C_DutyCycle_2; //根据datasheet,Tlow/Thigh = 2  

  27.     I2C_InitStructure.I2C_OwnAddress1   =  0xA0;          

  28.     I2C_InitStructure.I2C_Ack           =  I2C_Ack_Enable;  

  29.     I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  

  30.       

  31.     I2C2_Init(&I2C_InitStructure);  

  32.   

  33.     for(i = 0; i 

  34.         AT24CXX_WriteByte(i, 100 + i);  

  35.         /* NOTE: 根据datasheet,两次字节写之间必须延迟5ms,也就是stop和start之间的间隔时间*/  

  36.         delay_ms(6);    

  37.     }  

  38.     printf("Write completed  ");  

  39.   

  40.     for(i = 0; i 

  41.         printf("%d ", AT24CXX_ReadByte(i));  

  42.         delay_ms(6);  

  43.     }  

  44.     printf(" ");  

  45. }  


注意:两次访问间隔必须大于5ms,这是datasheet规定的。


如果不加延时,第二次写入时候,写入设备地址后,无法接受到ACK,程序陷入死循环。


关键字:STM32  外设驱动  AT24C02  I2C接口

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机电子密码锁仿真 可修改密码