📄 keydlas_alarm.s43
字号:
; 此示例介绍430的低功耗设计方法,程序包含显示,键盘,ADC,定时器,中断等等.
; 在这个例子中有LED显示与行列式键盘,这些程序的编写在相应的地方已经介绍
; 这个程序还是要求显示出所按键的键值
; 但要求作到低功耗,所以大部分的事情在中断程序里实现,
; 显示用中断实现,而且5秒没有按键按下则自动关断显示,用以节省能耗
; 按健的值显示在最左边一位,
; ADC10(温度的ADC转换)显示在最右边的三位,
; 温度转换后暂时存放在220H---240H,然后求和,平均,-***H,/20H---->
; 以10禁进制显示实际温度值
; 约定:显示缓存在200H 以后的6个单元,显示位寄存器为 206H;208H为显示计数器
; 20Ah 按键计时器
; 增加了报警功能
; 用键盘输入两位10进制数,为温度警戒值
; 当温度大于设置值时输出报警
#include "msp430x13x.h"
RSEG CSTACK ; System stack
; DS 0
RSEG CODE ; Program code 的开始
Reset mov #SFE(CSTACK),SP ;
SetupWDT mov #WDTPW+WDTHOLD,&WDTCTL ;
SetupTA mov #TASSEL1+TACLR,&TACTL ; SMCLK, Clear TAR
SetupC0 mov #CCIE,&CCTL0 ; 使能CCR0 中断
mov #500,&CCR0 ;
SetupP1 bis #MC1,&TACTL ; 定时器工作在连续模式
eint ; 开中断
MOV #0FFDFH,&206H
MOV #200H,&208H
MOV #30000,&20AH
BIS.B #08H,&P4DIR
; MOV.B #21H,&201H
MOV.B #22H,&202H
MOV #220H,&210H ;ADC缓存的起始位置
mov.b #0,&212h
mov.b #0,&214h
Mainloop bis #LPM1,SR ; 低功耗模式
;---------------------------------------------------------------------------
TA0_isr add #500,&CCR0 ; Add Offset to CCR0
call #adc10
CMP #240h,&210H
JNZ TA0_0
CALL #ADCHULI
;
TA0_0 ; CMP #0,&20AH ;按键计时器,为0时,将关显示
; JZ TA0_1
CALL #KEY
CALL #DISPLAY_LED
DEC &20AH
CALL #ALARM
reti
TA0_1 CALL #KEY ;关显示
MOV.B #0,P5OUT
MOV.B #00,P5DIR
RETI
ALARM PUSH R5 ;报警子程序
PUSH R6
MOV.B &205H,R5
MOV.B &201H,R6
CLRC
SUB.B R6,R5
JNC ALARMEND
MOV.B &204H,R5
AND.B #0FH,R5
MOV.B &200H,R6
AND.B #0FH,R6
CLRC
SUB.B R6,R5
JNC ALARMEND
BIS.B #08H,&P4OUT ;超出警戒温度,报警
AND.B #0FH,&200H
ADD.B #10H,&200H
POP R6
POP R5
RET
ALARMEND BIC.B #08H,&P4OUT ;没有超出警戒温度,不报警
AND.B #0FH,&200H
POP R6
POP R5
RET
KEY PUSH.B &P1DIR
PUSH.B &P1OUT
CALL #KEYJUDGE ; 没有按键就退出,有就得到键值并处理
JNC KEY2 ;
MOV #2000,R15
KEY0 DEC R15
JNZ KEY0
CALL #KEYJUDGE
JNC KEY2 ;去抖动
CALL #KEYCODE ;得到键值
PUSH R9
KEY1 CALL #KEYJUDGE ;等待按键松开
JC KEY1
POP R9
tst.b &214h ;214H为一二进制计数器,当为0时键值被送到201H,否则送到200H
jz key11
mov.b r9,&200h
mov.b #0,&214h
jmp key12
key11 mov.b r9,&201h
mov.b #1,&214h
key12
MOV #50000,&20AH
CALL #KEY_TAB ;处理按键
KEY2 POP.B &P1OUT
POP.B &P1DIR
RET
KEY_TAB ;
NOP
RET
KEYCODE MOV.B #0,&P5DIR
MOV.B #0FH,&P1DIR ;低4位作为扫描线行输出,高3位作为列线读入
MOV #0,R9
MOV #1,R8
KEYCODELOOP MOV.B R8,&P1OUT ;R8为扫描信号的输出
BIT.B #10H,&P1IN
JC KEYCODE1 ;测试P1.4
BIT.B #20H,&P1IN
JC KEYCODE2 ;测试P1.5
BIT.B #40H,&P1IN
JC KEYCODE3 ;测试P1.6
RLA.B R8
ADD.B #3,R9
CMP.B #12,R9 ;4根行线扫描完了吗
JNZ KEYCODELOOP
KEYCODE1 ADD #0,R9
RET
KEYCODE2 ADD #1,R9
RET
KEYCODE3 ADD #2,R9
RET
KEYJUDGE MOV.B #0FFH,&P1DIR
MOV.B #0,&P1OUT
MOV.B #0FH,&P1DIR
MOV.B #0FH,&P1OUT
BIT.B #070H,&P1IN ; 测试3根列线是否为1,是否有按健
RET ; 若有,C=1
adc10 ;MOV.B #0,&P5DIR
NOP
NOP
bic #ENC,&ADC12CTL0 ;ENC=0
mov #REFON+ADC12ON,&ADC12CTL0 ;VER=片内1.5V
mov #SHP+ADC12SSEL_2,&ADC12CTL1 ;上升沿采样,主时钟
bis #1000h,&ADC12CTL1 ;选择MEM1 0001 0000 0000 0000
mov.b #1Ah,&ADC12MCTL1 ;选择ADC通道0A 0001 1010 参考电压:VER--VSS
bis #ENC,&ADC12CTL0 ; set ENC bit
nop
nop
nop
nop
nop
nop
nop
nop
bis #ADC12SC,&ADC12CTL0 ; 开始转换
testEOC1 bit #BIT1,&ADC12IFG ; 是否转换完毕 (ADC12IFG.0=1?)
jz testEOC1 ;
MOV &210H,R15 ;210H 为缓存指针
mov &ADC12MEM1,0(R15) ; 转存到220H--240H
INC &210H
INC &210H
MOV.B #0FFH,&P5DIR
RET
ADCHULI MOV #220H,&0210H
dec.b &212h
cmp.b #30,&212h
jnz adc104
mov.b #0,&212h
CLRC
MOV #0,R5
MOV #0220H,R15
ADC102 ADD @R15,R5
INC R15
INC R15
CMP #240H,R15
JNZ ADC102
RRA R5
RRA R5
RRA R5
RRA R5
BIC #0F000H,R5 ;除16得平均值
MOV R5,R6 ;后面用R6处理小数部分
RRA R5
RRA R5
RRA R5
RRA R5
; RRA R5
BIC #0F000H,R5 ;除32得
SUB #159,R5
MOV.B TABWENDU(R5),R5 ;从表中查得十进制数
MOV.B R5,&204H ;显示格式:两位正整数,一位小数,从最左边开始
BIC.B #0F0H,&204H
ADD.B #10H,&204H
MOV.B R5,&205H
RRA.B &205H
RRA.B &205H
RRA.B &205H
RRA.B &205H
BIC.B #0F0H,&205H
;203H 小数部分的计算,平均值后5位除以3.2
BIC #0FFE0H,R6 ;剩下最低5位。
MOV R6,R12
MOV #10,R11
CALL #MPYU
MOV #0,R13
MOV R14,R12
MOV #32,R11
CALL #DIVIDE
MOV.B R14,&203H
adc104 ret
DISPLAY_LED MOV.B #0FFh,&P1DIR ;
MOV.B #0FFH,&P5DIR
MOV &208H,R15
MOV.B @R15,R15
MOV.B TABLED(R15),R15 ;从表中查得显示码
MOV.B R15,&P5OUT
MOV.B
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -