STM32基于IIC协议的OLED模块的使用

2023-05-16

前言

一、项目涉及的内容

项目简介

二、模块实操

1. IIC模块

1.1 IIC协议格式

1.2 开始信号与停止信号

1.3 写数据

1.3.1 硬件IIC代码编写

1.3.2 软件模拟IIC代码编写

2. OLED板块


前言

本篇文章对使用IIC协议操作OLED屏幕进行了总结。


一、项目涉及的内容

本项实验的硬件组成有STM32F103C8T6开发板、OLED模块(0.96寸4针IIC接口OLED显示屏),设计到的软件模块有GPIO、IIC、系统定时器SysTick,接下来对这些主要模块进行讲解,回顾项目的重点,希望大家也能有所收获。

项目简介

通过IIC进行数据传输,操控OLED屏幕显示文字、图像。


二、模块实操

1. IIC模块

IIC(Inter-Integrated Circuit)总线是一种由 PHILIPS 公司开发的两线式串行总线,用于连接微控制器及其外围设备。一个 I2C 总线只需要使用两条总线线路就可以进行通讯,一条双向串行数据线(SDA) ,一条串行时钟线(SCL)。数据线SDA即用来表示数据,时钟线SCL用于数据收发同步。SCL由主机产生,SDA由主机或者从机产生。

I2C是同步串行通信,同时它属于半双工,也就是说同一时间SDA只能由一个设备发送信号。IIC是以字节的方式进行传输的,每次传输8位(一个字节)。

接口是通过SCL与SDA连接到IIC总线上的,接口可以下述4种模式中的一种运行:
● 从发送器模式
● 从接收器模式
● 主发送器模式
● 主接收器模式
模块默认地工作于从模式。接口在生成起始条件后自动地从从模式切换到主模式;当仲裁丢
失(两个及以上的主设备要同时通信时的优先级判定)或产生停止信号时,则从主模式切换到从模式。主模式时, I2C接口启动数据传输并产生时钟信号。串行数据传输总是以起始条件开始并以停止条件结束。
 

1.1 IIC协议格式

IIC的通讯方式简单概括一下就是:

  1. 主机产生开始信号,跟在起始条件后的1或2个字节是地址(7位模式为1个字节, 10位模式为2个字节),字节的最后一位确定读/写。从机I2C接口能识别它自己的地址(7位或10位)和广播呼叫地址,I2C中与从机地址相同的从机开始与主机进行通讯。
  2. 第二个字节传送从机寄存器地址,也就是我们要往哪个地址传输内容,分为数据寄存器和命令寄存器两种,跟名字一样传输到对应寄存器表示要传输数据/命令。
  3. 第三个字节开始才是传送给从机数据看命令是多少或者数据是多少,主机每发送完一
    个字节数据,都要等待从机的应答信号(ACK),重复这个过程,可以向从机传输 N 个数据,
    这个 N 没有大小限制。

图片来源:零死角玩转 STM32F103—霸道>>>第24章  I2C—读写EEPROM>>>图 24-4 I2C 通讯复合格式


1.2 开始信号与停止信号

I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答
信号。
开始信号: SCL 为高电平时, SDA 由高电平向低电平跳变,开始传送数据
结束信号: SCL 为高电平时, SDA 由低电平向高电平跳变,结束传送数据。
应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,
表示已收到数据。 CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号, CPU 接
收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为
受控单元出现故障。
这些信号中,起始信号是必需的,结束信号和应答信号可以不要。

 图片来源:STM32F1xx中文参考手册>>>24 I2C接口>>>24.3 I2C功能描述>>>24.3.1 模式选择

IIC通讯中,数据和地址都是按8位/字节进行传输,高位在前。跟在起始条件后的1或2个字节是地址(7位模式为1个字节, 10位模式为2个字节)。地址只在主模式发送。我们选择的是7位地址模式,可以看到我们发送起始信号之后,在一个字节传输的8个时钟后的第9个时钟期间,接收器必须回送一个应答位(ACK)给发送器。


1.3 写数据

IIC通讯有软件的方式和硬件的方式两种,软件方式引脚定义会更灵活,硬件方式引脚是固定的,但通讯的效率会更高一些。

1.3.1 硬件IIC代码编写

STM32的IIC片上外设专门负责实现IIC通讯协议,只要配置好这个外设,它就会自动根据协议的要求产生通讯信号,收发数据并缓存起来,CPU只要检测该外设的状态和访问数据寄存器就能完成数据收发。

stm32F1系列的硬件I2C外设默认情况下使用PB6和PB7两个引脚。

图片来源:STM32F1xx中文参考手册 >>> 8.3.9 I2C1 复用功能重映射

我们分别配置GPIO口与I2C外设的结构体成员,然后调用库函数GPIO_Init()与 I2C_Init() 把结构体的配置写入到寄存器中。

//硬件IIC初始化配置
void I2C_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	I2C_InitTypeDef I2C_InitStructure;
	
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE);		
	
	//PB6 --SCL; PB7 --SDA
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init( GPIOB, &GPIO_InitStructure); //初始化GPIO配置

	I2C_DeInit( I2C1);	//复位初始化IIC的配置
	I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //使能响应
	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //指定地址长度,可为7或10
	I2C_InitStructure.I2C_ClockSpeed = 400000; //设置SCL时钟频率,400kHz
	I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //时钟占空比,可选low/high = 2:0或16:9
	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //指定工作模式为IIC,可选IIC模式及SMBUS模式
	I2C_InitStructure.I2C_OwnAddress1 = 0X10; //自身的IIC设备地址
	I2C_Init( I2C1, &I2C_InitStructure); //初始化IIC外设配置
	I2C_Cmd( I2C1, ENABLE); //使能IIC外设
}

IIC主机发送符合协议内容的数据出去之后,IIC外设会产生相应的时间EVx,也就是IIC外设的相关寄存器会自动置0或置1,我们只要去读取对应的寄存器就可以确定事件是否发生。

 图片来源:STM32F1xx中文参考手册>>>24 I2C接口>>>24.3.1 模式选择>>>图245 主发送器传送序列图

图片来源:STM32F1xx中文参考手册>>>24 I2C接口>>>24.3.3 I2C主模式>>>图242 I2C的功能框图

我们要发送数据,要做的有以下几件事情:

  1. 先检查IIC总线是否有被其他的主机使用
  2. 如果IIC总线处于空闲状态,我们就使用库函数I2C_GenerateSTART()产生IIC起始信号
  3. 发送从机地址
  4. 发送寄存器地址,确定是要输入命令还是数据内容
  5. 往命令/数据寄存器发送数据内容
  6. 关闭IIC总线,让IIC总线重新进入空闲状态等待被主机激活

其中除了一开始检查IIC总线是否处于繁忙状态外,每一件事情我们都要去检测对应的EVx事件是否发生,等待每一个事情触发事件后我们继续进行下一步,检测的函数以及对应的事件都已经在文件stm32f10x_i2c.h与stm32f10x_i2c.c中定义好了。

//硬件IIC写字节
void I2C_WriteByte(uint8_t addr, uint8_t data)
{
	//先检查I2C总线是否繁忙
	while( I2C_GetFlagStatus( I2C1, I2C_FLAG_BUSY)); 
	//开启I2C1
	I2C_GenerateSTART( I2C1, ENABLE); 	
	while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_MODE_SELECT)); //检查是否应答,等待触发EV5
	//发送器件地址
	I2C_Send7bitAddress( I2C1, Slave_Address, I2C_Direction_Transmitter); 	
	while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));	//等待触发EV6
    //发送寄存器地址
	I2C_SendData( I2C1, addr);	
	while( !I2C_CheckEvent( I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));	//等待触发EV8
	//发送数据
	I2C_SendData( I2C1, data);	
	while( !I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) ); //等待触发EV8_2
	//关闭I2C1总线
	I2C_GenerateSTOP( I2C1, ENABLE);	
}

1.3.2 软件模拟IIC代码编写

我们也可以直接控制STM32的两个GPIO引脚分别用作SCL及SDA,然后按照上述信号的时序要求,遵循通讯协议,控制引脚的输出(如果是接收数据则是读取SDA电平),就可以实现IIC通讯。直接控制 GPIO 引脚电平产生通讯时序,由 CPU 控制每个时刻的引脚状态,这种方式称之为“软件模拟协议”方式。

我们进行初始化配置的时候,就不需要配置IIC外设了,只需要对GPIO口进行配置就可以了。

//软件模拟IIC协议初始化
void OLED_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
	
	//PB0 --SCL; PB1 --SDA
    //I2C支持多个主设备与多个从设备连接在同一根总线上,如果不开漏输出,会出现短路现象
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init( GPIOB, &GPIO_InitStructure);
	
	OLED_SCLK_Set(); //初始化时钟总线高电平
	OLED_SDIN_Set(); 初始化总线高电平
}

 软件模拟IIC时序的话,就要按照IIC协议规定的方式严格执行控制引脚的输出。

 图片来源:STM32F1xx中文参考手册>>>24 I2C接口>>>24.3 I2C功能描述>>>24.3.1 模式选择

//模拟I2C起始信号
static void OLED_IIC_Start(void)
{
	OLED_SCLK_Set(); //时钟总线高电平
	OLED_SDIN_Set(); //数据总线高电平
	us_delay(1);
	
	OLED_SDIN_Clr();
	us_delay(1);
	OLED_SCLK_Clr();
	us_delay(1);
}

//模拟I2C结束信号
static void OLED_IIC_Stop(void)
{
	OLED_SDIN_Clr(); //数据总线低电平
	us_delay(1);
	OLED_SCLK_Set(); //时钟总线高电平
	us_delay(1);
	OLED_SDIN_Set();
	us_delay(1);	
}

//模拟I2C读取从机应答信号
static unsigned char IIC_Wait_Ack(void)
{
	unsigned char ack;
	OLED_SCLK_Clr(); //时钟总线低电平
	us_delay(1);
	OLED_SDIN_Set(); //数据总线高电平
	us_delay(1);	
	OLED_SCLK_Set(); //时钟总线高电平
	us_delay(1);
	
	if(OLED_READ_SDIN()) //无应答
	{
		ack = IIC_NO_ACK;
	}
	else
	{
		ack = IIC_ACK;
	}		
	OLED_SCLK_Clr(); //时钟线置低
	us_delay(1);	
	return ack;
}

传输时, SCL 为高电平的时候 SDA 表示的数据有效,即此时的 SDA 为高电平时表示数据“ 1”,为低电平时表示数据“0”。当 SCL为低电平时, SDA 的数据无效,一般在这个时候 SDA 进行电平切换,为下一次表示数据做好准备。传输数据的时候,将SCL置低,然后设置SDA总线对应的引脚电平为高/低,SDA电平确定后再讲SCL置高,将8个位由高到低依次发送出去。

//IIC传输一个字节,传输时先从高位开始
static void Write_IIC_Byte(unsigned char IIC_Byte)
{
	unsigned char i; //定义变量
	for(i=0;i<8;i++)
	{
		OLED_SCLK_Clr();  //时钟线置低
		us_delay(1);
		if(IIC_Byte & 0x80) //读取最高位
			OLED_SDIN_Set();  //最高位为1
		else
			OLED_SDIN_Clr();  //最高位为0
		
		us_delay(1);
		OLED_SCLK_Set(); //时钟线置高,产生上升沿把数据送出去
		us_delay(1);
		
		IIC_Byte <<= 1; //数据左移一位
	}
	OLED_SCLK_Clr();  //时钟线置低
	us_delay(1);
	
	IIC_Wait_Ack();   //从机等待(这边应该是要监测返回值是否正确,当不应答时重新进行连接或者暂停传输数据)
}

2. OLED板块

我们用的0.96寸OLED显示屏芯片是SSD1306,这里我们将OLED屏幕作为从机,数据和应答都是通过SDA发送的,SSD1306的IIC通讯接口的数据总线是由SDAout和SDAin输入组成的,SDAin和SDAout绑定到了一起作为SDA,SDAout引脚可以不连接,当不连接时,应答信号将会被IIC总线忽略。

当主机通过开始条件初始化IIC通讯,并且广播的从机地址与我们要接收数据的从机地址相同时,发起开始信号的主机与从机双方将建立通讯,控制字节或数据字节开始通过SDA传输。

数据位的解读是基于D/C#位引脚的输入,如果 D/C#引脚是高,D[7:0]就被解读为写到图像显示数据 RAM( GDDRAM)中的显示数据,GDDRAM 列地址指针将会在每次数据写之后自动加 1。
如果是低, D[7:0]的输入就被解读为一个命令。然后数据输入就会被解码并写到相关的命令
寄存器中。

GDDRAM 是一个为映射静态 RAM 保存位模式来显示。该 RAM 的大小为 128 * 64 为, RAM
分为 8 页,从 PAFE0 到 PAGE7,用于单色 128 * 64 点阵显示,如下图所示
 

 

 图片来源:SSD1306-OLED驱动芯片中文手册

SSD1306 中有三种不同的内存地址模式:页地址模式,水平地址模式,垂直地址模式。我们使用页地址模式,在页地址模式下,在显示 RAM 读写之后,列地址指针自动加一。如果列地址指针达到了列的结束地址,列地址指针重置为列开始地址并且页地址指针不会改变。用户需要设置新的页
和列地址来访问下一页 RAM 内容
。页地址模式下 PAGE 和列地址指针的移动模式参考下图
 

使用下面的步骤来定义开始 RAM 访问的位置:
1. 通过命令 B0h 到 B7h 来设置目标显示位置的页开始地址
2. 通过 00h~0Fh 来设置低开始列地址的指针
3. 通过命令 10h~1Fh 来设置高开始列地址
比如说,如果页地址设置为 B2h,低列地址是 03h 高列地址为 00h,那么就意味着开始列是
PAGE2 的 SEG3.RAM 访问指针的位置如下图所示。输出数据字节将写到 RAM 列 3 的位置。

 OLED屏幕的初始化代码用到的指令都是芯片手册上有固定的格式,厂家一般会提供初始化代码,格式略有不同,这部分就不贴出来了。

下边代码分别是设置屏幕显示的位置、显示字符、显示字符串、显示中文、显示图片

  • 设置图像显示的起点行、列
//设置数据写入的起始行,列
//x:列的起始低地址与起始高地址
//y:起始页地址  0-7
void OLED_Set_Pos(unsigned char x, unsigned char y)
{
	OLED_WR_Byte( 0xb0+y, OLED_CMD); //写入页地址
	OLED_WR_Byte( x&0x0f, OLED_CMD); //写入列的地址,低半个字节
	OLED_WR_Byte( (x&0xf0)>>4 | 0x10, OLED_CMD); //写入列地址,高半个字节		
}
  •  设置OLED屏幕显示ASCII码字符,有8*16与6*8两种字符大小
//显示字符
void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char chr)
{
	unsigned char j = 0;
	chr = chr - ' '; //获取字符的偏移量
	
	if( x >= Max_Column)//让x限制在128列内
		x=0;	
	
	if( SIZE == 16) //字符8*16(高度是16,所以要分为两个上下两部分来发送)
	{		
		OLED_Set_Pos(x,y); //上半段
		for(j=0; j<8; j++)
		{
			OLED_WR_Byte( F8X16[chr*16+j],OLED_DAT);
		}	
		OLED_Set_Pos(x,y+1); //下半段
		for(j=0; j<8; j++)
		{
			OLED_WR_Byte( F8X16[chr*16+j+8],OLED_DAT);
		}			
	}
	else if( SIZE == 6) //字符6*8
	{
		OLED_Set_Pos(x,y);
		for(j=0; j<6; j++)
			OLED_WR_Byte( F6x8[chr*8][j],OLED_DAT);
	}		
	
}	
  •  设置OLED屏幕显示字符串
//显示字符串
void OLED_ShowString(unsigned char x, unsigned char y, unsigned char *chr)
{
	unsigned char j=0;
	while(chr[j] != '\0') //判断是不是最后一个字符
	{
		if(SIZE == 16)
		{
			if( x >= Max_Column)
			{
				x=0;
				y=y+2;
			}	
			OLED_ShowChar(x,y,chr[j]);	//显示字符
			x=x+8; //一个字符占8列
		}
		else if(SIZE == 6)
		{
			if( x >= Max_Column)
			{
				x=0;
				y=y+1;
			}
			OLED_ShowChar(x,y,chr[j]);	//显示字符			
			x=x+6; //一个字符占6列			
		}
		j++; //下一个字符
	}
	
}
  • 设置OLED屏幕显示中文字体 
//显示文字
void OLED_ShowChinese(unsigned char x, unsigned char y, unsigned char list)
{
	unsigned char i=0;
	
	OLED_Set_Pos(x, y); //中文字体上半部分
	for(i=0;i<16;i++)
	{
		OLED_WR_Byte( F16x16[list*32+i], OLED_DAT); //一个字体占用了16+16个字节,所以是list乘以32,下半部分就再加上16
	}
	
	OLED_Set_Pos(x,y+1); //中文字体下半部分
	for(i=0;i<16;i++)
	{
		OLED_WR_Byte( F16x16[list*32+16+i], OLED_DAT);
	}		
}
  •  设置OLED屏幕显示bmp格式图像
//显示图片
void OLED_DrawBMP(unsigned char x0, unsigned char y0, unsigned char x1, unsigned char y1, unsigned char BMP[])
{
	unsigned int j =0;
	unsigned char x,y;
	if(y1%8 == 0)
		y = y1/8;
	else
		y = y1/8 +1;
	for(y=y0;y<y1;y++)
	{
		OLED_SetPos(x0,y); 
		for(x=x0;x<x1;x++)
		{
			WriteDat(BMP[j++]);
		}
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32基于IIC协议的OLED模块的使用 的相关文章

  • 51单片机 数码管中断操作

    实践目的 1 掌握中断的概念和思想 2 掌握51单片机中断系统和相关软硬件设计 实践内容 1 利用单片机的P0口接数码管的字段脚 P1 0脚接共阴极 P3 2 P3 3引脚接独立按键产生外部中断信号 编写程序 当程序正常运行时数码管显示H字
  • GCC - 如何停止链接 malloc?

    我正在努力将我的代码缩减到最小的骨架大小 我使用的是只有 32k 闪存的 STM32F0 需要很大一部分闪存用于数据存储 我的代码已经有大约 20k 闪存大小 其中一些是由于使用了 STM32 HAL 函数 我可以在以后需要时对其进行解释和
  • 如何让printf在STM32F103上工作?

    我是 STM32F103 世界的新手 我有一个STM32F103的演示代码 我正在使用arm none eabi来编译它 我尝试了在谷歌上可以找到的内容 但到目前为止没有任何效果 我已经花了三天时间来解决这个问题 任何人都可以给我一个运行良
  • STM32 F072上的软件如何跳转到bootloader(DFU模式)?

    STM32应用笔记2606对此进行了讨论 但没有简单的代码示例 该答案已使用 IAR EWARM 在 STM32F072 Nucleo 板上进行了测试 这个答案使用 STM32标准外设库 仅此而已 请注意 验证您是否成功进入引导加载程序模式
  • 134-基于stm32单片机矿井瓦斯天然气浓度温湿度检测自动通风系统Proteus仿真+源程序...

    资料编号 134 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 ds1302时钟 DHT11温湿度 电机 蜂鸣器 制作一个基于stm32单片机矿井瓦斯天然气浓度温湿度检测自动通风系统Proteus仿真 2 通过DH
  • 138-基于stm32单片机汽车多功能仪表盘显示系统Proteus仿真+源程序

    资料编号 138 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 ds1302时钟 LED灯 蜂鸣器 电位器 制作一个基于stm32单片机汽车多功能仪表盘显示系统Proteus仿真 2 通过DHT1
  • 136-基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真+源程序

    资料编号 136 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 蜂鸣器 制作一个基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真 2 通过DHT11传感器检测当前温湿度 并且显示到L
  • rt-thread studio中新建5.02版本报错

    先吐槽一下 rt thread studio出现BUG真多 好多时间都是在找BUG 但里面用好多控件还是挺好用的 真是又爱又恨 所以一般使用功能不多的话还是用keil多一点 创建5 02版本工程之后直接进行编译 直接会报下面这个错误 资源
  • STM32F103

    提示 来源正点原子 参考STM32F103 战舰开发指南V1 3PDF资料 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 开发环境硬件普中科技 接线图在g
  • 毕业设计 江科大STM32的智能温室控制蓝牙声光报警APP系统设计

    基于STM32的智能温室控制蓝牙声光报警APP系统设计 1 项目简介 1 1 系统构成 1 2 系统功能 2 部分电路设计 2 1 stm32f103c8t6单片机最小系统电路设计 2 2 LCD1602液晶显示电路设计 2 2 风
  • [屏驱相关]【SWM166-SPI-Y1.28C1测评】+ 有点惊艳的开箱

    耳闻华芯微特许久了 看到论坛得评测活动赶紧上了末班车 毕竟对有屏幕得板子也是很喜欢得 京东快递小哥客客气气 微笑着把快递给了我 好评 直接拆了包 在此之前没看过视频号 所以这个圆盘盘得模具还是有点惊喜的 正面照如下 开机有灯光秀 还有动画
  • HAL 锁定和解锁函数如何使用以及为什么?

    我试图理解另一位程序员编写的代码 它使用了I C http en wikipedia org wiki I C2 B2C通信以将数据写入 STM32 微控制器的 EEPROM 一般来说 我理解他的代码是如何工作的 但我不明白他为什么使用HA
  • 在 Atollic TrueStudio、STM32CubeMX 中导入 C 库

    我目前正在开发 STM32F767ZI Nucleo 板和一个小安全芯片 microchip atecc508a 通过 i2c 连接进行连接 该芯片有一个可用的库加密验证库 https github com MicrochipTech cr
  • 跟着野火学FreeRTOS:第一段(任务定义,切换以及临界段)

    在裸机系统中 系统的主体就是 C P U CPU CP U 按照预先设定的程序逻辑在 m a i n
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • STM32的HAL中实现单按、长按和双按功能

    我正在尝试实现单击 双击和长按功能来执行不同的功能 到目前为止 我已经理解了单击和长按的逻辑 但我不知道如何检测双击 至于代码 我使用计数器实现了单击和长按 但代码仅停留在第一个 if 条件上 bool single press false
  • STM32内部时钟

    我对 STM32F7 设备 意法半导体的 Cortex M7 微控制器 上的时钟系统感到困惑 参考手册没有充分阐明这些时钟之间的差异 SYSCLK HCLK FCLK 参考手册中阅读章节 gt RCC 为 Cortex 系统定时器 SysT
  • PWM DMA 到整个 GPIO

    我有一个 STM32F4 我想对一个已与掩码进行 或 运算的 GPIO 端口进行 PWM 处理 所以 也许我们想要 PWM0b00100010一段时间为 200khz 但随后 10khz 后 我们现在想要 PWM0b00010001 然后
  • 使用 STM32F0 ADC 单独读取不同的输入

    STM32F072CBU 微控制器 我有多个 ADC 输入 并且希望单独读取它们 STMcubeMX 生成样板代码 假设我希望按顺序读取所有输入 但我无法弄清楚如何纠正这个问题 这篇博文 http blog koepi info 2015

随机推荐

  • CVPR2019:无监督深度追踪

    本文提出了一种无监督的视觉跟踪方法 与使用大量带注释数据进行监督学习的现有方法不同 xff0c 本文的CNN模型是在无监督的大规模无标签视频上进行训练的 动机是 xff0c 强大的跟踪器在向前和向后预测中均应有效 xff08 即 xff0c
  • 各种智能优化算法比较与实现(matlab版)

    各种智能优化算法比较与实现 xff08 matlab版 xff09 一 方法介绍 1免疫算法 xff08 Immune Algorithm xff0c IA xff09 1 1算法基本思想 免疫算法是受生物免疫系统的启发而推出的一种新型的智
  • 我与人工智能的故事

    本文作者 xff1a 诸葛越 前 言 人工智能的三次浪潮 2018年年初 xff0c 招聘季正如火如荼地进行 xff0c 而 数据科学家 和 算法工程师 绝对算得上热门职业 人工智能 机器学习 深度学习 建模 卷积神经网络 等关键词 xff
  • ovn-architecture

    参考 文章目录 1 Name2 Description2 1 Information Flow in OVN OVN中的信息流向 2 2 Chassis Setup2 3 Logical Networks2 4 Life Cycle of
  • IDEA创建maven项目添加jar包依赖出错

    Problem1 xff1a 由于网络原因无法下载jar包 解决方法 xff1a 在maven的settings xml文件的 lt mirrors gt 标签中配置阿里镜像 lt mirror gt lt id gt nexus aliy
  • 判断一个字符串是否为回文字符串

    题目 输入一个字符串 xff0c 判断该字符串中除去空格之后的字符串是否为回文字符串 要求 xff1a 不可使用 Java 已实现的方法替换空格 xff0c 不可消耗额外的空间 代码实现 此处为判断方法的实现 public static b
  • Spring中的 JdbcTemplate和声明式事务控制

    Spring中的 JdbcTemplate和声明式事务控制 JdbcTemplate概述 JdbcTemplate的作用 xff1a 他就是用于和数据库交互的 xff0c 实现CRUD操作 如何创建该对象 在dao的实现类中定义并用set方
  • SpringMVC(一)

    SpringMVC xff08 一 xff09 SpringMVC的基本概念 三层架构 表现层业务层持久层 MVC模型 Model xff08 模型 xff09 xff1a 通常就是指我们的数据模型 xff0c 一般情况下用于封装数据 Vi
  • SpringMVC(二)

    SpringMVC xff08 二 xff09 响应数据和结果视图 返回值分类 xff1a 字符串voidModelAndView 对象 xff1a 是 spring 提供的一个对象 xff0c 可以用来调整具体的 JSP 视图 span
  • SpringMvc(三)

    SpringMvc xff08 三 xff09 SSM 整合可以使用多种方式 xff0c 一般会选择 XML 43 注解 的方式 整合的思路 xff1a 搭建整合环境先把spring 的配置搭建完成再使用 spring 整合SpringMV
  • 工厂方法模式(Factory Method)--多态工厂的实现

    工厂方法模式 xff08 Factory Method xff09 多态工厂的实现 定义 xff1a 定义一个用于创建对象的接口 xff0c 让子类决定实例化哪一个类 xff0c 工厂方法使一个类的实例化延迟到其子类 类图 xff1a 外链
  • 无人机自主定位导航避障VINS+fast_planner实测~

    厦大研一研究的一个项目 xff0c 将项目开发用到的技术和难点在这记录一下 常更新 xff0c 先把框架写好 xff0c 有空的时候就过来更新 xff0c 要是有漏的或者有错误的地方 xff0c 请大佬指点 因为采用的是TX2 xff0c
  • rs_D455相机内外参标定+imu联合标定

    IMU标定 lt launch gt lt node pkg 61 34 imu utils 34 type 61 34 imu an 34 name 61 34 imu an 34 output 61 34 screen 34 gt lt
  • GVINS论文简明解读

    VIN与GNSS融合的必要性 VIN系统只工作在局部坐标系下 x y z yaw不可观 里程计存在不可避免的漂移 而GNSS系统可提供无漂移的全局定位 VIN与GNSS融合的难点 不同于cmaera与imu此类的外参标定 GNSS坐标与VI
  • onos2.5.2编译安装

    onos编译安装 Ubuntu18 04 1 前置下载安装 1 1 前置包安装 参考docker file sudo apt get install y ca certificates zip python python3 git bzip
  • C++和C的区别(汇总)

    1 C是面向过程的语言 xff0c 而C 43 43 是面向对象的语言 2 C和C 43 43 动态管理内存的方法不一样 xff0c C是使用malloc free函数 xff0c 而C 43 43 除此之外还有new delete关键字
  • PX4学习笔记—通过串口发送自定义数据

    最近因为项目需要实现一个通过pixhawk串口收发自定义数据的功能 搜索发现 xff0c 博客上大神们FantasyJXF FreeApe的博文已经详细介绍了通过pixhawk串口读取自定义数据 xff0c 这部分功能实现后就可以将自己开发
  • 一步步入门搭建SpringSecurity OAuth2(密码模式)

    什么是OAuth2 xff1f 是开放授权的一个标准 xff0c 旨在让用户允许第三方应用去访问改用户在某服务器中的特定私有资源 xff0c 而可以不提供其在某服务器的账号密码给到第三方应用 大概意思就是比如如果我们的系统的资源是受保护的
  • STM32驱动SG90舵机与HC_SR04超声波模块

    前言 一 项目涉及的内容 项目简介 二 模块实操 1 SysTick系统定时器模块 2 SG90 舵机模块 3 HC SR04 超声波模块 4 main函数 总结 前言 这篇文章的内容主要对一个超声波 43 舵机小项目进行总结 xff0c
  • STM32基于IIC协议的OLED模块的使用

    前言 一 项目涉及的内容 项目简介 二 模块实操 1 IIC模块 1 1 IIC协议格式 1 2 开始信号与停止信号 1 3 写数据 1 3 1 硬件IIC代码编写 1 3 2 软件模拟IIC代码编写 2 OLED板块 前言 本篇文章对使用