• stm32之31.iic


    iic双线制。一根是SCL,作为时钟同步线;一根是SDA,作为数据传输线
    SDN 

    1. #include "iic.h"
    2. #define SCL PBout(8)
    3. #define SDA_W PBout(9)
    4. #define SDA_R PBin(9)
    5. void IIC_GPIOInit(void)
    6. {
    7. GPIO_InitTypeDef GPIO_InitStructure;
    8. //使能时钟G
    9. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    10. //3、配置PG9
    11. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    12. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    13. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    14. GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL;
    15. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 ;
    16. GPIO_Init(GPIOB, &GPIO_InitStructure);
    17. }
    18. static void __IIC_SDAMode( GPIOMode_TypeDef GPIO_Mode)
    19. {
    20. GPIO_InitTypeDef GPIO_InitStructure;
    21. //使能时钟G
    22. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    23. //3、配置PG9
    24. GPIO_InitStructure.GPIO_Mode = GPIO_Mode;
    25. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    26. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    27. GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL;
    28. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ;
    29. GPIO_Init(GPIOB, &GPIO_InitStructure);
    30. }
    31. //1、主机发送启动信号操作
    32. //启动信号:在SCL的高电平期间,SDA产生下降沿
    33. void IIC_Start(void)
    34. {
    35. //设置SDA引脚为输出模式
    36. __IIC_SDAMode(GPIO_Mode_OUT);
    37. //先保持一段时间空闲>=4us
    38. SCL = 1;
    39. SDA_W = 1;
    40. delay_us(5);
    41. //开始启动信号
    42. SDA_W = 0;//下降沿
    43. delay_us(5);
    44. SCL = 0;//保证启动信号后面函数能顺畅的接上
    45. }
    46. //2、主机发送停止信号操作
    47. //停止信号:在SCL的高电平期间,SDA产生上升沿
    48. void IIC_Stop(void)
    49. {
    50. //SDA设置为输出模式
    51. __IIC_SDAMode(GPIO_Mode_OUT);
    52. SDA_W = 0;
    53. SCL = 0;
    54. delay_us(5);
    55. SCL = 1;//先拉高 --- 高电平期间
    56. delay_us(5);
    57. SDA_W = 1;//产生上升沿
    58. }
    59. //3、主机给从机发送8个数据位
    60. void IIC_WriteByte(unsigned char WData)
    61. {
    62. //SDA设置为输出模式
    63. __IIC_SDAMode(GPIO_Mode_OUT);
    64. for(int i=0;i<8;i++)
    65. {
    66. SCL = 0;
    67. delay_us(2);
    68. SDA_W = (WData>>(7-i)) & 0x01;
    69. delay_us(3);
    70. SCL = 1;
    71. delay_us(5);
    72. }
    73. SCL = 0;
    74. }
    75. //4、主机读取从机发送过来8个数据位
    76. void IIC_ReadByte(unsigned char *RData)
    77. {
    78. unsigned char TemData=0;//临时存放读取的8bit数据
    79. //SDA设置为输入模式
    80. __IIC_SDAMode(GPIO_Mode_IN);
    81. for(int i=0;i<8;i++)
    82. {
    83. SCL = 0;
    84. delay_us(5);//SCL低电平期间是给从机发送数据位的时间
    85. SCL = 1;
    86. delay_us(2);
    87. if(SDA_R)
    88. {
    89. //数字1
    90. TemData |= 0x80>>i; //1000 0000
    91. }
    92. delay_us(3);//高电平期间主机可以判断SDA_R读取
    93. }
    94. SCL = 0;
    95. *RData = TemData;//将读到的结果存放到外面的容器中
    96. }
    97. //5、主机读取从机发送过来1个应答位
    98. //返回读到的应答位 0---有应答 1-----无应答
    99. char IIC_ReadAck(void)
    100. {
    101. char Ack=1;
    102. //SDA设置为输入模式
    103. __IIC_SDAMode(GPIO_Mode_IN);
    104. SCL = 0;
    105. delay_us(5);//低电平期间给从机发送应答信号的时间
    106. SCL = 1;
    107. delay_us(2);//高电平期间给主机读取数据位的时间
    108. Ack = SDA_R;
    109. delay_us(3);
    110. SCL = 0;
    111. return Ack;//返回读取到的应答结果 外面做判断处理
    112. }
    113. //6、主机发送给从机1个应答位
    114. //主机调用这个函数可以传参自己决定是发有应答还是无
    115. void IIC_WriteAck(char Ack)
    116. {
    117. //SDA设置为输出模式
    118. __IIC_SDAMode(GPIO_Mode_OUT);
    119. SCL = 0;
    120. delay_us(2);
    121. SDA_W = Ack;
    122. delay_us(3);
    123. SCL = 1;
    124. delay_us(5);
    125. SCL = 0;
    126. }
  • 相关阅读:
    Qt篇——横向/竖向布局动态添加和移除控件
    golang的问题2
    J9数字论:什么是Web3.0概念?
    docker简易入门(极简,纯干货)
    Vue3中的Ref与Reactive:深入理解响应式编程
    能动的电脑配件「GitHub 热点速览 v.22.11」
    APP启动流程二(源码30)之APP进程创建
    365包包模式,月月换新包,如何做到流量经营,把握用户的心?
    Jmeter 接口测试,参数值为列表,如何参数化?
    “/home/test/cc/bk-server/docker-compose.yml“ docker配置
  • 原文地址:https://blog.csdn.net/weixin_55647158/article/details/132673382