2005-10-20 17:33:00 nesert 阅读数 1204
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4003 人正在学习 去看看 朱有鹏
目前正在写一个51系列单片机的模拟器,会陆续写一些开发过程及进展情况。。。
2014-09-27 17:15:23 sparkstrike 阅读数 4684
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4003 人正在学习 去看看 朱有鹏

单片机:STC12C5A60S2 晶振:24MHZ

51单片机读sd卡资料:http://download.csdn.net/detail/sparkstrike/7982195

sd卡引脚



一.IO接口

sbit CLK = P3^4;//同步时钟
sbit DI = P3^5;//Cmd/DataIn
sbit DO = P3^6;//DataOut
sbit CS = P3^7;//片选



二.模拟SPI

注:spi相关见http://blog.csdn.net/sparkstrike/article/details/39609235

//***********模拟spi写函数
void SPI_W(unsigned char Data){
	unsigned char i;
	for(i = 0; i<8; i++){
		Data <<= 1;
		CLK = 0;
		DI = CY;
		CLK = 1;
	};
	DI = 1;
}

//***********模拟spi读函数
unsigned char SPI_R(){
	unsigned char Data,i;
	DO = 1;//设置DO接口为输入状态
	for(i = 0; i<8; i++){
		Data <<= 1;
		CLK = 0;
		CLK = 1;
		Data |= DO;
	};
	return Data;
}

三.等待SD卡的回应(在写入一些命令后,sd卡会回应一些东西)

//**************读sd卡回应
unsigned char SD_Response(){
	unsigned char i,Response;
	for(i = 0; i<10; i++){
		Response = SPI_R();
		if(Response == 0x00)
			break;
		if(Response == 0x01)
			break;
	};
	return Response;
}


四.向sd卡写入命令

Cmd为命令,命令有复位命令、读命令、写命令等,4位的Arguement为地址,CRC为校验码

//***************向SD发命令
void SD_Cmd(unsigned char Cmd, unsigned long Argument, unsigned char CRC){
	unsigned char arg[4];
	arg[0] = (unsigned char)Argument;
	arg[1] = (unsigned char)(Argument >> 8);
	arg[2] = (unsigned char)(Argument >> 16);
	arg[3] = (unsigned char)(Argument >> 24);

	SPI_W(Cmd | 0x40);
	SPI_W(arg[3]);
	SPI_W(arg[2]);
	SPI_W(arg[1]);
	SPI_W(arg[0]);
	SPI_W(CRC);
}

五.初始化SD卡

SD卡有两种读写模式:SD模式和SPI模式,默认的读写模式为SD模式,单片机用SPI模式比较方便,要使用SPI模式需要在SD卡上电是对它写入CMD0命令和CMD1命令

/*************SD卡初始化,设置SPI模式
unsigned char SD_Init(){
	unsigned int delay = 0;
	unsigned char i;
	unsigned char Response = 0xff;
	
	CS = 1;
	for(i = 0; i<10; i++){
		SPI_W(0xff);//上电后给74个以上的时间脉冲
	};

	CS = 0;
	SD_Cmd(0x00, 0, 0x95);//命令CMD0,复位SD卡

	//等待复位成功
	i = 0;
	while(SD_Response() != 0x01){//等待SD卡回应信号
		i++;
		if(i > 100){
			return 0;//失败返回0
		};
	};

	CS = 1;
	SPI_W(0xff);//关片选后写8个空脉冲,SD卡复位完毕

	//设置SPI
	i = 0;
	CS = 0;
	while(Response != 0x00){//循环等待成功回应,若成功,回应信号为0x00
		SD_Cmd(0x01, 0, 0xff);//CMD1,将SD卡设置为SPI模式,无需CRC校验,填入0xff
		Response = SD_Response();
		if(i > 100){
			return 0;//尝试100次,失败返回0
		};
	};
	CS = 1;

	SPI_W(0xff);//给8个空脉冲
	return 1;
}


六.SD卡读写数据

因为sd卡的读写都是以扇区为单位的,所以这里定义一个全局变量,512表示一个扇区

unsigned int const len = 512;//扇区大小


1.写入数据:

adress为开始写的地址,一定要为512的整数倍,block为一个512字节的数组

//***************SD卡写入数据块
unsigned char SD_Block_W(unsigned char* block, unsigned long address){
	unsigned int i;
	unsigned char Response_Write;
	CS =0;
	SD_Cmd(0x18, address, 0xff);//CMD18,块写入命令
	while(SD_Response() != 0x00);//循环等待命令回应0x00
	for(i = 0; i<10; i++){
		SPI_W(0xff);//写入一定量空脉冲
	};

	SPI_W(0xfe);//0xfe为块头部,后面跟512b字节,+2bCRC(0xff,0xff)

	for(i=0; i<len; i++){
		SPI_W(block[i]);//写入512b字节
	};

	SPI_W(0xff);
	SPI_W(0xff);

	Response_Write = SPI_R()&0x0f;//写入CRC码后SD卡会回应一个xxx0,1001
	while(SPI_R() == 0);//等待SD卡回应

	CS = 1;
	SPI_W(0xff);//写入8个空脉冲

	if(Response_Write == 0x05){
		return 1;
	}else{
		return 0;
	};
}

2.读数据:

adress为开始读的地址,一定要为512的整数倍,block为一个512字节的数组

//****************从sd卡读数据块
void SD_Block_R(unsigned char* block, unsigned long address){
	unsigned int i;

	CS = 0;
	SD_Cmd(0x11, address, 0xff);//CMD11,数据块读写命令,

	while(SD_Response()!=0x00);//循环等待命令回应0x00

	while(SPI_R() != 0xfe); //0xfe为块读出的头, 后面紧跟512字节的数据块+2字节的CRC

	for(i=0; i<len ; i++){
		block[i] = SPI_R();//读数据
	};

	SPI_R();
	SPI_R();//两个字节的CRC。舍弃

	CS =1;
	SPI_R();//8个空脉冲
}

附:测试程序(程序从SD卡512000处写入512字节的数据,并读出)

/*********************************************************************************************/


#include <STC12C5A60S2.H> //单片机头文件

sbit CLK = P3^4;//同步时钟
sbit DI = P3^5;//Cmd/DataIn
sbit DO = P3^6;//DataOut
sbit CS = P3^7;//片选

unsigned int const len = 512;//扇区大小

void DELAY_MS (unsigned int a){
	unsigned int i;
	while( --a != 0){
		for(i = 0; i < 600; i++);
	}
}



//***********模拟spi写函数
void SPI_W(unsigned char Data){
	unsigned char i;
	for(i = 0; i<8; i++){
		Data <<= 1;
		CLK = 0;
		DI = CY;
		CLK = 1;
	};
	DI = 1;
}

//***********模拟spi读函数
unsigned char SPI_R(){
	unsigned char Data,i;
	DO = 1;//设置DO接口为输入状态
	for(i = 0; i<8; i++){
		Data <<= 1;
		CLK = 0;
		CLK = 1;
		Data |= DO;
	};
	return Data;
}


//**************读sd卡回应
unsigned char SD_Response(){
	unsigned char i,Response;
	for(i = 0; i<10; i++){
		Response = SPI_R();
		if(Response == 0x00)
			break;
		if(Response == 0x01)
			break;
	};
	return Response;
}


//***************向SD发命令
void SD_Cmd(unsigned char Cmd, unsigned long Argument, unsigned char CRC){
	unsigned char arg[4];
	arg[0] = (unsigned char)Argument;
	arg[1] = (unsigned char)(Argument >> 8);
	arg[2] = (unsigned char)(Argument >> 16);
	arg[3] = (unsigned char)(Argument >> 24);

	SPI_W(Cmd | 0x40);
	SPI_W(arg[3]);
	SPI_W(arg[2]);
	SPI_W(arg[1]);
	SPI_W(arg[0]);
	SPI_W(CRC);
}



//*************SD卡初始化
unsigned char SD_Init(){
	unsigned int delay = 0;
	unsigned char i;
	unsigned char Response = 0xff;
	
	CS = 1;
	for(i = 0; i<10; i++){
		SPI_W(0xff);//上电后给74个以上的时间脉冲
	};

	CS = 0;
	SD_Cmd(0x00, 0, 0x95);//命令CMD0,复位SD卡

	//等待复位成功
	i = 0;
	while(SD_Response() != 0x01){//等待SD卡回应信号
		i++;
		if(i > 100){
			return 0;//失败返回0
		};
	};

	CS = 1;
	SPI_W(0xff);//关片选后写8个空脉冲,SD卡复位完毕

	//设置SPI
	i = 0;
	CS = 0;
	while(Response != 0x00){//循环等待成功回应,若成功,回应信号为0x00
		SD_Cmd(0x01, 0, 0xff);//CMD1,将SD卡设置为SPI模式,无需CRC校验,填入0xff
		Response = SD_Response();
		if(i > 100){
			return 0;//尝试100次,失败返回0
		};
	};
	CS = 1;

	SPI_W(0xff);//给8个空脉冲
	return 1;
}


//***************SD卡写入数据块
unsigned char SD_Block_W(unsigned char* block, unsigned long address){
	unsigned int i;
	unsigned char Response_Write;
	CS =0;
	SD_Cmd(0x18, address, 0xff);//CMD18,块写入命令
	while(SD_Response() != 0x00);//循环等待命令回应0x00
	for(i = 0; i<10; i++){
		SPI_W(0xff);//写入一定量空脉冲
	};

	SPI_W(0xfe);//0xfe为块头部,后面跟512b字节,+2bCRC(0xff,0xff)

	for(i=0; i<len; i++){
		SPI_W(block[i]);//写入512b字节
	};

	SPI_W(0xff);
	SPI_W(0xff);

	Response_Write = SPI_R()&0x0f;//写入CRC码后SD卡会回应一个xxx0,1001
	while(SPI_R() == 0);//等待SD卡回应

	CS = 1;
	SPI_W(0xff);//写入8个空脉冲

	if(Response_Write == 0x05){
		return 1;
	}else{
		return 0;
	};
}

//****************从sd卡读数据块
void SD_Block_R(unsigned char* block, unsigned long address){
	unsigned int i;

	CS = 0;
	SD_Cmd(0x11, address, 0xff);//CMD11,数据块读写命令,

	while(SD_Response()!=0x00);//循环等待命令回应0x00

	while(SPI_R() != 0xfe); //0xfe为块读出的头, 后面紧跟512字节的数据块+2字节的CRC

	for(i=0; i<len ; i++){
		block[i] = SPI_R();//读数据
	};

	SPI_R();
	SPI_R();//两个字节的CRC。舍弃

	CS =1;
	SPI_R();//8个空脉冲
}



void main (void){
	unsigned char xdata block[len];
	int i;
	//初始化SD卡
	SD_Init();
	for(i=0;i<512;i++){
		block[i]=0xaa;
	};
	//从512000处写sd卡
	SD_Block_W(block, len*1000);
	//从512000处读sd卡
	SD_Block_R(block, len*1000);
	
}





2018-09-29 16:52:44 u014798590 阅读数 7037
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4003 人正在学习 去看看 朱有鹏

目录
一、单片机读取ID卡(工作原理及电路)
二、单片机读取ID卡(产生载波)
三、单片机读取ID卡(EM41000的数据格式)
四、单片机读取ID卡(硬件调试及读码)

一、非接触卡的读卡原理

本系列文章主要探讨125KHz频段下的ID卡,13.5MHz频段IC卡不在本文探讨范围内。

1、简介
ID卡全称是(Identification Card)是一种只读型的非接触式卡,出厂时,厂家会将ID号写死在芯片内部,不允许进行二次修改,国内常见的ID卡为EM4100、EM4102卡等。

2、读卡流程
读卡器通过持续发射特定频率的射频信号,当ID卡进去其工作范围内时,将产生感应电流(想象变压器),ID卡得电后,将自身芯片内的编码信息通过天线发送出去;读卡器接收到从标签发送来的调制信号,经过解调后,得到ID卡的编码信息。

3、工作原理
(1)单片机通过控制 8050(NPN 型)和 8550( PNP 型) 构成了推挽式功率放大电路,再通过LC谐振电路, 产生 125KHz 的读卡驱动信号。

LC谐振电路具有选频能力,它可以将有用的频率成分保留下来,而将无用的频率成分滤除,比如收音机、电视机。收音机的天线会同时接收多个电台发射的不同载波的广播节目,而我们收听时,必须在这众多广播节目中选出我们所要接收的那一套广播节目,这就是选频(选台)。改变谐振电路的谐振频率,使其谐振在所需要接收台的载频上,从而选择出所接收台的广播信号,而滤除掉除此之外的其他台及外来的无用信号,这就完成了选台。

(2)当有 ID 卡靠近读卡器线圈时,谐振把能量感应到 ID 卡内的线圈上, 对卡内的电容进行充电,ID 卡将以此作为电源, 通过负载调制的方法,向读卡器发送信息。原理如下所示。

如果变压器的副边突然接入一个大的负载,变压器原边电压就会瞬间降低,切除负载,变压器的原边电压就会马上恢复。前面说了,射频卡相当于变压器的副边,卡内也有这样一个负载,接通负载时射频场的振荡幅度会减小,切除负载,射频场的幅度会恢复。卡片通过负载是否接入来表示发送的数据,读写器探测到射频场的幅度改变,就能知道卡片发送什么数据了。这就是卡片回送数据的原理。

通过S开关的不断切换,将Rmod电阻不断并联,从而更改负载电阻的大小,当谐振回路两端的电压发生变化时,由于线圈电感耦合,这种变化会传递给读写器,表现为读写器线圈两端电压的振幅发生变化,因此产生对读写器电压的调幅,从而产生包络。
在这里插入图片描述

(3)包络检波:
读卡器内部流程如下图所示。
在这里插入图片描述

由于我们需要在产生的载波上,读取ID卡的编码,这时候调制信号的包络就是曼切斯特码,此时就需要包络检波电路来“提取”对应的曼切斯特码。
包络的相关知识可以看这里

包络:当用一个低频信号对一个高频信号进行幅度调制(即调幅)时,低频信号就成了高频信号的包络线。这样的信号称为调幅信号。 从调幅信号中将低频信号解调出来的过程,就叫做包络检波。

4、电路
(1)推挽式功率放大电路
在这里插入图片描述
(2)LC谐振电路
在这里插入图片描述
(3)包络检波电路
在这里插入图片描述
(4)滤波整形电路
在这里插入图片描述

2013-07-02 11:13:35 tianyi416182362 阅读数 1551
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4003 人正在学习 去看看 朱有鹏

  很早以前编的模拟电梯的51单片机程序

    ORG 0000H

 STOP:ORL  P1,#00H

MOV 30H,#01H

      LCALL DISPLAY

LOOP1:LCALL LOOP

      LCALL  KEY80;外部调用123456

      LJMP  LOOP1

 

KEY80:LCALL LOOP          ;电梯在一楼

D80:  CJNE A,#0EEH,D90    ;判断按键1是否按下

      LJMP KEY1

D90:  CJNE A,#0DEH,D81   

      LCALL U11

      LJMP KEY2

D81:  CJNE A,#0BEH,D82

      LCALL U11

      LJMP KEY2

D82:  CJNE A,#7EH,D83

      LCALL U22

      LJMP KEY3

D83:  CJNE A,#0EDH,D84

      LCALL U22

      LJMP KEY3    

D84:  CJNE A,#0DDH,KEY80

      LCALL U33

      LJMP KEY4

 

KEY50: LCALL LOOP         ; 电梯在二楼

D50:  CJNE A,#0EEH,D91   

      LCALL DN11

      LJMP  KEY1

D91 : CJNE A,#0DEH,D92

      LCALL KEY2

D92:  CJNE A,#0BEH,D51

      LCALL KEY2

D51:  CJNE A,#7EH,D52

      LCALL U11

      LJMP  KEY3

D52:  CJNE A,#0EDH,D53

      LCALL U11

      LJMP  KEY3

D53:  CJNE A,#0DDH,KEY50

      LCALL U22

      LJMP  KEY4

 

KEY60: LCALL LOOP         ; 电梯在三楼

D60:  CJNE A,#0EEH,D61   

      LCALL DN22

      LJMP  KEY1

D61:  CJNE A,#0DEH,D62

      LCALL DN11

      LJMP  KEY2

D62:  CJNE A,#0BEH,D93

      LCALL DN11

      LJMP  KEY2

D93:  CJNE A,#7EH,D94

      LCALL KEY3

D94:  CJNE A,#0EDH,D63

      LCALL KEY3

D63:  CJNE A,#0DDH,KEY60

      LCALL U11

      LJMP  KEY4

 

 

KEY70:LCALL LOOP         ; 电梯在四楼

D70:  CJNE A,#0EEH,D71   

      LCALL DN33

      LJMP  KEY1

D71:  CJNE A,#0DEH,D72

      LCALL DN22

      LJMP  KEY2

D72:  CJNE A,#0BEH,D73

      LCALL DN22

      LJMP  KEY2

D73:  CJNE A,#7EH,D74

      LCALL DN11

      LJMP  KEY3

D74:  CJNE A,#0EDH,D95

      LCALL DN11

      LJMP  KEY3

D95:  CJNE A,#0DDH,KEY70

      LCALL KEY4

 

KEY1: LCALL LOOP         ;从一楼上

D10:  CJNE A,#7DH,D11   

      LCALL U1

      LJMP KEY6

D11:  CJNE A,#0EBH,D12

      LCALL U2

      LJMP KEY7

D12:  CJNE A,#0DBH,KEY1

      LCALL U3

      LJMP KEY8

 

 

KEY2: LCALL LOOP

D20:  CJNE A,#0BDH,D21    ;二楼

      LCALL DN1

      LJMP KEY5

D21:  CJNE A,#0EBH,D22

      LCALL U1

      LJMP KEY7

D22:  CJNE A,#0DBH,KEY2

      LCALL U2

      LJMP KEY8

 

KEY3: LCALL LOOP

D30:  CJNE A,#0BDH,D31   ;三楼

      LCALL DN2

      LJMP KEY5

D31:  CJNE A,#7DH,D32    

      LCALL DN1

      LJMP KEY6

D32:  CJNE A,#0DBH,KEY3

      LCALL U1

      LJMP KEY8

 

KEY4:LCALL LOOP

D40:  CJNE A,#0BDH,D41   ;四楼

      LCALL DN3

      LJMP KEY5

D41:  CJNE A,#7DH,D42   

      LCALL DN2

      LJMP KEY6

D42:  CJNE A,#0EBH,KEY4

      LCALL DN1

      LJMP KEY7

 

DH:LJMP KEY80

DJ:LJMP KEY50

DK:LJMP KEY60

DL:LJMP KEY70

 

KEY5: LCALL LOOP         ;一楼

D15:  CJNE A,#7DH,D16   

      LCALL U1

      LJMP KEY50

D16:  CJNE A,#0EBH,D17

      LCALL U2

      LJMP KEY60

D17:  CJNE A,#0DBH,DH

      LCALL U3

      LJMP KEY70

 

  

KEY6:

      LCALL LOOP 

D25:  CJNE A,#0BDH,D26    ;二楼

      LCALL DN1

      LJMP KEY80

D26:  CJNE A,#0EBH,D27

      LCALL U1

      LJMP KEY60

D27:  CJNE A,#0DBH,DJ

      LCALL U2

      LJMP KEY70

 

 

KEY7: LCALL LOOP

D35:  CJNE A,#0BDH,D36   ;三楼

      LCALL DN2

      LJMP KEY80

D36:  CJNE A,#7DH,D37   

      LCALL DN1

      LJMP KEY50

D37:  CJNE A,#0DBH,DK

      LCALL U1

      LJMP KEY70

 

 

KEY8: LCALL LOOP

D45:  CJNE A,#0BDH,D46  ;四楼

      LCALL DN3

      LJMP KEY80

D46:  CJNE A,#7DH,D47  

      LCALL DN2

      LJMP KEY50

D47:  CJNE A,#0EBH,DL

      LCALL DN1

      LJMP KEY60

 

 

 

 

U1:   LCALL LOOP      ;上一层楼

      CJNE A,#0BBH,U1

      LCALL U0

      INC 30H

         LCALL DISPLAY

      RET

U2:   LCALL LOOP          ;上两层楼

      CJNE A,#0BBH,U2

      LCALL U0

      INC 30H

      LCALL DISPLAY

      LCALL U0

      INC 30H

      LCALL DISPLAY

      RET

U3:   LCALL LOOP           ;上三层楼

      CJNE A,#0BBH,U3

      LCALL U0

      INC 30H

      LCALL DISPLAY

      LCALL U0

      INC 30H

      LCALL DISPLAY

      LCALL U0

      INC 30H

      LCALL DISPLAY

      RET

 

 

 

DN1:  LCALL LOOP          ;下一层楼

      CJNE A,#0BBH,DN1

      LCALL DN0

      DEC 30H

      LCALL DISPLAY

      RET

DN2:  LCALL LOOP         ;下两层楼

      CJNE A,#0BBH,DN2

      LCALL DN0

      DEC 30H

      LCALL DISPLAY

      LCALL DN0

      DEC 30H

      LCALL DISPLAY

      RET

DN3:  LCALL LOOP           ;下三层楼

      CJNE A,#0BBH,DN3

      LCALL DN0

      DEC 30H

      LCALL DISPLAY

      LCALL DN0

      DEC 30H

      LCALL DISPLAY

      LCALL DN0

      DEC 30H

      LCALL DISPLAY

      RET

 

 

U11:  LCALL LOOP      ;上一层楼 

      LCALL U0

      INC 30H

      LCALL DISPLAY

      RET

U22:  LCALL LOOP          ;上两层楼  

      LCALL U0

      INC 30H

      LCALL DISPLAY

      LCALL U0

      INC 30H

      LCALL DISPLAY

      RET

U33:  LCALL LOOP           ;上三层楼   

      LCALL U0

      INC 30H

      LCALL DISPLAY

      LCALL U0

      INC 30H

      LCALL DISPLAY

      LCALL U0

      INC 30H

      LCALL DISPLAY

      RET

 

DN11: LCALL LOOP          ;下一层楼   

      LCALL DN0

DEC 30H

         LCALL DISPLAY

      RET

DN22: LCALL LOOP         ;下两层楼 

      LCALL DN0

      DEC 30H

      LCALL DISPLAY

      LCALL DN0

      DEC 30H

      LCALL DISPLAY

      RET

DN33: LCALL LOOP           ;下三层楼      

      LCALL DN0

      DEC 30H

      LCALL DISPLAY

      LCALL DN0

      DEC 30H

      LCALL DISPLAY

      LCALL DN0

      DEC 30H

      LCALL DISPLAY

      RET

 

LOOP:                     ;按键判断

      MOV P0,#0FH

      MOV A,P0

      CJNE A,#0FH,D1

      LJMP LOOP

D1:   MOV 40H,A

      MOV P0,#0F0H

      MOV A,P0

      MOV 41H,A

D2:   MOV P0,#0F0H

      MOV A,P0

      CJNE A,41H,D3

      LJMP D2

D3:   MOV A,41H          

      ADD A,40H

      RET

 

                           

U0:                       ;往上

     Z1:MOV  R5,#3

    Z11:MOV  R3,#108

START2:MOV  R0,#05

START3:MOV   A,R0

       MOV   DPTR,#TABLE

       MOVC  A,@A+DPTR

       JZ   START2

       CPL  A

       MOV   P1,A

       CALL  DELAY

       INC   R0

       DJNZ  R3,START3

       DJNZ  R5,Z11

       RET

 

 

 

DN0:                       ;往下

     L1:MOV R5,#3

     L11:MOV  R3,#108

  START:MOV R0,#00H

START1:MOV  A,R0

       MOV  DPTR,#TABLE

       MOVC   A,@A+DPTR

       JZ  START

       CPL  A

       MOV P1,A

       CALL DELAY

       INC  R0

       DJNZ  R3,START1

       DJNZ  R5,L11

       RET

 

DELAY:

       MOV  R1,#40

  D99: MOV  R2,#248

       DJNZ  R2,$

       DJNZ  R1,D99

       RET

TABLE: 

         DB 03H,09H,0CH,06H

         DB 00

         DB 03H,06H,0CH,09H

         DB 00

DISPLAY:                   ;显示程序

         MOV A,30H

         MOV P2,A

         RET

END

 

 

2018-10-01 23:17:05 u014798590 阅读数 3928
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4003 人正在学习 去看看 朱有鹏

由于本人除了比较矮之外,还比较穷,手头只有台古董模拟示波器,带宽只有20M,所以有些波形需要“意会”,废话不多说,我们来看图说话。

目录
一、单片机读取ID卡(工作原理及电路)
二、单片机读取ID卡(产生载波)
三、单片机读取ID卡(EM41000的数据格式)
四、单片机读取ID卡(硬件调试及读码)

1、功率放大电路及125Khz载波测量
A点为示波器测量处,signalcarrier为单片机产生125KHz波形
在这里插入图片描述
实际波形
在这里插入图片描述

2、LC谐振电路及正弦波测量
B点为示波器测量点
在这里插入图片描述
在这里插入图片描述

3、包络检波电路及检波波形
C点为示波器测量点
在这里插入图片描述
在这里插入图片描述

4、放大整形电路及输出波形测量
测量点为OutSignal。
在这里插入图片描述
在这里插入图片描述

5、波形分析与读码
通过上面最终输出的波形,单片机已经可以识别到输出的曼切斯特码了。
首先我们使用市面上能买到的读卡器,读取一下本次测试用的ID卡卡号
1 E 0 0 6 8 B 0 9 8
通过在EM4100的数据格式一文中的格式,我们进行拆解,如下图所示
在这里插入图片描述

下面是一段随机截取的输出波形。我们进行分析
在这里插入图片描述
1111111111100110111001000,对照上图列表中的数据,然后发现根本对不上,,,,,
回过头来,我们在来看看关于曼切斯特码的格式。

从低到高跳变表示“1”,从高到低跳变表示“0”。(百度百科)

这时候我们取反一下上面得到的编码
0000000000011001000110111(这下就可以对应上了吧~~~~~)

现在再让我们来看下维基百科上的相关图片,相信就会一目了然。
在这里插入图片描述
接下来我们将编写解码程序,敬请期待。

单片机模拟spi通信

阅读数 766

没有更多推荐了,返回首页