大家好,我是单片机初学者,刚学汇编程序,用PIC16F876A-A/SP做了块实验板,调A/D模块部分快一个星期了,没调试成功,想借助宝地请各位老师指点下。
下面是相关的实验板原理图
实验板原理图
此汇编程序实现A/D转换功能,应用于pic单片机上,A/D采用中断方式。该程序通过单片机的RA5模拟通道送入一直流电压,当送入的直流电压大于2.5V时,继电器1(RCO口输出高电平),当送入的直流电源低于2.5V,继电器1(RC0口输出低电平)。为了防止干扰,本程序对直流电压采样10次后再作判断,中间的采样结果用间接寻址的方式存取。
INCLUDE "P16F876A.INC"
TIMES EQU 0X20
DEY EQU TIMES+1
ACCALO EQU TIMES+2 ;存放加数或减数低8位
ACCAHI EQU TIMES+3 ;存放加数或减数高8位
ACCBLO EQU TIMES+4 ;存放被加数或被减数低8位
ACCBHI EQU TIMES+5 ;存放被加数或被减数高8位
FLAG EQU TIMES+6
DEYH EQU TIMES+7
DEYL EQU TIMES+8
BEGFSR EQU 0X30 ;间接寻址FSR的起始值(宏定义方式给出)
ORG 0000H ;直接执行主程序
NOP
GOTO MAIN ;无条件跳转到主程序
ORG 0004H
NOP
GOTO INTSERVE ;转向中断服务子程序
RETFIE ;中断返回
ORG 0100H
;***双字节减法子程序,入口地址ACCB-ACCA,出口地址ACCB***
D_sub CALL NEG_A ;求ACCA的补码
;***双字节加法子程序,入口地址ACCB+ACCA,出口地址ACCB***
D_ADD MOVF ACCALO,0 ;ACCB和ACCA低半字节相加
ADDWF ACCBLO
BTFSC STATUS,C ;有进位否?
INCF ACCBHI ;有,ACCB高字节加1,再加ACCAHI
MOVF ACCAHI,0 ;ACCA、ACCB高半字节相加
ADDWF ACCBHI
RETURN ;子程序返回
;************** ACCA取补子程序*****************
NEG_A COMF ACCALO ;ACCALO取反加1
INCF ACCALO
BTFSC STATUS,Z ;低8位有进位吗?
DECF ACCAHI ;有,ACCAHI减1,再取反
COMF ACCAHI ;否则ACCAHI直接取反
RETURN ;子程序返回
;*********初始化子程序***************
INITIAL
BSF STATUS,RP0 ;选1页
BCF STATUS,RP1
MOVLW 03FH ;0011 1111
MOVWF TRISA ;设置RA口为输入方式
MOVLW 81H ;1000 0001
MOVWF TRISB ;设置RB口 RB1 RB2 RB3 RB4 RB5为口输出方式
;RB0口输入方式 RB6 RB7口为三态
MOVLW 00H
MOVWF TRISC ;设置RC口为输出方式
MOVLW 80H ;1000 0000
MOVWF ADCON1 ;转换结果右移,即ADRESH寄存器的高6位为0,
;且把RA0 RA1 RA2 RA3 RA4 RA5设置成模拟量
;输入口
BSF PIE1,ADIE ;允许A/D中断
BCF STATUS,RP0 ;选0页
MOVLW 34H ;
MOVWF PORTB ;设置RB口输出电平为 0011 0100 ,关闭LED发
;光管,关闭输出控制继电器
MOVLW 00H
MOVWF PORTC ;设置RC口输出电平为 0000 0000 ,关闭主继电
;器 电流、电压给定输出为0
MOVLW 0A9H ;1010 1001
MOVWF ADCON0 ;选择A/D转换通道RA5,且打开A/D工作状态,
;并使A/D转换时钟位32tosc
CLRF INTCON ;总中断禁止
BSF INTCON,PEIE ;外围中断允许 把寄存器INTCON中PEIE位置1
CLRF PIR1 ;清除A/D转换标志位
CLRF FLAG
RETURN
;*********软件延时子程序****************
DELAY MOVLW 0XFF
MOVWF DEYH
AGAIN1 MOVLW 0XFF
MOVWF DEYL
AGAIN2 NOP
DECFSZ DEYL
GOTO AGAIN2
DECFSZ DEYH
GOTO AGAIN1
RETURN
;*************** A/D中断服务子程序*****************
INTSERVE
BCF PIR1,ADIF ;清除A/D转换标志
MOVF ADRESH,W
MOVWF INDF ;读取并存储A/D转换结果的高2位
INCF FSR
BANKSEL ADRESL
MOVF ADRESL,W
MOVWF INDF
INCF FSR ;读取并存储A/D转换结果的低8位
BCF STATUS,RP0
DECF TIMES,1 ;A/D转换次数减1
MOVLW 0X02
MOVWF DEY
LOOP13 DECFSZ DEY,1
GOTO LOOP13 ;给予一定的延时,保证两次A/D转换期间
;2tAD的间隔时间和电容的采样时间
BSF ADCON0,2 ;启动下一次A/D转换
RETFIE ;中断返回
;********** 主电源开关继电器控制*************
K1
BSF PORTC,0
RETURN
K2 BCF PORTC,0
RETURN
;****************************************
MAIN NOP
CALL INITIAL ;初始化
LOOP
BCF STATUS,RP0 ;选1页
MOVLW BEGFSR
MOVWF FSR ;给出间接寻址时FSR的初值
MOVLW 0X0A
MOVWF TIMES ;每一轮A/D连续采样10次
BSF INTCON,GIE ;总中断打开,可以进行A/D转换中断
MOVLW 19H
MOVWF 31H
DELAY15US
DECFSZ 31H
GOTO DELAY15US
BSF ADCON0,2 ;启动A/D转换
LOOP1
MOVF TIMES,W
BTFSS STATUS,Z
GOTO LOOP1 ;等待A/D转换中断
BCF INTCON,GIE ;A/D转换次数到10次,关闭中断
NOP
CLRF ACCBHI
CLRF ACCBLO ;双精度加法的结果寄存器清0,为后面准备
MOVLW 0X0A
MOVWF TIMES
MOVLW BEGFSR
MOVWF FSR
LOOP15 MOVF INDF,W
MOVWF ACCAHI
INCF FSR
MOVF INDF,W
MOVWF ACCALO
INCF FSR
CALL D_ADD
DECFSZ TIMES
GOTO LOOP15
NOP ;计算得到10次A/D转换的和
BANKSEL ACCAHI
MOVLW 0X14
MOVWF ACCAHI
CLRF ACCALO
CALL D_sub ;通过双精度减判断模拟量是否达到报警限
;度(1400H=200H*0AH,200H与2.5V对应)
BTFSS ACCBHI,7
CALL K1 ;若ACCBHI的最高位为1,则证明减法结
;果为负,即直流电压值超过2.5V,RC0置1
NOP
BTFSC ACCBHI,7
CALL K2 ;若ACCBHI的最高位为1,则证明减法结
;果为正负,即直流电压值低于超过2.5V,
;RC0清零
CALL DELAY ;软件延时,使电压检测不要过于频繁
GOTO LOOP ;重复检测输入的直流电压值
END
cdq1.rar
(2.03 KB, 下载次数: 3)
2011-12-24 09:48 上传
点击文件名下载附件
汇编语言代码
kk2.rar
(18.16 KB, 下载次数: 3)
2011-12-24 09:48 上传
点击文件名下载附件
仿真电路图
这段程序在MPLAB IDE中软仿是可以运行的,用PICKIT3硬仿一直停留在A/D打开后,不能检测到A/D完成中断标记位,一直循环在
LOOP1
MOVF TIMES,W
BTFSS STATUS,Z
GOTO LOOP1 ;等待A/D转换中断
跳不出去,请大家指点下,在线期待大家的回复!我的QQ:179755240,和大家交个朋友
此帖出自
小平头技术问答
一周热门 更多>