📄 ioi2c.c
字号:
/******************** (C) COPYRIGHT 2007 STMicroelectronics ********************
* File Name : IOI2C.c
* Author : liuwenhui
* Version : V1.0
* Date : 10/08/2007
* Description : This file provides all the GPIO firmware functions.
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
#include "stm32f10x_lib.h"
u8 E0; //非应答信号标志位
u8 NACK=0; //错误标志位
#define I2C_SDA GPIO_Pin_2
#define I2C_SCL GPIO_Pin_1
void SetSDAIn(void);
void SetSDAOut(void);
void I2Cdelay(u8 nTim)
{
int i,j,k;
for (i=0; i<nTim; i++)
for(k=0; k<10; k++)
j++;
}
//启动I2C总线子函数
void I2CStart(void)
{
GPIO_SetBits(GPIOA, I2C_SDA); //PA2(SDA)脚=1;3.3V
GPIO_SetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=1;3.3V
I2Cdelay(5);
GPIO_ResetBits(GPIOA, I2C_SDA); //PA2(SDA)脚=0;0v
I2Cdelay(5);
GPIO_ResetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=0;0v
}
//停止I2C总线数据传送子函数
void I2CStop(void)
{
GPIO_ResetBits(GPIOA, I2C_SDA); //PA2(SDA)脚=0;0v
GPIO_SetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=1;3.3V
I2Cdelay(5);
GPIO_SetBits(GPIOA, I2C_SDA); //PA2(SDA)脚=1;3.3V
I2Cdelay(5);
GPIO_ResetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=0;0v
}
//发送应答位子程序
void Ack(void)
{
GPIO_ResetBits(GPIOA, I2C_SDA); //PA2(SDA)脚=0;0v
GPIO_SetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=1;3.3V
I2Cdelay(5);
GPIO_SetBits(GPIOA, I2C_SDA); //PA2(SDA)脚=1;3.3V
GPIO_ResetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=0;0v
}
//发送非应答位子程序
void NoAck(void)
{
GPIO_SetBits(GPIOA, I2C_SDA); //PA2(SDA)脚=1;3.3V
GPIO_SetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=1;3.3V
I2Cdelay(5);
GPIO_ResetBits(GPIOA, I2C_SDA); //PA2(SDA)脚=0;0v
GPIO_ResetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=0;0v
}
//应答位检查子程序,若检测不到非应答信号,置位E0
void TestAck(void)
{
u8 nSDA = 0;
GPIO_SetBits(GPIOA, I2C_SDA); //PA2(SDA)脚=1;3.3V
SetSDAIn();
GPIO_SetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=1;3.3V
E0=0;
I2Cdelay(1); //短延时
nSDA= GPIO_ReadInputDataBit(GPIOA, I2C_SDA); // 读取PA2(SDA)脚状态
if(nSDA==1) //如果SDA为1,表明非应答,置位非应答标志E0
E0=1;
GPIO_ResetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=0;0v
SetSDAOut();
}
//写一个字节数据子程序,n为待发送的数据
//发送时先假设为从高位往地位的顺序发送
void Write8Bit(u8 n)
{
u8 i;
u8 nSDA;
for(i=8;i>0;i--)
{
nSDA=n&0x80;
if (nSDA==0)
{
//SDA脚发0
GPIO_ResetBits(GPIOA, I2C_SDA); //PA2(SDA)脚=0;0v
}
else
{
//SDA脚发1
GPIO_SetBits(GPIOA, I2C_SDA); //PA2(SDA)脚=1;3.3V
}
GPIO_SetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=1;3.3V
I2Cdelay(5);
GPIO_ResetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=0;0v
GPIO_ResetBits(GPIOA, I2C_SDA); //PA2(SDA)脚=0;0v
n=n<<1;
}
}
//读一个字节数据子程序
u8 Read8Bit(void)
{
u8 temp,rbyte=0;
u8 nSDA = 0x68;
for(temp=8;temp>0;temp--)
{
GPIO_SetBits(GPIOA, I2C_SDA); //PA2(SDA)脚=1;3.3V
SetSDAIn();
GPIO_SetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=1;3.3V
I2Cdelay(1); //短延时
rbyte=rbyte<<1;
nSDA= GPIO_ReadInputDataBit(GPIOA, I2C_SDA); // 读取PA2(SDA)脚状态
rbyte=rbyte|nSDA;
GPIO_ResetBits(GPIOA, I2C_SCL); //PA1(SCL)脚=0;0v
SetSDAOut();
I2Cdelay(10); //延时
}
return(rbyte);
}
// 写1个字节数据到24C02子程序
void WriteOneByteI2C(u8 *Wdata,u8 SlaveAddress, u8 Address)
{
//Wdata为待发送字节,SlaveAddress为I2C外围器件的寻址地址,Address为数据写入地址
u8 i;
I2CStart(); //启动
Write8Bit(SlaveAddress); //写入器件的寻址地址
// 应答检查前一定要延时
for(i=0;i<255;i++)
I2Cdelay(0xef);
TestAck(); //应答检查
if(E0==1)
{
NACK=1; //若非应答表明器件错误或已坏,置错误标志位NACK
return;
}
Write8Bit(Address); //写入器件的寻址地址
// 应答检查前一定要延时
for(i=0;i<255;i++)
I2Cdelay(0xef);
TestAck(); //应答检查
if(E0==1)
{
NACK=1; //若非应答表明器件错误或已坏,置错误标志位NACK
return;
}
Write8Bit(*Wdata); //写一个字节
// 应答检查前一定要延时
for(i=0;i<255;i++)
I2Cdelay(0xef);
TestAck(); //应答检查
if(E0==1)
{
NACK=1; //若非应答表明器件错误或已坏,置错误标志位NACK
return;
}
I2CStop(); //全部发送完则停止
}
// 读24C02中的1个字节数据子程序
void ReadOneByteI2C(u8 *Rdata,u8 SlaveAddress,u8 Address)
{ //Wdata为待发送字节,SlaveAddress为I2C外围器件的寻址地址,Address为数据写入地址
u8 i;
I2CStart(); //启动
Write8Bit(0xa0); //写入器件的寻址地址
// 应答检查前一定要延时
for(i=0;i<255;i++)
I2Cdelay(0xef);
TestAck(); //应答检查
if(E0==1)
{
NACK=1; //若非应答表明器件错误或已坏,置错误标志位NACK
return;
}
Write8Bit(Address); //写入器件的寻址地址
// 应答检查前一定要延时
for(i=0;i<255;i++)
I2Cdelay(0xef);
TestAck(); //应答检查
if(E0==1)
{
NACK=1; //若非应答表明器件错误或已坏,置错误标志位NACK
return;
}
I2CStart(); //重新启动
Write8Bit(SlaveAddress); //写入器件的寻址地址
// 应答检查前一定要延时
for(i=0;i<255;i++)
I2Cdelay(0xef);
TestAck(); //应答检查
if(E0==1)
{
NACK=1; //若非应答表明器件错误或已坏,置错误标志位NACK
return;
}
*Rdata=Read8Bit(); //读入一个字节
Ack(); //应答
NoAck(); //非应答
I2CStop(); //停止
}
void SetSDAIn(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOC clock */
/* Enable GPIOA clock */
/* Configure PC.06, PC.07, PC.08 and PC.09 as output push-pull */
GPIO_InitStructure.GPIO_Pin = I2C_SDA;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void SetSDAOut(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOC clock */
/* Enable GPIOA clock */
/* Configure PC.06, PC.07, PC.08 and PC.09 as output push-pull */
GPIO_InitStructure.GPIO_Pin = I2C_SDA;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -