原创 MAX4080测量电流的PIC程序

2009-8-15 01:21 4561 7 7 分类: MCU/ 嵌入式

;*****************************************************************************************
;功能:配合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条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /2 下一条