51单片机实验05 -点阵

目录

 一,熟悉矩阵led小灯

1,点亮矩阵的一只led

 2,点亮矩阵的一排led

3,点亮矩阵的全部led

static 关键字

unsigned 关键字

4,点阵的静态显示

 2)心形矩阵显示代码

3)效果

二,课后练习题

1、用点阵做一个9到0的倒计时牌显示。

1)效果

2)代码

2、尝试实现流水灯、数码管和点阵的同时显示。

1)效果

2)代码


资料见本文所在的专栏:

 一,熟悉矩阵led小灯

1,点亮矩阵的一只led

1)基础

2)代码 

#include<reg52.h>
sbit enled=P1^4;   // 138译码器使能  
sbit addr3=P1^3;
sbit addr2=P1^2;
sbit addr1=P1^1;
sbit addr0=P1^0; 
sbit led=P0^0;  // 这里只点亮led点阵的左上角第一个led小灯
void main(){
   	   enled=0;  // 控制点阵led	的 U4(138)使能,需要e2低电平
	   addr3=0;	 // 控制点阵led	的 U4(138)使能,需要e1低电平

	   addr2=0;   // y0输出低电平,使Q10晶体管开关打开,使led灯能够点亮
	   addr1=0;
	   addr0=0;

	   led=0;    // 控制一只小灯点亮
	   while(1);  // 长亮
}

 3)效果

 2,点亮矩阵的一排led

1)基础

2)代码

#include<reg52.h>
sbit enled=P1^4;   // 138译码器使能  
sbit addr3=P1^3;
sbit addr2=P1^2;
sbit addr1=P1^1;
sbit addr0=P1^0;
void main(){
   	   enled=0;  // 控制点阵led的 U4(138)使能,需要e2低电平
	   addr3=0;	 // 控制点阵led的 U4(138)使能,需要e1低电平

	   addr2=0;   // y0输出低电平,使Q10晶体管开关打开,使led灯能够点亮
	   addr1=0;
	   addr0=0;  // 选择了第1行的led

	   P0=0x00;    // 控制列上的led,如果写成0x01,则左边第一列不亮,剩下其它列的led亮
	   while(1);  // 长亮
}

3)效果

3,点亮矩阵的全部led

1)代码

下面用到了定时器及中断器(在单片机中带有break关键字的switch语句和中断器是绝配,天造地设的一对)一旦中断器检测到break关键字,就会停下来。在动态显示中,不管是点阵还是数码管点亮的持续时间通常为1ms左右,然后切换到下一个数码管。这意味着在1ms的时间内,数码管应该能够完成从关闭到完全点亮,再到关闭的完整过程。就会有“鬼影”,即会有视觉残留,我们会看到小灯有明显的亮暗波动,所以定时器和中断器的使用就很有必要。

#include<reg52.h>
sbit enled=P1^4;   // 138译码器使能  
sbit addr3=P1^3;
sbit addr2=P1^2;
sbit addr1=P1^1;
sbit addr0=P1^0;
void main(){
   	   enled=0;  // 控制点阵led	的 U4(138)使能,需要e2低电平
	   addr3=0;	 // 控制点阵led	的 U4(138)使能,需要e1低电平
		  
	  EA=1;		  // 总使能中断打开
	  ET0=1;	  // 定时器T0使能中断打开
	  TMOD=0x01;  // 定时器T0的模式为1
	  TH0=0xFC;   // 定时1ms
	  TL0=0x67;
	  TR0=1;  // 开启定时器T0
	   while(1);  // 长亮
}

void InterrutpTimer0()  interrupt 1{	  // 中断服务函数
	  static  unsigned char rowmilisec=0; // 用于存储亮起的行,且是每一毫秒亮一行
	  TMOD=0x01;   // 只要有溢出造成的中断,就将T0初始值重新赋值
	  TH0=0xFC;   
      P0=0xFF;   //关闭段
 switch(rowmilisec){
	  case 0:addr2=0;addr1=0;addr0=0;P0=0x00;rowmilisec++;break;	 
	  case 1:addr2=0;addr1=0;addr0=1;P0=0x00;rowmilisec++;break;	
	  case 2:addr2=0;addr1=1;addr0=0;P0=0x00;rowmilisec++;break;	 
	  case 3:addr2=0;addr1=1;addr0=1;P0=0x00;rowmilisec++;break;		 
	  case 4:addr2=1;addr1=0;addr0=0;P0=0x00;rowmilisec++;break;		
	  case 5:addr2=1;addr1=0;addr0=1;P0=0x00;rowmilisec++;break;	 
	  case 6:addr2=1;addr1=1;addr0=0;P0=0x00;rowmilisec++;break;		 
	  case 7:addr2=1;addr1=1;addr0=1;P0=0x00;rowmilisec=0;break;
	  }
}

在51单片机中,总使能中断EAEnable All Interrupt的缩写。具体来说,EA是中断允许寄存器(IE寄存器)中的一个位,用于控制是否允许CPU响应所有中断请求。

  • 当EA=0时,CPU会屏蔽所有中断请求,即不会响应任何中断。
  • 当EA=1时,CPU会开放所有中断请求,即会根据其他中断使能位(如ES、ET0、ET1、EX0、EX1等)的设置来响应相应的中断。

static 关键字

在函数内部声明一个变量为 static 时,该变量的生命周期会持续到程序执行完毕,而不是在函数返回时结束。此外,static 变量只会初始化一次,即当程序开始运行时。在后续的函数调用中,该变量会保持其上一次被修改后的值。

在中断服务函数 InterrutpTimer0 中,rowmilisec 被声明为 static 是为了确保它能在每次中断调用之间保持其值。这是一个定时器中断,它会在定时器溢出时定期被调用。由于 rowmilisec 用于跟踪已经过去的毫秒数(或行),所以需要它在每次中断之间保持其值,以便知道下一行应该是什么。

unsigned 关键字

unsigned 关键字指定了一个整数类型,它只能存储非负值。与 signed 类型(如 int)相比,unsigned 类型没有符号位,因此它可以存储两倍于相同大小 signed 类型的正数。

在上面的代码中rowmilisec 被用来作为一个计数器,从 0 计数到 7,然后回到 0。由于这个值永远不会是负数,所以使用 unsigned char 是合适的。这不仅可以确保值始终是非负的,而且还可以节省一个位(符号位)

2)效果

4,点阵的静态显示

1)基础 

经过点亮点阵的一只led,一排led,全部led灯相关操作,现在我们开始来让其静态的展示我们指定的图案。要绘制图案,就需要使用到《点阵液晶取模》程序。

对应软件及资源的网盘连接,见本文专栏。之后下载app里面的字模软件即可,如下👇 

之后绘制想要的图案请按照电子书的步骤来: 

 这里绘制出来的是心形图像并使用软件取模得到P0口所需要的值,如下👇

 2)心形矩阵显示代码

#include<reg52.h>
sbit enled=P1^4;   // 138译码器使能  
sbit addr3=P1^3;
sbit addr2=P1^2;
sbit addr1=P1^1;
sbit addr0=P1^0;
unsigned char code heart_matrix[]={  // 心型矩阵真值表
		   0xFF,0x99,0x00,0x00,0x00,0x81,0xC3,0xE7 
};
void main(){
   	   enled=0;  // 控制点阵led	的 U4(138)使能,需要e2低电平
	   addr3=0;	 // 控制点阵led	的 U4(138)使能,需要e1低电平
		  
	  EA=1;		  // 总使能中断打开
	  ET0=1;	  // 定时器T0使能中断打开
	  TMOD=0x01;  // 定时器T0的模式为1
	  TH0=0xFC;   // 定时1ms
	  TL0=0x67;
	  TR0=1;  // 开启定时器T0
	   while(1);  // 长亮
}

void InterrutpTimer0()  interrupt 1{	  // 中断服务函数
	  static  unsigned char rowmilisec=0; // 用于存储亮起的行,且是每一毫秒亮一行
	  // 只要有溢出造成的中断,就将T0初始值重新赋值
	  TH0=0xFC;  
	  TL0=0x67; 
	  P0=0xFF;  // 关闭列
	  switch(rowmilisec){
	  case 0:addr2=0;addr1=0;addr0=0;P0=heart_matrix[0];rowmilisec++;break;	 
	  case 1:addr2=0;addr1=0;addr0=1;P0=heart_matrix[1];rowmilisec++;break;	
	  case 2:addr2=0;addr1=1;addr0=0;P0=heart_matrix[2];rowmilisec++;break;	 
	  case 3:addr2=0;addr1=1;addr0=1;P0=heart_matrix[3];rowmilisec++;break;		 
	  case 4:addr2=1;addr1=0;addr0=0;P0=heart_matrix[4];rowmilisec++;break;		
	  case 5:addr2=1;addr1=0;addr0=1;P0=heart_matrix[5];rowmilisec++;break;	 
	  case 6:addr2=1;addr1=1;addr0=0;P0=heart_matrix[6];rowmilisec++;break;	 
	  case 7:addr2=1;addr1=1;addr0=1;P0=heart_matrix[7];rowmilisec=0;break;	
	  }  
}

3)效果

二,课后练习题

1、用点阵做一个9到0的倒计时牌显示。

1)效果

矩阵实现每隔1s倒计时(从9到0)

2)代码
 

#include<reg52.h>
sbit enled=P1^4;   // 138译码器使能  
sbit addr3=P1^3;
sbit addr2=P1^2;
sbit addr1=P1^1;
sbit addr0=P1^0;
unsigned char code matrix[10][8]={  // 数字矩阵真值表 
		{0xFF,0xC3,0xDB,0xDB,0xC3,0xDF,0xDF,0xFF},//9
		{0xFF,0xC3,0xDB,0xC3,0xDB,0xDB,0xC3,0xFF},//8  
		{0xFF,0xC3,0xDF,0xDF,0xDF,0xDF,0xDF,0xFF}, 	 //7
		{0xFF,0xC3,0xFB,0xC3,0xDB,0xDB,0xC3,0xFF},	 //6   
		{0xFF,0xC3,0xFB,0xC3,0xDF,0xDF,0xC3,0xFF},  //5
		{0xFF,0xEB,0xEB,0xEB,0xC3,0xEF,0xEF,0xFF},	 //4  
		{0xFF,0xC3,0xDF,0xC3,0xDF,0xDF,0xC3,0xFF},	//3
		{0xFF,0xC3,0xDF,0xDF,0xC3,0xFB,0xC3,0xFF},	//2	   
		{0xFF,0xDF,0xDF,0xDF,0xDF,0xDF,0xDF,0xFF},  // 1
		{0xFF,0xC3,0xDB,0xDB,0xDB,0xDB,0xC3,0xFF} //0
        };
void main(){
   	  enled=0;  // 控制点阵led	的 U4(138)使能,需要e2低电平
	  addr3=0;	 // 控制点阵led	的 U4(138)使能,需要e1低电平
	  EA=1;		  // 总使能中断打开
	  ET0=1;	  // 定时器T0使能中断打开
	  TMOD=0x01;  // 定时器T0的模式为1
	  TH0=0xFC;   // 定时1ms
	  TL0=0x67;
	  TR0=1;  // 开启定时器T0
	  while(1);
	 
}
void  Timer0()  interrupt 1{	  // 中断服务函数
	  static  unsigned char rowmilisec=0; 
	  static unsigned char 	 ind=0;
	  static unsigned int  milisec=0;  //int容纳1000以上的数值
	  // 只要有溢出造成的中断,就将T0初始值重新赋值
	  TH0=0xFC;  
	  TL0=0x67; 
	  P0=0xFF;
	  switch(rowmilisec){
	  case 0:addr2=0;addr1=0;addr0=0;P0=matrix[ind][0];rowmilisec++; break;	 
	  case 1:addr2=0;addr1=0;addr0=1;P0=matrix[ind][1];rowmilisec++;break;	
	  case 2:addr2=0;addr1=1;addr0=0;P0=matrix[ind][2];rowmilisec++;break;	 
	  case 3:addr2=0;addr1=1;addr0=1;P0=matrix[ind][3];rowmilisec++; break;		 
	  case 4:addr2=1;addr1=0;addr0=0;P0=matrix[ind][4];rowmilisec++; break;		
	  case 5:addr2=1;addr1=0;addr0=1;P0=matrix[ind][5];rowmilisec++; break;	 
	  case 6:addr2=1;addr1=1;addr0=0;P0=matrix[ind][6];rowmilisec++; break;	 
	  case 7:addr2=1;addr1=1;addr0=1;P0=matrix[ind][7];rowmilisec=0;break;	
	  default:break;
	  }	   
	  milisec++;
	  if(milisec==1000){  //1s更新数字
	     ind++;
	     milisec=0;
		 if(ind ==10){    // 倒计时一轮之后继续倒计时
		 ind=0;
		 }
	  }
}


2、尝试实现流水灯、数码管和点阵的同时显示。

  • 点阵:从9倒计时到0(间隔1s);
  •  流水灯:从最左边往右1s移动一个,到头之后再从左开始;
  • 数码管:使用最左边的一支数码管,让其从9倒计时到0(间隔1s);

1)效果

点阵和数码管同时倒计时led流水灯从左到右

2)代码

#include<reg52.h>
sbit addr3 = P1^3;
sbit enled = P1^4;
void setTimer0(unsigned long ms);//设置定时器的定时毫秒数
void scan();//点阵,led流水灯,数码管扫描函数
unsigned char T0H_att = 0;	// 用来存储临时产生的定时器初始值
unsigned char T0L_att = 0;
	unsigned char code zzb_matrix[10][8]={  // 数字矩阵真值表 
		{0xFF,0xC3,0xDB,0xDB,0xC3,0xDF,0xDF,0xFF},//9
		{0xFF,0xC3,0xDB,0xC3,0xDB,0xDB,0xC3,0xFF},//8  
		{0xFF,0xC3,0xDF,0xDF,0xDF,0xDF,0xDF,0xFF}, 	 //7
		{0xFF,0xC3,0xFB,0xC3,0xDB,0xDB,0xC3,0xFF},	 //6   
		{0xFF,0xC3,0xFB,0xC3,0xDF,0xDF,0xC3,0xFF},  //5
		{0xFF,0xEB,0xEB,0xEB,0xC3,0xEF,0xEF,0xFF},	 //4  
		{0xFF,0xC3,0xDF,0xC3,0xDF,0xDF,0xC3,0xFF},	//3
		{0xFF,0xC3,0xDF,0xDF,0xC3,0xFB,0xC3,0xFF},	//2	   
		{0xFF,0xDF,0xDF,0xDF,0xDF,0xDF,0xDF,0xFF},  // 1
		{0xFF,0xC3,0xDB,0xDB,0xDB,0xDB,0xC3,0xFF} //0
        };
unsigned char code zzb_smg[]={//数码管显示字符转换表0~9(P0值)	
	0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,0x80, 0x90 //0~9
//	, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E	// A~F
	};
unsigned char code zzb_led[8] = { // 指定led亮起的P0值?数码管位
	  0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F
	};
unsigned char off_smg[]={  // 关闭数码管的段,消隐	    
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
	};
bit flag1s = 0;//1s定时标志,flag1s只存储一位,所以使用bit来声明定义
unsigned char interrupt_t0 = 0;//记录T0中断次数
static char row_matrix=-1;	// 矩阵的行,设置成-1是为了让它在i=0时,显示9,而不是8。	   
static unsigned char ind_smg=0;	// 数码管索引
void main()
{
   // unsigned long sec_smg = 0;	 // 数码管秒数
	enled = 0;
	setTimer0(1);	 //定时器定时1ms
	while(1)
	{
		if(flag1s == 1)		  
		{
			flag1s = 0;
			//sec_smg++; // 记录数码管显示的秒数,因为这里只显示9~0,所以不用sec_smg这个变量
			row_matrix++; //实现点阵的图片刷新(更新)
			if(row_matrix>9){  // 点阵只有8行,之所以本来应该是大于8就让它置零,是因为我们一开始设置了row_matrix=-1
			   row_matrix=0;
			}	
			/*off_smg[0] = zzb_smg[sec%10];	 // 如果想要多位显示,可以把相应的代码块注释去掉
		    off_smg[1] = zzb_smg[sec/10%10];
			off_smg[2] = zzb_smg[sec/100%10];
			off_smg[3] = zzb_smg[sec/1000%10];
			off_smg[4] = zzb_smg[sec/10000%10];*/
			off_smg[5] = zzb_smg[9-ind_smg]; // ind_smg=0,数码管显示9-0=9
			   ind_smg++;
				if(ind_smg>9){ 
			   ind_smg=0;
			}	
		}
	}	
}
void scan()
{	
	static unsigned char i = 0;
	P0 = 0xFF;
	if(i>7)//扫描数码管与LED小灯
	{
		addr3 = 1;	// led流水灯亮
		P1 = (P1&0xF8)|(i-8); 
		if(i==14){ 
		off_smg[6]=zzb_led[interrupt_t0];
		} 
		P0 = off_smg[i-8];
	}
	else  //i<7时扫描点阵
	{
		addr3 = 0;  // 点阵对应的led打开     
		P1 = (P1&0xF8)|i;
		if(row_matrix>=0){
		P0 = zzb_matrix[row_matrix][i];
		   }
	}
	i++;	
	if(i>15) i=0;  // 
}
void setTimer0(unsigned long milisec)
{
    unsigned long n;
	n = 11059200/12;
	n=(n*milisec)/1000;
	n = 65536-n;
	n += 12;  //补偿中断函数引起的误差,编写《教材手把手教你学51单片机-C语言版》的作者经过多次尝试加12是最佳的
	T0H_att = (unsigned char)(n>>8);
	T0L_att = (unsigned char)n;
	TMOD=0x01;
	EA = 1;	
	ET0 = 1;
	TH0 = T0H_att;
	TL0 = T0L_att;
	TR0 = 1;
}									   
void InterruptTimer0() interrupt 1
{
	static unsigned long milisec = 0;
	TH0 = T0H_att;
	TL0 = T0L_att;
	milisec++;
	if(milisec>=1000)
	{
		milisec=0;
		interrupt_t0++;
		flag1s=1;
		if(interrupt_t0>7)//interrupt_t0为LED数组索引
			interrupt_t0=0;	
	}
	scan();//点阵、数码管、LED扫描
}

 有任何问题请在评论区留言或者是私信我,一天8h在线。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

6.nginx负载均衡

说明 增加服务器的数量,将请求分发到各个服务器上。 将原来请求集中到单个服务器上的情况改为将请求分发到多个服务器上。 案例 浏览器请求地址http://ip/edu/a.html, 负载均衡的效果,平分到8080和8081两台服务上中。 准备工作 tomcat8080配置 tomcat8081配置 直接通过…

----几种接口的使用---

Compareable接口 对于给数组中的变量成员排序&#xff0c;我们能想到用sort&#xff0c;根据成员之间的大小进行排序&#xff0c;那么如果数组中的成员是对象的话&#xff0c;单单只是用sort去排序肯定是步成功的&#xff0c;因为并不知道要根据什么去排序&#xff0c; 这时要…

【C++】编译

三、C编译 前面给大家演示了如何从写C代码到编译代码再到执行代码的全过程。这个过程中非常重要的编译环节&#xff0c;被我们一个按钮或者一个ctrlF7快捷键就给带过了。其实这个环节非常重要&#xff0c;如果你非常了解这个环节&#xff0c;你开发源代码就会更加自信和清醒&a…

CorelDRAW 2024开启设计新纪元,终身永久版与中文破解版的全面解析及安装攻略

当我们谈论图形设计软件时&#xff0c;CorelDRAW无疑是一个响亮的名字。作为一款强大的矢量图形编辑工具&#xff0c;它以其丰富的功能和用户友好的界面赢得了全球设计师的喜爱。随着CorelDRAW 2024的发布&#xff0c;这个备受瞩目的版本带来了前所未有的创新特性&#xff0c;进…

Vulnhub-DC-1,7

靶机IP:192.168.20.141 kaliIP:192.168.20.128 网络有问题的可以看下搭建Vulnhub靶机网络问题(获取不到IP) 前言 1和7都是Drupal的网站&#xff0c;只写了7&#xff0c;包含1的知识点 信息收集 用nmap扫描端口及版本号 进入主页查看作者给的提示&#xff0c;不是暴力破解的…

ROS2底层机制源码分析

init ->init_and_remove_ros_arguments ->init ->Context::init 保存初始化传入的信号 ->install_signal_handlers→SignalHandler::install 开线程响应信号 ->_remove_ros_arguments 移除ros参数 ->SingleNodeManager::instance().…

条件判断if语句与case语句

一、条件测试 test命令进行条件测试&#xff0c;然后根据返回值来判断条件是否成立。 常用操作符&#xff1a; -e &#xff1a;既可以测试文件又可以测试目录是否存在 -d &#xff1a;测试目录是否存在 -f &#xff1a;测试文件是否存在 -r &#xff1a;测试当前用户是否…

前端加载 动画特效

效果图: 完整代码: <!DOCTYPE html> <html> <head><meta charset="UTF-8" /><title>加载动画</title><style type="text/css">/* 设置页面背景颜色 */body {background: #ECF0F1;}/* 定义加载动画容器的样式…

抖店没人做了?不是项目不行了,而是商家们都换思路去玩了

我是王路飞。 有没有发现现在很多抖店新手都在吐槽&#xff0c;抖店不好做了&#xff0c;做不起来&#xff0c;没人做了&#xff0c;太内卷了...... 对这种做不起来还在怪项目本身的&#xff0c;一定要离他远一点&#xff0c;省得被他的负能量给影响到自己的状态。 任何项目…

怎么学习汇川Codesys PLC教程?

前言 各位好&#xff0c;我在B站和抖音上都有发布视频的&#xff0c;搜索我的名称“阿凡工控分享”即可。在CSDN上发表文章也是想把我的一点见解和经验分享出来&#xff0c;进一步的方便大家进行学习。 我是正文 本文主要也是为了方便大家学习汇川的Codesys PLC而制作的&…

Java并发编程之线程池源码解析与实现详解

Java并发编程是现代开发中非常重要的一个领域。使用线程池来管理和控制线程的创建和生命周期&#xff0c;可以更加高效地利用系统资源&#xff0c;提高系统的并发性能。线程池是一种常见的并发编程模型&#xff0c;Java提供了ThreadPoolExecutor类来实现线程池。本文将详细解析…

⌈ 传知代码 ⌋ MonoCon解读与复现

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

写给大数据开发:好的指标定义、特性与业务价值

在大数据时代&#xff0c;数据的质量对于业务决策和数据分析至关重要。好的数据不仅丰富&#xff0c;而且准确、及时&#xff0c;为业务提供有力支撑。 文章目录 数据定义与特性数据对业务的价值指标展示与规范化定义一些指标的定义好的数据是业务成功的关键 数据定义与特性 好…

在 Wed 中应用 MyBatis(同时使用MVC架构模式,以及ThreadLocal 事务控制)

1. 在 Wed 中应用 MyBatis&#xff08;同时使用MVC架构模式&#xff0c;以及ThreadLocal 事务控制&#xff09; 文章目录 1. 在 Wed 中应用 MyBatis&#xff08;同时使用MVC架构模式&#xff0c;以及ThreadLocal 事务控制&#xff09;2. 实现步骤&#xff1a;1. 第一步&#xf…

python爬虫爬取微博评论--完整版(超详细,大学生不骗大学生)

目录 一、找到页面 二、学会使用检查元素 2.1 打开检查元素界面 2.2 找到所有评论所在的位置 2.2.1 搜索评论 2.2.2 找到data表 三、基础部分代码实现 四、格式化输出 4.1 了解存储格式 4.2 单独取出内容 4.3 取出所有评论内容 4.4 格式化读取信息 五、导出成表格…

【ARM Cache 与 MMU 系列文章 7.4 -- ARMv8 MMU 配置 寄存器使用介绍】

请阅读【ARM Cache 及 MMU/MPU 系列文章专栏导读】 及【嵌入式开发学习必备专栏】 文章目录 MMU 转换控制寄存器 TCR_ELxTCR_ELx 概览TCR_ELx 寄存器字段详解TCR 使用示例Normal MemoryCacheableShareability MMU 内存属性寄存器 MAIR_ELxMAIR_ELx 寄存器结构内存属性字段Devic…

两种典型的嵌入式系统架构模式

大多数嵌入式系统都具备实时特征&#xff0c;那么&#xff0c;这种嵌入式系统的典型架构可概括为两种模式&#xff0c;即层次化模式架构和递归模式架构。 1.层次化模式架构 为了达到概念一致性&#xff0c;许多系统通过层次化的方法进行搭建。这样做的结果是&#xff1a;位于高…

【漏洞复现】海洋CMS /js/player/dmplayer/dmku/ SQL注入漏洞复现(CVE-2024-29275)

0x01 产品简介 海洋CMS是一套专为不同需求的站长而设计的内容管理系统&#xff0c;灵活、方便、人性化设计、内容的专业网站。海洋CMS基于PHPMySql技术开发&#xff0c;完全开源免费、无任何加密代码。简单易用是最大的特色&#xff0c;可快速建立一个海量 0x02 漏洞概述 海…

翻译: Gen AI生成式人工智能学习资源路线图一

Introduction 介绍 本文档旨在作为学习现代人工智能系统背后的关键概念的手册。考虑到人工智能最近的发展速度&#xff0c;确实没有一个好的教科书式的资源来快速了解 LLMs 或其他生成模型的最新和最伟大的创新&#xff0c;但互联网上有大量关于这些主题的优秀解释资源&#x…

.NET周刊【6月第2期 2024-06-09】

国内文章 C#开源实用的工具类库&#xff0c;集成超过1000多种扩展方法 https://www.cnblogs.com/Can-daydayup/p/18230586 文章介绍了一个免费的C#工具类库Z.ExtensionMethods&#xff0c;可以通过NuGet包管理器轻松集成。该库支持.NET Standard 2.0和.NET Framework 4.0&am…