单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解

我也是在百度,单片机论坛,很多地方找帖子,最后在自己电脑上成功了,之后我教我同学设置联调,出现了一些问题,和我电脑不一样的地方,下面进行解答。写的不好,望大家见谅。

我学的单片机的课程教材是以STC15W4K32S4系列的单片机讲的,所以下面将以STC15的为例
我遇到了两种情况,先说共有的地方,遇到情况不一样的时候将分开说明。

文章目录

    • 1.软件安装
    • 2.安装STC15的芯片包
    • 3.Keil和Protues开始建立联系
    • 4.开始编译(这里会有些电脑出现错误)
    • 5.选择Proteus Debug
    • 6.勾选创建Hex文件
    • 7.打开Proteus
    • 8.最后一步啦,启动联调
    • 9.代码

1.软件安装

STC15是51单片机的增强型,也是用51的keil来写程序,下面是keil5 C51安装应用程序,KEIL_LIC,Proteus7.8安装包(我是之前安装的Proteus7,老师课程里说用Proteus8,我感觉哪个都行,不过最新版的Proteus8.9有点问题,最后调试的时候问题就出现,所以尽量不要安装最新版的Proteus
在这里插入图片描述
在这里插入图片描述
安装Keil5 C51,Protues,这里就不再详细说安装步骤了,不过要注意的是Keil5 C51最好用英文版的,尽量不要汉化,汉化有时会出现问题。

2.安装STC15的芯片包

可以在STC官网上下载stc-isp-15xx-v6.87B,双击打开就行,在左侧的单片机型号里找STC15W4K32S4–>IAP15W4K58S4,如下图
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第1张图片
之后在右侧Keil仿真设置选项,下面有个添加型号和头文件到Keil…选项,单击
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第2张图片
找到
Keil5 C51的安装路径
我的安装路径是Keil5_Load,我是之前将MDK和C51兼容了,所以下面有ARM,这点可以不用在意,与联调没有任何关系。
比如我这个,就放到Keil5_Load就行,点Keil5_Load即可,再点确定,其实就放到C51这个文件夹的上一层文件夹即可,下图Keil5_Load里有个C51文件夹。点确定后,会提示安装成功,这样STC15的库就安好了。
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第3张图片
之后打开Keil5 C51,可以新建一个工程文章最后有完整代码,可以复制下来,注意建一个asm文件,打开魔法棒,习惯这样称呼了,长得像而已,如下图
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第4张图片
Device下面,找到刚刚装的STC15的库单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第5张图片
这样就能在Keil里选择STC15的芯片了。

3.Keil和Protues开始建立联系

网上下载VDM51.dll文件,找到Keil5 C51的安装路径,里面C51->BIN,放着这里面。
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第6张图片
打开Keil5 C51的安装路径,里面有个TOOLS.INI文件,如下图,我把ARM和C51兼容了,所以多了一些东西,这些可以不用管。
双击打开即可
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第7张图片
找到TDRV9,在这一行后面添加
TDRV10=BIN\VDM51.DLL (" Proteus Debug ")
你会发现,前面前面几行都是按顺序写的,我这里是TDRV9,所以我紧跟着是TDRV10,如果前面不是TDRV9,那么前面是几,在后面跟着加一就可。
注意:在最后一行,是刚刚添加STC库的时候自动在这个文件里修改的,这一行可以剪切到刚刚咱们添加的Protues Debug的那一行后面,同样,也需要注意顺序来写.
保存,关闭即可。
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第8张图片

4.开始编译(这里会有些电脑出现错误)

首先,没有问题的情况,就是0 Error(s), 0 Warning(s)恭喜!!!第4点的东西就不用看了!!

代码是没有问题的,是一些Keil配置的问题,下面来说解决办法
1.打开魔法棒(Options for Target)->Device->右侧以第一个方框勾选
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第9张图片
2.打开魔法棒(Options for Target)->LX51 Misc->写REMOVEUNUSED单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第10张图片
之后再编译一下,应该就没问题了。

5.选择Proteus Debug

按照下面的图,选择Proteus Debug,如果没有的话,返回第4步查看哪里出了问题。
一般修改了Keil的设置,要把所有的Keil窗口都关了,再打开。单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第11张图片

6.勾选创建Hex文件

在魔法棒->Output里勾选Create HEX File一定要勾选!!!!,之后Protues要用到这个文件。
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第12张图片

7.打开Proteus

可以自己连接电路。
启动远程调试,如果是英文版的,找一下对应的意思即可,很容易找到的。
注意!!!再次点调试里面看看对勾打上没有!! 如果没有,Proteus没装好,重新装一下,或者换个版本的Protues。
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第13张图片
双击单片机,或者点击右键编辑属性,在Program File 后面有个打开文件的图标,点开,找到刚刚创建的Hex文件。
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第14张图片

8.最后一步啦,启动联调

将Keil 和Proteus的页面在桌面各占半壁江山,在Keil里点放大镜一样的东西。可以看前面有一张图。
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第15张图片
点运行
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第16张图片
哇!!!成功啦!!
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第17张图片
去打盘游戏放松一下,嘻嘻嘻!!
如果出现下面,说明Proteus没有打开远程调试,返回看第8步
单片微机原理与接口技术——基于STC15W4K32S4:关于KEIL5 C51和Proteus联调问题详解_第18张图片
联调好啦!!!终于能面对汇编为所欲为啦!!操练起来!!!

9.代码

	 ;程序名称:interrupt.asm
;程序说明:74HC595驱动数码管动态显示例,通过按键触发外部中断,P3.2进行计数,P3.3清零,实验箱上完成
;算法说明:由两片74HC595芯片分别驱动段和位,数码管动态扫描显示:修改延时子程序,可以改变扫描频率,达到不同显示效果
;		  按键触发外部中断,下降沿有效
;		  R5,R4存放计数的结果,R5存放计数的千位和百位,R4存放计数的十位和个位
;		  为了明显看到实验结果,R5R4初始化为9990,从此计数,每次加1,计数超过9999后会回到0000重新计数
;		  实现正常的计数操作,只需要把102行,103行的R5,R4的初值改为0即可
;
;*******************************************************************
;*******************************************************************
;软件设置:可能电脑配置不同,该工程的设置可能不同
			;打开keil文件,protues工程,编译,仿真,如果出现错误,则按下方的步骤设置
			;1.打开魔法棒(Options for Target)->Device->右侧以第一个方框勾选
			;2.打开魔法棒(Options for Target)->LX51 Misc->写REMOVEUNUSED
;*******************************************************************
;*******************************************************************

P0M1	DATA	0x93	; P0M1.n,P0M0.n 	=00--->Standard,	01--->push-pull
P0M0	DATA	0x94	; 					=10--->pure input,	11--->open drain
P1M1	DATA	0x91	; P1M1.n,P1M0.n 	=00--->Standard,	01--->push-pull
P1M0	DATA	0x92	; 					=10--->pure input,	11--->open drain
P2M1	DATA	0x95	; P2M1.n,P2M0.n 	=00--->Standard,	01--->push-pull
P2M0	DATA	0x96	; 					=10--->pure input,	11--->open drain
P3M1	DATA	0xB1	; P3M1.n,P3M0.n 	=00--->Standard,	01--->push-pull
P3M0	DATA	0xB2	; 					=10--->pure input,	11--->open drain
P4M1	DATA	0xB3	; P4M1.n,P4M0.n 	=00--->Standard,	01--->push-pull
P4M0	DATA	0xB4	; 					=10--->pure input,	11--->open drain
P5M1	DATA	0xC9	; P5M1.n,P5M0.n 	=00--->Standard,	01--->push-pull
P5M0	DATA	0xCA	; 					=10--->pure input,	11--->open drain
P6M1	DATA	0xCB	; P6M1.n,P6M0.n 	=00--->Standard,	01--->push-pull
P6M0	DATA	0xCC	; 					=10--->pure input,	11--->open drain
P7M1	DATA	0xE1	;
P7M0	DATA	0xE2	;
P4      DATA    0C0H
P5      DATA    0C8H
KEY     EQU     R3       ;R3 用于存储按键的编号:0~F
XSP		DATA	40H
YSP		DATA	50H



;*************	IO口定义	**************/
	SER		BIT		P0.6	;	//pin 14	SER		data input
	STCLK	BIT		P0.7	;	//pin 12	RCLk	store (latch) clock
	SHCLK	BIT		P0.5	;	//pin 11	SRCLK	Shift data clock


	ORG		0000H              			;程序起始地址
	LJMP	MAIN
	ORG		0003H
	LJMP	EX0_INT
	ORG		0013H
	LJMP	EX1_INT
	ORG		0030H

MAIN:
  //初始化单片机
	MOV		SP,		#60H				;设堆栈指针 ,远离工作区
	//显示缓冲区,初始化全显示“-”
	MOV		20H,	#17  				;左第1位数码管要显示字符
	MOV		21H,	#17					;左第2位数码管要显示字符
	MOV		22H,	#17					;左第3位数码管要显示字符
	MOV		23H,	#17					;左第4位数码管要显示字符
	MOV		24H,	#17					;左第5位数码管要显示字符
	MOV		25H,	#17					;左第6位数码管要显示字符
	MOV		26H,	#17					;左第7位数码管要显示字符
	MOV		27H,	#17					;左第8位数码管要显示字符
	  // 显示位码缓冲区  ,零有效
	MOV		30H,	#0FEH				;选中第1个数码管
	MOV		31H,	#0FDH				;选中第2个数码管
	MOV		32H,	#0FBH				;选中第3个数码管
	MOV		33H,	#0F7H				;选中第4个数码管
	MOV		34H,	#0EFH				;选中第5个数码管
	MOV		35H,	#0DFH				;选中第6个数码管
	MOV		36H,	#0BFH				;选中第7个数码管
	MOV		37H,	#07FH				;选中第8个数码管
	// 端口初始化
	CLR		A
	MOV		P0M1,	A 					;设置为准双向口
 	MOV		P0M0,	A
	MOV		P1M1,	A 					;设置为准双向口
 	MOV		P1M0,	A
	MOV		P2M1,	A 					;设置为准双向口
 	MOV		P2M0,	A
	MOV		P3M1,	A 					;设置为准双向口
 	MOV		P3M0,	A
	MOV		P4M1,	A 					;设置为准双向口
 	MOV		P4M0,	A
	MOV		P5M1,	A 					;设置为准双向口
 	MOV		P5M0,	A
	MOV		P6M1,	A 					;设置为准双向口
 	MOV		P6M0,	A
	MOV		P7M1,	A 					;设置为准双向口
 	MOV		P7M0,	A
    //MOV     KEY,	#17     			; 按键编号初始化为横线的编号17
	//MOV		PSW,	#0
	MOV     P3,		#0FFH  				;P3口接独立按键:P32-》SW17 P33-》SW18,外部中断0 和外部中断1,
										;可以采用中断编程识别,也可以独立按键扫描识别,本例子采用扫描法
	MOV		DPTR,	#SEGCODE			;DPTR指向显示码存储区
	
	
	
	MOV		R4,		#90
	MOV		R5,		#99					;方便检测,从9990开始每次加1
	
	
	
//中断初始化
	SETB	EX0 						;打开外部中断0
	SETB	IT0 						;外部中断0下降沿触发
	CLR		PX0						 	;
	SETB	EX1 						;打开外部中断1
	SETB	IT1 						;外部中断1下降沿触发
	SETB	PX1
	SETB	EA  						;打开总中断开关	
	
	
	LCALL	REBUFFER					;显示R5R4里的数值
	
	

MAINLOOP:   ;主程序死循环
         LCALL DISPLAY  				;动态显示8位数字
         LJMP  MAINLOOP



 //扫描动态显示子程序:先写段码,再写位码
DISPLAY:
	MOV		R0,		#20H				; R0指向显示缓冲区,全部数码管扫描完毕后,重新循环扫描
	MOV		R1,		#30H				;R1指向第一个数码管

	DISPLAYi:
		MOV		A,		@R1				; 取位码
		LCALL	WR595					; 位码送入595
		MOV		A,		@R0				;取段码
		MOV		DPTR,	#SEGCODE		;DPTR指向显示码存储区
		MOVC	A,		@A+DPTR			;
		LCALL	WR595					; 段码送入595
		LCALL	LH595					; 锁存发送到595的数据
		INC		R0						;
		INC		R1						;
		CJNE	R0,		#28H,		DISPLAYi
		RET

//写入595子程序:串行发送累加器A中的8位数据到74HC595,R2作为移位次数计数器
 WR595:
	MOV		R2,		#08H
	WR595i:
		RLC		A						//带进位左环移
		MOV		SER,	C 				//赋值
		//	产生一个移位脉冲,将P2.1上数据移入595
		CLR SHCLK
			NOP
			NOP
		SETB	SHCLK					//方波,上升沿有效
		DJNZ	R2,		WR595i			//减一不为零跳转,等于零则说明8位数据移入完毕
		RET

//数据锁存子程序:将接收到的8位数据送到并行输出端
  LH595:
	CLR STCLK
		NOP
		NOP
	SETB	STCLK						//方波,上升沿有效,将移入的8位数据送到并行输出端
	RET

//延时400ms子程序,用于数码管闪烁显示报警
DELAY400MS:								;@12.000MHz
	NOP
	NOP
	NOP
	PUSH	30H
	PUSH	31H
	PUSH	32H
	MOV		30H,	#15
	MOV		31H,	#152
	MOV		32H,	#82
NEXT0:
	DJNZ	32H,	NEXT0
	DJNZ	31H,	NEXT0
	DJNZ	30H,	NEXT0
	POP		32H
	POP		31H
	POP		30H
	RET
;//延时1ms子程序:修改R7可以改变延时时间的长短,控制扫描速度,12MHz时钟,延时约1ms
;DELAY1ms:
	;MOV		R7,		#2
	;DEL2:
		;MOV		R6,		#248
		;NOP
	;DEL3:
		;DJNZ	R6,		DEL3
		;DJNZ	R7,		DEL2
	;RET									; 子程序返回
//延时4ms子程序:用于按键消除抖动,实际应用时可以根据按键灵敏度修改
DELAY4ms:								;@12.000MHz
	MOV		40H,	#38
	MOV		41H,	#85
	NEXT:
		DJNZ	41H,	NEXT
		DJNZ	40H,	NEXT
		RET
//外部中断0中断处理服务函数
EX0_INT:
		PUSH	ACC 		;现场保护
		INC		R4			;R5R4一开始设置的初值为9990,每次加1,可以较快地看到到达9999后归零的现象
		
		CLR     C			;清除CY
		MOV		A,	R4		;判断R4是否到达100,溢出后向R5进位
		SUBB	A,	#100
		JC		JR5			;C=1,跳转,不进位,C=0,不跳转,向下向R5进位
		R4_OV_100:
			MOV		R4,		#0
			INC		R5
		JR5:
		CLR     C			;清除CY
		MOV		A,	R5		;判断R5是否到达100,溢出后R5R4归零
		SUBB	A,	#100
		JC		SEGSHOW		;C=1,跳转,刷新数码管缓存区,C=0,不跳转,向下R5R4归零
		R5R4_OV_10000:
			MOV		R4,		#0
			MOV		R5,		#0
		SEGSHOW:
		LCALL	REBUFFER
		POP		ACC
		RETI

			
//外部中断1中断处理服务程序;数码管归零
EX1_INT:
	PUSH	ACC	;保护现场
	MOV		R4,		#0		;R5R4归零
	MOV		R5,		#0
	LCALL	REBUFFER
	POP	ACC
	RETI  

REBUFFER:
	MOV		A,		R4
	MOV		B,		#10
	DIV		AB
	MOV		27H,	B		;得到个位
	MOV		26H,	A		;得到十位
	
	MOV		A,		R5
	MOV		B,		#10
	DIV		AB
	MOV		25H,	B		;得到百位
	MOV		24H,	A		;得到千位
	
	RET

	
		


SEGCODE:						;标准字库
;	 0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
DB	03FH,006H,05BH,04FH,066H,06DH,07DH,007H,07FH,06FH,077H,07CH,039H,05EH,079H,071H
;  black  -    H    J    K	  L	   N	o    P	  U    t    G    Q    r    M    y
DB	000H,040H,076H,01EH,070H,038H,037H,05CH,073H,03EH,078H,03dH,067H,050H,037H,06EH
;    0.   1.   2.   3.   4.   5.   6.   7.   8.   9.   -1
DB	0BFH,086H,0DBH,0CFH,0E6H,0EDH,0FDH,087H,0FFH,0EFH,046H



	END               ;

你可能感兴趣的:(STC15)