📄 main.asm
字号:
;*************************************************************************
; main.c
; LM75A数字温度计
;*************************************************************************
;*************************************************************************
;复位和中断向量入口
;*************************************************************************
;复位入口
ORG 0x0000
LJMP PreMain
;T1中断入口:
ORG 0x001B
LJMP T1INTSVC
;*************************************************************************
;定义全局BIT、IRAM变量的分配起始符号
;*************************************************************************
GLOBAL_BIT SET 0x22.0
GLOBAL_IRAM SET 0x30
;*************************************************************************
;文件包含
;*************************************************************************
$INCLUDE(Branch.INC) ;分支判断
$INCLUDE(Calc.INC) ;运算类程序
$INCLUDE(Pointer.INC) ;通用指针处理
$INCLUDE(Disp.INC) ;数码管显示驱动程序
$INCLUDE(I2C.INC) ;I2C总线驱动程序
;*************************************************************************
;定义主程序全局变量
;*************************************************************************
;*************************************************************************
;函数:GlobalInit()
;功能:全局变量赋初值操作
;*************************************************************************
GlobalInit:
CLR A
MOV T1INTSVC_n, A
RET
;*************************************************************************
;程序段:PreMain
;功能:进入主程序之前的初始化操作
;*************************************************************************
PreMain:
MOV SP, #(GLOBAL_IRAM-1)
LCALL GlobalInit
LJMP main
;*************************************************************************
;函数:Delay()
;功能:延时0.001~65.536s
;参数:
; t>0时,延时(t*0.001)s
; t=0时,延时65.536s
;*************************************************************************
;void Delay(unsigned int t)
;t = (R6,R7)
Delay:
;{
; do
Delay_do:
; {
; TH0 = 0xFC;
; TL0 = 0x66;
; TR0 = 1;
; while ( !TF0 );
; TR0 = 0;
; TF0 = 0;
MOV TH0, #0xFC
MOV TL0, #0x66
SETB TR0
JNB TF0, $
CLR TR0
CLR TF0
; } while ( --t != 0 );
DJNZ_W R6,R7, Delay_do ;宏DJNZ_W的定义见Branch.INC
;}
RET
;*************************************************************************
;函数:SysInit()
;功能:系统初始化
;*************************************************************************
;void SysInit()
SysInit:
;{
; TMOD &= 0xF0;
; TMOD |= 0x01; //设置T0为16位定时器
ANL TMOD, #0xF0
ORL TMOD, #0x01
; DispInit(); //数码管扫描显示初始化
LCALL DispInit
; I2C_Init(); //初始化I2C总线
LCALL I2C_Init
;}
RET
;*************************************************************************
;函数:LM75A_GetTemp
;功能:读出LM75A的温度值
;返回:LM75A温度寄存器的数值(乘以0.125可得到摄氏度值)
;*************************************************************************
;int LM75A_GetTemp()
;返回值=(R6,R7)
LM75A_GetTemp:
;{
; unsigned char buf[2];
; int t;
; 分配:buf = R2
; 分配:t = (R6,R7)
PUSH 0x02
PUSH 0x05
PUSH 0x08
PUSH 0x09
PUSH 0x0A
; 分配buf[]
INC SP
MOV R2, SP
INC SP
; I2C_Gets(0x90,0x00,2,buf);
MOV 0x08, #PtrTypeIDATA ;PtrTypeIDATA的定义见Pointer.INC
MOV 0x09, #0
MOV 0x0A, R2
MOV R5, #2
MOV R6, #0x00
MOV R7, #0x90
LCALL I2C_Gets
; t = buf[0];
; t <<= 8;
; t += buf[1];
MOV A, R2
MOV R0, A
MOV A, @R0
MOV R6, A
INC R0
MOV A, @R0
MOV R7, A
; t >>= 5; //去掉无关位
MOV R0, #5
LM75A_GetTemp_SAR:
MOV A, R6
MOV C, ACC.7
RRC A
MOV R6, A
MOV A, R7
RRC A
MOV R7, A
DJNZ R0, LM75A_GetTemp_SAR
; return t;
DEC SP
DEC SP
POP 0x0A
POP 0x09
POP 0x08
POP 0x05
POP 0x02
;}
RET
;*************************************************************************
;函数:void ByteToStr(unsigned char *s, unsigned char c)
;功能:Byte型变量c转换为十进制字符串*s
;*************************************************************************
; *s = (0x08,0x09,0x0A)
; c = R7
ByteToStr:
PUSH 0x02
MOV R2, #0
ByteToStr_for:
MOV A, R2
MOV DPTR, #ByteToStr_Tab
MOVC A, @A+DPTR
MOV B, A
MOV A, R7
DIV AB
MOV R7, B
ADD A, #'0'
MOV R1, 0x08
MOV DPH, 0x09
MOV DPL, 0x0A
LCALL BytePtrST
INC_W 0x09, 0x0A
INC R2
CJNE R2, #2, ByteToStr_for
MOV A, R7
ADD A, #'0'
INC DPTR
LCALL BytePtrST
INC DPTR
CLR A
LCALL BytePtrST
POP 0x02
RET
ByteToStr_Tab:
DB 100,10
;*************************************************************************
;函数:strlen()
;功能:计算字符串*s的长度
;*************************************************************************
; unsigned char strlen(unsigned char *s)
; 返回值 = ACC
strlen:
PUSH 0x02
MOV 0x02, #0
MOV R1, 0x08
MOV DPH, 0x09
MOV DPL, 0x0A
strlen_Loop:
LCALL BytePtrLD
JZ strlen_endLoop
INC DPTR
INC R2
SJMP strlen_Loop
strlen_endLoop:
MOV A, R2
POP 0x02
RET
;*************************************************************************
;函数:DispTemp()
;功能:在数码管上显示出温度值
;参数:
; t:11位补码表示的温度,除以8以后才是摄氏温度值
;*************************************************************************
;void DispTemp(int t)
;t = (R6,R7)
DispTemp:
;{
; code unsigned char Tab[8][4] =
; {
; "000",
; "125",
; "250",
; "375",
; "500",
; "625",
; "750",
; "875"
; };
; unsigned char buf[4];
; bit s; //符号位
; unsigned char i; //整数部分
; unsigned char d; //小数部分
; unsigned char x; //临时变量
; 分配:buf = R5
; 分配:s = 0x21.0
; 分配:i = R2
; 分配:d = R3
; 分配:x = R4
PUSH 0x20
PUSH 0x02
PUSH 0x03
PUSH 0x04
PUSH 0x05
; 分配数组buf[]
INC SP
MOV A, SP
MOV R5, A
ADD A, #3
MOV SP, A
;//分离出符号
; s = 0;
CLR 0x21.0
; if ( t < 0 )
MOV A, R6
JNB ACC.7, DispTemp_endif1
; {
; s = 1;
SETB 0x21.0
; t = -t;
MOV A, R7
CPL A
ADD A, #1
MOV R7, A
MOV A, R6
CPL A
ADDC A, #0
MOV R6, A
; }
DispTemp_endif1:
;//分离出整数和小数部分
; i = t / 8;
; d = t % 8;
MOV A, R7
ANL A, #0x07
MOV R3, A
MOV R0, #3
DispTemp_00:
MOV A, R6
CLR C
RRC A
MOV R6, A
MOV A, R7
RRC A
MOV R7, A
DJNZ R0, DispTemp_00
MOV R2, A
;//整数部分转换成字符串
; ByteToStr(buf,i);
MOV R7, A
MOV 0x08, #PtrTypeIDATA ;PtrTypeIDATA的定义见Pointer.INC
MOV 0x09, #0
MOV 0x0A, R5
LCALL ByteToStr
; x = 4 - strlen(buf);
MOV 0x08, #PtrTypeIDATA
MOV 0x09, #0
MOV 0x0A, R5
LCALL strlen
CPL A
INC A
ADD A, #4
MOV R4, A
;//清除所有显示
; DispClear();
LCALL DispClear
;//显示符号
; if ( s ) DispChar(x,'-');
JNB 0x21.0, DispTemp_endif2
MOV R6, #'-'
MOV A, R4
MOV R7, A
LCALL DispChar
DispTemp_endif2:
; x++;
INC R4
;//显示整数部分
; DispStr(x,buf);
MOV 0x08, #PtrTypeIDATA
MOV 0x09, #0
MOV 0x0A, R5
MOV A, R4
MOV R7, A
LCALL DispStr
;//显示小数点
; DispDotOn(4);
MOV R7, #4
LCALL DispDotOn
;//显示小数部分
; DispStr(5,Tab[d]);
MOV 0x08, #PtrTypeCODE
MOV A, R3
RL A
RL A
ANL A, #0xFC
ADD A, #LOW(DispTemp_Tab)
MOV 0x0A, A
MOV A, #HIGH(DispTemp_Tab)
ADDC A, #0
MOV 0x09, A
MOV R7, #5
LCALL DispStr
;
MOV A, SP
CLR C
SUBB A, #4
MOV SP, A
POP 0x05
POP 0x04
POP 0x03
POP 0x02
POP 0x20
;}
RET
DispTemp_Tab:
DB '000',0x00
DB '125',0x00
DB '250',0x00
DB '375',0x00
DB '500',0x00
DB '625',0x00
DB '750',0x00
DB '875',0x00
;*************************************************************************
;函数:void main()
;功能:主函数
;*************************************************************************
;void main()
main:
;{
; int t;
; 分配:t = (R6,R7)
; SysInit();
LCALL SysInit
; for (;;)
main_for:
; {
; t = LM75A_GetTemp();
LCALL LM75A_GetTemp
; DispTemp(t);
LCALL DispTemp
; Delay(1000);
MOV R6, #HIGH(1000)
MOV R7, #LOW(1000)
LCALL Delay
; }
SJMP main_for
;}
;*************************************************************************
;程序结束
;*************************************************************************
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -