📄 ad=数码管.txt
字号:
楼主
--------------------------------------------------------------------------------
AD采样转两位数码管显示程序这是我写的AD转换程序,给不会AD转换的初学者参考借鉴,有错误的地方请大家指正。谢谢给予我帮助的朋友们!
建议大家想看程序的时候,最好复制到文本文档,这样相应的程序命令才能对齐,方便阅读,分析。
以下网址这个贴子,也很不错。对于AD转换到数码显示有很好的示范作用。是最基本的贴子,挺好!
http://pic16.com/bbs/dispbbs.asp?boardid=23&replyid=44155&id=8290&page=1&skin=0&Star=3
这个也不错,大家可以看到小数是怎么处理的。
http://pic16.com/bbs/dispbbs.asp?BoardID=8&ID=17832&replyID=&skin=1 作者SXWY
;************************************
;用两位数码管显示AD数值0.0V-----5.0V
;硬件配置,MCD2和DEMO板参照如下设置
;S1拔OFF, S4拔ON, S5的8为OFF其他ON,S13的2,ON其他OFF
;顺时针转动电位器,数字变小
;此程序用到的几个运算子程序见书<<PIC单片机子程序库及运算平台---庞严英 曹海建著>>
;子程序的调用注意出口参数,入口参数以及字节数,具体的运算可以不管
;AD显示值=ADRESH*50/255 50mV 采用高八位有效值ADRESH
;*****************************************************************
LIST P=16F877 ;列表伪指令
INCLUDE "P16F877.INC" ;把包含文件含入源程序
__CONFIG 3F39H ;设置芯片配置字,振荡方式为HS,其它全部禁止或关闭
;**********************运算子程序用到的RAM空间********************
SADR EQU 020H
SADRH EQU 021H
DADR EQU 022H
CNT EQU 023H
SOU EQU 024H
SOUH EQU 025H
RLT EQU 026H
RLTH EQU 027H
TEMP1 EQU 028H
TEMP2 EQU 029H
TEMP3 EQU 02AH
TEMP4 EQU 02BH
;*****************寄存器定义**********************************************
BCDHI_TEM EQU 30H ;暂存寄存器
BCDLO_TEM EQU 31H ;暂存寄存器
BHW EQU 32H ;电压转换结果BCD码的个位数
SHW EQU 33H ;电压转换结果BCD码的十位数
GHW EQU 34H ;电压转换结果BCD码的个位数
;**********************************************************
ORG 0000H
NOP
GOTO MAIN
ORG 0008H
MAIN
BANKSEL ADCON1
MOVLW B'00001110' ;转换结果左对齐,只选1个A/D通道RA0/AN0
MOVWF ADCON1 ;选择VDD和VSS作参考源
CLRF TRISC ;PORTC所有管脚设为输出(接LED)
MOVLW 01H ;设置RA0为输入,其它为输出
MOVWF TRISA
BANKSEL ADCON0
MOVLW B'10000001' ;选择:时钟时钟源为FOSC/8,允许ADC工作
MOVWF ADCON0 ;通道AN0,暂时不启动转换过程
CLRF PORTC ;清PORTC
;**********************************************************
START BSF ADCON0,GO ;开启A/D转换过程
CALL DELAY ;
WAIT BTFSS PIR1,ADIF ;等待A/D转换过程结束,检测ADC中断标志位
GOTO WAIT ;如果没有转换结束,则返回循环检测
MOVF ADRESH,W ;如果转换完毕,则把A/D结果读到W
MOVWF SOU
CALL ADUZH ;关键的部分,把二进制转为想要的BCD码0.0---5.0V
CALL XIANSHI ;显示送数码管显示,其中的小数字位置在这设定
GOTO START
;**********************************************************
ADUZH BCF STATUS,5 ;在此设定最大显示量程50即0X32
MOVLW 0X32 ;也可以把别的数放入,比如把0X32换为0X64(100)
; 但此数得小于D'255'
MOVWF RLT ;
CALL SUMUL ;把ADRESH*50相乘结果放在SOUH:SOU中
MOVLW 0FFH ;FF即255
MOVWF RLT
CALL DSDIV ;把上面乘的结果除以255
CALL SBTBCD2 ;把得到的商转换为显示的BCD码
MOVF SOUH,0
MOVWF BCDHI_TEM ;将BCD转换值放到中间寄存器
MOVF SOU,0
MOVWF BCDLO_TEM ;将BCD转换值放到中间寄存器
;----------下面将BCD转换结果分离后放在SHW,GHW中-----------------------
SWAPF BCDLO_TEM,0 ;取高位
ANDLW 0FH ;
MOVWF SHW ;存放十位数BCD码
MOVF BCDLO_TEM,0
ANDLW 0FH ;取低位
MOVWF GHW ;存放个位数BCD码
MOVF BCDHI_TEM,0
ANDLW 0FH ;保留低四位
MOVWF BHW ;存放百位数BCD码
RETURN
;*****************************************************************************
XIANSHI MOVLW 0FFH
MOVWF PORTC ;先熄灭所有数码管以免闪烁
MOVLW 03EH
MOVWF PORTA ;先熄灭所有数码管以免闪烁
MOVF GHW,0 ;
CALL CHABIAO ;
MOVWF PORTC ;显示个位数
BCF PORTA,4
CALL DELAY ;调用延时,避免显示抖动
BSF PORTA,4
MOVF SHW,0
CALL CHABIAO
ANDLW B'01111111' ;加上小数点.不加这一步量程可变成00--50
MOVWF PORTC ;显示十位位数
BCF PORTA,5
CALL DELAY ;调用延时,避免显示抖动
BSF PORTA,5
;注意:把0X32替换为0X64时把下面命令前加的引号去掉,才可以正确显示
;MOVF BHW,0
;CALL CHABIAO
;MOVWF PORTC ;显示百位数
;BCF PORTA,2
;CALL DELAY ;调用延时,避免显示抖动
;BSF PORTA,2
RETURN
;*******************延时子程序2ms**********************************
DELAY MOVLW 0FFH
MOVWF 034H
LP0 NOP
NOP
NOP
NOP
NOP
DECFSZ 034H
GOTO LP0
RETURN
;**********************************************************
CHABIAO
ADDWF PCL,F ;将W寄存器内的7段显示码地址与PC相加
RETLW 0C0H ;0 ;RETLW指令,将七段显示码存入W后返回
RETLW 0F9H ;1
RETLW 0A4H ;2
RETLW 0B0H ;3
RETLW 099H ;4
RETLW 092H ;5
RETLW 082H ;6
RETLW 0F8H ;7
RETLW 080H ;8
RETLW 090H ;9
;********************SUMUL********************
;本程序实现单字节无符号数乘法。
;入口参数:被乘数在SOU中,乘数在RLT中。
;出口参数:结果在SOUH:SOU中。
;占用资源:W,STATUS,023H,024H,025H,026H,一重堆栈。
SUMUL MOVLW 8
MOVWF CNT
MOVF SOU,W
CLRF SOU
CLRF SOUH
BCF STATUS,C
LOOP2 RRF RLT,F
BTFSC STATUS,C
ADDWF SOUH,F
RRF SOUH,F
RRF SOU,F
DECFSZ CNT,F
GOTO LOOP2
RETLW 0
RETURN
;********************DSDIV********************
;本程序实现双字节有符号数除法。
;入口参数:被除数在SOUH:SOU中,除数在RLTH:RLT中。
;出口参数:商在SOUH:SOU中,余数在RLTH:RLT中.
;占用资源:W,STATUS,021H,023H~02BH,一重堆栈。
;说 明: 1.用户在调用该子程序之前必须确定除数不为零,否则得不到正确结果.
; 2.余数一定为正数.
; 3.被除数绝对值一定要大于除数的绝对值,否则将出错.
DSDIV MOVLW .16 ;循环16次
MOVWF CNT
MOVF RLTH,W
XORWF SOUH,W
MOVWF SADRH ;SADRH暂存相除后的符号位
BTFSS SOUH,7
GOTO NEXT45
COMF SOU,F
COMF SOUH,F
INCF SOU,F
BTFSC STATUS,Z
INCF SOUH,F ;负数取相反数
NEXT45 BTFSS RLTH,7
GOTO NEXT46
COMF RLT,F
COMF RLTH,F
INCF RLT,F
BTFSC STATUS,Z
INCF RLTH,F ;负数取相反数
NEXT46 MOVF SOUH,W
MOVWF TEMP4
MOVF SOU,W
MOVWF TEMP3 ;被除数转移到TEMP4:TEMP3中
CLRF SOUH
CLRF SOU ;SOUH:SOU用来存放商
CLRF TEMP2
CLRF TEMP1 ;TEMP2:TEMP1得到余数
LOOP83 BCF STATUS,C
RLF TEMP3,F
RLF TEMP4,F
RLF TEMP1,F
RLF TEMP2,F
MOVF RLTH,W
SUBWF TEMP2,W ;检测是否余数大于除数
BTFSS STATUS,Z
GOTO NOCHK1
MOVF RLT,W
SUBWF TEMP1,W ;如果高位相等则检测低位
NOCHK1 BTFSS STATUS,C
GOTO NOGO1
MOVF RLT,W ;余数减除数
SUBWF TEMP1,F
BTFSS STATUS,C
DECF TEMP2,F
MOVF RLTH,W
SUBWF TEMP2,F
BSF STATUS,C ;结果中移入1
NOGO1 RLF SOU,F
RLF SOUH,F
DECFSZ CNT,F
GOTO LOOP83
MOVF TEMP1,W
MOVWF RLT
MOVF TEMP2,W
MOVWF RLTH ;余数归位
BTFSS SADRH,7
RETLW 0 ;结果是正数则返回
COMF SOU,F
COMF SOUH,F
INCF SOU,F
BTFSC STATUS,Z
INCF SOUH,F
RETLW 0
;********************SBTBCD2********************
;本程序实现单字节二进制数转化为2字节压缩BCD码。
;入口参数:原二进制数在SOU中。
;出口参数:结果在SOUH:SOU中。
;占用资源:W,STATUS,023H,024H,025H,028H,029H,两重堆栈。
IFNDEF SBTBCD21
#DEFINE SBTBCD21
SBTBCD2 MOVF SOU,W
MOVWF TEMP2
CLRF SOU
CLRF SOUH
BCF STATUS,C
MOVLW 8
MOVWF CNT
LOOPC RLF TEMP2,F
RLF SOU,F
RLF SOUH,F
DECFSZ CNT,F
GOTO ADJDEC
RETURN ;整个子程序结束
ADJDEC MOVLW SOU
MOVWF FSR
CALL ADJBCD ;调整SOU
MOVLW SOUH
MOVWF FSR
CALL ADJBCD ;调整SOUH
GOTO LOOPC
;********************调整BCD********************
ADJBCD MOVLW 03H
ADDWF INDF,W ;低四位加3
MOVWF TEMP1 ;暂存
BTFSC TEMP1,3 ;结果大于7,
MOVWF INDF ;则存起来
MOVLW 30H
ADDWF INDF,W ;高四位加3
MOVWF TEMP1
BTFSC TEMP1,7 ;结果大于7,
MOVWF INDF ;则存起来
RETLW 0
;**************************************************
END ;源程序结束
;**************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -