/*RAM*/
ADR_RAM1_MIN DATA 0000H ADR_RAM1_MAX DATA 1FFFH ADR_RAM2_MIN DATA 2000H ADR_RAM2_MAX DATA 3FFFH ADR_RAM3_MIN DATA 4000H ADR_RAM3_MAX DATA 5FFFH ADR_RAM4_MIN DATA 6000H ADR_RAM4_MAX DATA 7FFFH /*ADC0809*/
ADR_ADC0809_CH0_MIN DATA 0a000H ADR_ADC0809_CH0_MAX DATA 0bff8H
ADR_ADC0809_CH1_MIN DATA 0a001H ADR_ADC0809_CH1_MAX DATA 0bff9H /*8155*/
ADR_CONTROL_MIN DATA 8000H ADR_CONTROL_MAX DATA 9FF8H ADR_PA_MIN DATA 8001H ADR_PA_MAX DATA 9FF9H ADR_PB_MIN DATA 8002H ADR_PB_MAX DATA 9FFAH ADR_PC_MIN DATA 8003H ADR_PC_MAX DATA 9FFBH
GEWEI DATA 2FH; //个位BCD数据存放位置 SHIWEI DATA 30H; //十位BCD位数据存放位置 FUAHOWEI DATA 31H; //符号位 /*The mecro end*/
/*MAIN Structer start */
ORG 0000H SJMP MAIN ORG 0003H
SJMP ADC_Finish ORG 000BH SJMP TIM0_IRQ ORG 0023H
LJMP USART_Send MAIN:
MOV SP,#60H CLR A ; // 请累加器A SETB EA ; //开CPU中断
SETB ET0 ; //开定时器T0中断 MOV TMOD,#21H; //选用TO的计时方式1 MOV TH0,#3CH //定时器重装值 MOV TL0,#82H
/*----------------串口初始化------------------------------*/ MOV TH1,#0F4H MOV TL1,#0F4H MOV PCON,#80H SETB TR1 MOV SCON,#40H SETB ES SETB EX0; //开INT0外部中断 SETB IT0; //下降沿触发 SETB PT0; //定时中断优先级高 MOV R1,#10; //循环采样计数值 MOV R4,#20; //采样间隔为1s,定时中断为50ms,需要进 SETB TR0 ; //启动TO MOV DPTR,#ADR_ADC0809_CH0_MIN; //ADC0809地址给DPTR MOVX @DPTR,A; //启动ADC0809 /* 8155IO口工作模式设定 */ MOV DPTR,#ADR_CONTROL_MIN; //DPTR指向状态口 MOV A,#80H MOVX @DPTR,A; //令A,B,C口为输出 Loop:
LCALL LED_DIP ; //调用显示子程序 LCALL SCAN ; //调用扫描子程序 LJMP Loop /*串口发送接受中断程序*/ /*---若使用上位机,发送数据前先发送0x23*/ USART_Send:
PUSH PSW PUSH ACC SETB RS0 SETB RS1 MOV C,TI JC SEND
SJMP ACCEPT SEND:
CLR TI MOV A,R7 MOV SBUF,A
SJMP USART_DOWN ACCEPT:
CLR RI
MOV A,SBUF MOV R6,A
USART_DOWN: POP ACC POP PSW CLR RS0 CLR RS1 RETI
/*TIM0中断进行平均求值,进行数码管显示*/ ADC_Finish:
PUSH DPH PUSH DPL PUSH ACC CJNE R7,#00H,DUAL_MODE LJMP CH1_1 DUAL_MODE:
SETB RS1 CLR RS0 CJNE R6,#00H,CH1 MOV R6,#01H MOV DPTR,#ADR_ADC0809_CH0_MIN CH1:
MOV R6,00H
LJMP CHANLE_1_CONVENT CH1_1:
MOV DPTR,#ADR_ADC0809_CH1_MIN SING_CONVENT:
//MOV DPTR,#ADR_ADC0809_CH0_MIN MOVX A,@DPTR; //取值 MOV @R0,A ; //将采样值送到存储地址 MOVX @DPTR,A; //重新启动ADC0809 INC R0 ; //存储地址加一 DJNZ R1,INTLOOP; //判断是否存满十个数据,否,返回主函数 MOV R0,#32H //填满十个采样值后,更新采样首地址 MOV R1,#10 LJMP INTLOOP CHANLE_1_CONVENT: MOVX A,@DPTR; //取值
MOV @R0,A ; //将采样值送到存储地址 MOVX @DPTR,A; //重新启动ADC0809 INC R0 ; //存储地址加一 DJNZ R1,INTLOOP; //判断是否存满十个数据,否,返回主函数
MOV R0,#42H //填满十个采样值后,更新采样首地址 MOV R2,#10 LJMP INTLOOP INTLOOP:
POP ACC
POP DPL POP DPH RETI
/*INT0外部中断,ADC0809转换完毕,进行ADC0通道读取,并开始重新一次转化*/ TIM0_IRQ:
PUSH DPH PUSH DPL PUSH ACC
MOV TH0,#3CH; //定时中断服务函数 MOV TL0,#82H DJNZ R4,DONE; //若没到20次,直接返回主函数 MOV R4,#20 ACALL DATA_Explose; //求采样平均值子函数 DONE: POP ACC
POP DPL POP DPH RETI RETI C
/*-------------------------------键盘扫描程序-----------------------------*/ SCAN:
PUSH ACC PUSH DPL PUSH DPH MOV P1,#0FFH MOV A,P1
CJNE A,#0FFH,KEY_ON LJMP DOWN_KEY KEY_ON:
LCALL DELAY //10ms延时消抖 LCALL DELAY
MOV P1,#0FFH MOV A,P1
CJNE A,#0FFH,KEY_ON_Really LJMP DOWN_KEY KEY_ON_Really:
SETB RS0
CLR RS1 //使用1区寄存器 CJNE A,#0FEH,NEXT1 MOV R7,#0 NEXT1:
CJNE A,#0FDH,NEXT2 MOV R7,#1 NEXT2:
CJNE A,#0FBH,NEXT3 MOV R7,#2 NEXT3: MOV R7,#0 DOWN_KEY: CLR RS0 CLR RS1 POP DPH POP DPL POP ACC RET
DATA_Explose: PUSH ACC PUSH DPL PUSH DPH
/*把寄存器切换到1区*/ CLR RS1 SETB RS0 CLR A
MOV R4,#00H MOV R5,#00H MOV R3,#10 CLR C
MOV R1,#32H LOOP_ADD: ADDC A,@R1 JC ADD_High_8 SJMP ADD_Continue ADD_High_8: INC R4 CLR C
ADD_Continue: INC R1
DJNZ R3,LOOP_ADD MOV R5,A AD_AVE: