CH579M模拟IIC
来源:华佗健康网
在本文章中使用的是推挽输出:硬件上不需要外接电阻,我是用来和MXP6655XA陀螺仪通信的,模拟IIC仅供参考。
.h头文件
#define I2C_SCL GPIO_Pin_9
#define I2C_SDA GPIO_Pin_9#define SCL_High() GPIOB_SetBits(I2C_SCL)
#define SCL_LOW() GPIOB_ResetBits(I2C_SCL)#define SDA_High() GPIOA_SetBits(I2C_SDA)
#define SDA_LOW() GPIOA_ResetBits(I2C_SDA)
#define SDA_X() GPIOA_ReadPortPin(GPIO_Pin_9)#define SDA_OUT() GPIOA_ModeCfg(I2C_SDA, GPIO_ModeOut_PP_5mA)
#define SDA_IN() GPIOA_ModeCfg(I2C_SDA, GPIO_ModeIN_Floating)
#define interrupt GPIOB_ReadPortPin(GPIO_Pin_8)void MXC6655XA_Config();
void IIC_R_W_Config(uint8_t dir);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Send(uint8_t dat);
uint8_t IIC_Receive(uint8_t ACK);
void IIC_Ack(void);
void IIC_NAk(void);
uint8_t IIC_Wait_Ack(void);
int MXC6655XA_X(uint8_t addr,uint8_t Reg_HSB,uint8_t Reg_LSB);
int MXC6655XA_Y(uint8_t addr,uint8_t Reg_HSB,uint8_t Reg_LSB);
int MXC6655XA_Z(uint8_t addr,uint8_t Reg_HSB,uint8_t Reg_LSB);
uint8_t Write_MXC6655XA(uint8_t addr,uint8_t register1,uint8_t value);
.c文件
1:初始化时钟和数据脚
/********************************************************************************************
* 函数名称: MXC6655XA_Config()
* 功能说明: 初始化SCL和Data脚
* 输 入: 无
* 输 出: 无
*********************************************************************************************/void MXC6655XA_Config()
{
GPIOB_ModeCfg(GPIO_Pin_9,GPIO_ModeOut_PP_5mA);
GPIOA_ModeCfg(GPIO_Pin_9,GPIO_ModeOut_PP_5mA);
GPIOB_ModeCfg(GPIO_Pin_8,GPIO_ModeIN_Floating);}
2:配置数据脚输入和输出
/********************************************************************************************
* 函数名称: IIC_R_W_Config()
* 功能说明: 设置I2C_SDA引脚的读或写
* 输 入: 0=读入,1=写
* 输 出: 无
*********************************************************************************************/
void IIC_R_W_Config(uint8_t dir)
{
if(dir)GPIOA_ModeCfg(I2C_SDA, GPIO_ModeOut_PP_5mA); //SDA推挽输出模式
else GPIOA_ModeCfg(I2C_SDA, GPIO_ModeIN_PU); //SDA上拉输入模式
}
3:起始信号
/********************************************************************************************
* 函数名称: IIC_Start()
* 功能说明: 产生I2C传输的Start信号
* 输 入: 无
* 输 出: 无
*********************************************************************************************/
void IIC_Start(void)
{
IIC_R_W_Config(1); //SDA推挽输出
SDA_High(); //拉高数据线
SCL_High(); //拉高时钟线
DelayUs(5); //等待4.7Us以上
SDA_LOW(); //数据拉低产生一个(时高数低)信号
DelayUs(5); //等待4.7Us以上
SCL_LOW(); //时钟拉低}
4:停止位
/********************************************************************************************
* 函数名称: IIC_Stop()
* 功能说明: 产生I2C传输的Stop信号
* 输 入: 无
* 输 出: 无
*********************************************************************************************/
void IIC_Stop(void)
{
IIC_R_W_Config(1);
SCL_LOW(); // scl = 0
DelayUs(5);
SDA_LOW(); //sda=0
DelayUs(5);
SCL_High(); // scl = 1
DelayUs(5);
SDA_High(); // sda = 1
DelayUs(5);
}
5:发送
/********************************************************************************************
* 函数名称: IIC_Send()
* 功能说明: 向IIC总线发送一个字节的数据
* 输 入: 1byte data
* 输 出: 无
*********************************************************************************************/
void IIC_Send(uint8_t data)
{
uint8_t i;
IIC_R_W_Config(1); //数据线推挽输出
SCL_LOW(); //拉低时钟开始数据传输
for(i=0;i<8;i++)
{
if(data&0x80)SDA_High();//data每位和高位做比较HSB输出
else SDA_LOW();
data<<=1;
DelayUs(5);
SCL_High(); //拉高时钟等待从设备读取数据
DelayUs(5);
SCL_LOW(); //拉低时钟准备下一位数据
}
}
6:读取一个字节
/********************************************************************************************
* 函数名称: IIC_Receive()
* 功能说明: 从IIC总线接收一个字节的数据
* 输 入: 无
* 输 出: byte 从IIC总线上接收到得数据
* 注意事项: 无
*********************************************************************************************/
uint8_t IIC_Receive(uint8_t ACK)
{
uint8_t i,data;
IIC_R_W_Config(0); //数据线设置为浮空输入
for(i=0;i<8;i++)
{
SCL_LOW(); //时钟线拉低
DelayUs(4);
SCL_High(); //时钟线拉告
data<<=1; //数据左移
if(SDA_X())data|=0x01; //读取数据为高时,data置高
DelayUs(4);
}
if(!ACK)IIC_NAk(); //不应答
else IIC_Ack(); //应答
return data;}
7: 应答
/************************************************************************************************
* 函数名称: IIC_Ack()
* 功能说明: 在应答位位置产生应答,从而继续连续传输
* 输 入: 无
* 输 出: 无
*************************************************************************************************/
void IIC_Ack(void)
{
SCL_LOW(); //时钟拉低
IIC_R_W_Config(1); //数据作为推挽输出
SDA_LOW(); //拉低数据线即给于应答
DelayUs(4);
SCL_High(); //时钟拉高
DelayUs(4);
SCL_LOW(); //时钟拉低
}
8:非应答
/*********************************************************************************************
* 函数名称: IIC_NAk()
* 功能说明: 在应答位位置不产生应答,从而终止连续传输
* 输 入: 无
* 输 出: 无
**********************************************************************************************/
void IIC_NAk(void)
{
SCL_LOW();
IIC_R_W_Config(1); //数据推挽输出
SDA_High(); //数据线不拉低即不给于应答
DelayUs(4);
SCL_High(); //时钟拉高
DelayUs(4);
SCL_LOW(); //时钟拉低
}
9: 等待应答
/***********************************************************************************************
* 函数名称: IIC_Wait_Ack()
* 功能说明: 检测从机应答位
* 输 入: 无
* 输 出: uint8_t 0=ACK_OK 从机产生了应答;1=ACK_NO 从机没有产生应答
************************************************************************************************/
uint8_t IIC_Wait_Ack(void)
{
uint32_t i;
IIC_R_W_Config(1); //数据线推挽输出
SDA_High(); //数据线拉高
DelayUs(4);
IIC_R_W_Config(0); //数据线浮空输入
SCL_High(); // 时钟线拉高
while(SDA_X()){ //等待回应
i++;
if(i>1000){
IIC_Stop(); //数据线未被拉低,即未收到应答
return 1; //应答超时返回1
}
DelayUs(3);
}
SCL_LOW();
DelayUs(4);
return 0; //应答成功
}
与MXC6655XA陀螺仪通讯
/***********************************************************************************************
* 函数名称: MXC6655XA_X(uint8_t addr,uint8_t Reg_HSB,uint8_t Reg_LSB)
* 功能说明: X轴由范围值:-2048到+2047(以补码形式输出)
* 输 入:
* 输 出: 得到X轴加速度输出************************************************************************************************/int MXC6655XA_X(uint8_t addr,uint8_t Reg_HSB,uint8_t Reg_LSB)
{
uint8_t ii = 0;
uint8_t MSB = 0, LSB = 0;
IIC_Start(); //产生起始信号
IIC_Send(addr); //发送MXC6655XA_XYZ芯片地址及读写位,0表示写
if(IIC_Wait_Ack()) //检测MXC6655XA_XYZ是否有响应
{
IIC_Stop(); //产生停止信号
SDA_OUT(); //将SDA引脚恢复为输出模式
return 0;
}
IIC_Send(Reg_HSB); //发送寄存器地址
IIC_Wait_Ack(); //检测MXC6655XA_X是否有响应
IIC_Send(addr|0x1); //读取MXC6655XA_X陀螺仪地址数据
if(!IIC_Wait_Ack())MSB = IIC_Receive(1); //非应答
else MSB = IIC_Receive(0); //应答
IIC_Stop(); //停止
SDA_OUT(); //数据作为推挽输出
return 0;
}
驱动MXC6655XA三轴陀螺仪待更新!
因篇幅问题不能全部显示,请点此查看更多更全内容