Files
2021-10-25 00:33:34 +08:00

159 lines
3.1 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* iic.c
*
* Created on: Oct 24, 2021
* Author: wuwenfeng
*/
#include "iic.h"
#include "gpio.h"
#define iic_sda(x) HAL_GPIO_WritePin(iic_sda_GPIO_Port, iic_sda_Pin, x)
#define iic_scl(x) HAL_GPIO_WritePin(iic_scl_GPIO_Port, iic_scl_Pin, x)
#define read_iic_sda HAL_GPIO_ReadPin(iic_sda_GPIO_Port, iic_sda_Pin)
#define IIC_SDA_SET iic_sda(1)
#define IIC_SCL_SET iic_scl(1)
#define IIC_SDA_CLR iic_sda(0)
#define IIC_SCL_CLR iic_scl(0)
#define SDA_OUT() change_io_function(iic_sda_GPIO_Port, iic_sda_Pin,0)
#define SDA_IN() change_io_function(iic_sda_GPIO_Port, iic_sda_Pin,1)
#define READ_SDA read_iic_sda
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA_SET;
IIC_SCL_SET;
IIC_SDA_CLR;//START:when CLK is high,DATA change form high to low
IIC_SCL_CLR;//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL_CLR;
IIC_SDA_CLR;//STOP:when CLK is high DATA change form low to high
IIC_SCL_SET;
IIC_SDA_SET;//发送I2C总线结束信号
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
uint8_t IIC_Wait_Ack(void)
{
uint8_t ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA_SET;
IIC_SCL_SET;
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL_CLR;//时钟输出0
return 0;
}
//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL_CLR;
SDA_OUT();
IIC_SDA_CLR;
IIC_SCL_SET;
IIC_SCL_CLR;
}
//不产生ACK应答
void IIC_NAck(void)
{
IIC_SCL_CLR;
SDA_OUT();
IIC_SDA_SET;
IIC_SCL_SET;
IIC_SCL_CLR;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(uint8_t txd)
{
uint8_t t;
SDA_OUT();
IIC_SCL_CLR;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
//IIC_SDA=(txd&0x80)>>7;
if((txd&0x80)>>7)
IIC_SDA_SET;
else
IIC_SDA_CLR;
txd<<=1;
IIC_SCL_SET;
IIC_SCL_CLR;
}
}
//读1个字节,ack=1时,发送ACKack=0,发送nACK
uint8_t IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL_CLR;
IIC_SCL_SET;
receive<<=1;
if(READ_SDA)receive++;
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}
void IIC_SAND_DATE(unsigned char DEVICE_ADD,unsigned char IN_DEVICE_ADD,char *DATAS,uint16_t LONG)
{
IIC_Start();
IIC_Send_Byte(DEVICE_ADD);
if(IIC_Wait_Ack()){return;}
IIC_Send_Byte(IN_DEVICE_ADD);
if(IIC_Wait_Ack()){return;}
for(int a=0;a<LONG;a++)
{
IIC_Send_Byte(*DATAS);
DATAS++;
}
if(IIC_Wait_Ack()){return;}
IIC_Stop();
}
void IIC_READ_DATE(unsigned char DEVICE_ADD,unsigned char IN_DEVICE_ADD,char *DATAS,uint16_t LONG)
{
IIC_Start();
IIC_Send_Byte(DEVICE_ADD);
if(IIC_Wait_Ack()){return;}
IIC_Send_Byte(IN_DEVICE_ADD);
if(IIC_Wait_Ack()){return;}
IIC_Start();
IIC_Send_Byte(DEVICE_ADD+1);
if(IIC_Wait_Ack()){return;}
for(int a=0;a<LONG;a++)
{
*DATAS=IIC_Read_Byte(0);
DATAS++;
}
if(IIC_Wait_Ack()){return;}
IIC_Stop();
}