stm32驱动RFID高频读卡器读取IC卡

news2024/10/7 14:29:04

stm32驱动RFID读卡器读取IC卡

  • 1.介绍RFID
  • 2.RFID控制指令
    • 2.1 读IC卡号
    • 2.2 读IC卡数据块
    • 2.3 写数据到IC卡数据块
    • 2.4 读取RFID读卡器用户数据
    • 2.5 向RFID读卡器写入用户数据
  • 3.代码实例
    • 3.1 rfid.c 源文件
    • 3.2 rfid 头文件
  • 4. 结语

1.介绍RFID

RFID(Radio-Frequency Identification)高频读卡器是一种设备,用于读取和解析高频(13.56 MHz)频段上的RFID标签信息。这种读卡器通过无线射频技术与标签进行通信,并从标签中获取存储的数据。
RFID高频读卡器通常包括以下主要组件
读卡器天线:用于发射和接收射频信号,与标签进行通信。
处理器:负责解析和处理从标签接收到的数据,以及将数据传输给相应的应用程序。
电源和接口:提供电力和连接读卡器与其他设备/系统的接口。
控制单元:用于控制读卡器的操作和配置。
RFID高频读卡器常用于各种场景,如物流管理、库存跟踪、门禁控制、资产管理等。它们可以与其他设备(如计算机、智能手机、门禁系统)进行通信,以便实现各种应用需求。
需要注意的是,RFID技术还有其他频段,如低频(LF)和超高频(UHF),每个频段的读卡器具有不同的特点和应用领域。
我们这里介绍的是RFID高频读卡器。

2.RFID控制指令

2.1 读IC卡号

在这里插入图片描述
发送十六进制命令: 01 08 A1 20 00 01 00 76
成功, 读写器返回十六进制数据: 01 0C A1 20 00 04 00 0A DC EF F9 B7, 其中 04 00 为卡类型, 0A DC
EF F9 为卡号
失败, 读写器返回十六进制数据: 01 08 A1 20 01 00 00 76

2.2 读IC卡数据块

在这里插入图片描述
假如块 2 中的数据为: 78 56 34 12 87 A9 CB ED 78 56 34 12 02 FD 02 FD
例 1: 验证卡的 KEYA, 读数据块 2 的数据, LED 和蜂鸣器不提示, 命令与返回包如下:
上位机发送十六进制命令: 01 08 A3 20 02 00 00 77
成功, 读写器返回十六进制数据: 01 16 A3 20 00 78 56 34 12 87 A9 CB ED 78 56 34 12 02 FD 02 FD 63
失败, 读写器返回十六进制数据: 01 08 A3 20 01 00 00 74
例 2: 验证卡的 KEYB, 读数据块 2 的数据, LED 和蜂鸣器不提示, 命令与返回包如下:
上位机发送十六进制命令: 01 08 5C 20 02 00 00 88
成功, 读写器返回十六进制数据: 01 16 5C 20 00 78 56 34 12 87 A9 CB ED 78 56 34 12 02 FD 02 FD 9C
失败, 读写器返回十六进制数据: 01 08 5C 20 01 00 00 8B

2.3 写数据到IC卡数据块

在这里插入图片描述
写 16 字节数据 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF 到块 2
例 1: 验证卡的 KEYA, 写数据块 2, LED 与蜂鸣器的状态提示开启, 命令与返回包如下:
上位机发送十六进制命令: 01 17 A4 20 02 01 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF 6E
成功, 读写器返回十六进制数据: 01 08 A4 20 00 00 00 72
失败, 读写器返回十六进制数据: 01 08 A4 20 01 00 00 73
例 2: 验证卡的 KEYB , 写数据块 2, LED 与蜂鸣器的状态提示开启, 命令与返回包如下:
上位机发送十六进制命令: 01 17 5B 20 02 01 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF 91
成功, 读写器返回十六进制数据: 01 08 5B 20 00 00 00 8D
失败, 读写器返回十六进制数据: 01 08 5B 20 01 00 00 8C

2.4 读取RFID读卡器用户数据

在这里插入图片描述
例 :用户在从地址 03 开始存储了 6 个字节的数据, 分别是 01 02 03 04 05 06, 查询这个 6 个字节数据, 命令与
返回包如下:
上位机发送十六进制命令: 02 08 B5 20 03 06 00 65
读写器返回十六进制数据: 02 0C B5 20 00 01 02 03 04 05 06 63
每次读用户内存的字节数不超过 16 字节, 地址空间从 0x00-0x1F,总共 32 字节。

2.5 向RFID读卡器写入用户数据

在这里插入图片描述
读写器提供 32 字节的内存空间, 地址空间 0-1F, 供用户存储数据, 当内存使用(比如存储用户自己的序列号,
验证码, 用于跟自己的设备或者上位机管理软件验证, 是否为合法读写设备) ; 用户可以简单的通过命令对读写
器提供的存储空间进行存取。 可以将数据存储在指定的地址空间。 每次存储数据字节数不能大于 16 字节。
例 1:如在地址 05 开始处顺序存储 5 个字节:0x12 0x34,0x56,0x78,0x09 , 令与返回包如下:
上位机发送十六进制命令: 03 0B C5 20 05 12 34 56 78 09 16
成功, 读写器返回十六进制数据: 03 08 C5 20 00 00 00 11
失败, 读写器返回十六进制数据: 03 08 C5 20 01 00 00 10

3.代码实例

这里我写了以上操作指令代码,这些代码可移植性强,方便调用。你们可以结合自己的需要去使用。
比如搞一个门禁系统,校园卡等

3.1 rfid.c 源文件

这里就是串口代码没提供,代码太多了,贴不下,你们可以用你们自己的串口代码。
不过我也会提供完成源码。

#include "stm32f10x.h"
#include "usart3.h"
#include "usart.h"
#include "rfid.h"
#include "stdio.h"

unsigned char Uart3RxBuf[UART3_RX_BUF_LEN];
unsigned char Uart3RxDataConut = 0;
unsigned char Rx3Flag = 0;

unsigned char Cmd_Read_Id[8] = {0x01,0x08,0xa1,0x20,0x00,0x00,0x00,0x00};
unsigned char Cmd_Read_Block[8]	= {0x01,0x08,0xa3,0x20,0x00,0x00,0x00,0x00};
unsigned char Cmd_Write_Block[23] = {0x01,0x17,0xa4,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

unsigned char WBlockData[16] = {0x11,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
//CircularBuffer *Uart2_Circular_Buffer;
unsigned char Cmd_Write_RFID[0x0B]={0x03, 0x0B, 0xC5, 0x20, 0x05, 0x12, 0x34, 0x56, 0x78, 0x09, 0x16};
 //                          命令类型  包长度  命令  设备地址  起始地址  数据长度   保留  校验和
unsigned char Cmd_Read_RFID[]={0x02,   0x08,   0xB5,  0x20,    0x03,      0x06,     0x00,  0x65};

//延时,10000000大约为1S
void Delay(__IO unsigned int nCount)
{
  for (; nCount != 0; nCount--);
}

void Uart3_Send_Data(unsigned char *buf,unsigned char num)
{
	unsigned char i;
	for(i=0;i<num;i++)
	{ 
	 	USART_SendData(USART3, buf[i]);
	 	while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
	}	
}

unsigned char RxCheckSum(unsigned char *ptr,unsigned char len) //计算校验值 
{
	unsigned char i;
	unsigned char checksum;
	checksum = 0;
	for(i=0;i<(len-1);i++)
	{
		   checksum ^= ptr[i];
	}
	checksum = ~checksum;
	if(ptr[len-1] == checksum)
		return 	STATUS_OK;
	else 
		return 	STATUS_ERR;
}

void TxCheckSum(unsigned char *ptr,unsigned char len)
{
	unsigned char i;
	unsigned char checksum;
	checksum = 0;
	for(i=0;i<(len-1);i++)
	{
		   checksum ^= ptr[i];
	}
	checksum = ~checksum;
	ptr[len-1] = checksum;
}
//ReadId():读IC卡ID号(卡号)
//参数:*idout,读取的卡号保存到它所指向的存储空间
//返回值:0:成功读取卡号,1:读卡号失败
unsigned char ReadId(void)
{
	unsigned char status;
	unsigned char i;
	unsigned char idout[6];
	Cmd_Read_Id[5] = 0x01;//开启蜂鸣器提示
	//Cmd_Read_Id[5] = 0x00;//关闭蜂鸣器提示
	TxCheckSum(Cmd_Read_Id,Cmd_Read_Id[1]);		//计算校验和
	Uart3_Send_Data(Cmd_Read_Id,Cmd_Read_Id[1]);		 //发送读卡号ID命令
	Delay(2000000);//等待模块返回数据,大于150MS
 	if(Rx3Flag == 1)
 	{	
		Rx3Flag = 0;
		status = RxCheckSum(Uart3RxBuf,Uart3RxBuf[1]);//对接收到的数据校验
		if(status != STATUS_OK)  //判断校验和是否正确
		{
			return STATUS_ERR;
		}
		status = Uart3RxBuf[4];
		if(status != STATUS_OK)	//判断是否正确的读到卡
		{
		 	return STATUS_ERR;
		}
		if((Uart3RxBuf[0] == 0x01)&&(Uart3RxBuf[2] == 0xa1))//判断是否为读卡号返回的数据包
		{
			for(i=0;i<6;i++)//获取卡号ID,6字节		 
			{
				idout[i] = Uart3RxBuf[i+5];//从数组的第5个字节开始为卡号,长度为6字节
			}
			for(i=0;i<6;i++)
		{
			while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); //Ñ­»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï   
			USART_SendData(USART1,idout[i]); 
		}
			return STATUS_OK;		 //成功返回0
		}
 	} 
	return STATUS_ERR;			//失败返回1
}


//ReadId():读IC卡数据块
//参数:*idout,读取的数据保存到它所指向的存储空间
//参数:block,块号
//返回值:0:成功读取,1:读读取失败
unsigned char ReadDataFromBlock(unsigned char *dataout,unsigned char block)
{
	unsigned char status;
	unsigned char i;
	Cmd_Read_Block[4] = block;
	Cmd_Read_Block[5] = 0x01;//开启蜂鸣器提示
//	Cmd_Read_Block[5] = 0x00;//关闭蜂鸣器提示
	TxCheckSum(Cmd_Read_Block,Cmd_Read_Block[1]);	//数据校验
	Uart3_Send_Data(Cmd_Read_Block,Cmd_Read_Block[1]);		 //发送读数据块命令
	Delay(2000000);//等待模块返回数据,大于150MS
 	if(Rx3Flag == 1)
 	{	
		Rx3Flag = 0;
		status = RxCheckSum(Uart3RxBuf,Uart3RxBuf[1]);//对接收到的数据校验
		if(status != STATUS_OK)		 //判断校验和是否正确
		{
			return 	STATUS_ERR;
		}
		status = Uart3RxBuf[4];		//获取返回包状态
		if(status != STATUS_OK)	//判断是否正确的读到卡
		{
			return STATUS_ERR;
		}
		if((Uart3RxBuf[0] == 0x01)&&(Uart3RxBuf[2] == 0xa3))//判断是否为读块数据返回的数据包
		{
			for(i=0;i<16;i++)//获取块数据,16字节	,一个数据块的大小为16字节	 
			{
				dataout[i] = Uart3RxBuf[i+5];//从数组的第5个字节开始为数据,长度为16字节
			}
			return STATUS_OK;		 //成功返回0
		}
	}
	return STATUS_ERR;			//失败返回1
}
//ReadId():写数据到指定的数据块
//参数:*idout,指向要写入数据的缓冲区
//参数:block,块号
//返回值:0:写入成功,1:写入失败
unsigned char WriteDataToBlock(unsigned char *datain,unsigned char block)
{
	unsigned char status;
	unsigned char i;
	Cmd_Write_Block[4] = block;
	for(i=0;i<16;i++)
	{
		Cmd_Write_Block[6+i] = datain[i];
	}
	TxCheckSum(Cmd_Write_Block,Cmd_Write_Block[1]);	//数据校验
	Uart3_Send_Data(Cmd_Write_Block,Cmd_Write_Block[1]);		 //发送写命令
	Delay(2000000);//等待模块返回数据,大于150MS
 	if(Rx3Flag == 1)
 	{	
		Rx3Flag = 0;
		status = RxCheckSum(Uart3RxBuf,Uart3RxBuf[1]);//对返回的数据进行校验
		if(status != STATUS_OK) //判断校验是否通过
		{
			return STATUS_ERR;
		}
		status = Uart3RxBuf[4];
		if(status != STATUS_OK) //判断校验是否通过
		{
			return STATUS_ERR;
		}
		if((Uart3RxBuf[0] == 0x01)&&(Uart3RxBuf[2] == 0xa4))//判断是否为写块数据返回的数据包
		{
				return STATUS_OK;		 //成功返回0
		}
 	} 
	return STATUS_ERR;			//失败返回1
}
//读RFID用户空间
unsigned char Read_RFID(unsigned char addr,unsigned char len)
{
  unsigned char status;
  unsigned char i;
    Cmd_Read_RFID[4]=addr;
    Cmd_Read_RFID[5]=len;
	TxCheckSum(Cmd_Read_RFID,Cmd_Read_RFID[1]);		//计算校验和
	Uart3_Send_Data(Cmd_Read_RFID,Cmd_Read_RFID[1]);		 //发送读用户数据命令
	Delay(2000000);//等待模块返回数据,大于150MS
 	if(Rx3Flag == 1)
 	{	
        
		Rx3Flag = 0;
		status = RxCheckSum(Uart3RxBuf,Uart3RxBuf[1]);//对接收到的数据校验
		if(status != STATUS_OK)  //判断校验和是否正确
		{
			return STATUS_ERR;
		}
		status = Uart3RxBuf[4];
		if(status != STATUS_OK)	//判断是否正确的读到卡
		{
		 	return STATUS_ERR;
		}
		if((Uart3RxBuf[0] == 0x02)&&(Uart3RxBuf[2] == 0xB5))//判断是否为读RFID用户信息返回的数据包
		{
			
			for(i=0;i<Cmd_Read_RFID[5];i++)   //将读取的RFID打印到串口
		{
			while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); 
			USART_SendData(USART1,Uart3RxBuf[i+5]); 
		}
			return STATUS_OK;		 //成功返回0
		}
 	} 
	return STATUS_ERR;	
}
//写RFID 用户空间
unsigned char Write_RFID(unsigned char addr,unsigned char * data,unsigned char len)
{ 
    unsigned char status;
	unsigned char i;
    unsigned char cmd[22]={0x03, 0x0B, 0xC5, 0x20};
	cmd[4] =addr;//地址
    cmd[1]=6+len;//长度
	for(i=0;i<len;i++)
	{
		cmd[5+i] = data[i];
	}
	TxCheckSum(cmd,cmd[1]);	//数据校验
	Uart3_Send_Data(cmd,cmd[1]);	 //发送写命令
	Delay(2000000);//等待模块返回数据,大于150MS
 	if(Rx3Flag == 1)
 	{	
		Rx3Flag = 0;
		status = RxCheckSum(Uart3RxBuf,Uart3RxBuf[1]);//对返回的数据进行校验
		if(status != STATUS_OK) //判断校验是否通过
		{
			return STATUS_ERR;
		}
		status = Uart3RxBuf[4];
		if(status != STATUS_OK) //判断校验是否通过
		{
			return STATUS_ERR;
		}
		if((Uart3RxBuf[0] == 0x03)&&(Uart3RxBuf[2] == 0xc5))//判断是否为写块数据返回的数据包
		{        
             for(i=0;i<len;i++)   //将写入的数据打印到串口
		{
			while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); 
			USART_SendData(USART1,cmd[i+5]); 
		}
				return STATUS_OK;		 //成功返回0
		}
 	} 
	return STATUS_ERR;			//失败返回1
}

3.2 rfid 头文件

#ifndef _RFID_H
#define _RFID_H

#define STATUS_OK			0x00
#define STATUS_ERR    0x01

#define UART3_RX_BUF_LEN 30
extern unsigned char Uart3RxBuf[];
extern unsigned char Uart3RxDataConut ;
extern unsigned char Rx3Flag;
unsigned char ReadId(void);
unsigned char Write_RFID(unsigned char addr,unsigned char * data,unsigned char len);
unsigned char Read_RFID(unsigned char addr,unsigned char len);
#endif

4. 结语

以上就说指令集以及实现代码了。你们可以拿去使用,改造成你项目中所需要的。
最后如果想要串口代码或者完整工程的可以评论区或者私信我哦!

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

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

相关文章

篮球比赛管理系统的设计与实现(论文+源码)_kaic

摘要 迅猛发展并日益成熟的网络已经彻底的影响了我们的方方面面。人们也确实真切的体会到了网络带给我们的便捷。本网站的设计理念在于作为一个天津大学生台球联盟推广网&#xff0c;就是能够尽可能详细地展示、介绍台球联盟资讯信息&#xff0c;播放视频&#xff0c;同时为广…

关于Eclipse代码断点调试与相关快捷键

关于Eclipse代码断点调试与相关快捷键 功能快捷键 首先关于DeBug测试的快捷键&#xff1a; Debug F5&#xff1a;Step Into&#xff08;debug&#xff09; F6&#xff1a;Step over&#xff08;debug&#xff09; F7&#xff1a;Step return&#xff08;debug&#xff09; F8&a…

化妆品行业知识分享

目录 一、产品基本信息 1.产品的组成 2. 产品分类 3.常见术语 二、产品特性 1.生产特性 2.销售特性 3.采购特性 4.研发特性 三、行业痛点与解决方案 1.行业主要存在的痛点 2.日常业务解决方案&#xff1a; 3.供应商管理解决方案&#xff1a; 四、总结 一、产品基本信息 1.产品的…

C++基础(13)——STL(stack、queue、list)

前言 本文主要介绍C中STL中的stack、queue和list容器 7.5&#xff1a;stack容器 7.5.1&#xff1a;stack容器基本概念 栈中只有顶端元素才可以被外界调用&#xff0c;因此栈不允许有遍历的行为&#xff0c;其中string、vector、deque都可以遍历 7.5.2&#xff1a;栈的常用接…

AT32F437网络通信

网络时间长了ping不通&#xff0c;解决方法 https :// https://hjha.bar:8443/vod 123456789 /play/id/32052/sid/1/nid/1.html

PYTHON强制升级openpyxl方法--已验证有效

当执行for i, row in enumerate(worksheet.iter_rows(min_row1, max_rowworksheet.max_row,values_onlyTrue)) 出现以下错误时&#xff1a;TypeError: iter_rows() got an unexpected keyword argument ‘values_only’ 说明openpyxl版本过低&#xff0c;需要升级&#xff0c;当…

指令模板:采访大纲生成 | AIGC实践

最近收获了一些朋友的谬赞&#xff0c;说我“执行力太强了”&#xff0c;可以持续输出内容。 呃&#xff0c;其实吧&#xff0c;这些素材都是从我的实际工作和生活中来的&#xff0c;只是稍加整理而已。 要说起来&#xff0c;AIGC的出现已经完全改变了我的工作方式。在遇到问题…

《中国多媒体与网络教学学报》简介及投稿邮箱

《中国多媒体与网络教学学报》简介及投稿邮箱 中国多媒体与网络教学学报 创刊于2002年&#xff0c;是经国家新闻出版总署批准的中央级电子期刊,是国内最早以多媒体形式发表中小学信息化教学改革前沿成果的学术期刊群,是教育部重点成果的发表平台之一,由教育部主管、清华大学主…

谈找工作线上途径

谈找工作 目录概述需求&#xff1a; 设计思路实现思路分析1.51job2.拉勾网 猎聘网站智联招聘网站后记 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait…

DDOS攻击防御实战(威胁情报)

背景&#xff1a; 不知道大家最近有没有关注到&#xff0c;百度云CDN不支持免费了&#xff0c;网站安全问题越来越严重了…… 常见攻击 DDOS Distributed Denial of Service 分布式拒绝服务攻击可以使很多的计算机在同一时间遭受到攻击&#xff0c;使攻击的目标无法正常使用&…

C++基础(14)——STL(set、pair、map)

前言 本文主要介绍C中STL中的set、pair和map容器 7.8&#xff1a;set、multiset容器 7.8.1&#xff1a;set容器基本概念、构造函数和赋值&#xff08;、insert&#xff09; set容器中所有元素都会在插入的时候自动排序 set和multiset的区别 set不允许有重复的元素&#xff…

i5/i7该选谁?差距大不大?i5-13490F、i7-13790F深度测试

一、i5、i7还是性能差不多吗&#xff1f; 自从2017年Zen架构发布开始&#xff0c;Intel与AMD在CPU性能竞争上就进入了激烈的内卷。随着双方在产品竞争上日趋白热化&#xff0c;同世代不同档次CPU产品的性能差距被明显拉大。 那么&#xff0c;过去那种“i5、i7性能差不多&#x…

self-attention(transformer)

自注意力机制 在传统的CNN中&#xff0c;都是对感受野内部的事情进行关联后理解。 感受野实际上关乎了模型对全局信息的理解。 而本质上&#xff0c;感受野是一种特殊的注意力机制&#xff0c;也就是说感受野是一种受限的、具有特定参数的注意力。 之前的内容如DANet&#…

基于webpack开发vue-cli

一、vue-cli开发 1. 项目整体目录 2. package.json {"name": "vue-cli","version": "1.0.0","description": "","main": "index.js","scripts": {"start": "npm …

机器学习常识 23: U-Net

摘要: U-Net 集编码-解码于一体, 是一种常见的网络架构. 图 1. U-Net 例. 如图 1 所示, U-Net 就是 U 形状的网络, 前半部分 (左边) 进行编码, 后半部分 (右边) 进行解码. 编码部分, 将一个图像经过特征提取, 变成一个向量. 前面说过: 深度学习本质上只做件事情, 就是特征提取…

【ESXi 7.x/8.x】ESXi 配置备份与还原

目录 1. 使用 ESXi命令行备份数据&#xff08;1&#xff09;将已更改的配置与持久存储同步&#xff08;2&#xff09;备份 ESXi 主机的配置数据&#xff08;3&#xff09;下载配置文件通过浏览器下载配置文件通过wget命令下载 &#xff08;4&#xff09;注意事项 2. 还原 ESXi …

基于Java班主任助理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

一直报错npm ERR! cb() never called!删除缓存仍然不行

看到npm下载包出错, 通常我们会手动删除node-modules这个文件夹来解决. 但是往往现实很骨感, 然后我们会找网上各种方法来解决, 比如这篇文章 但是当所有方法都尝试了一遍, 仍然还是出错, 这到底是什么原因呢? 可以使用npm config ls 查看一下我们电脑上是否会有一份.npmrc…

前端Vue自定义顶部搜索框 热门搜索 历史搜索 用于搜索跳转使用

前端Vue自定义顶部搜索框 热门搜索 历史搜索 用于搜索跳转使用&#xff0c; 下载完整代码请访问uni-app插件市场地址&#xff1a;https://ext.dcloud.net.cn/plugin?id13128 效果图如下&#xff1a; #### 自定义顶部搜索框 用于搜索跳转使用方法 使用方法 <!-- 自定义顶…

【MySQL新手入门系列四】:手把手教你MySQL数据查询由入门到学徒

SQL语言是与数据库交互的机制&#xff0c;是关系型数据库的标准语言。SQL语言可以用于创建、修改和查询关系数据库。SQL的SELECT语句是最重要的命令之一&#xff0c;用于从指定表中查询数据。在此博客中&#xff0c;我们将进一步了解SELECT语句以及WHERE子句以及它们的重要性。…