OLED显示屏驱动:8080并口,IIC,SPI三种驱动方式

2023-05-16

本文介绍了对OLED的几种驱动方式,8080并口,IIC,SPI三种驱动方式,采用的单片机是STM32F407.

文章目录

    • 一.OLED驱动原理介绍
    • 二.8080并口驱动方式
    • 三.IIC驱动方式
    • 四.SPI驱动方式

一.OLED驱动原理介绍

OLED模块的驱动芯片为SSD1306,其显存大小总共为 12864bit 大小,SSD1306 将
这些显存分为了 8 页,其对应关系如表 17.1.3 所示:
SSD1306显存表
可以看出,SSD1306 的每页包含了 128 个字节,总共 8 页,这样刚好是 128
64 的点阵大小。因为每次写入都是按字节写入的,这就存在一个问题,如果我们使用只写方式操作模块,那么,每次要写 8 个点,这样,我们在画点的时候,就必须把要设置的点所在的字节的每个位都搞清楚当前的状态(0/1?),否则写入的数据就会覆盖掉之前的状态,结果就是有些不需要显示的点,显示出来了,或者该显示的没有显示了。这个问题在能读的模式下,我们可以先读出来要写入的那个字节,得到当前状况,在修改了要改写的位之后再写进 GRAM,这样就不会影响到之前的状况了。但是这样需要能读 GRAM,对于 4 线 SPI 模式/IIC 模式,模块是不支持读的,而且读->改->写的方式速度也比较慢。
所以我们采用的办法是在 STM32F4 的内部建立一个 OLED 的 GRAM(共 128*8 个字节),在每次修改的时候,只是修改 STM32F4 上的 GRAM(实际上就是 SRAM),在修改完了之后,一次性把 STM32F4 上的 GRAM 写入到 OLED 的 GRAM。当然这个方法也有坏处,就是对于那些 SRAM 很小的单片机(比如 51 系列)就比较麻烦了。
SSD1306 的命令比较多,这里我们仅介绍几个比较常用的命令,这些命令如表 17.1.4 所示:
SSD1306常用命令表
我们再来介绍一下 OLED 模块的初始化过程,SSD1306 的典型初始化框图如下图:
在这里插入图片描述

二.8080并口驱动方式

介绍一下模块的 8080 并行接口,8080 并行接口的发明者是 INTEL,该总线也被广泛应用于各类液晶显示器,使得 MCU 可以快速的访问 OLED。ALIENTEK OLED 模块的 8080 接口方式需要如下一些信号线:
CS:OLED 片选信号。
WR:向 OLED 写入数据。
RD:从 OLED 读取数据。
D[7:0]:8 位双向数据线。
RST(RES):硬复位 OLED。
DC:命令/数据标志(0,读写命令;1,读写数据)。
模块的 8080 并口读/写的过程为:先根据要写入/读取的数据的类型,设置 DC 为高(数据)/低(命令),然后拉低片选,选中 SSD1306,接着我们根据是读数据,还是要写数据置 RD/WR为低,然后:
在 RD 的上升沿, 使数据锁存到数据线(D[7:0])上;
在 WR 的上升沿,使数据写入到 SSD1306 里面;
SSD1306 的 8080 并口写时序图如图 17.1.3 所示:
在这里插入图片描述
在这里插入图片描述
OLED配置及驱动程序:

/*******************OLED.c代码*************************/
//OLED显存
//[0]0 1 2 3 ... 127	
//[1]0 1 2 3 ... 127	
//[2]0 1 2 3 ... 127	
//[3]0 1 2 3 ... 127	
//[4]0 1 2 3 ... 127	
//[5]0 1 2 3 ... 127	
//[6]0 1 2 3 ... 127	
//[7]0 1 2 3 ... 127 		   
u8 OLED_GRAM[128][8];//定义SRAM缓存区

//更新显存到LCD		 
void OLED_Refresh_Gram(void)
{
	u8 i, n;
	for (i = 0; i < 8; i++)
	{
		OLED_WR_Byte(0xb0 + i, OLED_CMD);    //设置页地址(0-7)
		OLED_WR_Byte(0x00, OLED_CMD);      //设置显示位置-列低地址
		OLED_WR_Byte(0x10, OLED_CMD);      //设置显示位置-列高地址   
		for (n = 0; n < 128; n++)OLED_WR_Byte(OLED_GRAM[n][i], OLED_DATA); //更新到OLED
	}
}
//通过拼凑的方法向OLED输出一个8位数据
//data:输出的数据
void OLED_Data_Out(u8 data)
{
	u16 dat = data & 0X0F;
	GPIOC->ODR &= ~(0XF << 6);		//清空6~9
	GPIOC->ODR |= dat << 6;			   //D[3:0]-->PC[9:6]
	GPIO_Write(GPIOC, dat << 6);
	PCout(11) = (data >> 4) & 0X01;	//D4
	PBout(6) = (data >> 5) & 0X01;	//D5
	PEout(5) = (data >> 6) & 0X01;	//D6
	PEout(6) = (data >> 7) & 0X01;	//D7 
}
//向SSD1306写入一个字节
//dat:写入的数据/命令
//cmd:0:命令,1:数据
void OLED_WR_Byte(u8 dat, u8 cmd)
{
	OLED_Data_Out(dat);
	OLED_RS = cmd;
	OLED_CS = 0;
	OLED_WR = 0;
	OLED_WR = 1;
	OLED_CS = 1;
	OLED_RS = 1;
}
//开启OLED显示    
void OLED_Display_On(void)
{
	OLED_WR_Byte(0X8D, OLED_CMD);  //SET DCDCÃüÁî
	OLED_WR_Byte(0X14, OLED_CMD);  //DCDC ON
	OLED_WR_Byte(0XAF, OLED_CMD);  //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{
	OLED_WR_Byte(0X8D, OLED_CMD);  //SET DCDCÃüÁî
	OLED_WR_Byte(0X10, OLED_CMD);  //DCDC OFF
	OLED_WR_Byte(0XAE, OLED_CMD);  //DISPLAY OFF
}
// OLED清屏
void OLED_Clear(void)
{
	u8 i, n;
	for (i = 0; i < 8; i++)for (n = 0; n < 128; n++)OLED_GRAM[n][i] = 0X00;
	OLED_Refresh_Gram();//¸更新显存到LCD	
}
//画点 
//x:0~127
//y:0~63
//t:1填充,0清空			   
void OLED_DrawPoint(u8 x, u8 y, u8 t)
{
	u8 pos, bx, temp = 0;
	if (x > 127 || y > 63)return;//超出范围
	pos = 7 - y / 8;
	bx = y % 8;
	temp = 1 << (7 - bx);
	if (t)OLED_GRAM[x][pos] |= temp;
	else OLED_GRAM[x][pos] &= ~temp;
}
//按区域填充
void OLED_Fill(u8 x1, u8 y1, u8 x2, u8 y2, u8 dot)
{
	u8 x, y;
	for (x = x1; x <= x2; x++)
	{
		for (y = y1; y <= y2; y++)OLED_DrawPoint(x, y, dot);
	}
	OLED_Refresh_Gram();//更新显存到OLED
}
//在指定位置显示一个字符(需要调用字符显示字库数组,自行建立)
//x:0~127
//y:0~63
//mode:0反白显示 1正常显示			 
//size:字体 12/16/24
void OLED_ShowChar(u8 x, u8 y, u8 chr, u8 size, u8 mode)
{
	u8 temp, t, t1;
	u8 y0 = y;
	u8 csize = (size / 8 + ((size % 8) ? 1 : 0))*(size / 2);		//得到一个字符所占字节数
	chr = chr - ' ';                                    //得到偏移后的值		 
	for (t = 0; t < csize; t++)
	{
		if (size == 12)temp = asc2_1206[chr][t]; 	 	//调用1206字体
		else if (size == 16)temp = asc2_1608[chr][t];	//调用1608字体
		else if (size == 24)temp = asc2_2412[chr][t];	//调用2412字体
		else return;								//没有的字库
		for (t1 = 0; t1 < 8; t1++)
		{
			if (temp & 0x80)OLED_DrawPoint(x, y, mode);
			else OLED_DrawPoint(x, y, !mode);
			temp <<= 1;
			y++;
			if ((y - y0) == size)
			{
				y = y0;
				x++;
				break;
			}
		}
	}
}
//字符串显示函数
void OLED_ShowString(u8 x, u8 y, const u8 *p, u8 size)
{
	while ((*p <= '~') && (*p >= ' '))       //判断是不是非法字符
	{
		if (x > (128 - (size / 2))) { x = 0; y += size; }
		if (y > (64 - size)) { y = x = 0; OLED_Clear(); }
		OLED_ShowChar(x, y, *p, size, 1);
		x += size / 2;
		p++;
	}
}
//m^n函数
u32 mypow(u8 m, u8 n)
{
	u32 result = 1;
	while (n--)result *= m;
	return result;
}
//数字显示函数	  
void OLED_ShowNum(u8 x, u8 y, u32 num, u8 len, u8 size)
{
	u8 t, temp;
	u8 enshow = 0;
	for (t = 0; t < len; t++)
	{
		temp = (num / mypow(10, len - t - 1)) % 10;
		if (enshow == 0 && t < (len - 1))
		{
			if (temp == 0)
			{
				OLED_ShowChar(x + (size / 2)*t, y, ' ', size, 1);
				continue;
			}
			else enshow = 1;
		}
		OLED_ShowChar(x + (size / 2)*t, y, temp + '0', size, 1);
	}
}
//显示数字,高位是0,还是显示
//x,y:起点坐标
//num:数值(0~999999999);	 
//len:长度(即要显示的位数)
//size:字体大小
//mode:
//[7]:0,不填充;1,填充0.
//[6:1]:保留
//[0]:0,非叠加显示;1,叠加显示.
void OLED_ShowxNum(u16 x, u16 y, u32 num, u8 len, u8 size, u8 mode)
{
	u8 t, temp;
	u8 enshow = 0;
	for (t = 0; t < len; t++)
	{
		temp = (num / OLED_Pow(10, len - t - 1)) % 10;
		if (enshow == 0 && t < (len - 1))
		{
			if (temp == 0)
			{
				if (mode & 0X80)OLED_ShowChar(x + (size / 2)*t, y, '0', size, mode & 0X01);
				else OLED_ShowChar(x + (size / 2)*t, y, ' ', size, mode & 0X01);
				continue;
			}
			else enshow = 1;
		}
		OLED_ShowChar(x + (size / 2)*t, y, temp + '0', size, mode & 0X01);
	}
}
//计算整数位数(为下面显示float型数据用)
int DataNum(int num)
{
	int i;
	if ((int)num == 0)i = 1;
	else
		for (i = 0; num != 0; i++)
			num = num / 10;
	return i;
}
//显示float型数据
//num:输入的float型数据
void OLED_ShowFloatNum(u16 x, u16 y, double num, u8 size, u8 mode)
{
	int a = DataNum((int)num);
	if ((int)num == 0)                                             //如果输入的float型数据整数部分是0,则加1(便于调用ShowxNum函数)
	{
		OLED_ShowxNum(x + size / 2, y, 10000 * (num + 1), 5, size, mode);        //显示电压的小数部分,如果是3.0011的话,这里显示30011
		OLED_ShowxNum(x, y, (int)num, DataNum((int)num), size, mode);    //显示电压的整数部分,如果是3.0011的话,这里显示3
		OLED_ShowChar(x + a * size / 2, y, '.', size, mode);                 //显示小数点
	}
	else                                                         //如果输入的float型数据整数部分是不是0,则正常显示
	{
		if (num - (int)num == 0)                                        //如果是正整数
		{
			OLED_ShowxNum(x, y, (int)num, DataNum((int)num), size, mode);      //显示整数
			OLED_ShowChar(x + a * size / 2, y, '.', size, mode);                  //显示小数点
			OLED_ShowChar(x + (a + 1)*size / 2, y, '0', size, mode);              //显示小数点后一个0
		}
		else                                                        //如果不是正整数
		{
			OLED_ShowxNum(x + size / 2, y, 10000 * num, DataNum((int)num) + 4, size, mode);    //显示电压的小数部分,如果是3.0011的话,这里显示30011
			OLED_ShowChar(x + a * size / 2, y, '.', size, mode);                           //显示小数点
			OLED_ShowxNum(x, y, (int)num, DataNum((int)num), size, mode);//显示电压的整数部分,如果是3.0011的话,这里显示3
		}
	}
}

//初始化SSD1306					    
void OLED_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG, ENABLE);//IO口时钟使能

	  //GPIO初始化设置
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_11;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_5;
	GPIO_Init(GPIOE, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
	GPIO_Init(GPIOG, &GPIO_InitStructure);

	OLED_WR = 1;
	OLED_RD = 1;

	OLED_CS = 1;
	OLED_RS = 1;

	OLED_RST = 0;
	delay_ms(100);
	OLED_RST = 1;

	//以下为SSD1306设置初始化代码,基本不用改动				  
	OLED_WR_Byte(0xAE, OLED_CMD); //关闭显示
	OLED_WR_Byte(0xD5, OLED_CMD); //设置时钟分频因子,振荡频率
	OLED_WR_Byte(80, OLED_CMD);   //[3:0],分频因子;[7:4],振荡频率
	OLED_WR_Byte(0xA8, OLED_CMD); //设置驱动路数
	OLED_WR_Byte(0X3F, OLED_CMD); //默认0X3F(1/64) 
	OLED_WR_Byte(0xD3, OLED_CMD); //设置显示偏移
	OLED_WR_Byte(0X00, OLED_CMD); //默认为0

	OLED_WR_Byte(0x40, OLED_CMD); //设置显示开始行 [5:0],行数.

	OLED_WR_Byte(0x8D, OLED_CMD); //电荷泵设置
	OLED_WR_Byte(0x14, OLED_CMD); //bit2 开启/关闭
	OLED_WR_Byte(0x20, OLED_CMD); //设置内存地址模式
	OLED_WR_Byte(0x02, OLED_CMD); //[1:0],00列地址模式;01行地址模式;10,页地址模式;默认10;
	OLED_WR_Byte(0xA1, OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;
	OLED_WR_Byte(0xC0, OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
	OLED_WR_Byte(0xDA, OLED_CMD); //设置COM口硬件引脚配置
	OLED_WR_Byte(0x12, OLED_CMD); //[5:4]配置

	OLED_WR_Byte(0x81, OLED_CMD); //对比度设置
	OLED_WR_Byte(0xEF, OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮)
	OLED_WR_Byte(0xD9, OLED_CMD); //设置预充电周期
	OLED_WR_Byte(0xf1, OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;
	OLED_WR_Byte(0xDB, OLED_CMD); //设置VCOMH 电压倍率
	OLED_WR_Byte(0x30, OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;

	OLED_WR_Byte(0xA4, OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
	OLED_WR_Byte(0xA6, OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示	    						   
	OLED_WR_Byte(0xAF, OLED_CMD); //开启显示	 
	OLED_Clear();//OLED清屏
}
/*******************OLED.h代码*************************/
//-----------------OLED端口定义----------------  					   
#define OLED_CS 	PBout(7)
#define OLED_RST    PGout(15)	
#define OLED_RS 	PDout(6)
#define OLED_WR 	PAout(4)		  
#define OLED_RD 	PDout(7)

#define OLED_CMD  	0		//写命令
#define OLED_DATA 	1		//写数据
/*******************main()函数代码*************************/
int main(void)
{
	OLED_Init();				//初始化OLED
	while (1)
	{
		OLED_ShowChar(100, 30, 'K', 16, 1);//显示字符
		OLED_ShowString(64, 52, "CODE:", 12);//显示字符串
		OLED_ShowFloatNum(10, 30, 0.1213, 16, 1);//显示小数
		OLED_ShowChinese(26, 10, 3, 1);//显示汉字
		OLED_Refresh_Gram(2);//更新显示到OLED,此句非常重要,将数据写到SSD1306的GRAM区域
		delay_ms(1000);
	}
}

三.IIC驱动方式

一些驱动方式与显示代码均与上面一致,因此这里只介绍IIC写数据/命令驱动代码,也即重写OLED_WR_Byte(u8 dat,u8 cmd)函数,其他均不变!

//向SSD1306写入一个字节
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据
void WriteCmd(u8 command)    //写命令函数
{
    IIC_Start();
    IIC_Send_Byte(0x78);//OLED地址
    IIC_Wait_Ack(t);
    IIC_Send_Byte(0x00);//写命令寄存器地址
    IIC_Wait_Ack();
    IIC_Send_Byte(command);
    IIC_Wait_Ack();
    IIC_Stop();
}
void WriteData(u8 data)      //写数据函数
{
    IIC_Start();
    IIC_Send_Byte(0x78);//OLED地址
    IIC_Wait_Ack();
    IIC_Send_Byte(0x40);//写数据寄存器地址
    IIC_Wait_Ack();
    IIC_Send_Byte(data);
    IIC_Wait_Ack();
    IIC_Stop();
}
void OLED_WR_Byte(u8 dat,u8 cmd)  //为了直接替换上面,做一个封装函数
{	 
	if(cmd)
	  WriteData(dat);
	else
	  WriteCmd(dat);
} 

这里采用的是模拟IIC通信方式,在main函数中要先配置IIC初始化

四.SPI驱动方式

SPI模式使用的信号线有如下几条:
CS:OLED 片选信号。
RST(RES):硬复位 OLED。
DC:命令/数据标志(0,读写命令;1,读写数据)。
SCLK:串行时钟线。在 4 线串行模式下,D0 信号线作为串行时钟线 SCLK。
SDIN:串行数据线。在 4 线串行模式下,D1 信号线作为串行数据线 SDIN。
在 4 线串行模式下,只能往模块写数据而不能读数据。
在 4 线 SPI 模式下,每个数据长度均为 8 位,在 SCLK 的上升沿,数据从 SDIN 移入到
SSD1306,并且是高位在前的。DC 线还是用作命令/数据的标志线。在 4 线 SPI 模式下,写操作的时序如图 17.1.6 所示:
在这里插入图片描述
一些驱动方式与显示代码均与上面一致,因此这里只介绍SPI写数据/命令驱动代码,也即重写OLED_WR_Byte(u8 dat,u8 cmd)函数,其他均不变!

//向SSD1306写入一个字节
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据

//STM32F407采用硬件SPI发送数据(也可采用模拟SPI方式发送数据,在后续的博客中会有介绍)
void OLED_Write_Byte(uint8_t dat)
{  
    SPI1_ReadWriteByte(dat);      //调用硬件SPI写数据函数
}
//写数据
void OLED_Write_Data(uint8_t dat)
{
    CS=0;
    DC=1;
    OLED_Write_Byte(dat);
}
//写命令
void OLED_Write_Cmd(uint8_t cmd)
{ 
    CS=0;
    DC=0;
    OLED_Write_Byte(cmd);
}
//为了直接替换上面,做一个封装函数
void OLED_WR_Byte(u8 dat,u8 cmd)
{	 
	if(cmd)
	  OLED_Write_Data(dat);
	else
		OLED_Write_Cmd(dat);
} 

小结:OLED的驱动方式非常简单,应用起来也非常的方便,分辨率也较高,作为平时辅助开发的小工具也是极好的。在上文中对于各种字符的显示均给出了驱动程序,可以非常方便的调用,另外对于字符取模也有很多可用的小软件,大家可自行应用。
至此,OLED显示屏的几种驱动方式均已介绍完,也预示着第一篇博客的完结。作为刚入行半年的嵌入式小白,小心翼翼的编辑每一行文字。但由于技术水平有限,难免会有诸多错误之处,还希望得到诸位大神的批评指教,也希望借此平台可以和大家畅所欲言,共同进步!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OLED显示屏驱动:8080并口,IIC,SPI三种驱动方式 的相关文章

  • STM32软件模拟iic驱动oled(显示汉字,图片)(一)

    一 iic驱动模式 1 硬件驱动 xff1a 所谓硬件驱动就是使用STM32板子上固定的iic接口 xff0c 但是由于板载iic数量有限 xff0c 且大多和别的外设有引脚复用 xff0c 在别的外设使用的情况下还得通过重映射引到别的引脚
  • 通信协议详解(二):IIC总线协议(传输时序+数据格式+设计实现)

    文章目录 一 IIC xff08 Inter Integrated Circuit xff09 介绍二 传输协议1 时序传输时序写操作时序数据有效性开始 amp 结束信号从机应答信号 2 数据格式 三 设计实现1 时钟2 传输过程3 三态门
  • SPI通信协议详解

    SPI是Serial Peripheral Interface的缩写 xff0c 意即串行外设接口 SPI是一种高速的 全双工 同步通信总线 xff0c 常用于处理器与板载外设 xff08 比如Flash存储器 实时时钟芯片 AD DA芯片
  • IIC的通信波形分析

    关于IIC xff0c 不解释它的历史了 xff0c 有兴趣自己去百度看看 xff0c 本文的图片是由周立功的LAB6021逻辑分析仪抓取的 xff0c 通信的波形是抓取的cypress的psoc 4000芯片得到的 最近项目需要用到触摸I
  • Single SPI、Dual SPI、Qaud SPI

    博主目前已经用上了 QSPI
  • 关于IKEv2中安全策略索引SPI的生成

    首先引入一个PF key的概念 PF KEY Key Management API 提供IKE模块和IPSec核心之间的接口 在RFC 2367中 有一个SADB GETSPI消息 这个消息就是实现允许一个进程获取SPI值 该值标识所给的s
  • OLED显示小数

    OLED显示小数并不是很难的 在通用的OLED库中是没有显示小数的 需要自己去写 写的方法大致是这样的 写出0到9的ACSLL值 只需要将小数点后面的位数 一位一位的写数字对应的ACSLL值即可 其中小数点 也是写同样对应的ACSLL值 只
  • FPGA驱动0.96oled显示屏 (4线 SPI) verilog语言

    之前也陆陆续续看了很多博客 也都能在自己的屏幕上显示出来 但是问题就是不知道怎么修改代码显示自己希望显示的东西 而且由于没注释原因看不太懂 最终的实现效果最终实现效果视频 b站视频链接1 评论区有人给了源码的百度网盘链接 csdn博客链接1
  • I2C走线技巧、及上拉电阻、电源电压、总线电容三者间的函数关系

    目录 I2C总线PCB布线注意事项 博客其他文档可以学习 https www cnblogs com zhiqiang zhang I2C总线线路的走线方式 I2C器件与I2C总线的接线方式 I2C总线连接规范 I2C总线中上拉电阻 电源电
  • windows server2008 开启端口

    windows server 2008大多数端口都是默认关闭的 这里我们使用tomcat的8080端口为例 演示如何开启一个端口 打开服务器管理器 gt 配置 gt 高级安全windows防火墙设置 gt 入站规则 右键 gt 新建规则 点
  • Android-模块化通信-简单实用的android spi机制

    目录 前言 一 spi是什么 二 ServiceLoader 1 ExportTableLoader 2 ExportTable 3 LazyLoader 4 ServiceLoader 三 应用 四 总结 前言 为了实现Android 模
  • I2C与SPI通信总线协议

    仅以寄存器地址为8Bit的器件为例 例如MPU6500 LSM6DS3 I2C通信协议 I2C 的要点是了解I2C通信帧的组成部分 START起始位 STOP停止位 ACK NACK信号 从机器件地址 从机寄存器地址 I2C读的时序比较繁琐
  • 难懂?这样理解SPI与CAN很简单!

    难懂 这样理解SPI与CAN很简单 什么是串行通讯 为什么仍需使用串行通讯 SPI与CAN SPI 接口特点 CAN现场总线特点 什么是串行通讯 在正式进入主题前 我么先来介绍一下什么叫做 串行通信 串行通信是计算机的一种数据传输通信方式
  • Tomcat 配置 闪退 catalina.bat start

    过年的时候配置好的Tomcat 今天一用竟然启动不了 我晕 java home catalina base catalina home 全部是原来的配置 没有修改过 为什么不能用了那 遇到的问题如下 1 启动Tomcat在cmd中输入 ca
  • SD卡系列之---SD初始化(SPI)

    SD卡分为SDIO模式与SPI模式 SDIO模式使用SD总线协议 使用4根数据线进行数据传输 SPI使用1收1发2根数据线数据传输 理论上SDIO模式会比SPI模式速度快4倍 但SDIO模式还牵扯到CRC校验位的计算 所以 如果使用CPU有
  • 谁在驱动程序代码中调用“probe”函数?

    我试图理解thisomap2 panda 板的 mcspi 驱动程序代码 我不明白谁打电话probe函数以及调用链是什么this驱动代码 设备连接时如何通知驱动程序 探针函数由spi omap2 mcspi c保存在static struc
  • 是什么让 SPI 比 I2C 协议更快 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我了解 I2C 和 SPI 通信的基础知识 因为两者都是同步协议 我想知道是什么让 SPI 比 I2C 更快 如果我没记错的话 使用 I2
  • 在 ARM 处理器上执行存储在外部 SPI 闪存中的程序

    我有一个 ARM 处理器 能够与外部闪存芯片连接 写入芯片的是为 ARM 架构编译的程序 可供执行 我需要知道如何将这些数据从外部闪存获取到 ARM 处理器上以供执行 我可以提前运行某种复制例程 将数据复制到可执行内存空间吗 我想我可以 但
  • 如何用 C 语言从串行(SPI)连接读取数据?

    我正在尝试编写一个程序 该程序将安装在 Linux MCU Raspberry Pi 上 该程序将读取从另一个 MCU 我将自己构建的自制程序 发送到它的串行数据 我研究了如何做到这一点 并认为我有 大局 但仍然缺少一些东西 其一 我需要启
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能

随机推荐

  • 深度视场角(Depth Field of View)

    深度视场角 Depth Field of View Realsense相机深度图的建立依赖双目立体成像原理 xff0c 其有效视场是左 右成像器视场的重叠部分 xff0c 如下图所示 顺带一提 xff0c 这张图不能用于计算双目相机深度成像
  • ROS: Publisher and Subscriber

    通过上一节编写ROS的第一个程序hello world xff0c 我们对ROS的整个编程开发过程有了基本的了解 xff0c 现在我们就来编写真正意义上的使用ROS进行节点间通信的程序 由于之前已经建好了catkin ws这样一个工作空间
  • phpStorm2018安装教程

    1 鼠标右击 PhpStorm 2018 2 3 压缩包选择 解压到PhpStorm 2018 2 3 2 双击打开解压后的 PhpStorm 2018 2 3 文件夹 3 鼠标右击 PhpStorm 2018 2 3 exe 选择 以管理
  • 学习Java第一个星期感受和收获

    最近在学习java xff0c 学了有一个星期 xff0c 说一说这个星期的收获和总结吧 xff01 首先我也是从一个小白做起 xff0c 这个星期学习了很多 xff0c 很多java基础知识 xff0c 我印象比较深刻的是基本数据类型和引
  • MySql知识体系总结(2021版)

    一 MySQL三层逻辑架构 MySQL的存储引擎架构将查询处理与数据的存储 提取相分离 下面是MySQL的逻辑架构图 xff1a 1 第一层负责连接管理 授权认证 安全等等 每个客户端的连接都对应着服务器上的一个线程 服务器上维护了一个线程
  • freertos与linux区别,μClinux、μC/OS-II、eCos、FreeRTOS和djyos操作系统的特点及不足-嵌入式系统-与非网...

    基于 STM 平台且满足实时控制要求操作系统 xff0c 有以下 5 种可供移植选择 分别为 Clinux C xff0f OS II eCos FreeRTOS 和都江堰操作系统 djyos 下面分别介绍这五种嵌入式操作系统的特点及不足
  • SM4加密算法原理以及C语言实现

    文章目录 一 算法原理描述1 密钥及密钥参量 xff1a 2 加密算法 3 解密算法 xff1a 4 密钥扩展算法 xff1a 二 C语言算法实现 h部分代码 xff1a c部分代码 xff1a 一 算法原理描述 SM4分组密码算法是一个迭
  • SIM900A GPRS无线通信

    文章目录 一 模块介绍1 基本概况2 GPRS通信开发说明 二 TCP连接实现及其源码1 TCP连接实现方法2 程序源码 xff08 基于MSP430F149单片机 xff09 1 main c2 Config h及Config c3 SI
  • UCOSII-信号量与信号量集

    文章目录 一 前言1 任务间的同步2 事件 二 信号量1 信号与信号量介绍2 信号量常用函数3 信号量使用流程 xff08 互斥信号量和信号量两种 xff09 4 互斥型信号量使用5 使用一般信号量做任务同步 三 信号量集 事件标志组 1
  • UCOSII-消息邮箱与消息队列

    文章目录 一 事件控制块及事件处理函数1 等待任务列表2 事件控制块的结构3 操作事件控制块的函数4 空事件控制块列表 二 消息邮箱1 消息邮箱介绍2 消息邮箱操作步骤 三 消息队列1 消息指针数组2 队列控制块3 消息队列的操作流程 四
  • float型数据与4字节之间的转换

    文章目录 一 前言二 地址指针转换的方法三 共用体的方法 xff08 注意要定义全局变量数组s xff0c 即地址要分配为固定地址 xff09 一 前言 在与上位机之间进行数据收发 xff0c 要将float型数据转换成字节进行传输 xff
  • USB虚拟串口实现多字节数据接收,基于stm32h743

    文章目录 一 USB虚拟串口原理简介二 接收函数实现源码三 小结 一 USB虚拟串口原理简介 USB 虚拟串口 xff0c 简称 VCP xff0c 是 Virtual COM Port 的简写 xff0c 它是利用 USB 的 CDC 类
  • EC20/EC25 4G模块AT指令开发总结

    文章目录 一 EC25 20 4G模块简介二 AT指令总结1 通用AT指令2 建立TCP UDP连接相关AT指令 三 TCP传输数据流程四 UDP传输数据流程五 总结 一 EC25 20 4G模块简介 EC25 是一系列带分集接收功能的 L
  • C语言实现socket网络编程及多线程编程

    文章目录 一 概述二 TCP socket网络编程1 server端程序实现 xff08 tcp server cpp xff09 2 client端程序实现 xff08 tcp client cpp xff09 3 编译与执行 三 UDP
  • 基于openssl实现https双向身份认证及安全通信

    文章目录 一 概述二 代码设计2 1 ssl server c程序设计2 2 ssl client c程序设计 三 测试 一 概述 https基于SSL TLS提供安全的通信信道 xff0c 基于证书认证技术实现服务器和客户端之间的身份认证
  • ubuntu的不同版本

    ubuntu是现在最流行的Linux安装包 xff0c 本文介绍了ubuntu的各种版本 一 Ubuntu 每个ubuntu的版本都包含一个版本号 xff08 version number xff09 和一个代码名 xff08 code n
  • Linux下通过service服务管理用户进程

    文章目录 一 service配置介绍1 1 service配置文件1 2 配置文件的区块1 3 修改配置文件后重启1 4 服务管理 二 设计一个可执行程序三 设计一个service管理 home ubuntu test servicetes
  • c++中多态调用场景下基类析构函数的virtual声明

    文章目录 一 基类析构函数未加virtual声明的情况1 1 基础示例演示1 2 进阶示例演示 二 基类析构函数添加virtual声明的情况三 总结 一 基类析构函数未加virtual声明的情况 在多态场景中 xff0c 可通过基类的指针指
  • protobuf协议原理及实现,基于c++

    文章目录 一 protobuf协议简介1 1 protobuf协议简介1 2 数据交互xml json protobuf格式比较1 3 关于 ProtoBuf 的一些思考 二 protobuf库安装三 protobuf库使用第一步 xff0
  • OLED显示屏驱动:8080并口,IIC,SPI三种驱动方式

    本文介绍了对OLED的几种驱动方式 xff0c 8080并口 xff0c IIC xff0c SPI三种驱动方式 xff0c 采用的单片机是STM32F407 文章目录 一 OLED驱动原理介绍二 8080并口驱动方式三 IIC驱动方式四