论坛元老
 
- 积分
- 3347
- 金钱
- 3347
- 注册时间
- 2013-4-10
- 在线时间
- 333 小时
|
发表于 2018-3-10 00:54:56
|
显示全部楼层
********************************************************************************************/
#include "ctiic.h"
#include "delay.h"
#define IIC_CLK_SET GPIOF->BSRR = 1<<7 //快速IO操作定义
#define IIC_CLK_CLR GPIOF->BRR = 1<<7
#define IIC_SDA_SET GPIOF->BSRR = 1<<9
#define IIC_SDA_CLR GPIOF->BRR = 1<<9
//IO方向设置
#define CT_SDA_IN() {GPIOF->CRH &= 0xffffff0f; GPIOF->CRH |= 0x00000080;GPIOF->ODR |= 1<<9;} //设为输入
#define CT_SDA_OUT() {GPIOF->CRH &= 0xffffff0f; GPIOF->CRH |= 0x00000030;GPIOF->ODR |= 1<<9;} //设为输出
//IO操作函数
#define CT_READ_SDA PFin(9) //输入SDA
/********************************************************************************************
函 数 名: 初始化IIC
调 用: CT_IIC_Init(void)
参 数: 无
反 回 值: 无
********************************************************************************************/
void CT_IIC_Init(void)
{
RCC->APB2ENR|=1<<7; //先使能外设IO PORTF时钟
GPIOF->CRH &= 0xFFFFFF0F; //PF9 推挽输出
GPIOF->CRH |= 0x00000030;
GPIOF->CRL &= 0x0FFFFFFF; //PF7 推挽输出
GPIOF->CRL |= 0x30000000;
GPIOF->ODR |= 1<<7; //PF7 输出高
GPIOF->ODR |= 1<<9; //PF9 输出高
}
/********************************************************************************************
函 数 名: 产生IIC起始信号
调 用: CT_IIC_Start(void)
参 数: 无
反 回 值: 无
********************************************************************************************/
void CT_IIC_Start(void)
{
CT_SDA_OUT(); //sda线输出
IIC_SDA_SET;
IIC_CLK_SET;
delay_us(2);
IIC_SDA_CLR; //START:when CLK is high,DATA change form high to low
delay_us(2);
IIC_CLK_CLR; //钳住I2C总线,准备发送或接收数据
}
/********************************************************************************************
函 数 名: 产生IIC停止信号
调 用: CT_IIC_Stop(void)
参 数: 无
反 回 值: 无
********************************************************************************************/
void CT_IIC_Stop(void)
{
CT_SDA_OUT(); //sda线输出
IIC_CLK_CLR;
IIC_SDA_CLR; //STOP:when CLK is high DATA change form low to high
delay_us(2);
IIC_CLK_SET;
IIC_SDA_SET; //发送I2C总线结束信号
delay_us(2);
}
/********************************************************************************************
函 数 名: 等待应答信号到来
调 用: CT_IIC_Wait_Ack(void)
参 数: 无
反 回 值: 1,接收应答失败 0,接收应答成功
********************************************************************************************/
u8 CT_IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
CT_SDA_IN(); //SDA设置为输入
IIC_SDA_SET; //输入置高电平
delay_us(2);
IIC_CLK_SET;
delay_us(2);
while(CT_READ_SDA)
{
ucErrTime++;
if(ucErrTime>250){CT_IIC_Stop();return 1;}
}
IIC_CLK_CLR;//时钟输出0
return 0;
}
/********************************************************************************************
函 数 名: 产生ACK应答
调 用: CT_IIC_Ack(void)
参 数: 无
反 回 值: 无
********************************************************************************************/
void CT_IIC_Ack(void)
{
IIC_CLK_CLR;
CT_SDA_OUT();
IIC_SDA_CLR;
delay_us(2);
IIC_CLK_SET;
delay_us(2);
IIC_CLK_CLR;
}
/********************************************************************************************
函 数 名: 不产生ACK应答
调 用: CT_IIC_NAck(void)
参 数: 无
反 回 值: 无
********************************************************************************************/
void CT_IIC_NAck(void)
{
IIC_CLK_CLR;
CT_SDA_OUT();
IIC_SDA_SET;
delay_us(2);
IIC_CLK_SET;
delay_us(2);
IIC_CLK_CLR;
}
/********************************************************************************************
函 数 名: IIC发送一个字节
调 用: CT_IIC_Send_Byte(u8 txd)
参 数: txd 返回从机有无应答 1,有应答 0,无应答
反 回 值: 无
********************************************************************************************/
void CT_IIC_Send_Byte(u8 txd)
{
u8 t;
CT_SDA_OUT();
IIC_CLK_CLR; //拉低时钟开始数据传输
for(t=0;t<8;t++)
{
if(txd & 0x80)IIC_SDA_SET; //输出高电平
else IIC_SDA_CLR; //输出低电平
txd<<=1;
IIC_CLK_SET;
delay_us(2);
IIC_CLK_CLR;
delay_us(2);
}
}
/********************************************************************************************
函 数 名: 读1个字节
调 用: CT_IIC_Read_Byte(unsigned char ack)
参 数: ack ( ack=1时,发送ACK,ack=0,发送nACK )
反 回 值: 读到的数据
********************************************************************************************/
u8 CT_IIC_Read_Byte(u8 ack)
{
u8 i,receive=0;
CT_SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_CLK_CLR;
delay_us(2);
IIC_CLK_SET;
receive<<=1;
if(CT_READ_SDA)receive++;
}
if (!ack)CT_IIC_NAck();//发送nACK
else CT_IIC_Ack(); //发送ACK
return receive;
} |
|