【正点原子STM32连载】 第四十二章 IIC实验 摘自【正点原子】APM32F407最小系统板使用指南

news2025/4/23 15:59:36

1)实验平台:正点原子stm32f103战舰开发板V4
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html##

第四十二章 IIC实验

本章将介绍使用APM32F407驱动板载的EEPROM进行读写操作。通过本章的学习,读者将学习到使用GPIO模拟IIC时序以及EEPROM的驱动。
本章分为如下几个小节:
42.1 硬件设计
42.2 程序设计
42.3 下载验证

42.1 硬件设计
42.1.1 例程功能

  1. 按下KEY_UP和KEY0按键,分别对24C02进行数据的写入和读取操作,读取到的数据会显示至LCD
  2. 可通过USMART对24C02进行读写一字节数据的操作
  3. LED0闪烁,指示程序正在运行
    42.1.2 硬件资源
  4. LED
    LED0 - PF9
  5. 按键
    KEY0 - PE4
    KEY_UP - PA0
  6. USART1(PA9、PA10连接至板载USB转串口芯片上)
  7. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
  8. 24C02
    IIC_SCL - PB8
    IIC_SDA - PB9
    42.1.3 原理图
    本章实验使用了板载的24C02芯片,该芯片是一个EEPROM,MCU是通过两个GPIO与该EEPROM进行连接与通信的,该EEPROM与MCU的连接原理图,如下图所示:
    在这里插入图片描述

图42.1.3.1 EEPROM与MCU的连接原理图
42.2 程序设计
42.2.1 Geehy标准库的GPIO驱动
本章实验通过控制与EEPROM连接的GPIO模拟IIC时序,实现EEPROM的读写操作,对于GPIO,主要涉及GPIO的配置和读写操作,需要一下几个步骤:
①:配置GPIO引脚为通用输出模式、开漏输出和禁止上拉/下拉
②:在与EEPROM通信时,根据需求控制指定GPIO引脚输出指定电平
③:在与EEPROM通信时,根据需求读取指定GPIO引脚上的输入电平
在Geehy标准库中对应的驱动函数如下:
①:配置GPIO引脚
请见第10.2.1小节中配置GPIO引脚的相关内容。
②:设置GPIO引脚输出电平
请见第10.2.1小节中设置GPIO引脚输出电平的相关内容。
③:读取GPIO引脚输入电平
请见第11.2.1小节中读取GPIO引脚输入电平的相关内容。
42.2.2 IIC驱动
本章实验使用的IIC的软件模拟的IIC,即控制GPIO模拟IIC的时序与外部器件进行通信。IIC驱动主要负责向EEPROM驱动提供IIC操作的各种函数,例如:IIC起始信号、IIC停止信号等。本章实验中,IIC的驱动代码包括myiic.c和myiic.h两个文件。
IIC驱动中,对GPIO相关的宏定义,如下所示:

#define IIC_SCL_GPIO_PORT	GPIOB
#define IIC_SCL_GPIO_PIN	GPIO_PIN_8
#define IIC_SCL_GPIO_CLK_ENABLE()							\
    do {														\
    		RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);	\
    } while (0)

#define IIC_SDA_GPIO_PORT	GPIOB
#define IIC_SDA_GPIO_PIN	GPIO_PIN_9
#define IIC_SDA_GPIO_CLK_ENABLE()							\
    do {														\
    		RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);	\
    } while (0)

#define IIC_SCL(x) do { x ?										\
    		GPIO_SetBit(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN) :		\
    		GPIO_ResetBit(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN);	\
    } while (0)

#define IIC_SDA(x) do { x ?										\
    		GPIO_SetBit(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN) :		\
    		GPIO_ResetBit(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN);	\
    } while (0)

#define IIC_SDA_READ \
    GPIO_ReadInputBit(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN)
IIC驱动中,IIC的初始化函数,如下所示:
/**
 * @brief	初始化IIC
 * @param	无
 * @retval	无
 */
void iic_init(void)
{
    GPIO_Config_T gpio_init_struct;
    
    /* 使能时钟 */
    IIC_SCL_GPIO_CLK_ENABLE();						/* 使能IIC SCL引脚端口时钟 */
    IIC_SDA_GPIO_CLK_ENABLE();						/* 使能IIC SDA引脚端口时钟 */
    
    /* 配置IIC SCL引脚 */
    gpio_init_struct.pin	= IIC_SCL_GPIO_PIN;			/* IIC SCL引脚 */
    gpio_init_struct.mode	= GPIO_MODE_OUT;			/* 通用输出模式 */
    gpio_init_struct.speed	= GPIO_SPEED_100MHz;		/* 高速 */
    gpio_init_struct.otype	= GPIO_OTYPE_OD;			/* 开漏输出 */
    gpio_init_struct.pupd	= GPIO_PUPD_NOPULL;			/* 禁止上拉/下拉 */
    GPIO_Config(IIC_SCL_GPIO_PORT, &gpio_init_struct);	/* 配置IIC SCL引脚 */
    
    /* 配置IIC SDA引脚 */
    gpio_init_struct.pin	= IIC_SDA_GPIO_PIN;			/* IIC SDA引脚 */
    gpio_init_struct.mode	= GPIO_MODE_OUT;			/* 通用输出模式 */
    gpio_init_struct.speed	= GPIO_SPEED_100MHz;		/* 高速 */
    gpio_init_struct.otype	= GPIO_OTYPE_OD;			/* 开漏输出 */
    gpio_init_struct.pupd	= GPIO_PUPD_NOPULL;			/* 禁止上拉/下拉 */
    GPIO_Config(IIC_SDA_GPIO_PORT, &gpio_init_struct);	/* 配置IIC SDA引脚 */
    
    iic_stop();/* 停止IIC总线上所有设备 */
}

可以看到,IIC的初始化实际上就是配置IIC时钟与数据信号对应的GPIO引脚。
IIC驱动中对IIC的各种操作,例如产生IIC起始信号、产生IIC停止信号等,请读者结合IIC的时序规定查看本实验的配套实验源码。
42.2.3 EEPROM驱动
本章实验的EEPROM驱动主要负责向应用层提供EEPROM的初始化和读写数据等操作函数。本章实验中,EEPROM的驱动代码包括24cxx.c和24cxx.h两个文件。
EEPROM驱动中,EEPROM的初始化函数,如下所示:

/**
 * @brief	初始化AT24CXX
 * @param	无
 * @retval	无
 */
void at24cxx_init(void)
{
    iic_init();
}

可以看到,该函数实际上就是初始化了与EEPROM通讯的IIC。
EEPROM驱动中的其他对EEPROM的操作函数,例如:EEPROM的读写函数,请读者结合24C02 EEPROM芯片的数据手册查看本实验的配套实验源码。
42.2.4 实验应用代码
本章实验的应用代码,如下所示:
/* 待写入24C02的数据 */

static const uint8_t g_text_buf[] = {"APM32 IIC TEST"};

/* 待写入24C02数据的长度 */
#define TEXT_SIZE sizeof(g_text_buf)

int main(void)
{
    uint8_t t = 0;
    uint8_t key;
    uint8_t data[TEXT_SIZE];
    
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_3);	/* 设置中断优先级分组为组3 */
    sys_apm32_clock_init(336, 8, 2, 7);					/* 配置系统时钟 */
    delay_init(168);										/* 初始化延时功能 */
    usart_init(115200);									/* 初始化串口 */
    usmart_dev.init(84);								/* 初始化USMART */
    led_init();											/* 初始化LED */
    key_init();											/* 初始化按键 */
    lcd_init();											/* 初始化LCD */
    at24cxx_init();										/* 初始化AT24CXX */
    
    lcd_show_string(30, 50, 200, 16, 16, "APM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "IIC TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
    lcd_show_string(30, 110, 200, 16, 16, "KEY_UP:Write  KEY0:Read", RED);
    
    while (at24cxx_check() != 0)/* 检测不到24C02 */
    {
    		lcd_show_string(30, 130, 200, 16, 16, "24C02 Check Failed!", RED);
    		delay_ms(500);
    		lcd_show_string(30, 130, 200, 16, 16, "Please Check!      ", RED);
    		delay_ms(500);
    		LED0_TOGGLE();
    }
    /* 24C02检测正常 */
    lcd_show_string(30, 130, 200, 16, 16, "24C02 Ready!       ", RED);
    
    while (1)
    {
    		t++;
    		key = key_scan(0);
    		
    		if (key == WKUP_PRES)		/* 写入数据 */
    		{
    			lcd_fill(0, 150, 239, 319, WHITE); 
    			lcd_show_string(30, 150, 200, 16, 16, "Start Write 24C02....", BLUE);
    			at24cxx_write(0, (uint8_t *)g_text_buf, TEXT_SIZE);
    			lcd_show_string(30, 150, 200, 16, 16, "24C02 Write Finished!", BLUE);
    		}
    		else if (key == KEY0_PRES)	/* 读取数据 */
    		{
    			lcd_show_string(30, 150, 200, 16, 16, "Start Read 24C02.... ", BLUE);
    			at24cxx_read(0, data, TEXT_SIZE);
    			lcd_show_string(30, 150, 200, 16, 16, "The Data Readed Is:  ", BLUE);
    			lcd_show_string(30, 170, 200, 16, 16, (char *)data, BLUE);
    		}
    		
    		if (t == 20)
    		{
    			LED0_TOGGLE();
    			t = 0;
    		}
    		
    		delay_ms(10);
    }
}

从本章实验的应用代码中可以看到,在初始化完EEPROM后,会检测与EEPROM的连接是否正常,若与EEPROM的连接正常,则会不断地等待按键输入,若检测到KEY_UP按键被按下,则会往EEPROM的指定地址中写入指定的数据,若检测到KEY_0按键被按下,则会从EEPROM的指定地址中读取数据,并在LCD上进行显示。
42.3 下载验证
在完成编译和烧录操作后,若MCU与EEPROM的连接无误,则可以在LCD上看到“24C02 Ready!”的提示信息,此时可以按下KEY_UP按键往EEPROM的指定地址写入指定数据,然后再按下KEY_0按键从EEPROM的指定地址将写入的数据读回来在LCD上进行显示,此时便可以看到在LCD上显示了“APM32 IIC TEST”的提示信息,该提示信息就是从EEPROM中读回的数据。

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

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

相关文章

Zookeeper【Curator客户端Java版】从0到1——万字学习笔记

目录 初识Zookeeper Zookeeper作用 维护配置信息 分布式锁服务 集群管理 生产分布式唯一ID Zookeeper的设计目标 Zookeeper 工作机制 数据模型 ZooKeeper 命令操作 服务端常用命令 客户端常用命令 ZooKeeper JavaAPI操作 Curator 介绍 Curator API 常用操作 导入依赖 建立连接 …

腾讯wifi码推广如何代理?方法详解!

腾讯wifi码推广是一种利用微信扫码连接商家wifi的方式,用户看完广告后就可以免费上网,而推广者则可以获得广告收益。 那么怎样代理腾讯wifi码推广呢? 答案是腾讯官方没有这个项目,那是怎么回事呢,腾讯wifi码正确的名称…

时间复杂度O(n)

目录 一. 前言 二. 时间频度和空间复杂度 2.1. 时间频度 2.2. 空间复杂度 三. 时间复杂度 3.1. 概念 3.2. 常见的时间复杂度 3.3. 计算实例 四. 大O记法 五. 对数log小知识 一. 前言 同一问题可用不同算法解决,而一个算法的质量优劣将影响到算法乃至程序的…

【计算机网络笔记】数据交换之电路交换

系列文章目录 什么是计算机网络? 什么是网络协议? 计算机网络的结构 文章目录 系列文章目录为什么需要数据交换数据交换的类型电路交换什么是多路复用?频分多路复用(FDM)时分多路复用(TDM)波分…

深度神经网络压缩与加速技术

// 深度神经网络是深度学习的一种框架,它是一种具备至少一个隐层的神经网络。与浅层神经网络类似,深度神经网络也能够为复杂非线性系统提供建模,但多出的层次为模型提供了更高的抽象层次,因而提高了模型的能力。深度神经网络是一…

百度SEO优化全攻略(提高网站排名的5个方面)

百度SEO入门介绍: 随着互联网的不断发展,SEO已经成为网站优化的重要一环。而百度作为中国最大的搜索引擎,其SEO优化更是至关重要。SEO不仅能够提高网站排名,还能够提高网站流量、用户体验以及品牌知名度。因此,掌握百…

软件性能瓶颈问题之数据库性能问题定位

前言:数据库的性能瓶颈包括:数据库索引,锁,表空间,慢sql,数据量 一、性能问题 1.1 缺乏索引: 索引本质上是一种数据结构,允许数据库快速查找特定的数据 1.2 查询效率低&#xff1…

【数据库系统概论】第三章关系数据库标准语言SQL

选择题会考: 1.数据查询: SELECT:用于选择需要查询的列和行。 FROM:用于指定要查询的表。 WHERE:用于指定查询条件。 GROUP BY:用于按照指定的列对结果进行分组。 HAVING:用于指定分组条件…

解决jmeter软件显示为英文、返回数据乱码、设置编码格式的问题

一.jmeter软件每次打开都需要手动切换中文 1.修改配置文件,可以把jmeter设置成中文: 2.打开jmeter.properties配置文件,修改languagezh_CN 二.返回数据乱码 改配置文件 进入Jmeter的bin目录下,找到jmeter.properties文件&#…

科研上新 | 第2期:可驱动3D肖像生成;阅读文本密集图像的大模型;文本控制音色;基于大模型的推荐智能体

编者按:欢迎阅读“科研上新”栏目!“科研上新”汇聚了微软亚洲研究院最新的创新成果与科研动态。在这里,你可以快速浏览研究院的亮点资讯,保持对前沿领域的敏锐嗅觉,同时也能找到先进实用的开源工具。 本期内容速览 …

minio桶命名规则

一、背景 今天做项目需要上传图片到minio,上传失败,查看错误是桶未创建成功。 minio桶的创建具有自己的命名规则,不符合则无法创建。 二、命名规则 1、存储桶名称的长度必须介于 3(最小)到 63(最大&…

KBL610-ASEMI内置4颗84MIL芯片KBL610

编辑:ll KBL610-ASEMI内置4颗84MIL芯片KBL610 型号:KBL610 品牌:ASEMI 封装:KBL-4 恢复时间:>50ns 正向电流:6A 反向耐压:1000V 芯片个数:4 引脚数量&#xff1…

将C盘中的文件夹迁移到其他盘符

目录 1 微信文件 2 移动系统自带文件夹 3 清除软件的缓存 1 微信文件 微信文件默认存储在C盘中,放任不管可能会占用很大的空间 更改后文件会自动挪过去,在C盘中只保留较小的空间 2 移动系统自带文件夹 像文档,图片这种文件夹&#…

数据治理是一个怎样的体系化的过程?_光点科技

数据治理是一个复杂而系统化的过程,旨在确保企业能够有效地管理、维护和利用其日益增长的数据资产。这一过程涉及多个层面和步骤,需要有明确的框架和战略规划。 数据治理的体系化始于明确定义的目标和愿景。企业需要明确意识到数据对于业务成功的重要性&…

华泰证券:京东营收增长或短期承压

来源:猛兽财经 作者:猛兽财经 猛兽财经获悉,华泰证券近期发布研报称京东营收增长或短期承压。华泰证券主要观点如下:营收增长或短期承压,聚焦长期内生能力建设 考虑到消费情绪的恢复仍需一定时间,我们预计…

免疫球蛋白介绍

免疫球蛋白(Immunoglobulin,Ig)是广泛存在于哺乳动物血清、淋巴液、组织液和外分泌液中的一种具有抗体活性或化学结构与抗体相似的球蛋白,在机体防御疾病的重要成分在疾病研究、药物研发、疫苗评价中具有重要作用。抗体&#xff0…

PLL的环路滤波器

本篇文章仅为分享PLL学习过程及一些公式推导,如有错误,还请批评指正! 文章目录 1、一阶RC低通滤波器(II类锁相环)2、二阶RC低通滤波器A、加电容型B、加RC低通滤波器型 3、三阶低通滤波器 锁相环3大组成部分&#xff1…

浅谈IT运维-服务目录

目录 服务目录的作用 服务目录常见的应用场景 服务目录是否必须有 服务目录的视图分类 用户视图 客户视图 服务提供者视图 服务目录的分类原则 为什么要分类 服务目录的分类方法 服务目录划分的颗粒度把握 服务详情 服务目录包括:服务目录、服务详情两大…

Redis cluster 集群

redis集群redis集群是一个提供在多个redis节点间共享数据的程序集,redis集群可以支持多个master Redis集群支持多个master,每个master又可以挂载多个slave 读写分离、支持数据的高可用、支持海量数据的读写存储操作由于Cluster自动Sentinel的故障转移机制&#xff…

ChatGLM流式输出的报错修复

ChatGLM中的openai_api.py中的代码如下: # codingutf-8 # Implements API for ChatGLM2-6B in OpenAIs format. (https://platform.openai.com/docs/api-reference/chat) # Usage: python openai_api.py # Visit http://localhost:8000/docs for documents.import …