/*
* Copyright(C) Paul und Scherer (mct.de/mct.net)
*
* This example demonstrates how to...
*
* ... use an ADC channel to monitor the DAC output.
*
* ... reduce signal noise using low pass filtering.
*/
#include
#include
#include
/*
* Low pass (numerical simulation of an RC circuit)
*
* The behaviour of an RC circuit can be described with the formula
*
* (new)out := (1-K)*out+K*in, with 0<= K <=1, initial out =0
*
* In other words, the output is composed of a part of the previous
* output and a part of the current input. For K =0 the output will
* never change, and for K =1 it follows the input immediately. The
* choice for K is a trade-off: signal stability vs. response time.
*
* The above formula is rewritten as: (new)out := out-K*out+K*in or
*
* out += K*(in-out)
*
* To avoid using floats, this is transformed to integer arithmetic
* by replacing K with 1/F and multiplying both sides with factor F
*
* fout += in-fout/F, where fout = F*out, F >=1
*
* Return out.
*/
#define F 100
static int
lp(int in)
{
static long fout; // initial fout (=F*out) =0
return (fout += in-fout/F)/F; // return out (=fout/F)
}
/*
* Connect the DAC0 output to ADC0. The DAC output can be changed, by
* entering values between 0 and 4095. The output is sampled by ADC0,
* filtered through a low pass and then displayed. DAC and ADC values
* should not differ significantly.
*/
int
main(void)
{
/*
* Reference voltage
*
* Setting refcon to 1 activates the internal
* reference and connects it to the Vref pin.
*
* Note: A 0.47uF capacitor is required (from
* Vref to GND) for proper operation!
*/
Intern_refcon = 1;
Intern_dac0con = 0x12; // DAC range 0 to Vref
Intern_adccon = 0xa4; // ADC continuous conversion
while (1) {
char line[5]; // input buffer
unsigned long dac; // DAC data
while (!Intern_adcsta) ; // wait for result ready
printf("DAC ->ADC: %d\n", lp((Intern_adcdat>>16)&0xfff));
if (!kbhit()) continue; // new DAC data?
do {
fputs("\nNew DAC data (0.. 4095): ", stdout);
fgets(line, sizeof(line), stdin);
} while (sscanf(line, "%lu", &dac) != 1 || dac > 4095);
putchar('\n');
Intern_dac0dat = dac<<16;
}
}