找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4412|回复: 7
打印 上一主题 下一主题
收起左侧

STM32软件IIC SPI程序 方便移植

  [复制链接]
跳转到指定楼层
楼主
提供软IIC随意移植随意改接口
众所周知 stm32的硬件iIC协议不好用

单片机源程序如下:
  1. #include "myiic.h"
  2. #include "delay.h"

  3. //已删除所有延时 1 - 2us延时        若IIC通信出错或许是没有延时问题
  4. //或者时钟源问题

  5. void IIC_Init()
  6. {
  7.         GPIO_InitTypeDef  GPIO_InitStructure;
  8. /****************************IIC_SDA初始化***********************************************/
  9.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_IIC_SDA_PORT, ENABLE);        //使能SDA连接端口时钟   /
  10.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SDA;                                                                                //SDA端口配置                                           /
  11.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                                          //推挽输出                                                         /
  12.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                                        //IO口速度为50MHz                                 /
  13.         GPIO_Init(GPIO_SDA_PORT, &GPIO_InitStructure);                                                                 //根据设定参数初始化SDA /
  14. /****************************IIC_SCL初始化***********************************************/
  15.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_IIC_SCL_PORT, ENABLE);        //使能SCL连接端口时钟          /
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SCL;                                                                                //SCL端口配置                                                 /
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                                          //推挽输出                                                         /
  18.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                                        //IO口速度为50MHz                                 /
  19.         GPIO_Init(GPIO_SCL_PORT, &GPIO_InitStructure);                                                                 //根据设定参数初始化SCL /
  20. /****************************************************************************************/
  21. }


  22. /**********************************************/
  23. //                                                IIC Start
  24. //开始信号:在SCL为高电平时,SDA由高电平向低电平跳变,开始传输数据。
  25. /**********************************************/
  26. void IIC_Start()
  27. {
  28.         SDA_OUT();
  29.         IIC_SCL=1;
  30.         IIC_SDA=1;
  31.         delay_us(2);
  32.         IIC_SDA=0;
  33.         delay_us(2);
  34.         IIC_SCL=0;
  35. }


  36. /**********************************************/
  37. //                                                IIC Stop
  38. //结束信号:在SCL为高电平时,SDA由低电平向高电平跳变,结束传输数据。
  39. /**********************************************/
  40. void IIC_Stop()
  41. {
  42.         SDA_OUT();
  43.         IIC_SCL=1;
  44.         IIC_SDA=0;
  45.         delay_us(2);
  46.         IIC_SDA=1;
  47.         delay_us(2);

  48. }

  49. /**********************************************/
  50. //                                                IIC主机产生ACK应答信号
  51. /**********************************************/
  52. void IIC_ACK(void)
  53. {
  54.         SDA_OUT();
  55.         IIC_SCL=0;
  56.         IIC_SDA=0;
  57.         delay_us(2);
  58.         IIC_SCL=1;
  59.         delay_us(2);
  60.         IIC_SCL=0;
  61. }

  62. /**********************************************/
  63. //                                                IIC主机不产生ACK应答信号
  64. /**********************************************/
  65. void IIC_NACK(void)

  66. {
  67.         SDA_OUT();
  68.         IIC_SCL=0;
  69.         IIC_SDA=1;
  70.         delay_us(2);
  71.         IIC_SCL=1;
  72.         delay_us(2);
  73.         IIC_SCL=0;
  74. }


  75. /**********************************************/
  76. //                                                IIC Wait Ack
  77. //等待应答信号到来
  78. //返回值        1,接收应答失败
  79. //        0,接收应答成功
  80. /**********************************************/
  81. unsigned char IIC_Wait_Ack(void)
  82. {
  83.         u8 ucErrTime=0;
  84.         SDA_IN();      //SDA设置为输入  
  85.         IIC_SDA=1;
  86.         IIC_SCL=1;
  87.         delay_us(2);
  88.         while(READ_SDA)
  89.         {
  90.                 ucErrTime++;       
  91.                 if(ucErrTime>250)
  92.                         {
  93.                                 IIC_Stop();
  94.                                 return 1;
  95.                         }
  96.         }
  97.         IIC_SCL=0;//时钟输出0           
  98.         return 0;  
  99. }

  100. /**********************************************
  101. //                                                 IIC Write byte
  102. //IIC写一个字节          
  103. **********************************************/
  104. void IIC_Write_Byte(unsigned char data)
  105. {
  106.         unsigned char i;   
  107.         SDA_OUT();             
  108.         IIC_SCL=0;//拉低时钟开始数据传输
  109.         for(i=0;i<8;i++)
  110.         {              
  111.     IIC_SDA=(data&0x80)>>7;
  112.     data=data<<1;           
  113. //                delay_us(2);   //对TEA5767芯片这三个延时都是必须的
  114.                 IIC_SCL=1;
  115. //        delay_us(2);
  116.                 IIC_SCL=0;       
  117. //        delay_us(2);
  118.         }
  119. }

  120. /**********************************************
  121. // IIC Write Data
  122. **********************************************/
  123. void IIC_Write_Data(unsigned char Device_addr,unsigned char Reg_addr,unsigned char data)
  124. {
  125.   IIC_Start();
  126.         SDA_OUT();
  127.   IIC_Write_Byte(Device_addr | 0x00);        //器件地址(7位) + 读写位(读1写0)
  128.         IIC_Wait_Ack();       
  129.   IIC_Write_Byte(Reg_addr);                                                //要写入数据的寄存器地址
  130.         IIC_Wait_Ack();       
  131.   IIC_Write_Byte(data);
  132.         IIC_Wait_Ack();       
  133.   IIC_Stop();
  134. }

  135. /**********************************************
  136. //                                                 IIC Read byte
  137. //IIC读一个字节          
  138. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
  139. **********************************************/
  140. unsigned char IIC_Read_Byte(unsigned char Ack_EN)
  141. {
  142.         unsigned char i,receive=0;
  143.         SDA_IN();//SDA设置为输入
  144.         for(i=0;i<8;i++ )
  145.         {
  146.                 IIC_SCL=0;
  147.                 delay_us(2);
  148.                 IIC_SCL=1;
  149.                 receive<<=1;
  150.     if(READ_SDA)receive++;   
  151.                 delay_us(1);
  152.    }                                         
  153.     if (!Ack_EN)
  154.         IIC_NACK();//发送nACK
  155.     else
  156.         IIC_ACK(); //发送ACK   
  157.     return receive;
  158. }


  159. /**********************************************
  160. // IIC Read Data
  161. **********************************************/
  162. unsigned char IIC_Read_Data(unsigned char Device_addr,unsigned char Reg_addr,unsigned char ACK_EN)
  163. {
  164.         unsigned char receive;
  165.         IIC_Start();
  166.   IIC_Write_Byte(Device_addr | 0x00);        //器件地址(7位) + 读写位(写0)
  167.         IIC_Wait_Ack();       
  168.   IIC_Write_Byte(Reg_addr);                                                //要读数据的寄存器地址
  169.         IIC_Wait_Ack();       
  170.   IIC_Start();
  171.         SDA_IN();
  172.   IIC_Write_Byte(Device_addr | 0x01);        //器件地址(7位) + 读写位(读1)
  173.         IIC_Wait_Ack();       
  174.         receive=IIC_Read_Byte(0);
  175.         IIC_Wait_Ack();       
  176.   IIC_Stop();
  177.         return receive;
  178. }
复制代码

所有资料51hei提供下载:
IIC.zip (2.18 KB, 下载次数: 68)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:970124 发表于 2021-11-6 19:10 | 只看该作者
是不同芯片之间的吗
回复

使用道具 举报

板凳
ID:979629 发表于 2021-11-10 07:56 | 只看该作者
不同芯片之间稍加修改就可以通用吗?
回复

使用道具 举报

地板
ID:194006 发表于 2021-12-1 08:02 来自手机 | 只看该作者
正需要,不知能不能移植到51上
回复

使用道具 举报

5#
ID:154680 发表于 2023-5-22 17:13 | 只看该作者

正需要,不知能不能移植到51上
回复

使用道具 举报

6#
ID:1018021 发表于 2023-6-26 10:17 | 只看该作者
正在学习i2c,感谢楼主
回复

使用道具 举报

7#
ID:461428 发表于 2023-11-12 18:29 | 只看该作者
/SDA IO方向设置
#define SDA_IN()  {GPIOB->CRH&=0XFFFFFFF0;GPIOA->CRH|=8<<7;}
#define SDA_OUT() {GPIOB->CRH&=0XFFFFFFF0;GPIOA->CRH|=3<<7;}

#define IIC_SCL                PBout(6)//SCL
#define IIC_SDA                PBout(7)//SDA
#define        READ_SDA        PBin(7)        //SDA状态读取


请问下。GPIO7的口改变输入状态是GPIOB->CRH&=0XFFFFFFF0;GPIOA->CRH|=8<<7;???这个不应该是GPIO-8咩???怎么后面又是GPIOA??.求大神赐教。谢谢
回复

使用道具 举报

8#
ID:821429 发表于 2023-11-17 12:31 | 只看该作者
学习了。不过总听说芯片IIC不好用,具体什么原因?原本认为用现成的硬件比较方便  
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表