PFS122检测VDD及IO口的AD电压方法

控制/MCU

1877人已加入

描述

PFS122是应广推出的一颗,可以多次烧录的2K程序空间的带数字12位AD转换的单片机。目前以高性价比重新获得用户的喜爱,其价格优势明显,比九齐的062E的价格,可能还更具有优势。

PFS122的AD转换相对于PMS132等来说,显得比较劣势,主要是因为IC不能接外部参考电压,也不提供内部的2V,3V, 4V等参考电压。这样在处理VDD处于变化的应用环境,比如锂电池应用,就显得没有那么方便。

在处理VDD方面,也就是获取锂电池电压的时候,还有个别工程师的设计是使用两个电阻分压,再利用一个IO口去采集分压点来处理。这样处理用是能用,但是显得很不经济,也浪费IO口,甚至还浪费静态功耗。PFS122内部提供的参考电压1.2V,就是专门用来获取VDD电压的。也就是说1.2V相对来说是稳定的,那么不同的VDD电压,采集到稳定1.2V时,所得到的AD转换结果是不一样的,但是遵循比例:VDD/1.2V=4096/Nbg.

由上面的比例可以得到VDD = 40961.2V/Nbg= 409612000mV/Nbg

=4915200mV/Nbg=((4b0000)hex)mV/Nbg,(1)

Nbg: 是使用VDD做AD转换的参考电压,采用内部特殊通道1.2的标准电压所得的数值。

在获取IO的电压时,我们可以同样利用比列来计算,计算的基础是

;Vbg/VDD=Nbg/4096------------------(2)

;Vin/VDD=Nin/Nvdd=Nin/4096------- (3)

两个比列相除,可以消掉VDD和4096,得到Vin=(Nin/Nbg)*Vbg

;VIN=(Nin/Nbg)Vbg=(Nin/Nbg)1200=Nin1200/Nbg=0x4b0Nin/Nbg(4)

因此,只要有Nin和 Nbg的AD转换数值,就可以得到IO口的实际输入电压是多少。由公式(1)和公式(4),可以看出要得到VDD和Vin的实际电压,需要用到运算方式,三字节除以2字节,两字节乘以两字节的运算。对于习惯了MINI-C开发的用户来说,这些运算处理方式可以在“程序助手”中的/进阶实例/数据运算中获取。

EWORD div_src3;//被除数(商)

WORD div_val2, div_res2;//除数,余数

void EWord_Div_Word (void)

{ // div_src3[E] / div_val2[W] = div_src3[E] * div_val2[W] + div_res2[W]

BYTE div_cnt, div_tmp;

div_cnt = 8;

div_res2 = 0;

do
{
    div_src3    <<=        1;
    div_res2    <<<=    1;
    div_tmp        <<<=    1;
    div_cnt++;
    A    =    (div_res2 - div_val2) >> 8;

    if (div_tmp.0 || ! CF)
    {
        div_res2$1    =    A;
        div_res2$0    -=    div_val2$0;
        div_src3.0    =    1;
    }
} while (! div_cnt.5);

}

//--------------------------------------------------------------------------------//

//程序说明:

// 一个16位变量(范围065535)与一个定值(500,范围065535)相乘

// 两个乘数可以为定值,也可为变量

// 同为定值时可直接用“*”运算符

//注意事项:

// 1.案例为PMS154C,其他芯片可直接使用

//********************************************************************************//

#include "extern.h"

DWORD mul_t4;

WORD mul_x2;

WORD mul_y2;

void Word_Mul_Word (void)

{ // mul_t4[D] = mul_x2[W] * mul_y2[W]

mul_t4$3 = 0;

mul_t4$2 = 0;

BYTE    cnt;
cnt    =    16;

do
{
    mul_x2    >>=    1;
    if (CF)
    {
        mul_t4    +=    (mul_y2 << 16);
    }
    mul_t4    >>>=    1;
} while (--cnt);

}

但是对于一些不熟悉MINI-C的工程师朋友来说,用汇编弄起来就可能有点难度了。那也没有关系,你打赏我吧,我花了一些时间,整理了一些汇编的参考程序, 哈哈( 0 )。

pfs

汇编写起来比较累人,参考一下,16进制转10进制的汇编吧。

;-------HEX to BCD subroutine-------------------------

; Name :hex2bcd

; Input :temp0(H), temp1(L)

; Output :temp3(H), temp4(M),temp5(L)

; Stack level :2

; Function :16-bit-hex to 5-bit-dec

; Temp reg :temp2(counter register),temp6,fpp0_index

; Argument :

;--------------------------------------------

hex2bcd:

clear  hb@fpp0_index

mov    a, 0x10

mov    temp2, a

clear  temp3

clear  temp4

clear  temp5



set0   flag_c

shift:

slc    temp1

slc    temp0

slc    temp5

slc    temp4

slc    temp3

dzsn   temp2

goto   adjdec

ret

adjdec:

mov   a, la@temp5

    mov  lb@fpp0_index, a

    call  adjbcd

    mov   a, la@temp4

    mov  lb@fpp0_index, a

    call  adjbcd

    mov   a, la@temp3

    mov  lb@fpp0_index, a

    call  adjbcd

    goto  shift

adjbcd:

;---------------------------------

; mov a, 0x22

; idxm fpp0_index, a

;---------------------------------

idxm  a, fpp0_index

    add   a, 0x03

    mov   temp6, a

    t0sn  temp6.3

    idxm  fpp0_index, a

    idxm  a, fpp0_index

    add   a, 0x30

    mov   temp6, a

    t0sn  temp6.7

    idxm  fpp0_index, a

    ret   0x00

;-------------the end of hex2bcd---------------------

;-----------------------------------------------

;

;-------unsigned (eword)eint Div unsigned int-------------------

; Name :ueint_div_uint

; Input : temp2(D1H),temp3(D1M);temp4(D1L),temp5(D2H),temp6(D2L)

; Output : temp11(QH)temp12(QL),temp13(),

; temp7(remainer H),temp8(remainer L)

; Stack level :1

; Temp reg :temp0(bit count),temp1(bit0:flow flag),temp8(h),temp9(l)

; Function :unsigned eint div unsignedd int;D1/D2,

; Argument :

;--------------------------------------------

ueint_div_uint:

mov a, 0x18

mov temp0, a

clear  temp9

clear  temp7

clear  temp8

ediv_loop:

sl  temp4

slc  temp3

slc  temp2

slc  temp8

slc  temp7

slc  temp9

t0sn temp9.0

goto evalid_bit

mov  a, temp8

sub  a, temp6 

mov  a, temp7

subc  a, temp5

t0sn flag_c

goto einvalid_bit

evalid_bit:

mov  a, temp6

    sub  temp8, a

    mov  a, temp5

    subc  temp7, a        

    set1 flag_c

    goto eshift_result

einvalid_bit:

set0 flag_c

eshift_result:

slc  temp13

slc  temp12

slc  temp11

dzsn temp0

goto ediv_loop

ret

;-----------------------------------------------

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分