IIC(硬件实现)-GD32
#include "i2c.h"
void i2c_init(void){
i2c_deinit(I2C0);
//使能外设时钟
rcu_periph_clock_enable(RCU_I2C0);
rcu_periph_clock_enable(RCU_GPIOB);
//设置gpio口
gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
//设置i2c0
i2c_clock_config(I2C0, I2C_SPEED, I2C_DTCY_2); // i2c时钟配置
i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C0_OWN_ADDR);
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
//使能i2c0
i2c_enable(I2C0);
}
#ifndef __I2C_H
#define __I2C_H
#include "gd32f10x.h"
#define I2C_SPEED 100000
#define I2C0_OWN_ADDR 0xA0
void i2c_init(void); // 初始化i2c0
#endif
/***
功能:读温度寄存器的值
输入:
uint8_t lm75a_id: lm75a的iic从机地址
uint8_t *p:读取结果存放的位置
返回:无
*****/
void lm75a_read_temp_reg(uint8_t lm75a_id, uint8_t *p){
/******给LM75A写温度寄存器的指针字节********/ // 使用了I2C0(主模式)写功能,
while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)); // 如果I2C0繁忙,空等
i2c_start_on_bus(I2C0); // 在I2C0上生成一个起始位
while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)); // 如果起始位还没有发送,空等
i2c_master_addressing(I2C0, lm75a_id, I2C_TRANSMITTER); //发送地址,发送模式
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)); // 如果地址还没有发送,空等
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
i2c_data_transmit(I2C0, LM75A_TEMP_REG);
while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));
i2c_stop_on_bus(I2C0);
while(I2C_CTL0(I2C0) & 0x20);
/******读LM75A温度寄存器里面的两个字节的值********/ //使用了I2C0(主模式)读功能
i2c_ackpos_config(I2C0, I2C_ACKPOS_NEXT); //设置应答的位置
while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)); // 如果I2C0繁忙,空等
i2c_start_on_bus(I2C0); // 在I2C0上生成一个起始位
while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)); // 如果起始位还没有发送,空等
i2c_master_addressing(I2C0, lm75a_id, I2C_RECEIVER); //发送地址,接收模式
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
//从I2C_DATA读值
while(!i2c_flag_get(I2C0, I2C_FLAG_BTC));
while(!i2c_flag_get(I2C0, I2C_FLAG_RBNE)); // 如果I2C_DATA为空,空等
*p = i2c_data_receive(I2C0);
while(!i2c_flag_get(I2C0, I2C_FLAG_RBNE)); // 如果I2C_DATA为空,空等
*(p+1) = i2c_data_receive(I2C0);
i2c_stop_on_bus(I2C0);
while(I2C_CTL0(I2C0) & 0x20);
i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT); //设置应答的位置
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
}