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

STM32F103标准库开发---IIC主控实验---普通I/O口模拟---底层驱动程序

[复制链接]
STMCU小助手 发布时间:2022-9-7 15:22
IIC底层驱动程序
这次I是普通I/O端口模拟IIC通信实验
具体引脚配置如下:
1(AJZXY`OWAA2]LA6E)0B.png


IIC主控实验----底层驱动GPIO配置
GPIO初始化配置
具体代码如下:

  1. //初始化IIC
  2. void IIC_Init(void)
  3. {                                             
  4.         GPIO_InitTypeDef GPIO_InitStructure;
  5.         RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );        //使能GPIOB时钟
  6.            
  7.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
  8.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
  9.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  10.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  11.         
  12.         GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);         //PB6,PB7 输出高电平---空闲状态
  13. }
复制代码

时钟线(SCL)—GPIO功能配置
在IIC通信中,主控的时钟线(SCL) 一直是输出状态
具体程序如下:

  1. //时钟线(SCL):PB6输出---高电平
  2. #define SCL_H                  GPIO_SetBits(GPIOB,GPIO_Pin_6)  

  3. //时钟线(SCL):PB6输出---低电平                                                                                       
  4. #define SCL_L                  GPIO_ResetBits(GPIOB,GPIO_Pin_6)
复制代码

数据线(SDA)—GPIO功能配置
由于IIC通信是半双工通信方式
因而数据线(SDA)可能会是数据输入,也可能是数据输出。

  1. 数据线(SDA)输入模式
  2. //数据线(SDA):PB7输入
  3. #define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}

  4. //读取PB7的电平
  5. #define READ_SDA  GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)
复制代码

数据线(SDA)输出模式
  1. //数据线(SDA):PB7输出
  2. #define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}

  3. //数据线(SDA):PB7输出---高电平
  4. #define SDA_H          GPIO_SetBits(GPIOB,GPIO_Pin_7)        
  5. //数据线(SDA):PB7输出---低电平
  6. #define SDA_L          GPIO_ResetBits(GPIOB,GPIO_Pin_7)
复制代码

IIC主控实验----底层驱动程序
开始信号
当时钟线SCL 为高电平时,数据线SDA 由高电平向低电平跳变。

具体程序如下:

  1. void IIC_Start(void)//开始信号
  2. {
  3.         SDA_OUT();                        //数据线(SDA)输出模式
  4.         SDA_H;                                //数据线(SDA)输出高电平
  5.         SCL_H;                                //时钟线(SCL)输出高电平
  6.         delay_us(5);
  7.         SDA_L;                                //数据线(SDA)输出低电平
  8.         delay_us(5);
  9.         SCL_L;                                //时钟线(SCL)输出低电平
  10. }
复制代码

终止信号
当时钟线SCL 为高电平时,数据线SDA 由低电平向高电平跳变。

85e82cdd10414eafa919be9c7d480bf4.png

具体程序如下:

  1. void IIC_Stop(void)//终止信号
  2. {
  3.         SDA_OUT();                //数据线(SDA)输出模式
  4.         SCL_L;                        //时钟线(SCL)输出低电平
  5.         SDA_L;                        //数据线(SDA)输出低电平
  6.         delay_us(5);
  7.         SCL_H;                        //时钟线(SCL)输出高电平
  8.         SDA_H;                        //数据线(SDA)输出高电平
  9.         delay_us(5);
  10. }
复制代码

应答信号
我们这里写的是IIC主控程序,在读取从控数据的时候,需要回复应答信号。
产生应答信号,表示接收数据成功。

87595168bd4d4c1aa0c65f6957e146e7.png

具体程序如下:

  1. void IIC_Ack(void)//产生应答信号
  2. {
  3.         SCL_L;                        //时钟线(SCL)输出低电平
  4.         SDA_OUT();                //数据线(SDA)输出模式
  5.         SDA_L;                        //数据线(SDA)输出低电平
  6.         delay_us(2);
  7.         SCL_H;                        //时钟线(SCL)输出高电平
  8.         delay_us(5);
  9.         SCL_L;                        //时钟线(SCL)输出低电平
  10. }
复制代码

产生非应答信号,表示接收数据失败。

e71f596960034e5797457ea9bcbd1fd2.png

具体程序如下:

  1. void IIC_NAck(void)//不产生应答信号
  2. {
  3.         SCL_L;                        //时钟线(SCL)输出低电平
  4.         SDA_OUT();                //数据线(SDA)输出模式
  5.         SDA_H;                        //数据线(SDA)输出高电平
  6.         delay_us(2);
  7.         SCL_H;                        //时钟线(SCL)输出高电平
  8.         delay_us(5);
  9.         SCL_L;                        //时钟线(SCL)输出低电平
  10. }
复制代码


IIC主控程序,在写入数据到从控的时候,需要等待应答信号。

  1. //返回值:1,接收应答失败
  2. //        0,接收应答成功
  3. u8 IIC_Wait_Ack(void)//等待应答信号
  4. {
  5.         int uc=0;
  6.         SDA_IN();                //数据线(SDA)输入模式
  7.         SDA_H;  delay_us(1);
  8.         SCL_H;  delay_us(1);
  9.         while(READ_SDA)
  10.         {
  11.                 uc++;
  12.                 if(uc>250)//接收应答失败
  13.                 {
  14.                         IIC_Stop();//发送终止信号               
  15.                         return 1;
  16.                 }
  17.         }
  18.         SCL_L;
  19.         return 0;
  20. }
复制代码

数据传输
IIC总线进行数据传送时,时钟线(SCL)上的信号为高电平期间,数据线(SDA)上的数据必须保持稳定。
只有在时钟线(SCL)上的信号为低电平期间,数据线(SCL)上的高电平或低电平状态才允许变化。

e4fb93724d594f4b8cea33fae5a7e126.png

输出到数据线(SDA)上的每个字节必须是8位
数据传送时,先传送最高位(MSB),后传送最低位(LSB)
每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)

d41a30c5c86f40ca8c599ad13b0d5de8.png

IIC主控发送一个字节数据
具体程序如下:

  1. void IIC_Send_Byte(u8 txdata)//发送一个字节数据---高位在前,低位在后
  2. {
  3.         SDA_OUT();                                //数据线(SDA)输出模式
  4.         SCL_L;
  5.         for(int t=0;t<8;t++)        //高位在前,低位在后。
  6.         {
  7.                 if((txdata&0x80)>>7)           SDA_H;
  8.                 else                        SDA_L;
  9.                 txdata<<=1;
  10.                 delay_us(2);
  11.                 SCL_H;
  12.                 delay_us(2);
  13.                 SCL_L;
  14.                 delay_us(2);
  15.         }
  16. }
复制代码

IIC主控接收一个字节数据
具体程序如下:

  1. u8 IIC_Read_Byte(unsigned char ack)//读取一个字节数据---ack=1时,发送ACK,ack=0,发送nACK
  2. {
  3.         unsigned char rxdata=0,i;
  4.         SDA_IN();                //数据线(SDA)输入模式
  5.         for(i=0;i<8;i++)
  6.         {
  7.                 SCL_L;
  8.                 delay_us(2);
  9.                 SCL_H;
  10.                 rxdata<<=1;
  11.                 if(READ_SDA) rxdata++;
  12.                 delay_us(1);
  13.         }
  14.         if(!ack)   IIC_NAck();
  15.         else       IIC_Ack();
  16.         return rxdata;
  17. }
复制代码


————————————————
版权声明:根号五


08ca25e70b6748a585680b8b4fb6bb86.png
收藏 评论0 发布时间:2022-9-7 15:22

举报

0个回答

所属标签

相似分享

官网相关资源

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