蓝桥杯嵌入式学习笔记(6):IIC程序设计

news2024/11/22 14:49:20

目录

前言

1. IIC基本原理

2. 电路原理

3. 代码编程

3.1 预备工作

3.2 AT24C02写读功能编写

3.2.1 AT24C02写操作实现

3.2.2 AT24C02读操作实现

3.3 MCP4017写读功能编写

3.3.1 MCP4017写操作实现

3.3.2 MCP4017读操作实现

3.4 main.c编写

3.4.1 头文件引用

3.4.2 变量声明

3.4.3 液晶屏显示代码

3.4.4 编写主要main函数部分

4. 测试

5. 总结


前言

因本人备赛蓝桥杯嵌入式省赛,故编写此学习笔记进行学习上的记录。

上文我们实现了UART程序设计,本文我们进行异步的串口通信的程序设计。

1. IIC基本原理

I2C(IIC,Inter-Intergrated Circuit),两线式串行总线,由PHILIPS公司开发用于连接微控制器及其外围设备。

它是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,高速IIC总线一般可达400kbps以上。

IIC是半双工通信方式。

IIC总线是不同IC或模块之间的双向两线通信,这两条是串行数据线(SDA)和串行时钟线(SCL)。这两条线必须通过上拉电路连接至电源。数据传输只能在总线不忙时启动。

2. 电路原理

蓝桥杯嵌入式主要考察利用IIC原理去读取24C02存储器和MCP4017可编程电阻的读写,并已给出参考历程。

下图所示为MCP4017可编程电阻的内部示意图,A点悬空,如上图所示W和B分别接了VDD和GND,所以MCP4017可编程电阻的实际电阻值就是W与B之间的阻值。

如下图所示,其中编程电阻其实就是改变N。

 

Rwb的实际计算方式如下图所示,其中翻阅手册得知Rab为100k

 

不考虑Rw的影响,每一个编程电阻分量值(N属于1~127)为0.7874k,由竞赛板的电路图可以计算出Vwb的电压为\frac{3.3*0.78740*N}{0.78740*N+10}V。

3. 代码编程

3.1 预备工作

将竞赛公开包中的i2c_hal.c和i2c_hal.h文件分别拷贝到Test\Test_Project\Src\BSP\I2C\和Test\Test_Project\Inc\BSP\I2C\中,并更名为bsp_i2c.c和bsp_i2c.h(可以不改,为了规范😄)。打开Test_Project工程,进行文件Group的添加

更改bsp_i2c.c的依赖头文件

#include "I2C/bsp_i2c.h" 

注意,这里需要修改bsp_i2c.c中的unsigned char I2CWaitAck(void)函数内容,将SDA_Output_Mode()挪到delay1(DELAY_TIME)后。修改后的结果如下:

unsigned char I2CWaitAck(void)
{
    unsigned short cErrTime = 5;
    SDA_Input_Mode();
    delay1(DELAY_TIME);
    SCL_Output(1);
    delay1(DELAY_TIME);
    while(SDA_Input())
    {
        cErrTime--;
        delay1(DELAY_TIME);
        if (0 == cErrTime)
        {
            SDA_Output_Mode();
            I2CStop();
            return ERROR;
        }
    }
    SCL_Output(0);
    delay1(DELAY_TIME);
	SDA_Output_Mode();//本行代码改到delay1(DELAY_TIME)之后
    return SUCCESS;
}

接下来进行24C02存储器和MCP4017可编程电阻的函数的编写。

3.2 AT24C02写读功能编写

3.2.1 AT24C02写操作实现

1KB/2KB EEPROM能进行8字节页面写入,4KB、8KB和16KB设备能进行16字节写入。激发写页面写操作时序图如下

写页面时序 

AT24C02的芯片地址为1010(二进制),十进制为A,(W=0,R=1)

所以写的器件地址为0xA0

根据时序图编写AT24C02存储器的写操作

//AT24C02的写
void iic_24c02_write(unsigned char *pucBuf, unsigned char ucAddr, unsigned char ucNum)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	
	I2CSendByte(ucAddr);
	I2CWaitAck();
	
	while(ucNum--)
	{
		I2CSendByte(*pucBuf++);
		I2CWaitAck();
	}
	I2CStop();
	delay1(500);
}

3.2.2 AT24C02读操作实现

随机地址读取时序如图所示。随机读取需要一个空字节写序列来载入数据地址。

顺序读取时序如图所示。顺序读取由立即地址读取或随机地址读取激发。

根据时序图编写AT24C02存储器的读操作

//AT24C02的读
void iic_24c02_read(unsigned char *pucBuf, unsigned char ucAddr, unsigned char ucNum)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	
	I2CSendByte(ucAddr);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	
	while(ucNum--)
	{
		*pucBuf++ = I2CReceiveByte();
		if(ucNum)
			I2CSendAck();
		else
			I2CSendNotAck();
	}
	I2CStop();
}

3.3 MCP4017写读功能编写

3.3.1 MCP4017写操作实现

根据读时序,编写写电阻操作代码 

//MCP4017写电阻
void write_registor(uint8_t value)
{
	I2CStart();
	I2CSendByte(0x5E);
	I2CWaitAck();
	
	I2CSendByte(value);
	I2CWaitAck();
	I2CStop();
}

3.3.2 MCP4017读操作实现

 根据读时序,编写读电阻操作代码 

//MCP4017写读电阻
uint8_t read_registor(void)
{
	uint8_t value;
	I2CStart();
	I2CSendByte(0x5F);
	I2CWaitAck();
	
	value = I2CReceiveByte();
	I2CSendNotAck();
	I2CStop();
	
	return value;
}

3.4 main.c编写

3.4.1 头文件引用

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "LCD\bsp_lcd.h"
#include "I2C\bsp_i2c.h"

3.4.2 变量声明

//变量声明
__IO uint32_t uwTick_Lcd_Set_Point;//LCD减速

//*LCD显示专用变量
unsigned char Lcd_Disp_String[22];

//EEPROM的相关变量
unsigned char EEPROM_String_1[5] = {0x11,0x22,0x33,0x44,0x55};
unsigned char EEPROM_String_2[5] = {0};
//R4017
uint8_t R4017;

3.4.3 液晶屏显示代码

void Lcd_Proc(void)
{
	if((uwTick - uwTick_Lcd_Set_Point)<200)
		return;
	uwTick_Lcd_Set_Point = uwTick;
	
	sprintf((char*)Lcd_Disp_String,"EE:%x,%x,%x,%x,%x",EEPROM_String_2[0],EEPROM_String_2[1],EEPROM_String_2[2],EEPROM_String_2[3],EEPROM_String_2[4]);
	LCD_DisplayStringLine(Line2,Lcd_Disp_String);
	sprintf((char*)Lcd_Disp_String,"R:%5.2fKQ",0.7874*R4017);
	LCD_DisplayStringLine(Line3,Lcd_Disp_String);
	sprintf((char*)Lcd_Disp_String,"Voltage:%6.3fV",3.3*0.7874*R4017/(0.7874*R4017+10));
	LCD_DisplayStringLine(Line4,Lcd_Disp_String);
}

3.4.4 编写主要main函数部分

int main(void)
{
	HAL_Init();
	
    SystemClock_Config();
	LCD_Init();
	LCD_Clear(White);
	LCD_SetBackColor(White);
	LCD_SetTextColor(Blue);
	
	I2CInit();
	
	//读写M24C02存储器
	iic_24c02_write(EEPROM_String_1,0,5);
	HAL_Delay(1);
	iic_24c02_read(EEPROM_String_2,0,5);
	//读写MCP4017
	write_registor(0x0D);
	HAL_Delay(1);
	R4017 = read_registor();
	
    while (1)
    {
		Lcd_Proc();
    }
}

4. 测试

如果测试成功,则屏幕上会显示写入EEPROM1的数据,R电阻和电压值

由图可以看到,代码测试成功。

5. 总结

本文进行IIC的介绍,并利用IIC原理去实现了读取24C02存储器和MCP4017可编程电阻的读写,通过代码测试成功实现了存储器和可编程电阻的读写功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1551349.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

react-navigation:

我的仓库地址&#xff1a;https://gitee.com/ruanjianbianjing/bj-hybrid react-navigation&#xff1a; 学习文档&#xff1a;https://reactnavigation.org 安装核心包: npm install react-navigation/native 安装react-navigation/native本身依赖的相关包: react-nativ…

水电站生态流量监测解决方案:亲历水电站生态监控改造

​记得那是在2022年夏天,我所在的环保咨询公司接到了一项非常具有挑战性的监测项目。某省的环保部门要求对辖区内所有水电站的生态流量情况进行评估,并给出整改建议。作为项目负责人,我深知这项工作的重要意义。&#xff08;选自&#xff1a;智慧水务数字孪生安全监测解决方案提…

武汉星起航公司助力零经验新手卖家征战亚马逊跨境电商市场

在数字化浪潮的推动下&#xff0c;亚马逊跨境电商行业正逐渐成为众多创业者和企业家们的新战场。然而&#xff0c;对于零经验的新手卖家而言&#xff0c;这片广袤的电商海洋无疑充满了未知与挑战。在这个关键时刻&#xff0c;武汉星起航公司以其专业的服务和深厚的行业积累&…

怎么做扫描二维码填写数据?用二维码收集用户反馈的方法

现在很多人都开始使用扫码填表的方式来收集用户反馈、签到登记、问卷调查等类型的用途&#xff0c;这种方式的使用不仅减少了制作者的成本压力&#xff0c;采用无纸化登记也提高了用户填写数据的便利性。只需要制作一个二维码&#xff0c;分享之后就可以让许多人同时扫码填写数…

详解GPT模型的前世今生

省流版&#xff1a; GPT模型是一种基于神经网络的自回归语言模型。该模型使用了一个称为“Transformer”的架构&#xff0c;从而有效避免了传统的循环神经网络产生的梯度消失问题。从第一代GPT到现在的GPT4&#xff0c;没带都产生了不同的变化&#xff0c;其性能也越来越强大。…

【Java扫盲篇】String、String Buffer和String Builder的区别

你在面试时&#xff0c;面试官让你讲讲String String Buffer String Builder的区别&#xff0c;你是否能流畅的、完整的叙述出他们三者的区别? ✍先说结论 相同点&#xff1a; 他们的底层都是由char数组实现的。不同点&#xff1a; String对象一旦创建&#xff0c;是不能修…

android安卓餐厅点餐课设

一、引言 随着移动互联网的快速发展&#xff0c;手机应用已经成为我们日常生活中不可或缺的一部分。餐饮行业也积极借助移动应用的力量&#xff0c;提供更便捷、高效的点餐服务。本文将介绍一个基于安卓系统开发的餐厅点餐APP的课程设计项目&#xff0c;探讨其设计理念、功能特…

PostgreSQL数据库如何新建登录用户?

在PostgreSQL数据库中&#xff0c;如何创建新的登录用户呢&#xff1f; 默认情况&#xff0c;PostgreSQL数据库的默认用户是&#xff1a;postgres &#xff0c;如果我们需要创建一个新的低权限用户角色&#xff0c;应该如何操作&#xff1f;本章教程&#xff0c;简单介绍一下这…

JavaFX的安装和使用

JavaFX的安装 安装可以参考&#xff1a;IDEA安装JavaFx_idea2019 javafx 下载安装-CSDN博客 JavaFX的使用 在JavaFX中&#xff0c;类的成员函数和操作本身被模式化作为在目标类中的类&#xff0c;而参数和返回值被表示为属性。代表目标对象的属性名是“this”。代表返回值的…

【C++初阶】之类和对象(中)

【C初阶】之类和对象&#xff08;中&#xff09; ✍ 类的六个默认成员函数✍ 构造函数&#x1f3c4; 为什么需要构造函数&#x1f3c4; 默认构造函数&#x1f3c4; 为什么编译器能自动调用默认构造函数&#x1f3c4; 自己写的构造函数&#x1f3c4; 构造函数的特性 ✍ 拷贝构造…

经纬恒润RTaW-Pegase:车载网络通信建模与时间特性分析工具

▎RTaW简介 RTaW-Pegase是由法国国家信息与自动化研究所&#xff08;INRIA&#xff09;旗下的RTaW公司开发的产品。它主要用于构建和优化汽车、航空航天以及工业领域的通信网络&#xff0c;包括时间敏感网络&#xff08;TSN&#xff09;、CAN&#xff08;FD&#xff0c;XL&…

【系统架构师】-第12章-信息系统架构

信息系统架构(ISA)是指对某一特定内容里的信息进行统筹、规划、设计、安排等一系列有机处理的活动。 为了更好地理解信息系统架构的定义&#xff0c; 特作如下说明: (1)架构是对系统的抽象&#xff0c;它通过描述元素、元素的外部可见属性及元素之间的关系来反映这种抽象。因此…

【QT入门】 Qt代码创建布局之水平布局、竖直布局详解

往期回顾&#xff1a; 【QT入门】 Qt实现自定义信号-CSDN博客 【QT入门】 Qt自定义信号后跨线程发送信号-CSDN博客 【QT入门】 Qt内存管理机制详解-CSDN博客 【QT入门】 Qt代码创建布局之水平布局、竖直布局详解 先看两个问题&#xff1a; 1、ui设计器设计界面很方便&#xf…

PyQT5学习--新建窗体模板

目录 1 Dialog 2 Main Window 3 Widget Dialog 模板&#xff0c;基于 QDialog 类的窗体&#xff0c;具有一般对话框的特性&#xff0c;如可以模态显示、具有返回值等。 Main Window 模板&#xff0c;基于 QMainWindow 类的窗体&#xff0c;具有主窗口的特性&#xff0c;窗口…

计算机网络基础——网络安全/ 网络通信介质

chapter3 网络安全与管理 1. 网络安全威胁 网络安全&#xff1a;目的就是要让网络入侵者进不了网络系统&#xff0c;及时强行攻入网络&#xff0c;也拿不走信息&#xff0c;改不了数据&#xff0c;看不懂信息。 事发后能审查追踪到破坏者&#xff0c;让破坏者跑不掉。 网络…

Composer常见错误解决

Composer 是 PHP 开发中常用的依赖管理工具&#xff0c;但在使用过程中可能会遇到各种错误。以下是一些常见的 Composer 错误以及相应的解决方法&#xff0c;希望能帮助你更好地解决这些问题。 Memory exhausted 解决方法&#xff1a; 增加内存限制&#xff0c;可以通过在命令…

基于随机森林与LSTM神经网络的住宅用电比较分析及预测 代码+论文 完整毕设

摘要 本文旨在探讨基于随机森林&#xff08;Random Forest&#xff09;与长短期记忆神经网络&#xff08;Long Short-Term Memory, LSTM&#xff09;的住宅用电比较分析及预测方法。随机森林是一种集成学习方法&#xff0c;通过构建多个决策树进行预测&#xff0c;具有较强的鲁…

掌握多线程之精髓:优雅地等待线程结果并继续后续操作

在当今这个信息爆炸的时代&#xff0c;多线程编程已成为高效处理并发任务的重要工具。然而&#xff0c;如何在多线程编程中优雅地等待线程结果并继续后续操作&#xff0c;却是一个让人头疼的问题。今天&#xff0c;我们就来探讨如何使用Executors.newFixedThreadPool和executor…

让IIS支持.NET Web Api PUT和DELETE请求

前言 有很长一段时间没有使用过IIS来托管应用了&#xff0c;今天用IIS来托管一个比较老的.NET Fx4.6的项目。发布到线上后居然一直调用不同本地却一直是正常的&#xff0c;关键是POST和GET请求都是正常的&#xff0c;只有PUT和DELETE请求是有问题的。经过一番思考忽然想起来了I…

如何在群晖NAS中创建FTP公网地址实现远程上传下载本地文件

文章目录 1. 群晖安装Cpolar2. 创建FTP公网地址3. 开启群晖FTP服务4. 群晖FTP远程连接5. 固定FTP公网地址6. 固定FTP地址连接 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分…