此文章用于记录学习嵌入式过程中的代码,方便后续复习。也欢迎大佬指正,提出宝贵建议
(使用的是STM32f103c8t6,HAL库)
#include "MyIIC.h"
//通过更改下方三个函数,实现IIC通讯底层基础
void SCL_W(uint8_t PinState)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,PinState);
}
void SDA_W(uint8_t PinState)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,PinState);
}
uint8_t SDA_R(void)
{
return HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8);
}
//下方是实现各种信号
void IIC_Start(void)//开始信号
{
SCL_W(1);
SDA_W(1);
SDA_W(0);
SCL_W(0);
}
void IIC_Stop(void)//停止信号
{
SCL_W(0);
SDA_W(0);
SCL_W(1);
SDA_W(1);
}
void IIC_SendAck(uint8_t Bite)//发送应答(发送0代表应答)
{
SDA_W(Bite);
SCL_W(1);
SCL_W(0);
}
uint8_t IIC_RecAck(void)//接受应答(接受0代表有应答)/按照实际情况可考虑在开始时加入延时
{
//HAL_Delay(1);
uint8_t Bite;
SDA_W(1);//释放SDA
SCL_W(1);
Bite = SDA_R();
SCL_W(0);
return Bite;
}
void IIC_SendByte(uint8_t Byte)//发送一个字节,高位先行
{
uint8_t i;
for (i=0;i<8;i++)
{
SDA_W(!!(Byte & (0x80 >> i)));//此处处理来自江协科技代码,对于将字节中的每一字发送具有参考意义。
/*0x80--->1000 0000 Byte & (0x80 >> i)可检测Byte中每一位是否为0
!!是逻辑非(NOT)操作的双应用;!能将0转为1 ,将非0转为0.
因此!!能让0输出为0,将非0输出为1.
*/
SCL_W(1);
SCL_W(0);
}
/*此代码用于产生额外时钟信号,用来跳过应答。安装需要可接触此注释
SCL_W(1);
SCL_W(0);*/
}
uint8_t IIC_RecByte(void)//接受一个字节,高位先行/需要测试,如果芯片速度过快可按实际情况在开始时加入延时
{
//HAL_Delay(1);
uint8_t i;
uint8_t Byte=0;
SDA_W(1);//释放SDA
for (i=0;i<8;i++)//接受Byte我想到了两种逻辑。(1)先置于对应位,再输入值(2)先输入值,再置对应位
/*此处处理参考自CSDN 的 Z小旋 的文章 IIC原理超详细讲解
每一次先将新的数据置于最低位,然后向左移动一位。因此,先输入的值最后所在位更高,符合高位先行 */
{
SCL_W(1);
Byte<<=i;
if (SDA_R())
{
Byte+=1;
}
SCL_W(0);
}
return Byte;
}