multiplexing over 9 channels

master
Eggert Jung 5 years ago
parent 6999fa3f2d
commit 798d1648f2

@ -6,9 +6,11 @@
#include <stddef.h> #include <stddef.h>
#include "yaMBSiavr.h" #include "yaMBSiavr.h"
#define AVRG 1024 #define AVRG 512
volatile uint16_t adc_buffer[AVRG];
volatile float ch_values[9];
uint16_t adc_values[AVRG];
void init_clk(void) void init_clk(void)
{ {
@ -37,7 +39,7 @@ void init_clk(void)
void init_timer_100us(){ void init_timer_100us(){
TCC0.CTRLA |= TC_CLKSEL_DIV256_gc; TCC0.CTRLA |= TC_CLKSEL_DIV256_gc;
TCC0.PER = 13; // ==> 9615Hz TCC0.PER = 13; // ==> 9615Hz
TCC0.INTCTRLA |= TC_OVFINTLVL_MED_gc; TCC0.INTCTRLA |= TC_OVFINTLVL_HI_gc;
} }
void adc_init(void){ void adc_init(void){
@ -69,16 +71,17 @@ uint16_t adc_read(void){
float avrg(uint16_t * values, uint16_t length){ float avrg(uint16_t * values, uint16_t length){
uint64_t res = 0; uint64_t res = 0;
for(uint16_t i=0; i < length; i++){ //ommit first and last sample
for(uint16_t i=1; i < length-1; i++){
res += values[i]; res += values[i];
} }
return (float)(res)/length; return (float)(res)/(length-2);
} }
void dma_init(void){ void dma_init(void){
DMA.CTRL = DMA_ENABLE_bm; DMA.CTRL = DMA_ENABLE_bm;
//DMA.CH0.CTRLB = DMA_CH_TRNINTLVL_LO_gc; DMA.CH0.CTRLB = DMA_CH_TRNINTLVL_LO_gc;
DMA.CH0.TRFCNT = AVRG * 2; DMA.CH0.TRFCNT = AVRG * 2;
DMA.CH0.CTRLA = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_SINGLE_bm; DMA.CH0.CTRLA = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_SINGLE_bm;
@ -92,9 +95,9 @@ void dma_init(void){
DMA.CH0.SRCADDR1 = (((uintptr_t)&ADCA.CH0.RES) >> 0x08) & 0xFF; DMA.CH0.SRCADDR1 = (((uintptr_t)&ADCA.CH0.RES) >> 0x08) & 0xFF;
DMA.CH0.SRCADDR2 = (((uintptr_t)&ADCA.CH0.RES) >> 0x0F) & 0xFF; DMA.CH0.SRCADDR2 = (((uintptr_t)&ADCA.CH0.RES) >> 0x0F) & 0xFF;
DMA.CH0.DESTADDR0 = ((uintptr_t)adc_values) & 0xFF; DMA.CH0.DESTADDR0 = ((uintptr_t)adc_buffer) & 0xFF;
DMA.CH0.DESTADDR1 = ((uintptr_t)adc_values >> 0x08) & 0xFF; DMA.CH0.DESTADDR1 = ((uintptr_t)adc_buffer >> 0x08) & 0xFF;
DMA.CH0.DESTADDR2 = ((uintptr_t)adc_values >> 0x0F) & 0xFF; DMA.CH0.DESTADDR2 = ((uintptr_t)adc_buffer >> 0x0F) & 0xFF;
DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_DESTRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc; DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_DESTRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc;
@ -106,12 +109,7 @@ void modbusGet(void) {
{ {
switch(rxbuffer[1]) { switch(rxbuffer[1]) {
case fcReadHoldingRegisters: ; case fcReadHoldingRegisters: ;
float tmp[4]; modbusExchangeRegisters(ch_values, 0, 18);
tmp[0] = avrg(adc_values, AVRG) - 170;
tmp[1] = (tmp[0])/ 3926 * 1.95;
tmp[2] = (tmp[1]*980)/(3.3-tmp[1]);
tmp[3] = (tmp[2]-100)/0.3927;
modbusExchangeRegisters(tmp, 0, 8);
break; break;
default: default:
modbusSendException(ecIllegalFunction); modbusSendException(ecIllegalFunction);
@ -149,3 +147,25 @@ int main(void){
ISR(TCC0_OVF_vect){ ISR(TCC0_OVF_vect){
modbusTickTimer(); modbusTickTimer();
} }
ISR(DMA_CH0_vect){
static uint8_t pin = 0;
DMA.INTFLAGS |= DMA_CH0TRNIF_bm; // clear flag
DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_OFF_gc;
ADCA.CTRLB = 0; // stop ADC
uint8_t old_pin = pin;
pin=(pin+1)%1;
ADCA.CH0.MUXCTRL = pin << ADC_CH_MUXPOS_gp; // give MUX time to switch during averaging
float temp = avrg(adc_buffer, AVRG);
temp = temp - 170;
temp = (temp)/ 3926 * 1.95;
temp = (temp*993.5)/(3.3-temp);
temp = (temp-100)/0.3927;
ch_values[old_pin] = temp;
DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH0_gc;
ADCA.CTRLB = ADC_FREERUN_bm; // start ADC again
}

Loading…
Cancel
Save