历史上的今天
今天是:2025年08月05日(星期二)
2019年08月05日 | STM32学习笔记之IIC操作
2019-08-05 来源:eefocus
STM32中的IIC可分为硬件IIC和软件IIC,但实际应用中更倾向于软件IIC。即可自行指定两个端口为数据线和时钟线进行IIC的模拟。但是相对于52单片机的IIC协议,STM32的IIC时序操作完全一致,唯一的差别在与STM32需要对端口的信号输入输出端口进行配置。
IIC总线协议之起始信号: IIC的启动实在SDA和SCL均为高电平期间,SDA拉低后SCL接着拉低。
void IIC_Start(void)
{
SDA_OUT(); // 配置SDA为输出模式
SDA_SET;
SCL_SET; // 初始状态SDA、SCL均为高电平
delay_us(5);
SDA_CLR; // SDA拉低
delay_us(5); // 延时5us以上
SCL_CLR;
}
IIC总线协议之停止信号:IIC的停止是发生在SCL为高电平期间,SDA突然拉高。
void IIC_Stop(void)
{
SDA_OUT();
SDA_CLR;
SCL_SET;
delay_us(5);
SDA_SET;
delay_us(5);
}
IIC总线协议之伪造应答:IIC从器件的应答主要是发生在SCL为高电平期间,SDA为低电平,延时5us以后SCL拉低。
void IIC_Ack(void)
{
SDA_OUT();
SDA_CLR;
SCL_SET;
delay_us(5);
SCL_CLR;
delay_us(5);
}
IIC总线协议之伪造非应答:IIC器件的非应答是指在SCL为高电平期间,SDA也为高电平,延时5us以后SCL拉低。
void IIC_NoAck(void)
{
SDA_OUT();
SDA_SET;
SCL_SET;
delay_us(5);
SCL_CLR;
delay_us(5);
}
IIC总线协议之写单字节:IIC发送数据时从高到低位发送。
void IIC_WriteByte(unsigned char data)
{
unsigned char i ;
SDA_OUT();
for(i=0;i<8;i++)
{
if((data< SDA_SET;
else
SDA_CLR;
// __Nop(); //确保数据线上电平稳定
SCL_SET; // 时钟线高电平期间,数据线上数据稳定有效
delay_us(5);
SCL_CLR; // 时钟线为低电平期间,开始发送数据
}
}
IIC总线协议之读单字节:IIC读取数据时也是先读取高位。
unsigned char IIC_ReadByte(void)
{
unsigned char i,dat=0;
SDA_IN();
SDA_SET;
for(i=0;i<8;i++)
{
SCL_CLR;
delay_us(5);
SCL_SET;
dat<<=1;
if(SDA)
dat+=1;
}
SCL_CLR;
delay_us(5);
return(dat);
}
IIC总线协议之写数据:按照总线协议发送。
void IIC_WriteData(unsigned char add,unsigned char dat)
{
IIC_Start(); // 开启IIC总线
IIC_WriteByte(0XA0); // 写入从器件地址
IIC_Ack(); // 伪造应答
IIC_WriteByte(add); // 写入从器件内存地址
IIC_Ack(); // 伪造应答
IIC_WriteByte(dat); // 写入数据
IIC_Ack(); // 伪造应答
IIC_Stop(); // 停止IIC总线
}
IIC总线协议之读数据:在读取时首先发送从期间地址和要读取的内存地址,然后重新启动总线读取数据。
unsigned char IIC_ReadData(unsigned char add)
{
unsigned char temp=0;
IIC_Start();
IIC_WriteByte(0XA0);
IIC_Ack();
IIC_WriteByte(add);
IIC_Ack();
IIC_Start();
IIC_WriteByte(0XA1); // 从期间读操作
IIC_Ack();
temp=IIC_ReadByte(); // 读取值
SCL_CLR;
IIC_NoAck();
IIC_Stop();
return temp;
}
当然在这些操作之前,还需要配置相关的IO口。
void IIC_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct ;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7 ;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP ; // 推挽输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_Init(GPIOB,&GPIO_InitStruct);
GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); //先拉高
}
除此之外,还有关于端口的宏定义。
#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}
#define SCL_SET GPIO_SetBits(GPIOB,GPIO_Pin_6)
#define SCL_CLR GPIO_ResetBits(GPIOB,GPIO_Pin_6)
#define SDA_SET GPIO_SetBits(GPIOB,GPIO_Pin_7)
#define SDA_CLR GPIO_ResetBits(GPIOB,GPIO_Pin_7)
#define SDA GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)
最后当然是我们验证对24C02的数据读写结果是否正确。
int main(void)
{
u8 flag=0 ;
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600); //串口初始化为115200
LCD_Init();
POINT_COLOR=RED;
IIC_Config(); //IIC相关端口配置
flag=IIC_ReadData(0x00); // 读取之前开机次数
flag++; // 加1次
IIC_WriteData(0x00,flag); // 将当前开机启动次数写进去
printf("%d",flag); // 串口显示当前开机次数
while(1)
{
POINT_COLOR=RED;
LCD_ShowString(30,40,210,16,16,"This is the");
LCD_ShowNum(124,40,flag,2,16);
LCD_ShowString(140,40,210,24,16,"th Start The System");
LED0=!LED0;
delay_ms(1000);
}
}
到此,就完成了关于IIC协议操作24C02的操作,实现开机记录次数。
史海拾趣
|
!!!超级单片机开发工具!!! 单片机开发过程中用到的多功能工具,包括热敏电阻RT值--HEX数据转换;3种LED编码;色环电阻计算器;HEX/BIN 文件互相转换;eeprom数据到C/ASM源码转换;CRC校验生成;串口调试,带简单而实用的数据分 ...… 查看全部问答> |
|
长期以来,以Flash Memory为存储体的SD卡因具备体积小、功耗低、可擦写以及非易失性等特点而被广泛应用于消费类电子产品中。特别是近年来,随着价格不断下降且存储容量不断提高,它的应用范围日益增广。当数据采集系统需要长时间地采集、记录海量数 ...… 查看全部问答> |
|
底应该选择哪种无线技术?---- 各种无线技术简介及其选择 摘要:本文将简要介绍各种无线技术,包括:红外线、蓝牙技术、Zigbee技术、自组织网络、Wi-Fi技术、射频识别技术(RFID)、实时定位服务(RTLS)、微波存取全球互通技术(WiMax)、大功 ...… 查看全部问答> |
|
我想每个学电子的,都会为自己的发展方向而忧愁过。在选择从事方向时不知道就行选择哪一个? 究竟是做硬件好还是做软件好,还是全部都做? 希望网友能说是你的看法,给为选择的人们一定指引。。。… 查看全部问答> |
|
ucos中的OSUnMapTbl是一个很大的静态数组,提高查找速度 以前看过一个网页说 这中设计思想在硬件设计中也有应用,固化在芯片中什么的, 烦请请高手指点一下。… 查看全部问答> |
|
以MSP430单片机为核心,采用检测单元阵列进行人体检测,并结合自然光检测,实现照明系统的只能控制,解决了传统节能照明控制系统存在的检测不准确、可靠性不高的问题,达到了节能目的。实际应用验证了方案的可行性,具有良好的实用价值。 [ 本帖最 ...… 查看全部问答> |
|
一个四层楼的建筑,两个电梯:电梯1和电梯2要求:1,当处于某层的一个人按动“呼叫”命令时,距离他较近的电梯到来; 2,如果两个电梯和这个人距离一样,则“电梯1”到来 &nbs ...… 查看全部问答> |
|
How to deliver employee's welfare? The high welfare of valley song on the other hand can keep a talented person, can deliver the information of \"the valley song has good business enterprise quality\" to the north face denali external world on the other hand.As lon ...… 查看全部问答> |
|
#include #define Num_of_Results 8 uint ADC_BUF0[Num_of_Results]; uint ADC_BUF1[Num_of_Results]; uint sumI; //定义电流采样均值 uint sumV; ...… 查看全部问答> |




