[STM32F1] 软件模拟IIC通讯

[复制链接]
 楼主| kkzz 发表于 2023-11-14 12:00 | 显示全部楼层 |阅读模式


  1. void MyI2C_W_SCL(uint8_t BitValue);
  2. void MyI2C_W_SDA(uint8_t BitValue);
  3. uint8_t MyI2C_R_SDA(void);
  4. void MyI2C_Start(void);
  5. void MyI2C_Stop(void);
  6. void MyI2C_SendByte(uint8_t Byte);
  7. void MyI2C_SendBuffer(uint8_t *Buffer, uint32_t len);
  8. void MyI2C_RecvBuffer(uint8_t I2C_Slave_Addr, uint8_t AR_Addr, uint8_t *Buffer, uint32_t len);
  9. uint8_t MyI2C_ReceiveByte(void);
  10. void MyI2C_SendAck(uint8_t AckBit);
  11. uint8_t MyI2C_ReceiveAck(void);





  1. // 需要替换的函数
  2. GPIO_WriteBit();         // 引脚电平写入函数
  3. GPIO_ReadInputDataBit(); // 读引脚电平函数
  4. Delay_us(10);            // 延迟函数
  5. /**
  6. * [url=home.php?mod=space&uid=247401]@brief[/url] 拉高拉低SCL
  7. * @param {uint8_t} BitValue 0/1
  8. * [url=home.php?mod=space&uid=266161]@return[/url] {*}
  9. */
  10. void MyI2C_W_SCL(uint8_t BitValue)
  11. {
  12.     GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)BitValue);
  13.     Delay_us(10);
  14. }
  15. /**
  16. * @brief : 拉高拉低SDA
  17. * @param {uint8_t} BitValue 0/1
  18. * @return {*}
  19. */
  20. void MyI2C_W_SDA(uint8_t BitValue)
  21. {
  22.     GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)BitValue);
  23.     Delay_us(10);
  24. }
  25. /**
  26. * @brief : 读SDA电平
  27. * @return {*}
  28. */
  29. uint8_t MyI2C_R_SDA(void)
  30. {
  31.     uint8_t BitValue;
  32.     BitValue = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11);
  33.     Delay_us(10);
  34.     return BitValue;
  35. }

  36. void MyI2C_Init(void)
  37. {
  38.     /*使能外设时钟*/
  39.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  40.     /*结构体配置IIC引脚*/
  41.     GPIO_InitTypeDef GPIO_InitStructure;
  42.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  43.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
  44.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  45.     GPIO_Init(GPIOB, &GPIO_InitStructure);

  46.     GPIO_SetBits(GPIOB, GPIO_Pin_10 | GPIO_Pin_11); // 拉高引脚电平
  47. }

  48. /********************************************************************************************************************************************
  49. 修改上面的函数就行下面的都是封装好的
  50. IIC通讯原则 发送起始信号 发送一个字节 接收应答标志 发送下一个字节 接收应答标志 发送停止标志
  51. *******************************************************************************************************************************************/

  52. /**
  53. * @brief 发送开始标志
  54. * @return {*}
  55. */
  56. void MyI2C_Start(void)
  57. {
  58.     MyI2C_W_SDA(1);
  59.     MyI2C_W_SCL(1);
  60.     MyI2C_W_SDA(0);
  61.     MyI2C_W_SCL(0);
  62. }
  63. /**
  64. * @brief 发送停止标志
  65. * @return {*}
  66. */
  67. void MyI2C_Stop(void)
  68. {
  69.     /*SCL高电平期间SDA由低变高*/
  70.     MyI2C_W_SDA(0);
  71.     MyI2C_W_SCL(1);
  72.     MyI2C_W_SDA(1);
  73. }

  74. /**
  75. * @brief  起始位后SCL为低 可以放数据在SDA上,随后拉高SCL从机读取主机发送的数据,主机在拉低SCL进入下一位的发送
  76. * @param {uint8_t} Byte
  77. * @return {*}
  78. */
  79. void MyI2C_SendByte(uint8_t Byte)
  80. {
  81.     uint8_t i;
  82.     for (i = 0; i < 8; i++)
  83.     {
  84.         MyI2C_W_SDA(Byte & (0x80 >> i));
  85.         MyI2C_W_SCL(1);
  86.         MyI2C_W_SCL(0);
  87.     }
  88. }
  89. /**
  90. * @brief  发送buffer
  91. * @param {uint8_t} Byte
  92. * @return {*}
  93. */
  94. void MyI2C_SendBuffer(uint8_t *Buffer, uint32_t len)
  95. {
  96.     MyI2C_Start();
  97.     for (int i = 0; i < len; i++)
  98.     {
  99.         MyI2C_SendByte(Buffer[i]);
  100.         MyI2C_ReceiveAck();
  101.     }
  102.     MyI2C_Stop();
  103. }
  104. /**
  105. * @brief : 接收指定从机寄存器地址的buffer
  106. * @param {uint8_t} I2C_Slave_Addr 从机地址
  107. * @param {uint8_t} AR_Addr  寄存器地址
  108. * @param {uint8_t} *Buffer  数据
  109. * @param {uint32_t} len  数据长度
  110. * @return {*}
  111. */
  112. void MyI2C_RecvBuffer(uint8_t I2C_Slave_Addr, uint8_t AR_Addr, uint8_t *Buffer, uint32_t len)
  113. {

  114.     MyI2C_Start();

  115.     MyI2C_SendByte(I2C_Slave_Addr);
  116.     MyI2C_ReceiveAck();
  117.     MyI2C_SendByte(AR_Addr);
  118.     MyI2C_ReceiveAck();

  119.     MyI2C_Start();
  120.     MyI2C_SendByte(I2C_Slave_Addr | 0x01);
  121.     MyI2C_ReceiveAck();
  122.     for (int i = 0; i < len; i++)
  123.     {
  124.         Buffer[i] = MyI2C_ReceiveByte();
  125.         if (i == len - 1)
  126.         {
  127.             MyI2C_SendAck(1);
  128.         }
  129.         else
  130.         {
  131.             MyI2C_SendAck(0);
  132.         }
  133.     }

  134.     MyI2C_Stop();
  135. }

  136. /**
  137. * @brief  主机先拉高SDA是释放总线的意思,SCL此时为低 ,从机可以 放数据在SDA上,随后主机拉高SCL读取SDA的值在拉低SCL进入下一个周期
  138. * @param {uint8_t} Byte
  139. * @return {*}
  140. */
  141. uint8_t MyI2C_ReceiveByte(void)
  142. {
  143.     uint8_t i, Byte = 0x00;
  144.     MyI2C_W_SDA(1);
  145.     for (i = 0; i < 8; i++)
  146.     {
  147.         MyI2C_W_SCL(1);
  148.         if (MyI2C_R_SDA() == 1)
  149.         {
  150.             Byte |= (0x80 >> i);
  151.         }
  152.         MyI2C_W_SCL(0);
  153.     }
  154.     return Byte;
  155. }
  156. /**
  157. * @brief  发送应答位
  158. * @param {uint8_t} Byte 0应带继续接收,1不应答
  159. * @return {*}
  160. */
  161. void MyI2C_SendAck(uint8_t AckBit)
  162. {
  163.     MyI2C_W_SDA(AckBit);
  164.     MyI2C_W_SCL(1);
  165.     MyI2C_W_SCL(0);
  166. }
  167. /**
  168. * @brief  发送应答位
  169. * @param {uint8_t} Byte 0应带继续接收,1不应答
  170. * @return {*}
  171. */
  172. uint8_t MyI2C_ReceiveAck(void)
  173. {
  174.     uint8_t AckBit;
  175.     MyI2C_W_SDA(1);
  176.     MyI2C_W_SCL(1);
  177.     AckBit = MyI2C_R_SDA();
  178.     MyI2C_W_SCL(0);
  179.     return AckBit;
  180. }


帛灿灿 发表于 2024-8-1 07:04 | 显示全部楼层

如果在编程时加密锁定位被使能/锁定,就无法用普通编程器直接读取单片机内的程序
Bblythe 发表于 2024-8-1 08:07 | 显示全部楼层

编程器定位插字节
周半梅 发表于 2024-8-1 10:03 | 显示全部楼层

缩短距离较近的电容的寿命
Pulitzer 发表于 2024-8-1 11:06 | 显示全部楼层

利用协议、加密算法或这些算法中的安全漏洞来进行攻击
童雨竹 发表于 2024-8-1 13:02 | 显示全部楼层

大地的地会通过散热器(用绝缘体与漏极隔开)从这些节点获取能量
Wordsworth 发表于 2024-8-1 14:05 | 显示全部楼层

具存储功能的存储器芯片也能加密
Clyde011 发表于 2024-8-1 15:08 | 显示全部楼层

紫外光复位保护电路是不行的
公羊子丹 发表于 2024-8-1 16:01 | 显示全部楼层

交流节点会引起特有的问题
万图 发表于 2024-8-1 17:04 | 显示全部楼层

大部分能够读取或者识别Flash上的数据就能够获得Firmware文件
Uriah 发表于 2024-8-1 18:07 | 显示全部楼层

微探针技术都属于侵入型攻击
您需要登录后才可以回帖 登录 | 注册

本版积分规则

332

主题

11219

帖子

13

粉丝
快速回复 在线客服 返回列表 返回顶部