通过数字IO口对电容充放电,读取高低电平变化的时间来判断模拟量的值。硬件成本有要求,精度不是很高的情况下可以参考一下。C代码。
/*
项目:数字IO口取ADC值
芯片:HR6P59P2S2HL 内部4M
功能:热敏电阻与电容(224)并联,再串联100欧电阻到59 PA0
采样一次花时25ms左右
*/
#include <hic.h>
#define uint8 unsigned char
#define uint16 unsigned int
#define bool sbit
static volatile section0 sbit CHG_PIN @ (unsigned) &PA * 8 + 0 ;
volatile uint8 t8_ms;
volatile uint8 adcs_ms;
volatile uint8 adcs_value;
volatile uint16 delay;
volatile bool adcs_en;
void Clr_Ram_Asm()
{
__asm{
LCALL 0X3FF
MOVA CALR
BCC PSW,RP0
MOVI 0X10
MOVA IAA
CLR_BANK0
CLR IAD ;清除存储组0的RAM数据
INC IAA
JBS IAA,5
JUMP CLR_BANK0
MOVI 0X30
MOVA IAA
CLR_BANK1
CLR IAD ;清除存储组1的RAM数据
INC IAA
JBS IAA,6
JUMP CLR_BANK1
MOVI 0X50
MOVA IAA
CLR_BANK2
CLR IAD ;清除存储组2的RAM数据
INC IAA
JBS IAA,5
JUMP CLR_BANK2
MOVI 0X70
MOVA IAA
CLR_BANK3
CLR IAD ;清除存储组3的RAM数据
INC IAA
JBS IAA,7
JUMP CLR_BANK3
CLR IAA
};
}
void Init_Config()
{
__asm{
MOVI 0XFF
MOVA T8
MOVI B'00000000'
OPTION
MOVI B'11110001'
TRIS PA
MOVI B'00000000'
TRIS PB
};
PA = 0B00000000;
PB = 0B11111111;
INTC0 = 0;
T8IF = 0;
T8IE = 1;
GIE = 1;
}
void io_charge_cap()
{
t8_ms++;
if(t8_ms == 240)
{
__asm{
MOVI B'11110000'
TRIS PA
}
CHG_PIN = 1;
}
else if(t8_ms == 255)
{
t8_ms = 0;
__asm{
MOVI B'11110001'
TRIS PA
}
adcs_en = 1;
}
}
void cap_discharge_timer()
{
if(adcs_en == 1)
{
adcs_ms++; //最大时间25ms
if(adcs_ms >= 255)
adcs_ms = 254;
if(CHG_PIN == 0) //电压为1V时认为是低电平
{
adcs_value = adcs_ms;
adcs_en = 0;
}
}
else
{
adcs_ms = 0;
}
}
void isr(void) interrupt
{
if(T8IE&T8IF)
{
T8IF = 0;
T8 += 209; //4M 100us
// PA2 = PA2^1;
io_charge_cap();
cap_discharge_timer();
}
else
{
T8IF = 0;
}
}
void main()
{
Clr_Ram_Asm();
Init_Config();
while(1)
{
__Asm CWDT;
delay++;
if(delay==10000)
{
delay = 0;
PB = adcs_value;
}
}
}