章丘营销型网站建设,wordpress 加入引导页,陕西网站建设方案,东莞网络营销渠道一、初始化
理论知识链接#xff1a;
IIC理论知识
二、代码实现
1、SDA和SCL设置成开漏输出模式
开漏输出的作用#xff1a;
因为IIC总线是一种双向的通信协议#xff0c;需要使用开漏输出实现共享总线。开漏输出类似于一种线与的方式#xff0c;即无论总线上哪个设备…一、初始化
理论知识链接
IIC理论知识
二、代码实现
1、SDA和SCL设置成开漏输出模式
开漏输出的作用
因为IIC总线是一种双向的通信协议需要使用开漏输出实现共享总线。开漏输出类似于一种线与的方式即无论总线上哪个设备下拉了所有设备都能知道。IIC总线通常需要使用上拉电阻来保证总线上的高电平。
以GD32为例使用普通GPIO模拟IIC初始化如下
//PA1 -- SDA
//PA2 -- SCL#define iic_addr 0x30 //根据从机地址进行修改
#define GPIO_PORT_I2C GPIOA //根据引脚进行修改
#define GPIO_RCC_I2C RCU_GPIOA//根据引脚进行修改
#define GPIO_SCL_I2C GPIO_PIN_2//根据引脚进行修改
#define GPIO_SDA_I2C GPIO_PIN_1//根据引脚进行修改
#define delay_time 2 //2us//将引脚设置成开漏输出
void iic_init()
{rcu_periph_clock_enable(GPIO_RCC_I2C);//启动时钟gpio_mode_set(GPIO_PORT_I2C, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_SCL_I2C | GPIO_SDA_I2C);//默认上拉gpio_output_options_set(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_SCL_I2C | GPIO_SDA_I2C);//设置开漏输出i2c_stop();//复位一下
}2、写启动信号
启动信号表现形式为
静默状态SCL、SDA为高电平。启动信号SCL为高电平时SDA由高电平变成低电平
#define I2C_SCL_H gpio_bit_set(GPIO_PORT_I2C,GPIO_SCL_I2C)//拉高
#define I2C_SCL_L gpio_bit_reset(GPIO_PORT_I2C,GPIO_SCL_I2C)//拉低
#define I2C_SDA_H gpio_bit_set(GPIO_PORT_I2C,GPIO_SDA_I2C)//拉高
#define I2C_SDA_L gpio_bit_reset(GPIO_PORT_I2C,GPIO_SDA_I2C)//拉低//启动信号
/*
SCL ————————————————————\\___________SDA ——————————\\____________________
*/
void i2c_start()
{I2C_SDA_H;I2C_SCL_H;delay_us(delay_time);I2C_SDA_L;delay_us(delay_time);I2C_SCL_L;delay_us(delay_time);
}
3、写终止信号
终止信号表现形式为
静默状态SCL高电平、SDA为低电平。终止信号SCL为高电平时SDA由低电平变成高电平
/*
SCL ————————————————————————————————————————SDA /——————————————————_________________/
*/
void i2c_stop()
{I2C_SDA_L;I2C_SCL_H;delay_us(delay_time);I2C_SDA_H;
}4、发送一个字节数据
void i2c_sendbyte(unsigned char data)
{unsigned char i;for(i 0; i 8; i)//8bit 1byte{if(data 0x80)//取出最高位{I2C_SDA_H;}else{I2C_SDA_L;}delay_us(delay_time);I2C_SCL_H;delay_us(delay_time);I2C_SCL_L;if(i 7){I2C_SDA_H;//释放总线}data 1;delay_us(delay_time);}
}5、接收一个字节数据
#define I2C_SDA_READ gpio_input_bit_get(GPIO_PORT_I2C,GPIO_SDA_I2C)unsigned char i2c_readbyte()
{unsigned char i;unsigned char data 0x00;for(i 0; i 8; i){data 1;I2C_SCL_H;delay_us(delay_time);if(I2C_SDA_READ){data | 0x01;//存入数据}I2C_SCL_L;delay_us(delay_time);}return data;
}6、产生一个ACK信号
SCL为低电平时SDA写入低电平SCL为高电平时SDA读取低电平读取完成后将SDA拉高
/*
SCL /————————\_______/ \________________SDA /————————————————————————————————————__________________________/
*/
void i2c_ack()
{I2C_SDA_L;delay_us(delay_time);I2C_SCL_H;delay_us(delay_time);I2C_SCL_L;delay_us(delay_time);I2C_SDA_H;
}7、产生一个NACK信号
void i2c_nack()
{I2C_SDA_H;delay_us(delay_time);I2C_SCL_H;delay_us(delay_time);I2C_SCL_L;delay_us(delay_time);
}8、检测是否从机是否返回ACK
//0:表示ACK 1:表示NACK
unsigned char i2c_read_ack()
{unsigned char re;I2C_SDA_H;delay_us(delay_time);I2C_SCL_H;delay_us(delay_time);if(I2C_SDA_READ) re 1;else re 0;I2C_SCL_L;delay_us(delay_time);return re;
}9、发送地址和读操作并读回一个字节数据
unsigned char read_data()
{i2c_start();//启动信号i2c_sendbyte(iic_addr | 0x01);//发送地址和读位if(i2c_read_ack()) return 0;//如果没有读到ACK终止执行。unsigned char data i2c_readbyte();//读取数据i2c_stop();//发送终止信号return data;//返回接收的数据
}