单片机计算器开源

;硬件端口
PortDigPS		EQU		P0		;数码管段选硬件端口
PortDigCS		EQU		P2		;数码管位选硬件端口
PortKB			EQU		P1		;键盘输入硬件端口

;数码管使能
Dig4EN		EQU		0x01	;数码管1使能
Dig3EN		EQU		0x02	;数码管2使能
Dig2EN		EQU		0x04	;数码管3使能
Dig1EN		EQU		0x08	;数码管4使能
DigClose	EQU		0x00	;数码管关闭使能

DigValueNegative	EQU		0x10	;负号

;数码管值存储地址
Dig1Value	EQU		0x10	;数码管1值
Dig2Value	EQU		0x11	;数码管2值
Dig3Value	EQU		0x12	;数码管3值
Dig4Value	EQU		0x13	;数码管4值

;按键输入
KeyValue	EQU		0x14	;键值
;特殊键值
KeyNull		EQU		0xFF	;错误键值,立即数

;计算用变量
Operator	EQU		0x15	;运算符
OperandA	EQU		0x16	;操作数A
OperandB	EQU		0x17	;操作数B
ResultC		EQU		0x18	;结果C

;状态变量
StateWord		EQU		0x20		;标志字
StateError		EQU		0x20.0		;错误标志
StateNegative	EQU		0x20.1		;负数标志
StateOperandB	EQU		0x20.2		;当前输入操作数B

;操作符常量,与键值对应
OperatorAdd	EQU		0x0A
OperatorSub	EQU		0x0B
OperatorMul	EQU		0x0C
OperatorDiv	EQU		0x0D

;代码
	ORG		0x0000
 	AJMP	Start

;数码管显示函数
;参数:Dig1Value、Dig2Value、Dig3Value、Dig4Value
DigitalDisplay:
	PUSH	ACC
	MOV		DPTR,#DigitalTubeValue		;加载数码管显示内容地址
	;显示数码管1
	MOV		PortDigPS,#0x00		;清空之前的显示
	MOV		A,Dig1Value 
	MOVC	A,@A+DPTR
	MOV		PortDigCS,#Dig1EN
	MOV		PortDigPS,A
	;显示数码管2
	MOV		PortDigPS,#0x00
	MOV		A,Dig2Value
	MOVC	A,@A+DPTR
	MOV		PortDigCS,#Dig2EN
	MOV		PortDigPS,A
	;显示数码管3
	MOV		PortDigPS,#0x00
	MOV		A,Dig3Value
	MOVC	A,@A+DPTR
	MOV		PortDigCS,#Dig3EN
	MOV		PortDigPS,A
	;显示数码管4
	MOV		PortDigPS,#0x00
	MOV		A,Dig4Value
	MOVC	A,@A+DPTR
	MOV		PortDigCS,#Dig4EN
	MOV		PortDigPS,A
	POP		ACC
	RET
	
;关闭数码管显示函数
DigitalClose:
	MOV		PortDigCS,#DigClose
	RET

;矩阵键盘扫描函数,行列翻转法
;获取到的键值送入KeyValue,没有按键按下送入KeyNull
KeyBoardScan:
	PUSH	PSW
	PUSH	DPH
	PUSH	DPL
	PUSH	ACC
	PUSH	B
;PortKB		7-Row3,Row2,Row1,Row0,Col3,Col2,Col1,Col0-0
ReadRowValue:
	MOV		PortKB,#0xF0
	MOV		A,PortKB
	CJNE	A,#0xF0,ReadColValue	;A不为0xF0,认为有按键被按下
	SJMP	KeyBoardScanNull
ReadColValue:
	MOV		B,A
	ORL		A,#0x0F
	MOV		PortKB,A
	MOV		A,PortKB
GetKeyValue:
	MOV		DPTR,#KeyBoardValue
	ANL		A,#0x0F
	ORL		B,A				;键值
	MOV		R2,#0x00		;计数器
SearchKeyValueTable:
	MOV		A,R2
	MOVC	A,@A+DPTR
	CJNE	A,B,KeyValueAdd
	MOV		KeyValue,R2		;写键值
WaitKeyRelease:		;等待按键松开
	MOV		PortKB,#0xF0
	MOV		A,PortKB
	CJNE	A,#0xF0,WaitKeyRelease
	SJMP	KeyBoardScanFinish
KeyValueAdd:
	INC		R2
	CJNE	R2,#0x10,SearchKeyValueTable	;键值大于等于0x10,发生错误,KeyValue设置为0xFF,然后直接返回
KeyBoardScanNull:
	MOV		KeyValue,#KeyNull	;设置错误键值
KeyBoardScanFinish:
	POP		B
	POP		ACC
	POP		DPL
	POP		DPH
	POP		PSW
	RET

;清除
ClearEntity:
	MOV		Dig1Value,#0
	MOV		Dig2Value,#0
	MOV		Dig3Value,#0
	MOV		Dig4Value,#0
	MOV		Operator,#0x00
	MOV		OperandA,#0x00
	MOV		OperandB,#0x00
	MOV		ResultC,#0x00
	MOV		StateWord,#0x00
	RET

;数码管显示数字
;参数:ACC
DigitDisplayNumber:
	;清除原来的显示
	MOV		Dig1Value,#0
	MOV		Dig2Value,#0
	MOV		Dig3Value,#0
	MOV		Dig4Value,#0
	PUSH	ACC
	PUSH	B
	MOV		B,#10
	DIV		AB
	MOV		Dig4Value,B
	MOV		B,#10
	DIV		AB
	MOV		Dig3Value,B
	MOV		B,#10
	DIV		AB
	MOV		Dig2Value,B
	POP		B
	POP		ACC
	RET

;测试1
Test1:
	MOV		SP,#0x40		;重设堆栈指针,防止覆盖数据
Loop:
	CALL	DigitalClose	;数码管关显示
	CALL	KeyBoardScan	;扫描矩阵键盘
	;根据键值进行操作
	MOV		A,KeyValue
	CJNE	A,#KeyNull,KVJudge1
	SJMP	KVIsNull			;A==KeyNull
KVJudge1:
	CJNE	A,#0x09,KVJudge2
	SJMP	KVIsNumber			;A==0x09
KVJudge2:
	JC		KVIsNumber			;A <0x09
	CJNE	A,#0x0D,KVJudge3
	SJMP	KVIsOperator		;A==0x0D
KVJudge3:
	JC		KVIsOperator		;A==any(0x0A,0x0B,0x0C)
	CJNE	A,#0x0E,KVJudge4
	SJMP	KVIsCE				;A==0x0E
KVJudge4:
	CJNE	A,#0x0F,KVIsNull
	SJMP	KVIsEqual		;A==0x0F
;空值类型操作
KVIsNull:
	AJMP	LoopFinish
;数字类型操作
KVIsNumber:
	JB		StateOperandB,OperandBInput
OperandAInput:		;操作数A输入
	MOV		A,OperandA
	MOV		B,#10
	MUL		AB
	ADD		A,KeyValue
	MOV		OperandA,A
	CALL	DigitDisplayNumber			;设置显示数字
	SJMP	LoopFinish
OperandBInput:		;操作数B输入
	MOV		A,OperandB
	MOV		B,#10
	MUL		AB
	ADD		A,KeyValue
	MOV		OperandB,A
	CALL	DigitDisplayNumber			;设置显示数字
	SJMP	LoopFinish
;运算符类型操作
KVIsOperator:
	MOV		Operator,KeyValue
	SETB	StateOperandB				;置操作数为B
	SJMP	LoopFinish
;清空类型操作
KVIsCE:
	CALL	ClearEntity
	SJMP	LoopFinish
;等于类型操作
KVIsEqual:
	MOV		A,Operator
	CJNE	A,#OperatorAdd,IsItSub
	SJMP	CalculateAdd
IsItSub:
	CJNE	A,#OperatorSub,IsItMul
	SJMP	CalculateSub
IsItMul:
	CJNE	A,#OperatorMul,CalculateDiv
	SJMP	CalculateMul
CalculateAdd:
	CLR		C
	MOV		A,OperandA
	MOV		B,OperandB
	ADDC	A,B
	MOV		ResultC,A
	SJMP	CalculateFinish
CalculateSub:
	CLR		C
	MOV		A,OperandA
	MOV		B,OperandB
	SUBB	A,B
	MOV		ResultC,A
	SJMP	CalculateFinish
CalculateMul:
	CLR		C
	MOV		A,OperandA
	MOV		B,OperandB
	MUL		AB
	MOV		ResultC,A
	SJMP	CalculateFinish
CalculateDiv:
	CLR		C
	MOV		A,OperandA
	MOV		B,OperandB
	DIV		AB
	MOV		ResultC,A
	SJMP	CalculateFinish
CalculateFinish:
	;结果显示
	MOV		A,ResultC
	CALL	DigitDisplayNumber			;设置显示数字
LoopFinish:
	CALL	DigitalDisplay	;显示
	AJMP	Loop
	RET

Test2:
	MOV	P0,#0xFF
	MOV	P2,#00000011B
	SJMP	$
	RET

;程序入口
Start:
	CALL	Test1

;数码管值0~9、A~H对应值
DigitalTubeValue:
	DB		0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F	;0~9,编码0x00~0x09
	DB		0x77,0x7C,0x39,0x5E,0x79,0x71,0x3D,0x76		;A~H,编码0x0A~0x0H
	DB		0x40	;'-'

;按键值
KeyBoardValue:
	DB		0x77,0x7B,0x7D,0x7E		;Row3	7
	DB		0xB7,0xBB,0xBD,0xBE		;Row2	B
	DB		0xD7,0xDB,0xDD,0xDE		;Row1	D
	DB		0xE7,0xEB,0xED,0xEE		;Row0	E
	;		Col3 Col2 Col1 Col0
	;		7    B    D	   E	
	END

参考接线图,仿真与代码不对应,部分信号有效性需要修改

单片机课设写的计算器,51汇编,键盘扫描有点儿问题,没加延时消抖。

做个课设还被怀疑抄袭就离谱,是代码写得太整洁了还是注释加的太多了???

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值