HAL_Project/Project -APP-V1.0/Hardware/IIC/iic.c

124 lines
4.6 KiB
C
Raw 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.

#include "main.h" //包含需要的头文件
/*-------------------------------------------------*/
/*函数名初始化IIC接口 */
/*参 数:无 */
/*返回值:无 */
/*-------------------------------------------------*/
void iicInit(void) {
GPIO_InitTypeDef GPIO_InitStruct; //定义一个设置GPIO的变量
GPIOC_RCC_ENABLE;
GPIO_InitStruct.Pin = SDA_Pin; //设置SDA对应的IO口
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; //推免输出
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //高速
HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct); //设置
GPIO_InitStruct.Pin = SCL_Pin; //设置SCL对应的IO口
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //推免输出
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //高速
HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct); //设置
IIC_SCL_H; //SCL拉高
IIC_SDA_H; //SDA拉高
}
/*-------------------------------------------------*/
/*函数名IIC起始信号 */
/*参 数:无 */
/*返回值:无 */
/*-------------------------------------------------*/
void iicStart(void) {
IIC_SDA_H; //SDA拉高
IIC_SCL_H; //SCL拉高
delayUs(4); //延时
IIC_SDA_L; //SCL高电平的时候SDA由高到低起始信号
}
/*-------------------------------------------------*/
/*函数名IIC停止信号 */
/*参 数:无 */
/*返回值:无 */
/*-------------------------------------------------*/
void iicStop(void) {
IIC_SDA_L; //SDA拉低
IIC_SCL_H; //SCL拉高
delayUs(4); //延时
IIC_SDA_H; //SCL高电平的时候SDA由低到高发出停止信号
}
/*-------------------------------------------------*/
/*函数名:等待应答 */
/*参 数:无 */
/*返回值0成功 1失败 */
/*-------------------------------------------------*/
char iicWaitAck(void) {
unsigned char timeout=0; //定义一个变量,用于计算超时时间
IIC_SDA_H; //SDA拉高
IIC_SCL_H; //SCL拉高
while(READ_SDA) { //等待SDA变低电平表示应答到来不然一直while循环直到超时
timeout++; //超时计数+1
if(timeout>250) { //如果大于250
iicStop(); //发送停止信号
return 1; //返回1表示失败
}
delayUs(2); //延时
}
IIC_SCL_L; //SCL拉低
delayUs(20); //延时
return 0; //返回0表示成功
}
/*-------------------------------------------------*/
/*函数名:发送一个字节 */
/*参 数txd发送的字节 */
/*返回值:无 */
/*-------------------------------------------------*/
void iicSendByte(uint8_t txd) {
unsigned char t; //定义一个变量用于for循环
IIC_SCL_L; //SCL拉低开始数据传输
for(t=0; t<8; t++) { //for循环一位一位的发送从最高位 位7开始
IIC_SDA_OUT(((txd&0x80)>>7)); //给SDA数据线
txd<<=1; //左移一位,准备下一次发送
delayUs(2); //延时
IIC_SCL_H; //SCL拉高
delayUs(2); //延时
IIC_SCL_L; //SCL拉低
}
}
/*-------------------------------------------------*/
/*函数名:读取一个字节 */
/*参 数ack是否发送应答 1:发 0不发 */
/*返回值:读取的数据 */
/*-------------------------------------------------*/
unsigned char iicReadByte(uint8_t ack) {
unsigned char i; //定义一个变量用于for循环
unsigned char receive; //定义一个变量用于保存接收到的数据
receive = 0; //清除receive准备接收数据
IIC_SCL_L; //SCL拉低
delayUs(20); //延时
for(i=0; i<8; i++) { //for循环一位一位的读取
IIC_SCL_H; //SCL拉高
delayUs(20); //延时
receive<<=1; //左移一位,准备下次的读取
if(READ_SDA)receive++; //读取数据
delayUs(20); //延时
IIC_SCL_L; //SCL拉低
delayUs(20); //延时
}
if(!ack) { //不需要发送
IIC_SDA_H; //时钟脉冲的高电平期间保持稳定的高电平
IIC_SCL_H; //SCL拉高
delayUs(2); //延时
IIC_SCL_L; //SCL拉低
} else { //需要发送
IIC_SDA_L; //时钟脉冲的高电平期间保持稳定的低电平
IIC_SCL_H; //SCL拉高
delayUs(2); //延时
IIC_SCL_L; //SCL拉低
IIC_SDA_H; //SDA拉高
}
return receive;
}