STM32F103标准库开发—目录
AT24Cxx系列芯片中文数据手册----资源链接 点击下载
AT24C256读写操作----程序源码 点击下载
IIC底层驱动程序
这次I是普通I/O端口模拟IIC通信实验
具体引脚配置如下:
IIC接口 | GPIO端口 |
---|---|
时钟线(SCL) | PB6 |
数据线(SDA) | PB7 |
IIC主控实验----底层驱动GPIO配置
GPIO初始化配置
具体代码如下:
//初始化IIC
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); //PB6,PB7 输出高电平---空闲状态
}
时钟线(SCL)—GPIO功能配置
在IIC通信中,主控的时钟线(SCL) 一直是输出状态
具体程序如下:
//时钟线(SCL):PB6输出---高电平
#define SCL_H GPIO_SetBits(GPIOB,GPIO_Pin_6)
//时钟线(SCL):PB6输出---低电平
#define SCL_L GPIO_ResetBits(GPIOB,GPIO_Pin_6)
数据线(SDA)—GPIO功能配置
由于IIC通信是半双工通信方式
因而数据线(SDA)可能会是数据输入,也可能是数据输出。
数据线(SDA)输入模式
//数据线(SDA):PB7输入
#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
//读取PB7的电平
#define READ_SDA GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)
数据线(SDA)输出模式
//数据线(SDA):PB7输出
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}
//数据线(SDA):PB7输出---高电平
#define SDA_H GPIO_SetBits(GPIOB,GPIO_Pin_7)
//数据线(SDA):PB7输出---低电平
#define SDA_L GPIO_ResetBits(GPIOB,GPIO_Pin_7)
IIC主控实验----底层驱动程序
开始信号
当时钟线SCL 为高电平时,数据线SDA 由高电平向低电平跳变。
具体程序如下:
void IIC_Start(void)//开始信号
{
SDA_OUT(); //数据线(SDA)输出模式
SDA_H; //数据线(SDA)输出高电平
SCL_H; //时钟线(SCL)输出高电平
delay_us(5);
SDA_L; //数据线(SDA)输出低电平
delay_us(5);
SCL_L; //时钟线(SCL)输出低电平
}
终止信号
当时钟线SCL 为高电平时,数据线SDA 由低电平向高电平跳变。
具体程序如下:
void IIC_Stop(void)//终止信号
{
SDA_OUT(); //数据线(SDA)输出模式
SCL_L; //时钟线(SCL)输出低电平
SDA_L; //数据线(SDA)输出低电平
delay_us(5);
SCL_H; //时钟线(SCL)输出高电平
SDA_H; //数据线(SDA)输出高电平
delay_us(5);
}
应答信号
我们这里写的是IIC主控程序,在读取从控数据的时候,需要回复应答信号。
产生应答信号,表示接收数据成功。
具体程序如下:
void IIC_Ack(void)//产生应答信号
{
SCL_L; //时钟线(SCL)输出低电平
SDA_OUT(); //数据线(SDA)输出模式
SDA_L; //数据线(SDA)输出低电平
delay_us(2);
SCL_H; //时钟线(SCL)输出高电平
delay_us(5);
SCL_L; //时钟线(SCL)输出低电平
}
产生非应答信号,表示接收数据失败。
具体程序如下:
void IIC_NAck(void)//不产生应答信号
{
SCL_L; //时钟线(SCL)输出低电平
SDA_OUT(); //数据线(SDA)输出模式
SDA_H; //数据线(SDA)输出高电平
delay_us(2);
SCL_H; //时钟线(SCL)输出高电平
delay_us(5);
SCL_L; //时钟线(SCL)输出低电平
}
IIC主控程序,在写入数据到从控的时候,需要等待应答信号。
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)//等待应答信号
{
int uc=0;
SDA_IN(); //数据线(SDA)输入模式
SDA_H; delay_us(1);
SCL_H; delay_us(1);
while(READ_SDA)
{
uc++;
if(uc>250)//接收应答失败
{
IIC_Stop();//发送终止信号
return 1;
}
}
SCL_L;
return 0;
}
数据传输
IIC总线进行数据传送时,时钟线(SCL)上的信号为高电平期间,数据线(SDA)上的数据必须保持稳定。
只有在时钟线(SCL)上的信号为低电平期间,数据线(SCL)上的高电平或低电平状态才允许变化。
输出到数据线(SDA)上的每个字节必须是8位
数据传送时,先传送最高位(MSB),后传送最低位(LSB)
每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)
IIC主控发送一个字节数据
具体程序如下:
void IIC_Send_Byte(u8 txdata)//发送一个字节数据---高位在前,低位在后
{
SDA_OUT(); //数据线(SDA)输出模式
SCL_L;
for(int t=0;t<8;t++) //高位在前,低位在后。
{
if((txdata&0x80)>>7) SDA_H;
else SDA_L;
txdata<<=1;
delay_us(2);
SCL_H;
delay_us(2);
SCL_L;
delay_us(2);
}
}
IIC主控接收一个字节数据
具体程序如下:
u8 IIC_Read_Byte(unsigned char ack)//读取一个字节数据---ack=1时,发送ACK,ack=0,发送nACK
{
unsigned char rxdata=0,i;
SDA_IN(); //数据线(SDA)输入模式
for(i=0;i<8;i++)
{
SCL_L;
delay_us(2);
SCL_H;
rxdata<<=1;
if(READ_SDA) rxdata++;
delay_us(1);
}
if(!ack) IIC_NAck();
else IIC_Ack();
return rxdata;
}
版权声明:本文为MQ0522原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。