微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > LPC1788之IIC协议(包含片内集成和GPIO两种)

LPC1788之IIC协议(包含片内集成和GPIO两种)

时间:10-02 整理:3721RD 点击:
前一段时间,因为要用到一个屏幕,是IIC协议的,所以,对IIC协议进行了一定的研究,特此把它记录下来,方便以后的查看。
本次主要使用了LPC1788的来和GT910进行IIC通讯,因为LPC1788内部集成支持IIC总线,开始的时候,我使用的是GPIO模拟IIC,这样方便了解IIC。
具体如下:
GPIO模式下,配置引脚SCL,SDA引脚输入输出方式。

  1. static void iic_scl_out(void)//P0.20
  2. {
  3.         GPIO_SetDir(0,1<<20,1);//配置输出方式
  4. }

  5. static void iic_sda_out(void)//P0.19
  6. {
  7.         GPIO_SetDir(0,1<<19,1);//配置输出方式
  8. }

  9. static void iic_sda_in(void)//P0.19
  10. {
  11.         GPIO_SetDir(0,1<<19,0);//配置成输入方式,为了获取应答。
  12. }

复制代码

主机模式下,发送起始信号:

  1. extern void bsp_starti2c (void)//在SCL是高电平时,SDA产生下降沿
  2. {
  3.                 iic_sda_out();
  4.     SDA_H();
  5.     SCL_H();
  6.     IIC_delay( IIC_Delay_COUNT );
  7.     SDA_L();
  8.     IIC_delay( IIC_Delay_COUNT );
  9.     SCL_L();
  10.     IIC_delay( IIC_Delay_COUNT );
  11. }

复制代码

主机模式下发送数据,并设置是否需要应答

  1. extern uint32_t bsp_sendi2c (uint8_t dat, Bool ack)//ack是是否应答位
  2. {
  3.         uint32_t i;
  4.         iic_sda_out();
  5.         for (i = 0; i < 8; i++)
  6.         {
  7.                 SCL_L();
  8.                 IIC_delay( IIC_Delay_COUNT );               
  9.                 if (dat & 0x80)//SCL低电平时,SDA引脚电平变化。
  10.                 {
  11.                     SDA_H();
  12.                 }
  13.                 else
  14.                 {
  15.                     SDA_L();
  16.                 }
  17.                 IIC_delay( IIC_Delay_COUNT );               
  18.                 dat <<= 1;               
  19.                 SCL_H();//SCL置高电平,完成SDA数据发送。
  20.                 IIC_delay( IIC_Delay_COUNT );
  21.                 SCL_L();
  22.         }
  23.         
  24.         if (ack)//判断是否需要等待应答,如果是要发送的最后一byte数据,则可以不需要等待应答。
  25.         {
  26.                 iic_wait_ack();
  27.                 return 0;
  28.         }
  29.         else
  30.         {
  31.                 return 1;
  32.         }
  33. }

复制代码

等待应答函数:

  1. static void iic_wait_ack(void)
  2. {
  3.   unsigned int ys;
  4.         SCL_L();
  5.         IIC_delay( IIC_Delay_COUNT );
  6.         SDA_H();//SDA置高电平
  7.         IIC_delay( IIC_Delay_COUNT );
  8.         SCL_H();
  9.         iic_sda_in(); //开始准备接收应答位,如果SDA被拉低,说明应答,否则没有应答。
  10.         IIC_delay( IIC_Delay_COUNT );
  11.         do
  12.         {ys = GPIO_ReadValue (0);        
  13.         ys >>= 19;
  14.         ys &= 0x01;}
  15.         while(ys);//如果SDA一直是高电平, 说明没有应答。
  16.         SCL_L();        
  17. }

复制代码

读取数据

  1. extern uint32_t bsp_readi2c (uint8_t *retdat, Bool ack)//判断是否应答,如果是要接受的最后一字节数据,则不发送应答信号,否则要发送应答信号。
  2. {
  3.         uint8_t temp;
  4.         uint32_t i;
  5.         uint32_t ys;
  6.         SDA_H();
  7.         SCL_L();//SCL拉低,允许SDA数据发生变化。
  8.         IIC_delay( IIC_Delay_COUNT );
  9.         iic_sda_in(); //设置输入模式,准备读取引脚电平
  10.         for (i = 0; i < 8; i++)
  11.         {
  12.                 temp <<= 1; 先读取最高位
  13.                 SCL_H();
  14.                 iic_sda_in();
  15.                 IIC_delay( IIC_Delay_COUNT );
  16.                 ys = GPIO_ReadValue (0);
  17.                 ys >>= 19;
  18.                 ys &= 0x01;
  19.                 if (ys)
  20.                 {
  21.                         temp |= 0x01;
  22.                 }
  23.                 else
  24.                 {
  25.                         temp &= ~(0x01);
  26.                 }
  27.                 SCL_L();
  28.                 IIC_delay( IIC_Delay_COUNT );
  29.         }
  30.         *retdat = temp;
  31.         if (ack == TRUE)
  32.         {
  33.                 iic_ack();//发送应答信号
  34.         }
  35.         else
  36.         {
  37.                 iic_nack();//发送非应答信号
  38.         }
  39.         return 0;
  40. }

复制代码

发送iicstop信号

  1. extern void bsp_stopi2c (void)
  2. {
  3.           SCL_L();
  4.     IIC_delay( IIC_Delay_COUNT );//延时函数
  5.     SDA_L();
  6.     IIC_delay( IIC_Delay_COUNT );
  7.     SCL_H();//SCL置高电平
  8.     IIC_delay( IIC_Delay_COUNT );
  9.     SDA_H();//SDA产生上升沿,就是停止信号
  10.     IIC_delay( IIC_Delay_COUNT );
  11. }

复制代码





谢谢分享,学习了

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top