使用单片机的IO引脚直接驱动段码屏

news2024/12/27 11:49:06

使用单片机的IO引脚直接驱动段码屏,目的是为了降低成本。这种古老的应用,在低功耗产品中比较多见。
如:水表,燃气表等需要电池供电的产品。

下面纯属个人理解,未经测试

1/3Duty表示LCD共有3个COM引脚,分别占显示周期的1/3
1/2BIAS表示电压0和VCC

1、LCD的COM引脚电压
由于是1/2bias的LCD,因此需在COM引脚产生三种电压:0V、0.5VDD、VDD。实现方法如下:
1)、将LCD的COM引脚通过10K电阻分别连接至VDD和GND;
2)、当CPU连接到COM引脚的IO口配置为输入浮空时,则COM引脚会产生0.5倍VDD的电压;
3)、当CPU连接到COM引脚的IO口输出低电平时,则COM引脚会产生GND电压;
4)、当CPU连接到COM引脚的IO口输出高电平时,则COM引脚会产生VDD电压;
因此,在使用CPU的IO口直接驱动1/2bias的LCD时,要求CPU的IO引脚具有三态输出功能

 

2、显示方法:

1)、显示时,交替翻转COM引脚和SEG引脚电压
COM引脚电压为VCC,SEG引脚电压为0,交替后,则为COM引脚电压为0,SEG引脚电压为VCC;
2)、不显示时,交替翻转COM引脚和SEG引脚电压
COM引脚电压为VCC,SEG引脚电压为VCC,交替后,则为COM引脚电压为0,SEG引脚电压为0;

只要COM引脚和SEG引脚的电压差为+VCC或者-VCC,就可以点亮对应的LCD笔段即像素点,具体实现步骤如下:
第1次中断时设置COM0引脚输出High,其它COM引脚输出VDD/2,再根据要显示的数据设置各个SEG的输出;
第2次中断时设置COM0引脚输出Low,其它COM引脚输出VDD/2,再根据要显示的数据设置各个SEG的输出;
第3次中断时设置COM1引脚输出High,其它COM引脚输出VDD/2,再根据要显示的数据设置各个SEG的输出;
第4次中断时设置COM1引脚输出Low,其它COM引脚输出VDD/2,再根据要显示的数据设置各个SEG的输出;
第5次中断时设置COM2引脚输出High,其它COM引脚输出VDD/2,再根据要显示的数据设置各个SEG的输出;
第6次中断时设置COM2引脚输出Low,其它COM引脚输出VDD/2,再根据要显示的数据设置各个SEG的输出;
循环进行以上的6次循环设置,即可完成“使用单片机IO模拟驱动段码LCD”;

3、占空比和偏压比的关系:

一般来说,Bias的选择与COM使用个数有关,但不是绝对。见下图:

 

4、选择单片机直接驱动LCD,还是选择专用的驱动芯片,以及注意事项如下:
1)、单片机本身不带LCD驱动功能,在使用单片机IO直接驱动段码LCD时,偏压比只能选择1/2。
在LCD的COM引脚加上拉、下拉各1个电阻,阻值一般为100-200K;选择偏压比为1/3,也可以用,但效果没有1/2好。


2)、MCU+专用的LCD显示驱动芯片:
常用的驱动芯片有1621、1622,对应的偏压比为1/3、1/4,LCD的COM引脚就不需要外加电阻了,而且单片机可以选择相对脚位少的、资源少点的,这样单片机的价格会便宜,但驱动芯片不便宜;

若供电电压小于4.5V,建议选择1/2偏压。使用1/2偏压,液晶抖度相对大一些,在垂直视角看的会比较清楚,并且可以过12点法线
如果供电电压小于4.5V,选择1/3偏压,虽然也可以用,但是没有1/2偏压的显示效果好,且过不了12点垂直法线。

5、其它信息
一般LCD液晶屏有三个主要参数,工作中电压Duty(相匹配COM数)和BIAS(偏压,相匹配阀值)。
例如,3.3V、1/4 Duty、1/3 BIAS表明LCD的工作中电压为3.3V,有4个COM,阀值大概是1.1V(3.3/3=1.1)。
具体应用中,为确保显示实际效果优良,一般给电极两边加的电压差贴近LCD的工作中电压;若想不显示,一般
给电极两边加的电压差贴近0V。
必须需注意的是,lcd屏分子结构是必须用沟通交流数据信号来推动的,千万不能将直流电电压长期的加进电极
两边,不然,会危害lcd屏分子结构的电化学特点,造成显示实际效果模糊不清,使用期限降低的不良影响,不
可修复。
1/4 Duty、1/3 BIAS的LCD点亮方法如下:
点亮某一段时,必须确保给其电极两边加的电压差为3.3V,如COM1=3.3V,SEG1=0V,而且保持合适的时
间间距,然后再将COM1和SEG1引脚的电压翻转輸出,如COM1=0V,SEG1=3.3V;
不点亮某一段时,必须确保给其电极两边加的电压差为0V,如COM1=3.3V,SEG1=3.3V,,而且保持合适的时
间间距,然后再将COM1和SEG1引脚的电压翻转輸出,如COM1=0V,SEG1=0V;

 6、SegmentCodeScreen.c测试程序

以下程序未经测试,只是理论,没有板子测试。

#include "SegmentCodeScreen.h"

/*
使用单片机的IO引脚直接驱动段码屏,目的是为了降低成本。这种古老的应用,在低功耗产品中比较多见。
如:水表,燃气表等需要电池供电的产品。

1/3Duty表示LCD共有3个COM引脚,分别占显示周期的1/3
1/2BIAS表示电压0和VCC

LCD的COM引脚电压
由于是1/2bias的LCD,因此需在COM引脚产生三种电压:0V、0.5VDD、VDD。实现方法如下:
1)、将LCD的COM引脚通过10K电阻分别连接至VDD和GND;
2)、当CPU连接到COM引脚的IO口配置为输入浮空时,则COM引脚会产生0.5倍VDD的电压;
3)、当CPU连接到COM引脚的IO口输出低电平时,则COM引脚会产生GND电压;
4)、当CPU连接到COM引脚的IO口输出高电平时,则COM引脚会产生VDD电压;
因此,在使用CPU的IO口直接驱动1/2bias的LCD时,要求CPU的IO引脚具有三态输出功能;

由于是1/3duty的LCD,所以COM引脚的波形图如下:
COM0电压波形图:
3V      __               __                 
       |  |             |  |               
1.5V __|  |   __________|  |   ___________   
          |  |             |  |              
0V        |__|             |__|             
                                             
COM1电压波形图:                                  
3V            __               __             
             |  |             |  |           
1.5V ________|  |   __________|  |   _____
                |  |             |  |     
0V              |__|             |__|     
                                          
COM2电压波形图:                            
3V                  __               __    
                   |  |             |  |   
1.5V ______________|  |   __________|  |   
                      |  |             |  |
0V                    |__|             |__|
                                              
如果SEG1电压波形图如下,根据上面的COM0,COM1和COM2引脚波形,则SEG1和COM交点处的笔画码不会显示:
3V      __    __    __    __    __    __
       |  |  |  |  |  |  |  |  |  |  |  |
1.5V __|  |  |  |  |  |  |  |  |  |  |  |
          |  |  |  |  |  |  |  |  |  |  |  |
0V        |__|  |__|  |__|  |__|  |__|  |__|

如果SEG1电压波形图如下,根据上面的COM0,COM1和COM2引脚波形,则SEG1和COM交点处的笔画码会显示:
3V         __    __    __    __    __    __
          |  |  |  |  |  |  |  |  |  |  |  |
1.5V __   |  |  |  |  |  |  |  |  |  |  |  |
       |  |  |  |  |  |  |  |  |  |  |  |
0V     |__|  |__|  |__|  |__|  |__|  |__|

1)、显示时,交替翻转COM引脚和SEG引脚电压
COM引脚电压为VCC,SEG引脚电压为0,交替后,则为COM引脚电压为0,SEG引脚电压为VCC;
2)、不显示时,交替翻转COM引脚和SEG引脚电压
COM引脚电压为VCC,SEG引脚电压为VCC,交替后,则为COM引脚电压为0,SEG引脚电压为0;

只要COM引脚和SEG引脚的电压差为+VCC或者-VCC,就可以点亮对应的LCD笔段即像素点,具体实现步骤如下:
第1次中断时设置COM0引脚输出High,其它COM引脚输出VDD/2,再根据要显示的数据设置各个SEG的输出;
第2次中断时设置COM0引脚输出Low,其它COM引脚输出VDD/2,再根据要显示的数据设置各个SEG的输出;
第3次中断时设置COM1引脚输出High,其它COM引脚输出VDD/2,再根据要显示的数据设置各个SEG的输出;
第4次中断时设置COM1引脚输出Low,其它COM引脚输出VDD/2,再根据要显示的数据设置各个SEG的输出;
第5次中断时设置COM2引脚输出High,其它COM引脚输出VDD/2,再根据要显示的数据设置各个SEG的输出;
第6次中断时设置COM2引脚输出Low,其它COM引脚输出VDD/2,再根据要显示的数据设置各个SEG的输出;
循环进行以上的6次循环设置,即可完成“使用单片机IO模拟驱动段码LCD”;
*/

unsigned char Scan_SegmentCodeScreen_Counter;
unsigned int wei1_num=NUM0;//个位上的数码管1显示数据
unsigned int wei2_num=NUM0;//十位上的数码管1显示数据
unsigned int wei3_num=NUM0;//百位上的数码管显示数据
unsigned int wei4_num=NUM0;//千位上的数码管显示数据
unsigned int timer_value;//计数器的值
u16 Timer2MilliSecond;//毫秒计数器

void TIM2_Interrupt_Initializtion(u16 arr,u16 psc);

//函数功能:sel=1设置GPIOB13为输出口,sel=0,则设置GPIOB13为浮空输入
void COM0_PIN_Configuration(u8 sel)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	if(sel==1)
	{
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;     //选择第13脚
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
		GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
  }
	else
	{
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;     //选择第13脚
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
		GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
	}
}

//函数功能:sel=1设置GPIOB14为输出口,sel=0,则设置GPIOB14为浮空输入
void COM1_PIN_Configuration(u8 sel)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	if(sel==1)
	{
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;     //选择第14脚
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
		GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
  }
	else
	{
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;     //选择第14脚
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
		GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
	}
}

//函数功能:sel=1设置GPIOB15为输出口,sel=0,则设置GPIOB15为浮空输入
void COM2_PIN_Configuration(u8 sel)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	if(sel==1)
	{
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;     //选择第15脚
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
		GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
  }
	else
	{
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;     //选择第15脚
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
		GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
	}
}

//函数功能:设置GPIOB1为输出口
void SEG1_PIN_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;     //选择第1脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
}

//函数功能:设置GPIOB2为输出口
void SEG2_PIN_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;     //选择第2脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
}

//函数功能:设置GPIOB3为输出口
void SEG3_PIN_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;     //选择第3脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
}

//函数功能:设置GPIOB4为输出口
void SEG4_PIN_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;     //选择第4脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
}

//函数功能:设置GPIOB5为输出口
void SEG5_PIN_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;     //选择第5脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
}

//函数功能:设置GPIOB6为输出口
void SEG6_PIN_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;     //选择第6脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
}

//函数功能:设置GPIOB7为输出口
void SEG7_PIN_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;     //选择第7脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
}

//函数功能:设置GPIOB8为输出口
void SEG8_PIN_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;     //选择第8脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
}

//函数功能:设置GPIOB9为输出口
void SEG9_PIN_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;     //选择第9脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
}

//函数功能:设置GPIOB10为输出口
void SEG10_PIN_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;     //选择第10脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
}

//函数功能:设置GPIOB11为输出口
void SEG11_PIN_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;     //选择第11脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
}

//函数功能:设置GPIOB12为输出口
void SEG12_PIN_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;     //选择第12脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO口的最高工作频率为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIOB
}

void SegmentCodeScreen_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB的外设时钟

	COM0_PIN_Configuration(0);
	COM1_PIN_Configuration(0);
	COM2_PIN_Configuration(0);

	SEG1_PIN_Configuration();
	SEG2_PIN_Configuration();
	SEG3_PIN_Configuration();
	SEG4_PIN_Configuration();

	SEG5_PIN_Configuration();
	SEG6_PIN_Configuration();
	SEG7_PIN_Configuration();
	SEG8_PIN_Configuration();

	SEG9_PIN_Configuration();
	SEG10_PIN_Configuration();
	SEG11_PIN_Configuration();
	SEG12_PIN_Configuration();
}


void SegmentCodeScreen_Work(void)//定时器配置5ms扫描一次即可
{
	Scan_SegmentCodeScreen_Counter++;//下一位
  if(Scan_SegmentCodeScreen_Counter>5)//扫描完一轮才更新数值
	{
		Scan_SegmentCodeScreen_Counter=0;
		switch(timer_value%10000/1000)//求千位数
		{
			case 0:  wei4_num=NUM0; break;
			case 1:  wei4_num=NUM1; break;
			case 2:  wei4_num=NUM2; break;
			case 3:  wei4_num=NUM3; break;
			case 4:  wei4_num=NUM4; break;
			case 5:  wei4_num=NUM5; break;
			case 6:  wei4_num=NUM6; break;
			case 7:  wei4_num=NUM7; break;
			case 8:  wei4_num=NUM8; break;
			case 9:  wei4_num=NUM9; break;
		}
		switch(timer_value%1000/100)//求百位数
		{
			case 0:  wei3_num=NUM0; break;
			case 1:  wei3_num=NUM1; break;
			case 2:  wei3_num=NUM2; break;
			case 3:  wei3_num=NUM3; break;
			case 4:  wei3_num=NUM4; break;
			case 5:  wei3_num=NUM5; break;
			case 6:  wei3_num=NUM6; break;
			case 7:  wei3_num=NUM7; break;
			case 8:  wei3_num=NUM8; break;
			case 9:  wei3_num=NUM9; break;
		}
		switch(timer_value%100/10)//求十位数
		{
			case 0:  wei2_num=NUM0; break;
			case 1:  wei2_num=NUM1; break;
			case 2:  wei2_num=NUM2; break;
			case 3:  wei2_num=NUM3; break;
			case 4:  wei2_num=NUM4; break;
			case 5:  wei2_num=NUM5; break;
			case 6:  wei2_num=NUM6; break;
			case 7:  wei2_num=NUM7; break;
			case 8:  wei2_num=NUM8; break;
			case 9:  wei2_num=NUM9; break;
		}
		switch(timer_value%10)//求个位数
		{
			case 0:  wei1_num=NUM0; break;
			case 1:  wei1_num=NUM1; break;
			case 2:  wei1_num=NUM2; break;
			case 3:  wei1_num=NUM3; break;
			case 4:  wei1_num=NUM4; break;
			case 5:  wei1_num=NUM5; break;
			case 6:  wei1_num=NUM6; break;
			case 7:  wei1_num=NUM7; break;
			case 8:  wei1_num=NUM8; break;
			case 9:  wei1_num=NUM9; break;
		}
	}

	switch(Scan_SegmentCodeScreen_Counter)    //动态扫描
	{
		case 0: //COM0引脚正向驱动
			COM1_PIN_Configuration(0);//设置COM1引脚为输入浮空,COM1引脚因电阻分压得到电压为VDD/2
		  COM2_PIN_Configuration(0);//设置COM2引脚为输入浮空,COM1引脚因电阻分压得到电压为VDD/2
		  COM0_PIN_Configuration(1);//配置COM0引脚为输出口
		  COM0=1;//COM0引脚电压为VCC,则要求SEGx引脚电压为0

千位上的数码管/
		  if(wei4_num!=NUM0)
		  {
		    if(wei4_num&0x01)   SEG1=0;else SEG1=1;
		    if(wei4_num&0x02)   SEG2=0;else SEG2=1;
		    if(wei4_num&0x04)   SEG3=0;else SEG3=1;
			}
			else{SEG1=1;SEG2=1;SEG3=1;}//不显示

百位上的数码管
		 if(wei3_num&0x01)   SEG4=0;else SEG4=1;
		 if(wei3_num&0x02)   SEG5=0;else SEG5=1;
		 if(wei3_num&0x04)   SEG6=0;else SEG6=1;

十位上的数码管
		 if(wei2_num&0x01)   SEG7=0;else SEG7=1;
		 if(wei2_num&0x02)   SEG8=0;else SEG8=1;
		 if(wei2_num&0x04)   SEG9=0;else SEG9=1;

个位上的数码管
		 if(wei1_num&0x01)   SEG10=0;else SEG10=1;
		 if(wei1_num&0x02)   SEG11=0;else SEG11=1;
		 if(wei1_num&0x04)   SEG12=0;else SEG12=1;
		break;

		case 1://COM0引脚反向驱动
			COM1_PIN_Configuration(0);//设置COM1引脚为输入浮空,COM1引脚因电阻分压得到电压为VDD/2
		  COM2_PIN_Configuration(0);//设置COM2引脚为输入浮空,COM1引脚因电阻分压得到电压为VDD/2
		  COM0_PIN_Configuration(1);//配置COM0引脚为输出口
		  COM0=0;//COM0引脚电压为0,则SEGx引脚电压为VCC;

千位上的数码管/
			if(wei4_num&0x01)   SEG1=1; else SEG1=0;
			if(wei4_num&0x02)   SEG2=1; else SEG2=0;
			if(wei4_num&0x04)   SEG3=1; else SEG3=0;

百位上的数码管
		  if(wei4_num!=NUM0)
			{
		    if(wei3_num&0x01)   SEG4=1;   else SEG4=0;
		    if(wei3_num&0x02)   SEG5=1;   else SEG5=0;
		    if(wei3_num&0x04)   SEG6=1;   else SEG6=0;
			}
			else{SEG1=0;SEG2=0;SEG3=0;}//不显示

十位上的数码管
		 if(wei2_num&0x01)   SEG7=1;else SEG7=0;
		 if(wei2_num&0x02)   SEG8=1;else SEG8=0;
		 if(wei2_num&0x04)   SEG9=1;else SEG9=0;

个位上的数码管
		 if(wei1_num&0x01)   SEG10=1;else SEG10=0;
		 if(wei1_num&0x02)   SEG11=1;else SEG11=0;
		 if(wei1_num&0x04)   SEG12=1;else SEG12=0;
      break;

		case 2://COM1引脚正向驱动
			COM0_PIN_Configuration(0);//除COM1输出外,其余COM设为输入
		  COM2_PIN_Configuration(0);//除COM1输出外,其余COM设为输入
		  COM1_PIN_Configuration(1);//配置COM1引脚为输出口
		  COM1=1;//COM1引脚电压为VCC,则要求SEGx引脚电压为0

千位上的数码管/
		  if(wei4_num!=NUM0)
			{
		    if(wei4_num&0x08)   SEG1=0; else SEG1=1;
			  if(wei4_num&0x10)   SEG2=0; else SEG2=1;
			  if(wei4_num&0x20)   SEG3=0; else SEG3=1;
			}
			else{SEG1=1;SEG2=1;SEG3=1;}//不显示

百位上的数码管
		  if(wei3_num&0x08)   SEG4=0;else SEG4=1;
			if(wei3_num&0x10)   SEG5=0;else SEG5=1;
			if(wei3_num&0x20)   SEG6=0;else SEG6=1;

十位上的数码管
		  if(wei2_num&0x08)   SEG7=0;else SEG7=1;
			if(wei2_num&0x10)   SEG8=0;else SEG8=1;
			if(wei2_num&0x20)   SEG9=0;else SEG9=1;

个位上的数码管
		  if(wei1_num&0x08)   SEG10=0;else SEG10=1;
			if(wei1_num&0x10)   SEG11=0;else SEG11=1;
			if(wei1_num&0x20)   SEG12=0;else SEG12=1;
			break;

		case 3://COM1引脚反向驱动
			COM0_PIN_Configuration(0);//除COM1输出外,其余COM设为输入
		  COM2_PIN_Configuration(0);//除COM1输出外,其余COM设为输入
		  COM1_PIN_Configuration(1);//配置COM1引脚为输出口
		  COM1=0;//COM1引脚电压为0,则要求SEGx引脚电压为VCC

千位上的数码管/
		  if(wei4_num!=NUM0)
		  {
		    if(wei4_num&0x08)   SEG1=1; else SEG1=0;
			  if(wei4_num&0x10)   SEG2=1; else SEG2=0;
			  if(wei4_num&0x20)   SEG3=1; else SEG3=0;
			}
			else{SEG1=0;SEG2=0;SEG3=0;}//不显示

百位上的数码管
		  if(wei3_num&0x08)   SEG4=1;else SEG4=0;
			if(wei3_num&0x10)   SEG5=1;else SEG5=0;
			if(wei3_num&0x20)   SEG6=1;else SEG6=0;

十位上的数码管
		  if(wei2_num&0x08)   SEG7=1;else SEG7=0;
			if(wei2_num&0x10)   SEG8=1;else SEG8=0;
			if(wei2_num&0x20)   SEG9=1;else SEG9=0;

个位上的数码管
		  if(wei1_num&0x08)   SEG10=1;else SEG10=0;
			if(wei1_num&0x10)   SEG11=1;else SEG11=0;
			if(wei1_num&0x20)   SEG12=1;else SEG12=0;
			break;

		case 4:
			COM0_PIN_Configuration(0);//除COM2输出外,其余COM设为输入
		  COM1_PIN_Configuration(0);//除COM2输出外,其余COM设为输入
		  COM2_PIN_Configuration(1);//配置COM1引脚为输出口
		  COM2=1;//COM2引脚电压为VCC,则要求SEGx引脚电压为0

千位上的数码管/
		  if(wei4_num!=NUM0)
			{
		    if(wei4_num&0x40)    SEG1=0;else SEG1=1;
			  if(wei4_num&0x80)    SEG2=0;else SEG2=1;
			  if(wei4_num&0x100)   SEG3=0;else SEG3=1;
			}
		  else{SEG1=1;SEG2=1;SEG3=1;}//不显示

百位上的数码管/
		  if(wei3_num&0x40)    SEG4=0;else SEG4=1;
			if(wei3_num&0x80)    SEG5=0;else SEG5=1;
			if(wei3_num&0x100)   SEG6=0;else SEG6=1;

十位上的数码管/
		  if(wei2_num&0x40)    SEG7=0;else SEG7=1;
			if(wei2_num&0x80)    SEG8=0;else SEG8=1;
			if(wei2_num&0x100)   SEG9=0;else SEG9=1;

个位上的数码管/
		  if(wei1_num&0x40)    SEG10=0;else SEG10=1;
			if(wei1_num&0x80)    SEG11=0;else SEG11=1;
			if(wei1_num&0x100)   SEG12=0;else SEG12=1;
			break;

		case 5:
			COM0_PIN_Configuration(0);//除COM2输出外,其余COM设为输入
		  COM1_PIN_Configuration(0);//除COM2输出外,其余COM设为输入
		  COM2_PIN_Configuration(1);//配置COM1引脚为输出口
		  COM2=0;//COM2引脚电压为0,则要求SEGx引脚电压为VCC

千位上的数码管/
		  if(wei4_num!=NUM0)
			{
		    if(wei4_num&0x40)    SEG1=1;else SEG1=0;
			  if(wei4_num&0x80)    SEG2=1;else SEG2=0;
			  if(wei4_num&0x100)   SEG3=1;else SEG3=0;
			}
			else{SEG1=0;SEG2=0;SEG3=0;}//不显示

百位上的数码管/
		  if(wei3_num&0x40)    SEG4=1;else SEG4=0;
			if(wei3_num&0x80)    SEG5=1;else SEG5=0;
			if(wei3_num&0x100)   SEG6=1;else SEG6=0;

十位上的数码管/
		  if(wei2_num&0x40)    SEG7=1;else SEG7=0;
			if(wei2_num&0x80)    SEG8=1;else SEG8=0;
			if(wei2_num&0x100)   SEG9=1;else SEG9=0;

个位上的数码管/
		  if(wei1_num&0x40)    SEG10=1;else SEG10=0;
			if(wei1_num&0x80)    SEG11=1;else SEG11=0;
			if(wei1_num&0x100)   SEG12=1;else SEG12=0;
			break;
	}
}

//通用定时器2中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器2!
//TIM2_Interrupt_Initializtion(1000,36);//当arr=1000,psc=36时,则为0.5ms,误差为0.5us;
//TIM2_Interrupt_Initializtion(2000,36);//当arr=2000,psc=36时,则为1ms,误差为0.5us;
//TIM2_Interrupt_Initializtion(4000,36);//当arr=4000,psc=36时,则为2ms,误差为0.5us;
void TIM2_Interrupt_Initializtion(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能定时器TIM2的APB1外设时钟
	
	//定时器TIM2初始化
	TIM_TimeBaseStructure.TIM_Period = arr-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc-1; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	//计算公式:arr*psc/72000000/1,当arr=1000,psc=72时,则为1ms,误差为1us;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
	
 	TIM_SetCounter(TIM2,0);                      //设置TIM2的计数器值为0;
  TIM_ClearFlag(TIM2, TIM_FLAG_Update);        //清除TIM2溢出的待处理标志位
	TIM_ClearITPendingBit(TIM2, TIM_IT_Update ); //清除TIM2中断的待处理位
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //允许TIM2溢出产生中断

	//中断优先级NVIC设置
	//NVIC_PriorityGroup_4设置NVIC中断分组4:表示抢占优先级为4位,取值为0~15,没有响应优先级,取值为0
  //NVIC_PriorityGroup_3设置NVIC中断分组3:表示抢占优先级为3位,取值为0~7,响应优先级只有1位,取值为0~1
	//NVIC_PriorityGroup_2设置NVIC中断分组3:表示抢占优先级为2位,取值为0~3,响应优先级只有2位,取值为0~3
	//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM2中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 11;  //设置抢占优先级为11
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //设置响应优先级为0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化NVIC嵌套向量中断控制寄存器

	TIM_Cmd(TIM2, ENABLE);//使能TIM2外设

	SegmentCodeScreen_Init();

  Timer2MilliSecond=0;//毫秒计数器
	timer_value=0;
}

//函数功能:TIM2每1ms中断一次
void TIM2_IRQHandler()
{
	if (TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET) //TIM2计数器溢出产生中断
	{
	  Timer2MilliSecond++;//毫秒计数器加1

	  if(Timer2MilliSecond%5==0)//5毫秒时间到达
	  {
			SegmentCodeScreen_Work();
	  }

		if(Timer2MilliSecond%1000==0)//1秒时间到达
		{
			timer_value++;
			if(timer_value>999) timer_value=0;

			Timer2MilliSecond=0;
		}
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update); //清除TIM2计数器的溢出中断标志;
	}
}

7、SegmentCodeScreen.h

#ifndef _SegmentCodeScreen_H
#define _SegmentCodeScreen_H

#include "stm32f10x.h"
#include "sys.h"

/*
LCD引脚号码   1     2     3     4    5    6    7    8    9    10   11   12    13    14    15    
LCD引脚名字   COM0  COM1  COM2  SEG1 SEG2 SEG3 SEG4 SEG5 SEG6 SEG7 SEG8 SEG9  SEG10 SEG11 SEG12 
              COM0   --   --   --   1D   --   --   2D   COL  --   3D   --    --    4D    --    
              --   COM1   --   1E   1G   1C   2E   2G   2C   3E   3G   3C    4E    4G    4C         
              --    --   COM2  1F   1A   1B   2F   2A   2B   3F   3A   3B    4F    4A    4B
*/

/*
数码管1:
COM0和SEG2控制数码管1的D段
COM1和SEG1控制数码管1的E段
COM1和SEG2控制数码管1的G段
COM1和SEG3控制数码管1的C段
COM2和SEG1控制数码管1的F段
COM2和SEG2控制数码管1的A段
COM2和SEG3控制数码管1的B段
*/
#define COM0_SEG1_VALUE 0x01  //定义LCD引脚SEG1和COM0交点的值,对于数码管1来说,没有段
#define COM0_SEG2_VALUE 0x02  //定义LCD引脚SEG2和COM0交点的值,即定义数码管1的D段
#define COM0_SEG3_VALUE 0x04  //定义LCD引脚SEG3和COM0交点的值,对于数码管1来说,没有段
#define COM1_SEG1_VALUE 0x08  //定义LCD引脚SEG1和COM1交点的值,即定义数码管1的E段
#define COM1_SEG2_VALUE 0x10  //定义LCD引脚SEG2和COM1交点的值,即定义数码管1的G段
#define COM1_SEG3_VALUE 0x20  //定义LCD引脚SEG3和COM1交点的值,即定义数码管1的C段
#define COM2_SEG1_VALUE 0x40  //定义LCD引脚SEG1和COM2交点的值,即定义数码管1的F段
#define COM2_SEG2_VALUE 0x80  //定义LCD引脚SEG2和COM2交点的值,即定义数码管1的A段
#define COM2_SEG3_VALUE 0x100 //定义LCD引脚SEG3和COM2交点的值,即定义数码管1的B段

/*
数码管2:
COM0和SEG5控制数码管2的D段
COM0和SEG6控制数码管2的COL段,即“:”
COM1和SEG4控制数码管2的E段
COM1和SEG5控制数码管2的G段
COM1和SEG6控制数码管2的C段
COM2和SEG4控制数码管2的F段
COM2和SEG5控制数码管2的A段
COM2和SEG3控制数码管6的B段
*/
#define COM0_SEG4_VALUE 0x01  //定义LCD引脚SEG4和COM0交点的值,对于数码管2来说,没有段
#define COM0_SEG5_VALUE 0x02  //定义LCD引脚SEG5和COM0交点的值,即定义数码管2的D段
#define COM0_SEG6_VALUE 0x04  //定义LCD引脚SEG6和COM0交点的值,即定义数码管2的COL段
#define COM1_SEG4_VALUE 0x08  //定义LCD引脚SEG4和COM1交点的值,即定义数码管2的E段
#define COM1_SEG5_VALUE 0x10  //定义LCD引脚SEG5和COM1交点的值,即定义数码管2的G段
#define COM1_SEG6_VALUE 0x20  //定义LCD引脚SEG6和COM1交点的值,即定义数码管2的C段
#define COM2_SEG4_VALUE 0x40  //定义LCD引脚SEG4和COM2交点的值,即定义数码管2的F段
#define COM2_SEG5_VALUE 0x80  //定义LCD引脚SEG5和COM2交点的值,即定义数码管2的A段
#define COM2_SEG6_VALUE 0x100 //定义LCD引脚SEG6和COM2交点的值,即定义数码管2的B段

/*
数码管3:
COM0和SEG8控制数码管3的D段
COM1和SEG7控制数码管3的E段
COM1和SEG8控制数码管3的G段
COM1和SEG9控制数码管3的C段
COM2和SEG7控制数码管3的F段
COM2和SEG8控制数码管3的A段
COM2和SEG9控制数码管3的B段
*/
#define COM0_SEG7_VALUE 0x01  //定义LCD引脚SEG7和COM0交点的值,对于数码管3来说,没有段
#define COM0_SEG8_VALUE 0x02  //定义LCD引脚SEG8和COM0交点的值,即定义数码管3的D段
#define COM0_SEG9_VALUE 0x04  //定义LCD引脚SEG9和COM0交点的值,对于数码管3来说,没有段
#define COM1_SEG7_VALUE 0x08  //定义LCD引脚SEG7和COM1交点的值,即定义数码管3的E段
#define COM1_SEG8_VALUE 0x10  //定义LCD引脚SEG8和COM1交点的值,即定义数码管3的G段
#define COM1_SEG9_VALUE 0x20  //定义LCD引脚SEG9和COM1交点的值,即定义数码管3的C段
#define COM2_SEG7_VALUE 0x40  //定义LCD引脚SEG7和COM2交点的值,即定义数码管3的F段
#define COM2_SEG8_VALUE 0x80  //定义LCD引脚SEG8和COM2交点的值,即定义数码管3的A段
#define COM2_SEG9_VALUE 0x100 //定义LCD引脚SEG9和COM2交点的值,即定义数码管3的B段

/*
数码管4:
COM0和SEG11控制数码管4的D段
COM1和SEG10控制数码管4的E段
COM1和SEG11控制数码管4的G段
COM1和SEG12控制数码管4的C段
COM2和SEG10控制数码管4的F段
COM2和SEG11控制数码管4的A段
COM2和SEG12控制数码管4的B段
*/
#define COM0_SEG10_VALUE 0x01  //定义LCD引脚SEG10和COM0交点的值,对于数码管4来说,没有段
#define COM0_SEG11_VALUE 0x02  //定义LCD引脚SEG11和COM0交点的值,即定义数码管4的D段
#define COM0_SEG12_VALUE 0x04  //定义LCD引脚SEG12和COM0交点的值,对于数码管4来说,没有段
#define COM1_SEG10_VALUE 0x08  //定义LCD引脚SEG10和COM1交点的值,即定义数码管4的E段
#define COM1_SEG11_VALUE 0x10  //定义LCD引脚SEG11和COM1交点的值,即定义数码管4的G段
#define COM1_SEG12_VALUE 0x20  //定义LCD引脚SEG12和COM1交点的值,即定义数码管4的C段
#define COM2_SEG10_VALUE 0x40  //定义LCD引脚SEG10和COM2交点的值,即定义数码管4的F段
#define COM2_SEG11_VALUE 0x80  //定义LCD引脚SEG11和COM2交点的值,即定义数码管4的A段
#define COM2_SEG12_VALUE 0x100 //定义LCD引脚SEG12和COM2交点的值,即定义数码管4的B段

/*
  -----A----
 |         |
 F         B
 |         |
  ----G ---
 |         |
 E         C
 |         |   _
 -----D----   | |COL   
               -
根据上述定义,我们发现如下规律:
数码管的A段用0x80表示
数码管的B段用0x100表示
数码管的C段用0x20表示
数码管的D段用0x02表示
数码管的E段用0x08表示
数码管的F段用0x40表示
数码管的G段用0x10表示
数码管的COL段用0x04表示
*/

#define  NUM0     0x01EF//A段+B段+C段+D段+E段+F段    =  0x80+0x100+0x20+0x02+0x08+0x40
#define  NUM1     0x0120//B段+C段                    =  0x100+0x20
#define  NUM2     0x019A//A段+B段+G段+E段+D段        =  0x80+0x100+0x10+0x08+0x02
#define  NUM3     0x01B2//A段+B段+G段+C段+D段        =  0x80+0x100+0x10+0x20+0x02
#define  NUM4     0x0170//F段+G段+B段+C段            =  0x40+0x10+0x100+0x20
#define  NUM5     0x00F2//A段+F段+G段+C段+D段        =  0x80+0x40+0x10+0x20+0x02
#define  NUM6     0x00FA//A段+F段+E段+D段+C段+G段    =  0x80+0x40+0x08+0x02+0x20+0x10
#define  NUM7     0x01A0//A段+B段+C段                =  0x80+0x100+0x20
#define  NUM8     0x01FA//A段+B段+C段+D段+E段+F段+G段 =0x80+0x100+0x20+0x02+0x08+0x40+0x10
#define  NUM9     0x01F2//A段+B段+C段+D段+F段+G段     =0x80+0x100+0x20+0x02+0x40+0x10

//CPU引脚定义///
#define SEG1    PBout(1)  //PB1
#define SEG2    PBout(2)  //PB2
#define SEG3    PBout(3)  //PB3

#define SEG4    PBout(4)  //PB4
#define SEG5    PBout(5)  //PB5
#define SEG6    PBout(6)  //PB6

#define SEG7    PBout(7)  //PB7
#define SEG8    PBout(8)  //PB8
#define SEG9    PBout(9)  //PB9

#define SEG10   PBout(10)  //PB10
#define SEG11   PBout(11)  //PB11
#define SEG12   PBout(12)  //PB12

#define COM0    PBout(13)  //PB13
#define COM1    PBout(14)  //PB14
#define COM2    PBout(15)  //PB15

extern void TIM2_Interrupt_Initializtion(u16 arr,u16 psc);
#endif

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

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

相关文章

想半天憋不出几个字?试试AI扩写

大家在写文章时是否也经常这样?想了半天,结果只能写出几个字,但是要求往往又是几百多个字,那么有没有啥工具可以帮我们在原文的基础上扩写一下文章字数,让我们达到字数要求呢? 下面给大家介绍一下如何扩写文…

Rpcx (二):传输

一、Transport 传输 rpcx 可以通过 TCP、HTTP、UnixDomain、QUIC和KCP通信。你也可以使用http客户端通过网关或者http调用来访问rpcx服务。 TCP 这是最常用的通信方式。高性能易上手。可以使用TLS加密TCP流量。 Example: 101basic 服务端使用 tcp 做为网络名并且在注册中心…

什么是Data Lakehouse Architecture(DLA)?企业为何要创建DLA

公司捕获和存储的数据比以往任何时候都多,因为它们依赖数据来做出关键的业务决策、改进服务或产品,或为最终用户(客户)提供更好的服务。了解各种大数据存储技术对于为商业智能(BI)、数据分析和机器学习&…

山西教育杂志山西教育杂志社山西教育编辑部2024年第4期目录

课题研究 小学语文随堂小练笔策略研究 陈立固; 3-4 儿童戏剧工作坊载体下小学语文戏剧课堂的建构 郭黎明; 5-6《山西教育》投稿:cn7kantougao163.com 文化生态视域下小学英语教学的传统文化融入 周慧娟; 7-8 基于“主题语境”的初中英语课堂教学研究…

PCIe总线-PCIe简介

一、前言 PCIe总线是由PCI/PCI-X发展而来,但是两者之间有很大的不同。PCI/PCI-X采用的是并行总线,最大支持的频率为PCI-X2.0 的133MHz,传输速率最大仅为4262MB/s。同时使用并行总线,在PCB上也会造成布线资源紧张,线与…

MyBatis——动态 SQL

一、if 标签 <mapper namespace"com.powernode.mybatis.mapper.CarMapper"><select id"selectByMultiCondition" resultType"car">select * from t_car where<if test"brand ! null and brand ! ">brand like #{br…

ARM架构安全特性之标准安全 API

安全之安全(security)博客目录导读 目录 一、机密计算软件 二、Arm机密计算固件架构 三、认证校验 四、Veraison项目 五、独立于语言的安全API 六、平台抽象安全项目&#xff08;Platform AbstRaction for SECurity project&#xff09; 七、可移植平台安全API 八、…

(undone) 什么是马尔可夫链?Markov Chain

参考视频1&#xff1a;https://www.bilibili.com/video/BV1ko4y1P7Zv/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 参考视频2&#xff1a;https://www.bilibili.com/video/BV1xg4y1K7z4/?spm_id_from333.788&vd_source7a…

Vue3实战笔记(19)—封装菜单组件

文章目录 前言一、封装左侧菜单导航组件二、使用步骤三、小彩蛋总结 前言 在Vue 3中封装一个左侧导航菜单组件是一项提升项目结构清晰度和代码可复用性的关键任务。这个过程不仅涉及组件的设计与实现&#xff0c;还需考虑其灵活性、易用性以及与Vue 3新特性的紧密结合。以下是…

Golang | Leetcode Golang题解之第88题合并两个有序数组

题目&#xff1a; 题解&#xff1a; func merge(nums1 []int, m int, nums2 []int, n int) {for p1, p2, tail : m-1, n-1, mn-1; p1 > 0 || p2 > 0; tail-- {var cur intif p1 -1 {cur nums2[p2]p2--} else if p2 -1 {cur nums1[p1]p1--} else if nums1[p1] > n…

AXI Interconnect IP核用法

本文描述了如何使用Xilinx的Vivado Design Suite环境中的工具来定制和生成AXI Interconnect IP 核。Vivado Design Suite是一个强大的FPGA设计和开发环境&#xff0c;它允许用户定制和配置各种IP核以适应他们的特定设计需求。 以下是针对如何定制IP核的步骤的简要概述&#xf…

FullCalendar日历组件集成实战(2)

背景 有一些应用系统或应用功能&#xff0c;如日程管理、任务管理需要使用到日历组件。虽然Element Plus也提供了日历组件&#xff0c;但功能比较简单&#xff0c;用来做数据展现勉强可用。但如果需要进行复杂的数据展示&#xff0c;以及互动操作如通过点击添加事件&#xff0…

光数据传送器|光通讯传感器极速版OPT系列尺寸与安装步骤

光数据传送器|光通讯传感器极速版OPT系列是利用可见光及不可见光作为信息载体&#xff0c;无需光纤、网线等有线介质&#xff0c;在空中直接进行信息传输的无线方式通信。驱动光源以可见光及不可见光的高速明暗变化来传输数字信号&#xff0c;以极高光频率双向发射接收光信号&a…

AI与边缘设备,光子芯片,AI规划能力,自然语言驱动的AI游戏

1 Archetype AI 发布了一个创新的人工智能平台 —— Newton 这是一个专门为理解物理世界设计的基础模型。 Newton 设计用于连接实时物理数据&#xff0c;其数据源是全球数十亿传感器的输入&#xff0c;实现了对物理现实的直接解读。 利用从各种传感器&#xff08;如加速度计…

Linux进程间几种通信机制

一. 简介 经过前一篇文章的学习&#xff0c; 我们知道Linux下有两种标准&#xff1a;system V标准和 Posix标准。 System V 和 POSIX 标准是操作系统提供的接口标准&#xff0c;它们规定了操作系统应该如何实现一些基本功能&#xff0c;比如线程、进程间通信、文件处理等。 …

MySQL————创建存储过程函数 有参数传递

存储过程使用大纲 有参数传递 delimiter $$ 声明一个名称为get_student_introduce CREATE PROCEDURE gei_student_introduce(in p_name VARCHAR(20)) 开始操作 BEGIN 撰写真正在操作DMLDQL都行 select introduce 简介 from student WHERE userNamep_name; end $$ delimite…

[muduo网络库]——muduo库TimeStamp类(剖析muduo网络库核心部分、设计思想)

接着之前我们[muduo网络库]——muduo库logger类&#xff08;剖析muduo网络库核心部分、设计思想&#xff09;&#xff0c;我们接下来继续看muduo库中的TimeStamp类&#xff0c;这也是每一个类几乎都能用到的非常简单的类。 TimeStamp类 Timestamp类主要用于日志、定时器模块中…

C语言指针详解(三)

目录 前言 一. 回调函数是什么&#xff1f; 1.定义 2. 代码示例&#xff1a;计数器 2.1 使用回调函数改造前 2.2 使用回调函数改造后 二. qsort使用举例 1. qsort介绍 2. 使用qsort函数排序整型数据 3. 使用qsort排序结构体数据 三. qsort函数的模拟实现 四. sizeo…

单链表经典算法OJ题---力扣21

1.链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;【点击即可跳转】 思路&#xff1a;创建新的空链表&#xff0c;遍历原链表。将节点值小的节点拿到新链表中进行尾插操作 遍历的结果只有两种情况&#xff1a;n1为空 或 n2为空 注意&#xff1a;链表为空的情况 代…

[力扣题解] 96. 不同的二叉搜索树

题目&#xff1a;96. 不同的二叉搜索树 思路 动态规划 f[i]&#xff1a;有i个结点有多少种二叉搜索树 状态转移方程&#xff1a; 以n3为例&#xff1a; 以1为头节点&#xff0c;左子树有0个结点&#xff0c;右子树有2个结点&#xff1b; 以2为头节点&#xff0c;左子树有1个…