LCD12864串口高级操作

2023-05-16

在这里插入图片描述
上面是LCD12864的串口通信时序图。其中RW是方向位,RS是命令数据选择位,SID为数据线,SCLK为时钟线,CS为使能端。

其中CS为1时使能时序操作,由图可以看出,数据线在时钟线为低电平的时候变化,在时钟线为高电平时锁存。一次完整的通信由3个字节组成,第一个字节是引导码,由固定的5为高电平,1位方向位,1位命令数据选择位,1位低电平组成,第二个字节是数据或命令的高4位+4个低电平,第三个字节是数据或命令的低4位+4个低电平。

接下来我们实现基本时序。
为了程序方便移植,我在这里创建了一个GPIO管理结构体

//LCD12864.H文件
//GPIO管理控件
typedef struct gpio_set
{
	GPIO_TypeDef*  Port;
	uint16_t Pin;
}gpio_set_t;

//IO操作宏定义
#define LCD_IO_SET(Type,Val)  GPIO_WriteBit(LCD_setGPIO[Type].Port, LCD_setGPIO[Type].Pin,(BitAction)(Val))

#define LCD_DELAY_TIME   20  //LCD通讯脉宽调整宏定义
#define LCD_HIGH    0   //LCD接口处的电平状态值
#define LCD_LOW     1   //LCD接口处的电平状态值
#define LCD_CMD			1		//命令选择
#define LCD_DAT			0		//数据选择
//LCD12864.c文件
gpio_set_t LCD_setGPIO[3] = {
	{GPIOD,GPIO_Pin_14},
	{GPIOD,GPIO_Pin_13},
	{GPIOD,GPIO_Pin_12}
};

#define LCDCLK 0 //E
#define LCDSTD 1 //RW
#define LCDCS  2 //RS

通过上面提供的代码片段,我们可以很方便的操作IO口,以及在各平台移植。
继续。

///
//函数名:LCD_SendByte			    ///
//功  能:串口发送1byte字节           ///
//参  数:Data:要发送的字节           ///
///
static void LCD_SendByte(u8 Data)
{
	u8 i = 0;
	LCD_IO_SET(LCDCS,LCD_HIGH);//使能
	LCD_IO_SET(LCDCLK,LCD_LOW);//时钟线拉低
	delay_us(LCD_DELAY_TIME);//延时
	for(i = 0;i<8;i++)
	{
		LCD_IO_SET(LCDCLK,LCD_LOW);//时钟线拉低
		
		LCD_IO_SET(LCDSTD,((Data<<i) & 0x80)?LCD_HIGH:LCD_LOW);//电平变化
		delay_us(LCD_DELAY_TIME);//延时
		
		LCD_IO_SET(LCDCLK,LCD_HIGH);//时钟线拉高
		delay_us(LCD_DELAY_TIME);//延时
		
		LCD_IO_SET(LCDCLK,LCD_LOW);//时钟线拉低
	}
	
	LCD_IO_SET(LCDCLK,LCD_LOW);//时钟线拉低
	LCD_IO_SET(LCDCS,LCD_LOW);//失能
}
	
/
//函数名:LCD_Write							                             //
//功  能:给LCD写入一字节命令或数据                          //
//参  数:CmdSelect:1--Cmd,0--Data dat:要发送的字节          //
/
void LCD_Write(u8 CmdSelect,u8 dat)
{
	LCD_SendByte(CmdSelect? 0xf8 : 0xfa);//RW位为0:写。RS位:1--数据,0--命令
	LCD_SendByte( dat & 0xf0);//高4位
	LCD_SendByte((dat & 0x0f)<<4);//低4位
}	

OK,我们已经实现了基本的底层串口通信。我们只需要微调LCD_DELAY_TIME 宏定义来适当让通信速率处于一个合适的频率即可。

接下来是初始化IO口和LCD的初始化函数,这个就不用细讲了,按数据手册照着写就对了。


///                     
//函数名:LCD_Init							                           //                     
//功  能:初始化函数,包括初始化IO口和LCD指令               //
//参  数:																		             //                     
///                     
void LCD_Init(void)
{
	
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin  =  LCD_setGPIO[LCDCLK].Pin;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(LCD_setGPIO[LCDCLK].Port, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin  =  LCD_setGPIO[LCDSTD].Pin;
	GPIO_Init(LCD_setGPIO[LCDSTD].Port, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin  =  LCD_setGPIO[LCDCS].Pin;
	GPIO_Init(LCD_setGPIO[LCDCS].Port, &GPIO_InitStructure);
	
	
	LCD_Write(LCD_CMD,0x38);	  delay_ms(5);
	LCD_Write(LCD_CMD,0x38);	  delay_ms(5);
	LCD_Write(LCD_CMD,0x38);	  delay_ms(5);
	LCD_Write(LCD_CMD,0x06);	  delay_ms(5);
	LCD_Write(LCD_CMD,0x01);	  delay_ms(5);
	LCD_Write(LCD_CMD,0x0c);	  delay_ms(5);	
}

接着提供最基本的LCD显示字符串。值得注意的是一个汉字占2个字节,它不能以奇字节开头。比如LCD_StringPlay(0,0,“0好好学习”);这样操作是会乱码的。
正确的操作是LCD_StringPlay(0,0," 0好好学习");增加一个空格,让汉字对齐在偶数字节即可。

///
//函数名:LCD_StringPlay							             //
//功  能:指定地址显示字符串                       //
//参  数:x,y:地址。CorpInf:字符串指针             //
//		坐标定义:                                  //
//								x(0,7)                       //
//		*------------>                             //
//		|                                          //
//		|                                          //
//		|                                          //
//		| y(0,3)                                  //
//		v                                          //
///
void LCD_StringPlay(u8 x,u8 y,const char *CorpInf)
{
	u8 address; 
	
//	if(y==0){Address=0x80+x;}     
//	if(y==1){Address=0x90+x;}        
//	if(y==2){Address=0x88+x;}    
//	if(y==3){Address=0x98+x;}  
	
	//此处纯粹是位运算炫技,大概会比上面用法快那么一丁丁丁点。我编译了一下,也就
	//省10来个字节的ROM。有兴趣的可以对照上面逐句分析。
	
	address = 0x80 + ((y&0x01)<<4) + ((y&0x02)<<2) + x;
	
	LCD_Write(LCD_CMD,address);
	delay_ms(5);
	while(*CorpInf)
	{
		LCD_Write(LCD_DAT,*CorpInf++);
		delay_ms(1);
	}
	delay_ms(1);
}

如果是在STM32这种平台上,用上面那种低级的字符串操作函数,显得太抠了。
接下来通过C标准库实现printf打印函数,为了方便移植到51等资源较少的单片机上,我加了个宏定义来裁剪该功能。

该函数稍微改一下也可以移植到串口上。

#if (LCD_FMT_EN == 1)

#include "stdio.h"
#include "string.h"
#include "stdarg.h"

void LCD_Printf(u8 x,u8 y,const char *fmt,...)
{
	va_list ap;
	char string[64];
	va_start(ap,fmt);
	vsnprintf(string,64,fmt,ap);
	LCD_StringPlay(x,y,string);
	va_end(ap);
	
	//sprintf(str,"或者用以下替换%d",a);
	//LCD_StringPlay(x,y,string);
}
#endif 

基本的LCD12864操作就是上面这些,下面我们来搞一下绘图区。
LCD12864有两个显示区,一个用来显示字库中的图形,一个用来显示自己写的数据。通过指令0x30和0x36切换。具体见数据手册。

/
//函数名:LCD_RamPlay							                           //
//功  能:播放显示一整页数据                                 //
//			 可用来显示图片																		 //
//			 取模方式为从左到右逐行写
//参  数:*str:数据指针,播放该指针后面的1024字节数据(128*64)  //
/
void LCD_PagePlay(u8 *str)
{
	u8 i,j,k;
	
	LCD_Write(LCD_CMD,0x34);      
  LCD_Write(LCD_CMD,0x36);//扩展指令集
	i = 0x80;            
	for(j = 0;j < 32;j++)//上半屏
	{
      LCD_Write(LCD_CMD,i++);
      LCD_Write(LCD_CMD,0x80);
  		for(k = 0;k < 16;k++)
  		{
  		  LCD_Write(LCD_DAT,*str++);
  		}
	}
	i = 0x80;
 	for(j = 0;j < 32;j++)//下半屏
	{
 	    LCD_Write(LCD_CMD,i++);
      LCD_Write(LCD_CMD,0x88);	   
  		for(k = 0;k < 16;k++)
  		{
   		  LCD_Write(LCD_DAT,*str++);
   		} 
	}       
	LCD_Write(LCD_CMD,0x30);//基本指令集        
}

现在问题来了,如果我们想画圆,画直线,画表格、矩形等怎么操作呢?取一个模?然后调用上面的函数吗?这样肯定不行。
正常的操作是打点,根据算法打点打印出各种数学图形。

但是LCD12864的绘图区由于地址的原因,我们一次最少只能操作2个字节,做不到按位操作。如果我们像在任意地方打点,那我们必须知道该点所在的2个字节的其它bit的情况,不然我们这个地方打了点就会影响到其它地方的点位数据。

所以我们需要知道其它地方的点位数据情况,再通过位运算组成一整个半字,再写入LCD中。
实现打点函数的思路有2种:
1:读出LCD12864该半字地址数据,操作该数据,重新写入该数据。
2 :创建一个1024字节大小的显存,改变该地址对应位置的显存数据,重新写入该位置的显存数据。

方案一,读LCD12864太慢了,基本没什么实用价值。
方案二,费内存,需要开辟1k的RAM。资源太少的单片机实现不了。

我用的平台是STM32F103ZET6,1k字节是小意思。

下面是打点函数的代码:

//LCD显存
static u16 LCD_RAM[512];


//函数名:void LCD_PointPlay(u8 x,u8 y,u8 bitEn)   //
//功  能:打点                                     //
//参  数:x,y:打点坐标,bitEn:1--打点,0--消点      //
//                                                //
//		坐标定义:                                   //
//								x(0,127)                        //
//		*------------>                              //
//		|                                           //
//		|                                           //
//		|                                           //
//		| y(0,63)                                   //
//		v                                           //
									
void LCD_PointPlay(u8 x,u8 y,u8 bitEn)
{
	u16 point = ((u16)y<<7) + x;//x*128+y :当前点位序号
	u16 Index = point>>4;				//point/16:当前点位所在显存数组下标
	
	if(bitEn)
		LCD_RAM[Index] |=   0x8000>>(point & 0xf);	//point % 16 == 当前点位所在显存半字中的bit位
	else
		LCD_RAM[Index] &=  ~(0x8000>>(point & 0xf));
	LCD_Write(LCD_CMD,0x34);      
  LCD_Write(LCD_CMD,0x36);//扩展指令集
	//写入垂直地址
	LCD_Write(LCD_CMD,0x80 + (y & 0x1f));			
	//写入水平地址   
	//第一行0x80-0x87
	//第二行0x90-0x97
	//第三行0x88-0x8f
	//第四行0x98-0x9f
	LCD_Write(LCD_CMD,0x80 + (y >= 32 ? 0x08 :0) + (x>>4));
	//写入半字数据
	LCD_Write(LCD_DAT,(LCD_RAM[Index]&0xff00)>>8);
	LCD_Write(LCD_DAT,(LCD_RAM[Index]&0x00ff));
	LCD_Write(LCD_CMD,0x30);//基本指令集       
}

我实现打点函数其实不是为了画数学图形,我是为了反白某一行。LCD12864有个反白指令,但这是一条鸡肋指令,它要么反白第一第三行,要么反白第二第四行。着实让人难受…

先来两个清显存函数,一个清显存不显示,一个清显存并显示。


//
//函数名:LCD_RamInit							            //
//功  能:LCD_RAM全局赋值                     //
//参  数:Dat:赋给RAM的值                     //
//
void LCD_PointRamInit(u16 Dat)
{
	u16 x;
	for(x=0;x<512;x++)LCD_RAM[x] = Dat;
}

///
//函数名:LCD_PointPageFill							   //
//功  能:整页填充指定数据                 //
//参  数:Dat:显示的值,0即清屏            //
///
void LCD_PointPageFill(u16 Dat)
{
	u16 x;
	LCD_PointRamInit(0x0000);
	for(x = 0;x< 512 ;x++)
	{
		LCD_RAM[x] = Dat;
	}
	LCD_PagePlay((u8*)LCD_RAM);
}

前面说了LCD12864有两个显示区,我好像忘了说,真实的显示其实是这两个显示区数据的异或值。
异或是什么意思呢,就是如果这个点位有显示表示这个点为1,如果另外一个区这里也有显示表示这个点也为1,它们的异或值就是0;如果另外一个区这里没有显示,即为0,它们的异或值即为1。
明白了吗?我们只要在绘图区给某一行全部写1,即可反白该行。

///
//函数名:LCD_LineInvert							 //
//功  能:LCD指定行反白                //
//参  数:Line(0-3)                   //
//note	:同时只能有一行反白			     //
//			 用来做菜单时的指示					 //
///
void LCD_PointLineInvert(u8 Line)
{
	u16 x;
	LCD_PointRamInit(0x0000);//全部清0
	for(x = (Line<<7);x< (Line+1)<<7;x++)//反白一行
	{
		LCD_RAM[x] = 0Xffff;
	}
	LCD_PagePlay((u8*)LCD_RAM);//显示整个显存
}

打点相关的功能基本就以上,当然你还可以在打点函数的基础上实现画数学图形,以及任意连线等等等…

接下来我们继续讲LCD12864的字符串高级显示。
12864可以显示64个英文字符数字等或者32个汉字。
二话不说,先建立一个64字节大小的显存,用来存储对应位置的字节数据。

static u8 LCD_CharRAM[64];      //字符显存
static u8 chIndex     = 0;			//字符显存实时索引	

我们把整屏的显存先初始化为空格。

///
//函数名:LCD_CharInit							           //
//功  能:显存全部初始化为空格字符,索引清零     //
//参  数:无                                   //
///
void LCD_CharInit(void)
{
	u8 i = 0;
	for(i = 0;i<64;i++){
		LCD_CharRAM[i] = ' ';
	}
	chIndex = 0;
}

接着是光标操作

///
//函数名:LCD_CharCursor							             //
//功  能:光标定位指定地址                         //
//参  数:x,y:光标指定地址。									     //
//		坐标定义:                                  //
//								x(0,15)                        //
//		*------------>                             //
//		|                                          //
//		|                                          //
//		|                                          //
//		| y(0,3)                                   //
//		v                                          //
///
void LCD_CharCursor(u8 x,u8 y)
{
	//第一行0x80-0x87--0
	//第二行0x90-0x97--1
	//第三行0x88-0x8f--2
	//第四行0x98-0x9f--3
	u8 address = 0x80 + ((0x01&y)<<4) + ((0x02&y)<<2) + (x>>1);
	LCD_Write(LCD_CMD,address);	
	chIndex = ((y<<4)+x);
	if(x&0x01){
		LCD_Write(LCD_DAT,(LCD_CharRAM[chIndex-1]));
	}
}

不知道大家有没有看出来,这个函数有很大一部分心思是用在奇列地址定位上。
它的x坐标支持0-15。不像之前那个LCD_StringPlay,它的x坐标只能支持0-7。
当然,汉字仍然不能在奇列位置开始显示。

在上面这个光标定位的基础上,我们可以实现下面这个函数

///
//函数名:LCD_CharOut							          									 //
//功  能:将字符保存到当前显存中,并将当前显存位置的字符输出     //
//参  数:ch:要输出的字符																		 //
///
void LCD_CharOut(u8 ch)
{
	u8 address;
	LCD_CharRAM[chIndex] = ch;
	LCD_Write(LCD_DAT,LCD_CharRAM[chIndex++]);
	chIndex &= 0x3f;
	//第一行0x80-0x87--0x00-0x0f
	//第二行0x90-0x97--0x10-0x1f
	//第三行0x88-0x8f--0x20-0x2f
	//第四行0x98-0x9f--0x30-0x3f
	if(!(chIndex & 0x0f)){
		address = 0x80 + (chIndex & 0x10) + ((chIndex & 0x20)>>2);
		LCD_Write(LCD_CMD,address);
	}
}

这个函数就了不起了…它可以自动换行,并且同时把数据放到显存中…
自动换行,意味着我只需要在刚开始定位一次光标,接着一个字符一个字符的输出,它会挨着逐行顺序打印,每一行满了,接着下一个就会自动从下一行开始输出。

封装成字符串操作。

/
//函数名:LCD_CharString							          						     //
//功  能:打印字符串,每行最多16个英文字符,8个汉字字符。          //
//			 其中汉字字符不能再奇列地址。调用之前需至少定位一次光标, //
//			 之后将在初始光标位置按序打印,支持自动换行。            //
//参  数:无																									 	 //						 
/

void LCD_CharString(const char *str)
{
	while(*str)
	{
		LCD_CharOut(*str++);
	}
}

在上面的基础上实现printf格式化输出


#if (LCD_CHAR_FMT_EN == 1)

#include "stdio.h"
#include "string.h"
#include "stdarg.h"

/
//函数名:LCD_CharPrintf							          						     //
//功  能:LCD_CharString的格式化输出														 //       
//参  数:可变参数,同Printf																		 //						 
/
void LCD_CharPrintf(const char *fmt,...)
{
	va_list ap;
	char string[64];
	va_start(ap,fmt);
	vsnprintf(string,64,fmt,ap);
	LCD_CharString(string);
	va_end(ap);
	
	//sprintf(str,"或者用以下替换%d",a);
	//LCD_CharString(string);
}
#endif 

这样我们用LCD_CharPrintf函数操作就方便舒服多了。
比如无聊显示例子…

LCD_CharCursor(0,0);//光标定位
LCD_CharPrintf("%s二三四五六七八%s二三四五六七八%s二三四五六七八%s二三四五六七八","一","二","三","四");

显示:
一二三四五六七八
二二三四五六七八
三二三四五六七八
四二三四五六七八

/
我们再实现最后一个功能。这个功能我调试了半天时间。
它叫做滚屏,或者叫卷屏。

首先,一个全局静态变量,一个函数操作接口。

static u8 RollSumLine = 0;      //参与滚屏行数设置,0-4:note:及时设置为0也至少有一行参与滚屏


//函数名:LCD_CharScrollingSetline							          			//					 
//功  能:设置参与滚屏的行数 																		//
//参  数:line:参与滚屏的行数,Note:设置为0,也有一行参与滚屏  //																 
///

//函数名:LCD_CharScrollingSetline							          			//					 
//功  能:设置参与滚屏的行数 																		//
//参  数:line:参与滚屏的行数,Note:设置为0,也有一行参与滚屏  //																 
///
void LCD_CharScrollingSetline(u8 line)
{
	if(line>4){line = 4;}
	RollSumLine = line;
//	RollConUp   = 4 - RollSumLine;
//	RollConDown = RollSumLine;
}
///
//函数名:LCD_CharScrolling  						          						 //
//功  能:滚屏函数,打印字符串之前调用一次该函数,即可滚一行		 //
//参  数:derection:1--向上滚屏,0--向下滚屏									 //											 
///
void LCD_CharScrolling(u8 derection)
{
	u8 i = 0;
	
	if(derection){//向上滚屏
//		if(RollConUp < 4){
//			LCD_CharCursor(0,RollConUp++);
//		}
//		else{

		//每调用一次,就将显存中的数据往上移动一行,并将光标定位在最后一行
			for(i = ((4-RollSumLine)<<4);i<0x30;i++)
			{
				if((i&0x0f) == 0){
					LCD_CharCursor(0,i>>4);
				}
				LCD_CharOut(LCD_CharRAM[i+0x10]);
			}
			LCD_CharCursor(0,3);
			LCD_CharString("                ");
			LCD_CharCursor(0,3);
//		}
	}
	else{
//		if(RollConDown > 0){
//			LCD_CharCursor(0,--RollConDown);
//		}
//		else{
		//每调用一次,就将显存中的数据往下移动一行,并将光标定位在参与滚屏的首行
			for(i = (((RollSumLine)<<4)-1);i>=0x10;i--)
			{
				LCD_CharCursor((i&0x0f),i>>4);
				LCD_CharOut(LCD_CharRAM[i-0x10]);
			}
			LCD_CharCursor(0,4-RollSumLine);
			LCD_CharString("                ");
			LCD_CharCursor(0,4-RollSumLine);
//		}
	}
}

一些位运算的注释

异或运算:
	口诀:相同为0,相异为1。任何数跟0异或都是它本身,任何数跟1异或是它的取反
	用途 :  常用来指定位取反。比如取反byte的最高位:byte ^= 0x80;
位与运算:
	口诀:两个数同时为1才为1,否则为0
	用途一 :  常用来清零指定位,比如清零byte的最高位:byte &= 0x7f;
	用途二 :  可用来代替2的整数幂求余运算,比如 byte %= 8;可替换为 byte &= 0x07;
	```

位或运算:
口诀:两个数有1则为1,否则为0
用途一 :  常用来置位指定位,比如将byte的最高位置1:byte |= 0x80;
用途二 :  可用来代替2的整数幂求余运算,比如 byte %= 8;可替换为 byte &= 0x07;
```
移位运算:
	用途一 :  可用来替代2的整数幂的乘除法。比如byte *= 2,替换为 byte <<= 1。除法同理。
	```

源码链接
https://download.csdn.net/download/weixin_42992743/11596933

上班很无聊,有兴趣加我微信吹水呀!哈哈哈哈哈
在这里插入图片描述

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

LCD12864串口高级操作 的相关文章

随机推荐

  • 野火&洋桃STM32开发版学习指导完整版

    该文章是我历时一个月整理总结而成 xff0c 专门针对想要通过野火 amp 洋桃STM32开发板入门stm32的读者 由于csdn编辑限制 xff0c 该学习指导只包含文字信息 如需查看含图片的完整版可进入我的博客下载页 完整版内容详实 x
  • sumo学习——sumo的路网介绍

    2 sumo路网 这里的记录的内容 xff0c 并不以如何绘制或者如何建立一个路网体系为主 xff0c 而是较为详细的介绍 xff0c 在sumo中是如何定义路网格式的 这里所有的内容都是来自于sumo的软件说明翻译 xff0c 其中部分夹
  • webpack之devtool

    关于Devtool 该选项控制是否以及如何生成源映射 官网上给出的可选值有 xff1a 其中一些值适合开发 xff0c 一些用于生产 对于开发 xff0c 您通常需要快速的Source Maps xff0c 以bundle的大小为代价 xf
  • 汽车UDS诊断详解及Vector相关工具链使用说明——总述

    1 什么是诊断 车辆在运行过程中 xff0c 不可避免地会发生一些故障 xff0c 为了确保行车安全 xff0c 我们要求车上的ECU能够实时监测部件的运行状态 xff0c 一旦发现异常情况 xff0c 能通过点亮报警灯等方式提示驾驶员 但
  • 汽车UDS诊断详解及Vector相关工具链使用说明——2.2.7 动态定义DID(0x2C)

    1 概述 动态定义DID服务允许诊断仪在ECU内部动态定义一个临时的DID 可以通过该DID读取一段内存的数据 也可以通过改DID一次性读取多个原有DID的数据 动态定义DID既可以是支持22服务的DID 也可以是支持2A服务的周期性读取
  • 关于RTOS中信号量、互斥量、邮箱、消息队列的一些理解

    1 信号量 信号量有两种 xff1a 计数性信号量和二值信号量 xff0c 计数性信号量可以被获取多次 xff0c 二值信号量只有0和1两种状态 xff0c 只能被获取一次 信号量可以用来对资源进行保护 xff0c 防止多个任务同时访问某个
  • 英飞凌 AURIX 系列单片机的HSM详解(1)——何为HSM

    本系列的其它几篇文章 xff1a 英飞凌 AURIX 系列单片机的HSM详解 xff08 2 xff09 与HSM相关的UCB和寄存器 英飞凌 AURIX 系列单片机的HSM详解 xff08 3 xff09 开发方法 英飞凌 AURIX 系
  • DoIP(一)——基础概念

    1 DoIP概述 DoIP xff08 Diagnostic communication over Internet Protocol xff09 是基于车载以太网的诊断 xff0c 在OSI 七层模型中属于传输层 xff0c 其传输的诊断
  • DoIP(二)——报文类型

    我们上一篇文章提到 xff0c DoIP报头中有两字节的数据类型 xff08 Payload Type xff09 xff0c 代表DoIP报文类型 xff0c 本文就来详细介绍一下每一种报文类型 标准中对报文类型的定义如下 xff1a 数
  • AUTOSAR —— CAN网络管理(CanNm)

    1 网络状态 AUTOSAR网络管理节点内部有两个状态 xff0c 一个是Requested 被请求状态 xff0c 另一个是Released 被释放状态 xff0c 当节点的应用层需要使用总线进行通讯的时候 xff0c 会调用接口使得节点
  • S32K1XX系列单片机 ——(1)开发环境搭建

    本文介绍一下NXP S32系列单片机开发环境的搭建方法 xff0c 分两种 xff1a S32DS和Keil 1 S32DS S32DS是NXP开发的一款IDE xff0c 编译器是GCC xff0c 支持Lauterbach P amp
  • AUTOSAR —— S32K144 的 Fls 和 Fee 模块配置

    本文来简要介绍一下如何在EB中配置AUTOSAR Fls和Fee模块 Fls模块是Flash的驱动 xff0c 执行具体的Flash擦写读取等操作 Fee模块的全称是FlashEEPROMEmulation xff0c 即Flash模拟EE
  • NXP MCU CAN波特率(位时间)配置详解

    1 概述 本文将会详细讲解如何设置NXP MCU的CAN波特率 位时间 采样点等属性 波特率即CAN总线传输频率 xff0c 位时间是波特率的倒数 xff0c 例如波特率是500K xff0c 那么位时间 61 1 500000 61 0
  • 51单片机之蜂鸣器

    include 34 reg52 h 34 include 34 intrins h 34 typedef unsigned int ui typedef unsigned char uc define led P2 34 34 sbit
  • vnc配置

    centos版本在7 0以上的 一 安装 yum grouplist 查看是否已经安装过 yum groupinstall GNOME Desktop 如没有安装则运行命令安装 以root用户运行以下命令来安装vncserver yum i
  • 【WebAPI 验证】给 webapi加上token 验证(包括上传文件方法)

    需要给网站开发对接EMI 接口 xff0c 因此想通过Webapi 进行传递参数 xff0c 但是由于该方法不太安全 xff0c 因此不选用 xff0c 但是记录下该方法的使用 1 xff0c 创建WEBAPI 项目 xff0c 打开nug
  • 委托和事件

    一 委托与事件的区别 委托是一种用于存储方法引用的引用类型 xff0c 它定义了一种类型安全的调用回调方法的方式 事件使用委托来封装触发时将要调用的方法 xff0c 事件是一种函数成员 委托是指向一个方法的指针 xff0c 而且我们采取和调
  • OS文件/目录方法----获取当前py文件的路径

    获取当前py文件的路径 xff1a 1 直接获取 只返回当前文件的工作目录 aa 61 os getcwd print 39 当前文件的路径 39 aa 输出 当前文件的路径 G PycharmProjects SeleniumUnitte
  • vscode如何配置git-2022.10

    文章目录 1 vscode填写git配置2 打开git命令行界面 windows本地已经安装git 并配置成功 1 vscode填写git配置 在搜索框中搜索 terminal integrated automation profile w
  • LCD12864串口高级操作

    上面是LCD12864的串口通信时序图 其中RW是方向位 xff0c RS是命令数据选择位 xff0c SID为数据线 xff0c SCLK为时钟线 xff0c CS为使能端 其中CS为1时使能时序操作 xff0c 由图可以看出 xff0c