;*****************************************************************************************
;功能:配合MAX4080T芯片测量MAX3221通信模块的电流(大约在0~4mA之间),采样的电阻为50欧姆
; 电流直接通过液晶屏显示出来,现实的结果如下:
; MAX4080 PROG
; I="1".692mA
;原理:采样电压Vad=(采样值*5v)/1024,采样电阻Rsense两端的电压Vsense=Vad/20
; 通信模块的电流I=Vsense/Rsense
;硬件:PIC16F877A
;实现:用LCD1602的液晶屏显示采样电压值,基准选用内部的5v,采样通道为AN0,电压精度为
; 小数点后2位,显示时为小数点后3位
; 电流I=(采样值*5)/1024mA,将电流值转换成要显示的电流值的算法为软件模拟除法和乘法的
; 计算公式
;小节:显示的电流的值和送入ADC通道的电压在数值上是相等的,且软件在算法上没有误差
;*****************************************************************************************
#INCLUDE<P16F877a.INC>
__CONFIG _DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_HS_OSC
;芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡
;-------------------------------------------
ADL EQU 20H ;采样值存放寄存器
ADH EQU 21H
TEMP EQU 22H ;暂存器
COUNT EQU 26H ;定义计数寄存器地址
TMP1 EQU 27H ;定义临时寄存器地址
COUNTER EQU 28H
CNT EQU 29H
;-------------------------------------------
ADGE EQU 23H ;个位
ADSF EQU 24H ;十分位
ADBF EQU 25H ;百分位
ADQF EQU 33H ;千分位
ADLT EQU 30H ;采样值存放暂存器
ADHT EQU 31H
TIMES EQU 32H ;乘法倍数寄存器
;-------------------------------------------
#DEFINE RS PORTA,1 ;LCD的控制信号
#DEFINE RW PORTA,2
#DEFINE E PORTA,3
;-------------------------------------------
ORG 00H ;复位入口地址
NOP ;ICD需要的空指令
GOTO MAIN ;跳转到主程序入口
;-------------------------------------------
MAIN
;--------------配置AD模块----------------
BANKSEL TRISA
MOVLW 01H
MOVWF TRISA ;RA0设为输入引脚
BANKSEL ADCON1
MOVLW B'10001110'
MOVWF ADCON1 ;配置RA0为模拟引脚,基准为VDD,其余I/O为数字引脚
BANKSEL ADCON0
MOVLW B'01000001' ;选择AN0采样通道,转换时钟为Fosc/8,打开AD模块
MOVWF ADCON0
BCF PIR1,ADIF
;-------------LCD/I/O初始化-----------------
BSF STATUS,RP0 ;转体1
MOVLW 8EH
MOVWF ADCON1 ;
MOVLW 01H
MOVWF TRISA ;
MOVLW 00H
MOVWF TRISD ;定义D口为输出
BCF STATUS,RP0 ;回体0
;-------------------------------------------
CALL LCD_INIT ;LCD显示初始化,设置LCD显示模式
;******************************************************************************
; 开始ADC采样,每300ms采样一次,注意采样的速率不要超过LCD显示的反应时间
; 程序一直循环采样,注意采样结果寄存器并不在同一个体内,且ADIF要及时的清0
;******************************************************************************
ADC_AGAIN
CALL DELAY_100MS
BSF ADCON0,GO
;-------------------------------------
WAIT
BTFSS PIR1,ADIF ;转换是否完成
GOTO WAIT ;
;-------------------------------------
BCF PIR1,ADIF ;清标志
BANKSEL ADRESL ;保存采样结果的低八位
MOVF ADRESL,W
BANKSEL ADL
MOVWF ADL
BANKSEL ADRESH ;保存采样结果的高八位
MOVF ADRESH,W
MOVWF ADH
BCF STATUS,RP0
CALL DELAY_100MS ;延时200ms
CALL DELAY_100MS
;-------------------------------------
CALL AD_DATA ;调用数据处理子程序,得到电流值
CALL LCD_DISP ;显示结果
GOTO ADC_AGAIN
;*********************************************************************************************
; 以下为子程序
;*********************************************************************************************
;------------------------------------------------------------------------
; 数据处理子程序
;将采样值转换成相应的电流值,处理成为适合显示的数据进行存储
;------------------------------------------------------------------------
AD_DATA
CLRF ADGE ;清除显示寄存器
CLRF ADSF
CLRF ADBF
CLRF ADQF
MOVLW B'00000011' ;保留采样结果高字节的的低两位
ANDWF ADH,F
;-------------------求有多少个1mA-----------
MOVLW 05H ;采样结果乘以5
MOVWF TIMES
CALL AD_TIMES
AD_PRO2
MOVLW 04H ;除以400
SUBWF ADHT,W
BTFSS STATUS,C ;够减时,间跳
GOTO AD_PRO4 ;不够减时,发生借位,跳转
;--------------------------------
AD_PRO3 INCF ADGE,F
MOVLW 04H
SUBWF ADHT,F
;---------------------------------
GOTO AD_PRO2
;--------------计算有多少个0.1mA------------
AD_PRO4
MOVF ADLT,W ;余数存入ADL和ADH寄存器中
MOVWF ADL
MOVF ADHT,W
MOVWF ADH
MOVLW 0AH ;采样结果乘以0A
MOVWF TIMES
CALL AD_TIMES
;--------------------------------
AD_PRO20
MOVLW 04H
SUBWF ADHT,W
BTFSS STATUS,C ;够减时,间跳
GOTO AD_PRO40 ;不够减时,发生借位,跳转
;--------------------------------
MOVLW 04H
SUBWF ADHT,F
INCF ADSF,F
;---------------------------------
GOTO AD_PRO20
;-------------计算有多少个0.01mA------------
AD_PRO40
MOVF ADLT,W
MOVWF ADL
MOVF ADHT,W
MOVWF ADH
MOVLW 0AH
MOVWF TIMES
CALL AD_TIMES
;--------------------------------
AD_PRO21
MOVLW 04H
SUBWF ADHT,W
BTFSS STATUS,C ;够减时,间跳
GOTO AD_PRO41 ;不够减时,发生借位,跳转
;--------------------------------
MOVLW 04H
SUBWF ADHT,F
INCF ADBF,F
;---------------------------------
GOTO AD_PRO21
;-------------计算有多少个0.001mA-----------
AD_PRO41
MOVF ADLT,W
MOVWF ADL
MOVF ADHT,W ; 余数乘以10
MOVWF ADH
MOVLW 0AH
MOVWF TIMES
CALL AD_TIMES
AD_PRO22
MOVLW 04H
SUBWF ADHT,W
BTFSS STATUS,C ;够减时,间跳
GOTO OVER ;不够减时,发生借位,跳转
;--------------------------------
MOVLW 04H
SUBWF ADHT,F
INCF ADQF,F
;---------------------------------
GOTO AD_PRO22
;---------------------------------
OVER MOVLW 30H
ADDWF ADGE,F ;转换成要显示的字符内码
ADDWF ADSF,F
ADDWF ADBF,F
ADDWF ADQF,F
RETURN
;********************设置LCD显示模式***********************
LCD_INIT
CALL DELAY_100MS ;调用延时,刚上电LCD复位不一定有PIC快(2MS)
MOVLW 01H
MOVWF PORTD ;清屏命令,数据指针清零,所有显示清零
CALL ENABLE ;调用写命令程序
MOVLW 38H
MOVWF PORTD ;8位2行5x7点阵
CALL ENABLE
MOVLW 0CH ;显示开、光标不显示
MOVWF PORTD
CALL ENABLE ;当读或写一个字符后,地址指针加一,且光标加一
MOVLW 06H ;当写一个字符后,整屏显示不移动
MOVWF PORTD
RETURN
;-------------------------------------------------------------------------
; 显示子程序
; 将电流等数据送到LCD1602液晶屏上显示,
;-------------------------------------------------------------------------
LCD_DISP
CALL ENABLE ;设置数据地址指针
MOVLW 082H
MOVWF PORTD ;第一行的位置
CALL ENABLE
;--------------------------
MOVLW 4DH
CALL WRITE3 ;显示‘M’
;--------------------------
MOVLW 41H
CALL WRITE3 ;显示‘A’
;--------------------------
MOVLW 58H
CALL WRITE3 ;显示‘X’
;--------------------------
MOVLW 34H
CALL WRITE3 ;显示‘4’
;--------------------------
MOVLW 30H
CALL WRITE3 ;显示‘0’
;--------------------------
MOVLW 38H
CALL WRITE3 ;显示‘8’
;--------------------------
MOVLW 30H
CALL WRITE3 ;显示‘0’
;--------------------------
MOVLW 20H
CALL WRITE3 ;显示‘ ’
;--------------------------
MOVLW 50H
CALL WRITE3 ;显示‘P’
;--------------------------
MOVLW 52H
CALL WRITE3 ;显示‘R’
;--------------------------
MOVLW 4FH
CALL WRITE3 ;显示‘O’
;--------------------------
MOVLW 47H
CALL WRITE3 ;显示‘G’
;-------------------------------------------
CALL ENABLE ;设置数据地址指针
MOVLW 0C4H
MOVWF PORTD ;第二行的位置
CALL ENABLE
;--------------------------
MOVLW 49H
CALL WRITE3 ;显示‘I’
;--------------------------
MOVLW 3DH
CALL WRITE3 ;显示‘=’
;--------------------------
MOVF ADGE,W
CALL WRITE3 ;把个位数据送LCD显示
;--------------------------
MOVLW 2EH ;显示小数点‘.’
CALL WRITE3
;--------------------------
MOVF ADSF,W ;把十分位数据送LCD显示
CALL WRITE3
;--------------------------
MOVF ADBF,W ;把百分位数据送LCD显示
CALL WRITE3
;--------------------------
MOVF ADQF,W ;把千分位数据送LCD显示
CALL WRITE3
;--------------------------
MOVLW 6DH
CALL WRITE3 ;显示‘m’
;--------------------------
MOVLW 41H
CALL WRITE3 ;显示‘A’
;--------------------------
RETURN
;-------------------------------------------
; 写数据到LCD子程序
;-------------------------------------------
WRITE3
MOVWF PORTD ;
BSF RS
BCF RW
BCF E
CALL CHK_BUSY
BSF E
RETURN
;-------------------------------------------
; 写命令到LCD子程序
;-------------------------------------------
ENABLE
BCF RS ;写入控制命令的子程序
BCF RW
BCF E
CALL CHK_BUSY
BSF E
RETURN
;-------------------------------------------
; 判断总线是否忙子程序
; RS="0",RW=1,E=H,D0-D7=状态字
;-------------------------------------------
CHK_BUSY
BANKSEL TRISD
MOVLW 0FFH
MOVWF TRISD ;D口设置为输入
CLRF STATUS
BANKSEL PORTD ;
MOVLW 0FFH
MOVWF PORTD
BCF RS
BSF RW
CHECK_BUSY_1
NOP
NOP
NOP
BSF E
NOP
NOP
NOP
BTFSS PORTD,7 ;D7为高表示总线忙,为低表示总线空闲
GOTO $+6
NOP
NOP
NOP
BCF E
GOTO CHECK_BUSY_1
BCF E
BANKSEL TRISD
CLRF TRISD ;恢复D口为输出
CLRF STATUS
BANKSEL PORTD
RETURN
;-------------------------------------------
; 采样值倍乘法子程序
; ADLT,ADHT=TIMES*ADL,ADH
;-------------------------------------------
AD_TIMES
CLRF ADLT
CLRF ADHT
BCF STATUS,C
;----------------------------
aga MOVF ADL,W
ADDWF ADLT,F
BTFSS STATUS,C
GOTO $+2
;----------------------------
INCF ADHT,F
;----------------------------
MOVF ADH,W
ADDWF ADHT,F
DECFSZ TIMES,F
GOTO aga
RETURN
;------------------------------------------------
; 2.001ms秒延时程序
;------------------------------------------------
DELAY MOVLW 0FAH
MOVWF COUNTER
LP0 NOP
NOP
NOP
NOP
NOP
DECFSZ COUNTER,F
GOTO LP0
RETURN
;------------------------------------------------
; 100.2ms秒延时程序
;------------------------------------------------
DELAY_100MS MOVLW 32H
MOVWF CNT
LP2 MOVLW 0FAH
MOVWF COUNTER
LP1 NOP
NOP
NOP
NOP
NOP
DECFSZ COUNTER,F
GOTO LP1
DECFSZ CNT,F
GOTO LP2
RETURN
;------------------------------------------------------------------------------
END ;程序结束
文章评论(0条评论)
登录后参与讨论