stm32sd卡读写_stm32f103c8t6能干嘛

stm32sd卡读写_stm32f103c8t6能干嘛Stm32f103+RC522实现读卡写卡功能

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

 本篇文章内容总结下来就是

  1. 读卡            使用默认密码读卡所有扇区所有块的数据
  2. 写ID            使用默认密码读取卡一的0扇区的第一块数据并写入到卡二的0扇区的第一块里
  3. 密码读卡     不同厂家的初始密码不同,整理了一些默认密码,如果有收集到新的也可以补充进去
  4. 写全卡        使用默认密码读取卡一的全部扇区全部块数据并写入到卡二的全部扇区的全部块里

感谢@Khanivore!指出寻卡方法有参数没有写定义

目录

从来不按套路出牌的我

一.前期准备

STM32f103c8t6开发板

 Keil5编译器

串口工具

我就问你们什么叫专业

二.代码

简介RC522

代码功能

代码

总结

三.源码



从来不按套路出牌的我

没用的前言,看干货跳过这段

想必看到这篇文章的人都是已经翻阅了大量的文章资料,已经厌倦了那种通篇都是百度百科,通篇都是复制官方资料,通篇都是怎样点亮led灯的没有多少营养的文章

本篇文章除了插科打诨与耐人寻味的笑点之外尽可能的把干货提供给大家学习,我在学习RC522时大量的时间都花在查找资料上了,真正的编程时间可能只有找资料的三分之一,所以为了不让同样抱有学习热情的人因为找不到合适的资料而失去耐心最终失去学习的热情,我准备把我整理的干货拿出来与大家分享

没错,不务正业的我又回来了,这回是玩一玩Stm32单片机

当然也是从基础的C语言开始学习,大概自学了小半个月的C语言就开始上手Stm32了

自学是在B站看的视频,一边写笔记一边敲代码,好在有java的基础,不然我就和这行无缘了

好了废话不多说直接干货

一.前期准备

  1. Stm32f103c8t6开发板 1块
  2. RC522 1杯
  3. 杜邦线 适量
  4. 轻触开关 3g
  5. led灯  根据个人喜好添加
  6. ST-LINK V2 一根 也可以使用 CH340替代(根据个人喜好调整)
  7. 一台计算机 低于30吨的
  8. Keil5编译器 1千克
  9. 串口烧录程序 1匙
  10. 串口调试程序 1伊普西龙
  11. M1 CUID卡 2开尔文

 

STM32f103c8t6开发板

stm32sd卡读写_stm32f103c8t6能干嘛

 

RC522模块

stm32sd卡读写_stm32f103c8t6能干嘛

RC522相关资料:

链接: https://pan.baidu.com/s/1Qob5o4tv0_gBXrRk6AvLSQ

提取码: fkjt 

 

接线图

每个人接线的引脚不同,我这里是因为接入了其他无关紧要的模块才分开接线,不影响单独RC522连接STM32

RC522接线
RC522_RST  ======  GPIOA_Pin_0
RC522_MISO ======  GPIOA_Pin_1
RC522_MOSI ======  GPIOA_Pin_2  
RC522_SCK  ======  GPIOA_Pin_3  
RC522_SDA(NSS) ==  GPIOA_Pin_4
       GND ======  GND  
       ACC ======  ACC

按钮接线
KEY1_ACC === GPIOB_Pin_0
KEY2_ACC === GPIOB_Pin_1
     GND === GND

灯接线(也可以使用板载灯,这里使用板载灯)

LED5_ACC === GPIOA_Pin_5 //模式灯 在选择模式时用于显示当前模式用
LED6_ACC === GPIOA_Pin_6 //确认灯 在识别到卡1时会亮起提示换卡
    GND === GND

 我用最强画图工具<画图>绘制的接线图

 stm32sd卡读写_stm32f103c8t6能干嘛

 

 Keil5编译器

Keil5编译器

链接: https://pan.baidu.com/s/10jR0g10jxdosawc49IOazQ

提取码: uizh

Keil5开发环境

自己收集整理并添加一些自己常用的方法的Stm32f103c8t6开发环境,解压即用

Keil5开发环境

链接: https://pan.baidu.com/s/1U5sOv9lvs3wwKkisiAFYAA

提取码: z1ih 

串口工具

串口调试程序 串口烧录程序

链接: https://pan.baidu.com/s/11VCAXnfmO1FCQQVjirIkrQ

提取码: h1uz

失效私信我


我就问你们什么叫专业

stm32sd卡读写_stm32f103c8t6能干嘛

硬件配置,开发环境详细到这个地步,初学者能够直接上手学习

这就是专业

这就是一条龙服务,以后你们给其他人分享这篇文章时都可以说被一条龙服务过

二.代码

简介RC522

 

stm32sd卡读写_stm32f103c8t6能干嘛

官方文档一共有109页接下来都是复制这个文档所以大家可以走了[dog]

我就简单总结一下白话文:

1.RC522能读卡

2.RC522能写卡

3.RC522能… 就这样,就是能读卡能写卡,我们要它的功能也就是读卡写卡,我没必要为了实现一个读卡功能把这一百多也的文档看完,也没有必要为了实现一个功能就把它的原理全部吃透

介绍完毕

代码功能

  1. 读卡            使用默认密码读卡所有扇区所有块的数据
  2. 写ID            使用默认密码读取卡一的0扇区的第一块数据并写入到卡二的0扇区的第一块里
  3. 密码读卡     不同厂家初始密码不同,整理了一些初始密码,如果有收集到新的也可以补充进去
  4. 写全卡        使用默认密码读取卡一的全部扇区全部块数据并写入到卡二的全部扇区的全部块里

怎么样,干不干,全是干货,没有废话

1.读卡效果图

这是一张CUID白卡,一会复制可以用作对比

有人会问扇区啥意思 区块啥意思,这个就百度去吧好多文章在讲RC522或者复制卡的文章都会用很大篇幅讲什么是卡什么是扇区什么是区块什么是密码段,之后文章就结束了也不说怎么读怎么写怎么复制,最后来一句未完待续或者下一篇文章再详细的写,之后尸沉东京湾留下一段佳话,在这里因为我是旱鸭子就不写了

SQ代表扇区 0~15扇区

QK代表区块 0~3区块

stm32sd卡读写_stm32f103c8t6能干嘛

 

2.写ID效果图

这是一张目标卡,我们要将这张卡的0扇区的0块数据写到上面那张空白卡中

进行写操作 放上卡1=> 读取卡1=> 识别到卡1后打印卡唯一id,并提示可进行复制=> 放上卡2=> 写入卡2

1.读取卡1

stm32sd卡读写_stm32f103c8t6能干嘛

 

stm32sd卡读写_stm32f103c8t6能干嘛

读取卡2

stm32sd卡读写_stm32f103c8t6能干嘛

 已经写到卡2中了

3.密码读卡

每个扇区的3号区块存储的就是该扇区的密码,只有读取时携带相同的密码才能看到并修改该扇区的数据,如果没有密码都不会读到该扇区

因为厂家为了卡片的数据安全各厂会定义自己的读卡密码

个人收集了一部分密码分享一下

unsigned char KEY[14][6]={
													{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
													{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
													{0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5},
													{0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5},
													{0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
													{0x4D, 0x3A, 0x99, 0xC3, 0x51, 0xDD},
													{0x1A, 0x98, 0x2C, 0x7E, 0x45, 0x9A},
													{0x71, 0x4C, 0x5C, 0x88, 0x6E, 0x97},
													{0x58, 0x7E, 0xE5, 0xF9, 0x35, 0x0F},
													{0xA0, 0x47, 0x8C, 0xC3, 0x90, 0x91},
													{0x53, 0x3C, 0xB6, 0xC7, 0x23, 0xf6},
													{0x8F, 0xD0, 0xA4, 0xF2, 0x56, 0xE9},
													{0x66, 0x55, 0x44, 0x11, 0x22, 0x33},
													{0x66, 0x55, 0x44, 0x33, 0x22, 0x11}
};

 

4.写全卡效果

效果就是两张一模一样的卡

代码

磨叽了半天终于到了重点

代码里出现的 if(EN) if(CN) if(OLED) 代表是否打印对应语言,

EN 代表打印英文

CN 代表打印中文

OLED 代表在屏幕显示(因为接入一块OLED屏幕)

寻卡

要点:每次对卡进行操作时调用,两个方法一模一样,就是第二种去掉了打印

验证卡片信息,防冲撞,选卡


//感谢Khanivore!指出有连个变量没有声明
unsigned char TagType[2];
unsigned char SelectedSnr[4];



//				
//						寻卡方法
//					
	
char Pcdmain(){
		u8 status;
	  u8 ID_num[9];
		u8 *ID;	//卡号
		status= PcdRequest(REQ_ALL,TagType);//寻卡
			if(!status){
			status = PcdAnticoll(SelectedSnr);//防冲撞	
				if(!status){
				status=PcdSelect(SelectedSnr);//选卡
					if(!status){
						if(EN)printf("Read the success !! \r\n");
						if(CN)printf("寻找卡片成功 !! \r\n");
						if(OLED)GUI_ShowString(0,16,"1",16,1);
						
						ID = Card_ID(SelectedSnr,ID_num); //获取卡ID
						
						if(EN)printf("ID:%s !! \r\n",ID_num);
						if(CN)printf("卡号:%s !! \r\n",ID_num);
						if(OLED)GUI_ShowString(16,16,"ID:",16,1);
						if(OLED)GUI_ShowString(40,16,ID,16,1);
						return status;
					}else{
					if(EN)printf("The selected card \r\n");
					if(CN)printf("卡片未找到 \r\n");
					if(OLED)GUI_ShowString(0,16,"2",16,1);
					return status;
					}
				}else{
				if(EN)printf("Anti-collision \r\n");
				if(CN)printf("卡片冲突 \r\n");
				if(OLED)GUI_ShowString(0,16,"3",16,1);
				return status;
				}
			}else{
			if(EN)printf("Looking for failure \r\n");
			if(CN)printf("卡片未找到 \r\n");
			if(OLED)GUI_ShowString(0,16,"4",16,1);
			return status;
			}
		}



//				
//						寻卡方法
//					
	
char Pcdmain_3(){
		u8 status;
		status= PcdRequest(REQ_ALL,TagType);//寻卡
			if(!status){
			status = PcdAnticoll(SelectedSnr);//防冲撞	
				if(!status){
				status=PcdSelect(SelectedSnr);//选卡
					if(!status){
						return status;
					}else{
					return status;
					}
				}else{
				return status;
				}
			}else{
			return status;
			}
		}

 

读卡

要点:密码密码密码 如果密码不对那就结束了,初始密码需要在成员变量中定义


//				
//					notarize = 1 读卡
//					
		

unsigned char  DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //默认密码 	

void  notarize_type1(){
		u8 status;
		u8 section=0;
		u8 block = 0;
		unsigned char block_value[16];
	
		u8 i=0;
		status = Pcdmain();
			if(!status){
				if(EN)printf("function NO1 Read the card ...\r\n");
				if(CN)printf("功能1 读取卡片 \r\n");
				if(OLED)GUI_ShowString(48,0,"NO_1",16,1);
						for( section = 0 ; section <16 ; section++ ){
								status = PcdAuthState(KEYA, (section*4+3), DefaultKey, SelectedSnr);// 校验1扇区密码,密码位于每一扇区第3块
							if(!status)
								{		
									for(block = 0; block< 4 ; block++){
										status = PcdRead((section*4+block), block_value);  // 读卡,读取1扇区0块数据到buf[0]-buf[16] 
										if(EN)printf("SQ:%d , QK:%d     ",section,block);
											if(EN)printf("passA	");
											for (i = 0 ; i<6; i++)
											{
											if(EN)printf("%X ",block_value[i]);
											}
											if(EN)printf("		Value	");
											for (i = 6; i<10; i++)
											{
											if(EN)printf("%X ",block_value[i]);
											}
											if(EN)printf("		passB	");
											for (i = 10; i<16; i++)
											{    
											if(EN)printf("%X ",block_value[i]);
											}
											if(EN)printf("\r\n");
									}
								}else {
									if(EN)printf("wrong password \r\n");
									if(CN)printf("密码错误 \r\n");
									if(OLED)GUI_ShowString(0,16,"5",16,1);
								}
							}
							if(EN)printf("\r\n");
							if(EN)printf("\r\n");
							if(EN)printf("\r\n");
				
				
				
			}else{
				if(EN)printf("Looking for failure \r\n");
				if(CN)printf("卡片未找到 \r\n");
				if(OLED)GUI_ShowString(0,16,"4",16,1);
			}
	}

 

复制ID

ID的重要性就不用我多说了,因为通常的ID卡扇区0是出厂就定义好的ID不能再修改,所以也是唯一性的保障,大多数的系统也只会记录ID作为验证使用

而除了0扇区之外的扇区多为详细信息存储使用,如取电卡的电量值,水卡的水量值,饭卡的余额之类,因为这部分可以读写所以密码会与出厂密码不同


//				
//					notarize = 2 复制卡id
//					
		
	void  notarize_type2(){
		u8 status;
		u8 test_status = 0; //id在0扇区 , 测试使用其他扇区
		u8 block_num=0;
		u8 copy_tf = 1;
		unsigned char copy_value[16];
		status = Pcdmain_3();
			if(!status){
				if(EN)printf("function NO1 Read the card ...\r\n");
				if(CN)printf("功能2 复制卡片 \r\n");
				if(OLED)GUI_ShowString(48,0,"NO_2",16,1);
				
				//读取并复制卡1 指定扇区指定块数据
				
				status = PcdAuthState(KEYA, (test_status*4+3), DefaultKey, SelectedSnr);// 校验1扇区密码,密码位于每一扇区第3块	DefaultKey为默认密码
						if(!status)
							{	
									status = PcdRead((test_status*4+0), copy_value);  // 读卡,读取1扇区0块数据到buf[0]-buf[16]
										if(!status)
										{
											if(EN)printf("COPY: SQ:%d , QK:%d     ",test_status,0);
											if(EN)printf("passA	");
											for (block_num = 0; block_num<6; block_num++)
											{    
											if(EN)printf("%X ",copy_value[block_num]);
											}
											if(EN)printf("		Value	");
											for (block_num = 6; block_num<10; block_num++)
											{    
											if(EN)printf("%X ",copy_value[block_num]);
											}
											if(EN)printf("		passB	");
											for (block_num = 10; block_num<16; block_num++)
											{    
											if(EN)printf("%X ",copy_value[block_num]);
											}
										
											if(EN)printf("\r\n");
											}
									if(EN)printf("Read over \r\n");
									if(CN)printf("复制成功 替换目标卡片 \r\n");
									delay_ms(500);		
									if(OLED)GUI_ShowString(0,16,"COPY OK, CARD_2",16,1);				
											
											//读取第二张卡片
											do{
																LED6S;   	//PC13输出低电平
																//delay_ms(200);
																//LED6S;				//PC13输出高电平
												
												
												if(KEY1==0){
												status = Pcdmain_3();
													if(!status){
														if(EN)printf("Ready to write card 2 ...\r\n");
														if(CN)printf("写卡2\r\n");
														if(OLED)GUI_ShowString(0,0,"CARD2...",16,1);
															status = PcdAuthState(KEYA, (test_status*4+3), DefaultKey, SelectedSnr);// 校验1扇区密码,密码位于每一扇区第3块	
																if(!status){
																	status = PcdWrite((test_status*4+0), copy_value);  // 写卡,将buf[0]-buf[16]写入1扇区0块
																	if(!status){
																			
																		
																			LED6R;				//PC13输出高电平
																			delay_ms(20);
																			LED6S;   	//PC13输出低电平
																			delay_ms(20);
																			LED6R;				//PC13输出高电平
																			delay_ms(20);
																			LED6S;   	//PC13输出低电平
																			delay_ms(20);
																			LED6R;				//PC13输出高电平
																		
																			if(EN)printf("Copy success (*^▽^*) \r\n");
																			if(CN)printf("写入成功 (*^▽^*) \r\n");
																			if(OLED)GUI_ShowString(0,16,"Copy SUCC (*^▽^*)",16,1);
																		}else{
																			if(EN)printf("Copy the failure (╯‵□′)╯︵┻━┻ \r\n");
																			if(CN)printf("复制失败	 (╯‵□′)╯︵┻━┻  \r\n");
																			if(OLED)GUI_ShowString(0,16,"Copy the failure",16,1);
																		}
																	}else{
																		if(EN)printf("card 2 wrong password \r\n");
																		if(CN)printf("卡2密码错误 \r\n");
																		if(OLED)GUI_ShowString(0,16,"card 2 PASS WRONG",16,1);	
																	}
																	LED6R;				//PC13输出高电平
													}else{
														if(EN)printf("Looking for failure \r\n");
														if(CN)printf("卡片2未找到 \r\n");
														if(OLED)GUI_ShowString(0,16,"4",16,1);
														LED6R;				//PC13输出高电平
													}
													LED6R;				//PC13输出高电平
													copy_tf = 0;
												}
											}while(copy_tf);
											
											
											
											
								}else{
									if(EN)printf("wrong password \r\n");
									if(CN)printf("密码错误 \r\n");
									if(OLED)GUI_ShowString(0,16,"5",16,1);	
								}

			}else{
				if(EN)printf("Looking for failure \r\n");
				if(CN)printf("卡片未找到 \r\n");
				if(OLED)GUI_ShowString(0,16,"4",16,1);
			}
	}

 

密码测试

测试每个扇区的第3区块密码,当然幸运的话就是初始密码,点背的话也没关系只需要255*255*255*255*255*255 = 274,941,996,890,625次尝试也可以得到密码


//				
//					notarize = 3 常规密码测试
//					
		
		void  notarize_type3(){
		u8 status;
		u8 section=0;
		u8 block_num=0;
		u8 KEY_num = 0 ;
		unsigned char block_value[16];
	
		u8 i=0;
		status = Pcdmain_3();
			if(!status){
				if(EN)printf("function NO3 Password test ...\r\n");
				if(CN)printf("功能3 常规密码测试 \r\n");
				if(OLED)GUI_ShowString(48,0,"NO_3",16,1);
						for( section = 0 ; section <16 ; section++ ){
					for( KEY_num =0 ; KEY_num < 13 ; KEY_num++){
								status = Pcdmain_3();
						if(!status){
								//printf("section:%d  KEY:%d %d %d %d %d %d   ",section,KEY[KEY_num][0],KEY[KEY_num][1],KEY[KEY_num][2],KEY[KEY_num][3],KEY[KEY_num][4],KEY[KEY_num][5]);
								status = PcdAuthState(KEYA, (section*4+3), KEY[KEY_num], SelectedSnr);// 校验1扇区密码,密码位于每一扇区第3块
							if(!status)
								{
									status = 1;
									//for(block_num = 0; block_num< 4 ; block_num++){
										
										status = PcdRead((section*4+3), block_value);  // 读卡,读取1扇区0块数据到buf[0]-buf[16] 
										if(EN)printf("SQ:%d , QK:%d  KEY:%X %X %X %X %X %X   ",section,3,KEY[KEY_num][0],KEY[KEY_num][1],KEY[KEY_num][2],KEY[KEY_num][3],KEY[KEY_num][4],KEY[KEY_num][5]);
											if(EN)printf("passA	");
											for (i = 0 ; i<6; i++)
											{ 
											if(EN)printf("%X ",block_value[i]);
											}
											if(EN)printf("		Value	");
											for (i = 6; i<10; i++)
											{    
											if(EN)printf("%X ",block_value[i]);
											}
											if(EN)printf("		passB	");
											for (i = 10; i<16; i++)
											{    
											if(EN)printf("%X ",block_value[i]);
											}
											if(EN)printf("\r\n");
											
									//}	
									
									
									
								}else {
									
								}
							}
							status = 1;
						}
					}
							if(EN)printf("\r\n");
							if(EN)printf("\r\n");
							if(EN)printf("\r\n");
						
			}else{
				if(EN)printf("Looking for failure \r\n");
				if(CN)printf("卡片未找到 \r\n");
				if(OLED)GUI_ShowString(0,16,"4",16,1);
			}
	}

复制全卡

由于全卡每个扇区的密码不同所以复制全卡用处不大


//				
//					notarize = 4 复制全卡
//					
		
		void  notarize_type4(){
		u8 status;
		u8 section=0;
		u8 block = 0;
		u8 block_num=0;
		u8 copy_tf = 1;
		unsigned char block_value[16];
		unsigned char copy_value[16][3][16];
	
		status = Pcdmain_3();
			if(!status){
				if(EN)printf("function NO1 Read the card ...\r\n");
				if(CN)printf("功能1 读取卡片 \r\n");
				if(OLED)GUI_ShowString(48,0,"NO_4",16,1);
					for( section = 0; section <16 ; section++ ){
								status = PcdAuthState(KEYA, (section*4+3), DefaultKey, SelectedSnr);// 校验1扇区密码,密码位于每一扇区第3块
								if(!status)
								{	
									for(block = 0; block< 3 ; block++){
										status = PcdRead((section*4+block), block_value);  // 读卡,读取1扇区0块数据到buf[0]-buf[16] 
										for( block_num = 0; block_num < 16 ; block_num++){
											copy_value[section][block][block_num] = block_value[block_num];
										}
										}
								}
							}
							
											if(EN)printf("\r\n");
											if(EN)printf("\r\n");
											if(EN)printf("\r\n");
											if(EN)printf("\r\n");
							
							for(section = 0 ; section < 16 ; section++){
									for(block = 0 ; block < 3 ; block++){
											//for(block_num = 0 ; block_num < 16 ; block_num++){
											if(EN)printf("SQ:%d , QK:%d     ",section,block);
											if(EN)printf("passA	");
											for (block_num = 0; block_num<6; block_num++)
											{    
											if(EN)printf("%X ",copy_value[section][block][block_num]);
											}
											if(EN)printf("		Value	");
											for (block_num = 6; block_num<10; block_num++)
											{    
											if(EN)printf("%X ",copy_value[section][block][block_num]);
											}
											if(EN)printf("		passB	");
											for (block_num = 10; block_num<16; block_num++)
											{    
											if(EN)printf("%X ",copy_value[section][block][block_num]);
											}
											
											if(EN)printf("\r\n");
										

							//}
							}
										if(EN)printf("\r\n");
							}
											if(EN)printf("\r\n");
											if(EN)printf("\r\n");
											if(EN)printf("\r\n");
							
							
									if(EN)printf("Read over \r\n");
									if(CN)printf("复制成功 替换目标卡片 \r\n");
									if(OLED)GUI_ShowString(0,16,"COPY OK, CARD_2",16,1);				
											
											//读取第二张卡片
											do{
												if(KEY1==0){
												status = Pcdmain_3();
													if(!status){
														if(EN)printf("Ready to write card 2 ...\r\n");
														if(CN)printf("写卡2\r\n");
														if(OLED)GUI_ShowString(0,0,"CARD2...",16,1);
																for(section = 0 ; section < 16 ; section++){
																		//status = Pcdmain_3();
																		//if(!status){
																			status = PcdAuthState(KEYA, (section*4+3), DefaultKey, SelectedSnr);// 校验1扇区密码,密码位于每一扇区第3块	
																			if(!status){
																			for(block = 0 ; block < 3 ; block++){
																				//status = PcdWrite((section*4+block), copy_value[section][block]);  // 写卡,将buf[0]-buf[16]写入1扇区0块
																				//status = PcdWrite((section*4+block), zero);  // 写卡,将buf[0]-buf[16]写入1扇区0块
																				status = PcdWrite((4*4+3), setkey);  // 写卡,将buf[0]-buf[16]写入1扇区0块
																				
																				if(EN)printf("SQ:%d , QK:%d     ",section,block);
																				if(EN)printf("passA	");
																				for (block_num = 0; block_num<6; block_num++)
																				{    
																				if(EN)printf("%X ",copy_value[section][block][block_num]);
																				}
																				if(EN)printf("		Value	");
																				for (block_num = 6; block_num<10; block_num++)
																				{    
																				if(EN)printf("%X ",copy_value[section][block][block_num]);
																				}
																				if(EN)printf("		passB	");
																				for (block_num = 10; block_num<16; block_num++)
																				{    
																				if(EN)printf("%X ",copy_value[section][block][block_num]);
																				}
																				
																				if(EN)printf("\r\n");
																				
																			if(!status){
																				if(EN)printf("SQ:%d , QK:%d     Copy success (*^▽^*) \r\n",section,block);
																				if(CN)printf("SQ:%d , QK:%d     写入成功 (*^▽^*) \r\n",section,block);
																				if(OLED)GUI_ShowString(0,16,"Copy SUCC ",16,1);
																			}else{
																				if(EN)printf("SQ:%d , QK:%d     Copy the failure (* ̄︿ ̄) \r\n",section,block);
																				if(CN)printf("SQ:%d , QK:%d     复制失败    (* ̄︿ ̄) \r\n",section,block);
																				if(OLED)GUI_ShowString(0,16,"Copy the failure",16,1);
																			}
																				if(CN)printf("SQ:%d , QK:%d (*^▽^*) \r\n",section,block);
																			}
																		}else{
																		if(EN)printf("card 2 wrong password \r\n");
																		if(CN)printf("卡2密码错误 \r\n");
																		if(OLED)GUI_ShowString(0,16,"5",16,1);	
																	}		
														}	
													}else{
														if(EN)printf("Looking for failure \r\n");
														if(CN)printf("卡片2未找到 \r\n");
														if(OLED)GUI_ShowString(0,16,"4",16,1);
													}
													copy_tf = 0;
												}
											}while(copy_tf);	
			}else{
				if(EN)printf("Looking for failure \r\n");
				if(CN)printf("卡片未找到 \r\n");
				if(OLED)GUI_ShowString(0,16,"4",16,1);
			}
	}

总结

 最后显摆一下我的手工

stm32sd卡读写_stm32f103c8t6能干嘛

这篇文章写一半的时候就停了下来,在草稿中存了小半年,最后在年末穿上秋裤的时候想了想还是补全发出来吧

让我写文章的动力是因为C语言可以对这类单片机进行编程,进而读取环境数据,简单的温湿度模块,人体红外感应模块,触摸模块,光敏模块等等

而这与网络爬虫的作用很相似,一个是获取网络信息的自动程序,一个是获取现实世界信息的自动程序,这也是我为什么写爬虫写着写着就学起C的原因

当然爬虫这方面也在找一些有趣有挑战的网站,如果有人能分享有挑战的项目我也会尝试的

 

三.源码

stm32sd卡读写_stm32f103c8t6能干嘛

 

闲聊到这里,想要源码的两种途径

1.积分下载 链接我会放上来

https://download.csdn.net/download/qq_41873771/13992549

由于有部分人不尊重我的劳动成果,写了分享条件不遵守,依然私信直接发邮箱,现博客整顿所有资源取消积分下载,如有需要请私信说明缘由小问题我会直接解答,需要源码需要和我聊天,只要私信我的不管任何形式只要出现邮箱直接屏蔽拉黑

2.私信我 陪我聊聊天好么 秋梨膏

 

那么终于能完结这篇文章了,主要是我太懒,没有什么动力能刺激到我创作

预告一下,下次我要做……等一下有人敲门  我去看看……

 

 

 

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/191736.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • JVM架构和GC垃圾回收机制(JVM面试不用愁)[通俗易懂]

    JVM架构和GC垃圾回收机制(JVM面试不用愁)[通俗易懂]JVM架构和GC垃圾回收机制详解JVM架构图分析下图:参考网络+书籍,如有侵权请见谅(想了解Hadoop内存溢出请看:Hadoop内存溢出(OOM)分类、参数调优化)JVM被分为三个主要的子系统(1)类加载器子系统(2)运行时数据区(3)执行引擎1.类加载器子系统Java的动态类加载功能是由类加载器子系统处理。当它在运行时(不是编译时)首次引用一个类时,它加载、链…

  • JVM原理最全、清晰、通俗讲解,五天40小时吐血整理

    JVM原理最全、清晰、通俗讲解,五天40小时吐血整理JVM原理最全、清晰、通俗讲解,五天40小时吐血整理

  • 鱼眼镜头的成像原理到畸变矫正(完整版)

    鱼眼镜头的成像原理到畸变矫正(完整版)  最近刚接触鱼眼相机,发现网上资料还是比较零散的,于是把搜罗到的资料汇总梳理了一下(我不生产知识,我只是知识的搬运工耶嘿)。摄影入门之相机镜头的分类鱼眼镜头是怎么「鱼眼」的?1.什么是鱼眼镜头1.1镜头分类 镜头类型 特征描述 变焦镜头 在一定范围内可以变换焦距、从而得到不同宽窄的视场角,不同大小的影象和不同景物范围的照相机镜头。 定焦镜头 标准镜头 视角在40°~45°之间,焦距长度与底片对角线长度基本相等。

    2022年10月31日
  • 修改firefox地址栏的颜色

    修改firefox地址栏的颜色

  • One Piece1-541(ed2k)[通俗易懂]

    One Piece1-541(ed2k)[通俗易懂]1-143http://www.VeryCD.com/topics/143292/144-228http://www.VeryCD.com/topics/17082/229-325http://www.VeryCD.com/topics/39594/326-384http://www.VeryCD.com/topics/198051/385-458ht

    2022年10月19日
  • Unity3d场景快速烘焙【2020】

    Unity3d场景快速烘焙【2020】很多刚刚接触Unity3d的童鞋花了大量的时间自学,可总是把握不好Unity3d的烘焙,刚从一个坑里爬出来,又陷入另一个新的坑,每次烘焙一个场景少则几个小时,多则几十个小时,机器总是处于假死机状态,半天看不到结果,好不容易烘焙完了,黑斑、撕裂、硬边、漏光或漏阴影等缺陷遍布,惨不忍睹,整体效果暗无层次,或者苍白无力,灯光该亮的亮不起来,该暗的暗不下去,更谈不上有什么意境,痛苦的折磨,近乎失去了信心,一个团队从建模到程序,都没什么问题,可一到烘焙这一关,就堵得心塞,怎么也搞不出好的视觉效果,作品没法及时向用户交

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号