你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32实例-I2C-EEPROM 实验⑥-I2C 读写字节函数

[复制链接]
STMCU小助手 发布时间:2022-6-27 10:28
    通过前面 I2C 的介绍,我们知道,要进行 I2C 通信,需要编写起始信号、停止信号、应答和非应答信号。因为 I2C 通信是以字节为单位进行传输的,所以还需要编写 I2C 读写字节的函数。数据的读写是在 SDA 线上完成,读数据的时候要配置此管脚为输入模式,写数据的时候要配置为输出模式,具体代码如下:
  1. /****************************************************************
  2. * 函 数 名 : SDA_OUT
  3. * 函数功能 : SDA 输出配置
  4. * 输 入 : 无
  5. * 输 出 : 无
  6. *****************************************************************/
  7. void SDA_OUT(void)
  8. {
  9. GPIO_InitTypeDef GPIO_InitStructure;
  10. GPIO_InitStructure.GPIO_Pin=IIC_SDA_PIN;
  11. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  12. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
  13. GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);
  14. }
复制代码
  1. /****************************************************************
  2. * 函 数 名 : SDA_IN
  3. * 函数功能 : SDA 输入配置
  4. * 输 入 : 无
  5. * 输 出 : 无
  6. *****************************************************************/
  7. void SDA_IN(void)
  8. {
  9. GPIO_InitTypeDef GPIO_InitStructure;
  10. GPIO_InitStructure.GPIO_Pin=IIC_SDA_PIN;
  11. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
  12. GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);
  13. }
复制代码
  1. /****************************************************************
  2. * 函 数 名 : IIC_Start
  3. * 函数功能 : 产生 IIC 起始信号
  4. * 输 入 : 无
  5. * 输 出 : 无
  6. *****************************************************************/
  7. void IIC_Start(void)
  8. {
  9. SDA_OUT(); //sda线输出
  10. IIC_SDA=1;
  11. IIC_SCL=1;
  12. delay_us(5);
  13. IIC_SDA=0;//START:when CLK is high,DATA change form high to low
  14. delay_us(6);
  15. IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
  16. }
复制代码
  1. /****************************************************************
  2. * 函 数 名 : IIC_Stop
  3. * 函数功能 : 产生 IIC 停止信号
  4. * 输 入 : 无
  5. * 输 出 : 无
  6. *****************************************************************/
  7. void IIC_Stop(void)
  8. {
  9. SDA_OUT();//sda线输出
  10. IIC_SCL=0;
  11. IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
  12. IIC_SCL=1;
  13. delay_us(6);
  14. IIC_SDA=1;//发送I2C总线结束信号
  15. delay_us(6);
  16. }
复制代码
  1. /****************************************************************
  2. * 函 数 名 : IIC_Wait_Ack
  3. * 函数功能 : 等待应答信号到来
  4. * 输 入 : 无
  5. * 输 出 : 1,接收应答失败
  6. 0,接收应答成功
  7. ******************************************************************/
  8. u8 IIC_Wait_Ack(void)
  9. {
  10. u8 tempTime=0;
  11. SDA_IN(); //SDA设置为输入
  12. IIC_SDA=1;
  13. delay_us(1);
  14. IIC_SCL=1;
  15. delay_us(1);
  16. while(READ_SDA)
  17. {
  18. tempTime++;
  19. if(tempTime>250)
  20. {
  21. IIC_Stop();
  22. return 1;
  23. }
  24. }
  25. IIC_SCL=0;//时钟输出0
  26. return 0;
  27. }
复制代码
  1. /****************************************************************
  2. * 函 数 名 : IIC_Ack
  3. * 函数功能 : 产生 ACK 应答
  4. * 输 入 : 无
  5. * 输 出 : 无
  6. *****************************************************************/
  7. void IIC_Ack(void)
  8. {
  9. IIC_SCL=0;
  10. SDA_OUT();
  11. IIC_SDA=0;
  12. delay_us(2);
  13. IIC_SCL=1;
  14. delay_us(5);
  15. IIC_SCL=0;
  16. }
复制代码
  1. /****************************************************************
  2. * 函 数 名 : IIC_NAck
  3. * 函数功能 : 产生 NACK 非应答
  4. * 输 入 : 无
  5. * 输 出 : 无
  6. *****************************************************************/
  7. void IIC_NAck(void)
  8. {
  9. IIC_SCL=0;
  10. SDA_OUT();
  11. IIC_SDA=1;
  12. delay_us(2);
  13. IIC_SCL=1;
  14. delay_us(5);
  15. IIC_SCL=0;
  16. }
复制代码
  1. /****************************************************************
  2. * 函 数 名 : IIC_Send_Byte
  3. * 函数功能 : IIC 发送一个字节
  4. * 输 入 : txd:发送一个字节
  5. * 输 出 : 无
  6. *****************************************************************/
  7. void IIC_Send_Byte(u8 txd)
  8. {
  9. u8 t;
  10. SDA_OUT();
  11. IIC_SCL=0;//拉低时钟开始数据传输
  12. for(t=0;t<8;t++)
  13. {
  14. if((txd&0x80)>0) //0x80 1000 0000
  15. IIC_SDA=1;
  16. else
  17. IIC_SDA=0;
  18. txd<<=1;
  19. delay_us(2); //对 TEA5767 这三个延时都是必须的
  20. IIC_SCL=1;
  21. delay_us(2);
  22. IIC_SCL=0;
  23. delay_us(2);
  24. }
  25. }
复制代码
  1. /****************************************************************
  2. * 函 数 名 : IIC_Read_Byte
  3. * 函数功能 : IIC 读一个字节
  4. * 输 入 : ack=1 时,发送 ACK,ack=0,发送 nACK
  5. * 输 出 : 应答或非应答
  6. *****************************************************************/
  7. u8 IIC_Read_Byte(u8 ack)
  8. {
  9. u8 i,receive=0;
  10. SDA_IN();//SDA设置为输入
  11. for(i=0;i<8;i++ )
  12. {
  13. IIC_SCL=0;
  14. delay_us(2);
  15. IIC_SCL=1;
  16. receive<<=1;
  17. if(READ_SDA)receive++;
  18. delay_us(1);
  19. }
  20. if (!ack)
  21. IIC_NAck();//发送 nACK
  22. else
  23. IIC_Ack(); //发送 ACK
  24. return receive;
  25. }
复制代码

    SDA_OUT 函数功能是配置SDA 管脚为输出模式,SDA_IN 函数功能是配置SDA管脚为输入模式,这两个函数我们是通过初始化 GPIO 方式完成,当然也可以直接配置寄存器来修改管脚模式,这些内容在前面 GPIO 章节就已经介绍过,不清楚回过头看下或者查看下STM32中文参考手册 GPIO 的寄存器部分。

收藏 评论0 发布时间:2022-6-27 10:28

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版