模拟I2C标准驱动,使用NRF52832工程为例进行说明
- 头文件内容
#ifndef __IIC_H__
#define __IIC_H__
#include "nrf_drv_gpiote.h"
#include "nrf_delay.h"
#ifdef __cplusplus
extern "C" {
#endif
#define KSCL 23
#define KSDA 22
#define delay_us_iic nrf_delay_us
#define SCL_IIC_1 nrf_gpio_cfg_input(KSCL,NRF_GPIO_PIN_PULLUP)
#define SCL_IIC_0 do {\
nrf_gpio_cfg_output(KSCL);\
nrf_gpio_pin_clear(KSCL); \
}while(0)
#define SDA_IIC_1 nrf_gpio_cfg_input(KSDA,NRF_GPIO_PIN_PULLUP)
#define SDA_IIC_0 do { \
nrf_gpio_cfg_output(KSDA);\
nrf_gpio_pin_clear(KSDA); \
}while(0)
#define SCL_IIC_READ nrf_gpio_pin_read(KSCL)
#define SDA_IIC_READ nrf_gpio_pin_read(KSDA)
void siic_init(void);
#ifdef __cplusplus
}
#endif
#endif
- I2C IO初时化
/**
* @brieaf i2c初时化io引脚
*/
void siic_init(void)
{
//SDA SCL
nrf_gpio_pin_set(KSDA);
nrf_gpio_pin_set(KSCL);
nrf_gpio_cfg_output(KSDA);
nrf_gpio_cfg_output(KSCL);
}
- SCL输出高函数
/**
* @brieaf 时钟线拉高
* @retval 0-时钟线操作正常
* 1-时钟线异常
*/
static uint8_t SCL_IIC_SET(void )
{
SCL_IIC_1;
delay_us_iic(1);
//clock stretching/
uint32_t ucErrTime = HW_TIMEOUT;
if(!SCL_IIC_READ)
{
while(!SCL_IIC_READ)
{
if(--ucErrTime == 0)
{
return 1;
}
}
}
return 0;
}
- I2C启动信号
/**
* @brieaf 产生IIC起始信号
* START:when CLK is high,DATA change form high to low
*/
void IIC_Start(void)
{
SDA_IIC_1;
SCL_IIC_SET();
delay_us_iic(5);
SDA_IIC_0;
delay_us_iic(5);
SCL_IIC_0;
}
- I2C停止信号
/**
* @brieaf 产生IIC停止信号
* STOP:when CLK is high DATA change form low to high
*/
void IIC_Stop(void)
{
SCL_IIC_0;
SDA_IIC_0;
delay_us_iic(5);
SCL_IIC_SET();
delay_us_iic(5);
SDA_IIC_1;//发送I2C总线结束信号
delay_us_iic(5);
}
- 等待I2C应答信号
/**
* @brieaf 等待应答信号到来
* @retval 1,接收应答失败
* 0,接收应答成功
* /
uint8_t IIC_Wait_Ack(void)
{
SDA_IIC_1;
delay_us_iic(1);
//clock stretching/
if( SCL_IIC_SET() )
{
IIC_Stop();
return 1;
}
delay_us_iic(1);
uint32_t ucErrTime = HW_TIMEOUT;
while(SDA_IIC_READ)
{
if(--ucErrTime == 0)
{
IIC_Stop();
return 1;
}
}
/
SCL_IIC_0;
return 0;
}
- I2C应答信号
/**
* @brieaf 产生ACK应答
* /
void IIC_Ack(void)
{
SCL_IIC_0;
SDA_IIC_0;
delay_us_iic(2);
SCL_IIC_SET();
delay_us_iic(2);
SCL_IIC_0;
}
- I2C无应答信号
/**
* @brieaf 不产生ACK应答
* /
void IIC_NAck(void)
{
SCL_IIC_0;
SDA_IIC_1;
delay_us_iic(2);
SCL_IIC_SET();
delay_us_iic(2);
SCL_IIC_0;
}
- 发送一个字节数据
/**
* @brieaf IIC发送一个字节
* @param[in] txd -要发送的数据
* @retval 1-有应答
* 0-无应答
* /
void IIC_Send_Byte(unsigned char txd)
{
SCL_IIC_0;
for(uint8_t t=0;t>7)
{
SDA_IIC_1;
}
else
{
SDA_IIC_0;
}
txd
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?