#include "numicro_8051.h"
#define debug_log(format, args...) \
printf("%s - " format, __func__, ## args)
static float adc_vdd;
/***********************************************************************
***********************************************************************/
static void led_init(void)
{
P15_PUSHPULL_MODE;
P15 = 1;
}
/***********************************************************************
***********************************************************************/
static void console_init(unsigned long baudrate)
{
/* UART0 TX */
P06_PUSHPULL_MODE;
/* UART0 RX */
P07_INPUT_MODE;
/* UART0 mode 1, don't check stop bit, enable receive */
SCON = 0x50;
/* timer 1, mode 2 */
TMOD = 0x20;
/* UART0 double baud rate */
set_PCON_SMOD;
/* timer 1 is driven directly by the system clock */
set_CKCON_T1M;
/* UART0 clock source is timer 1 */
clr_T3CON_BRCK;
/* configure baud rate */
TH1 = 256 - 1000000 / baudrate;
/* enable timer 1 */
set_TCON_TR1;
/* initiate transmit operations */
set_SCON_TI;
}
#define RAVG_BUFCNT 40
typedef struct
{
unsigned int buffer[RAVG_BUFCNT];
unsigned int index;
unsigned long sum;
} RAVG;
static RAVG ravg_voltage;
static RAVG ravg_current;
#define SCALE_VOLTAGE 1.0
#define SCALE_CURRENT 1.0
/***********************************************************************
***********************************************************************/
static void ravg_run(RAVG* ravg, unsigned int data)
{
ravg->sum -= ravg->buffer[ravg->index];
ravg->sum += data;
ravg->buffer[ravg->index] = data;
ravg->index = (ravg->index + 1) % RAVG_BUFCNT;
}
/***********************************************************************
***********************************************************************/
static float ravg_average(RAVG* ravg)
{
return (float)ravg->sum / RAVG_BUFCNT;
}
/***********************************************************************
***********************************************************************/
static unsigned int adc_read_data(void)
{
clr_ADCCON0_ADCF;
set_ADCCON0_ADCS;
while ((ADCCON0 & SET_BIT7) == 0)
{
;
}
unsigned int data = (ADCRH << 4) | (ADCRL & 0x0f);
return data;
}
/***********************************************************************
***********************************************************************/
static unsigned int adc_bandgap_stored(void)
{
unsigned int data;
set_IAPEN;
IAPAL = 0x0C;
IAPAH = 0x00;
IAPCN = 0x04;
set_IAPGO;
data = IAPFD;
IAPAL = 0x0d;
IAPAH = 0x00;
IAPCN = 0x04;
set_IAPGO;
data = (data << 4) | (IAPFD & 0x0f);
clr_IAPEN;
debug_log("data = %u\n", data);
return data;
}
/***********************************************************************
***********************************************************************/
static unsigned int adc_bandgap_actual(void)
{
ENABLE_ADC_BANDGAP;
adc_read_data();
adc_read_data();
adc_read_data();
unsigned int data = adc_read_data();
debug_log("data = %u\n", data);
return data;
}
/***********************************************************************
***********************************************************************/
static void adc_read(RAVG* ravg)
{
unsigned int data = adc_read_data();
ravg_run(ravg, data);
}
/***********************************************************************
***********************************************************************/
static float adc_calc_value(RAVG* ravg, float scale)
{
float value = ravg_average(ravg) * adc_vdd / 4095.0 * scale;
return value;
}
/***********************************************************************
***********************************************************************/
static void adc_init(void)
{
unsigned int bg_stored = adc_bandgap_stored();
unsigned int bg_actual = adc_bandgap_actual();
float vbg = 3072.0 * bg_stored / 4096.0;
adc_vdd = 4095.0 / bg_actual * vbg;
debug_log("bg_stored = %u, bg_actual = %u, vbg = %f mV, adc_vdd = %f mV\n",
bg_stored, bg_actual, vbg, adc_vdd);
}
/***********************************************************************
***********************************************************************/
void main(void)
{
led_init();
console_init(10000);
adc_init();
unsigned long count = 0;
while (1)
{
if (RI)
{
char c = SBUF;
RI = 0;
printf("c = 0x%02X\n", c);
switch (c)
{
default:
break;
}
}
ENABLE_ADC_AIN6;
adc_read(&ravg_voltage);
ENABLE_ADC_AIN5;
adc_read(&ravg_current);
++count;
if (count == 1000)
{
count = 0;
float value = adc_calc_value(&ravg_voltage, SCALE_VOLTAGE);
debug_log("voltage = %f mV\n", value);
}
}
}