Hello guys,
I would like to ask I anyone can help me with this code, that i have found on the net
http://www.stm32duino.com/viewtopic.php?f=3&t=757&p=8474#p8474
and I would like thank the autor of this code
I am using STM32F103C to sample two 10KHz signal at same time, I am trying to change the code to use it but i belive that I am doing something wrong, cause I am begginer
/* MapleDualADC - A sample to perform dual ADC conversions using DMA */
//
// As written it performs a total of NUM_SAMPLES dual conversions (ADC1 and ADC2) on Maple Mini
// continuosly scanning the defined channels (D3->IN8 and D5->IN7 in the first conversion
// followed by D4->IN6 and D6->IN5 on the second conversion). In the example, repeated 4 times
// NUM_SAMPLES=(number INx channels converted/2) * number of times each channel is scanned
/*
Copyright (c) 2015 Roberto Cazzaro. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
*/
const float referenceVolts= 3.3;
#include <libmaple/dma.h>
#define CHANNELS_PER_ADC 2 // number of channels for each ADC. Must match values in ADCx_Sequence array below
#define NUM_SAMPLES 8 // number of samples for each ADCx. Each channel will be sampled NUM_SAMPLES/CHANNELS_PER_ADC
#define SAMPLE_RATE ADC_SMPR_71_5 // when using dual mode, each pair of channels must have same rate. Here all channels have the same
uint32 adcbuf[NUM_SAMPLES+1]; // buffer to hold samples, ADC1 16bit, ADC2 16 bit
uint8 ADC1_Sequence[]={8,6,0,0,0,0}; // ADC1 channels sequence, left to right. Unused values must be 0. Note that these are ADC channels, not pins
uint8 ADC2_Sequence[]={7,5,0,0,0,0}; // ADC2 channels sequence, left to right. Unused values must be 0
// calculate values for SQR3. Function could be extended to also work for SQR2 and SQR1. As is, you can sequence only 6 sequences per ADC
uint32 calc_adc_SQR3(uint8 adc_sequence[6]){
int SQR3=0;
for (int i=0;i<6;i++) // There are 6 available sequences in SQR3 (SQR2 also 6, and 4 in SQR1).
{
//each sequence is 5 bits
SQR3 |= adc_sequence[i] << ((i*5));
}
return SQR3;
}
// initialize DMA1, Channel1 (ADC)
void set_dma() {
dma_init(DMA1);
dma_setup_transfer(DMA1, DMA_CH1, &ADC1->regs->DR, DMA_SIZE_32BITS,
adcbuf, DMA_SIZE_32BITS, DMA_MINC_MODE);
dma_set_num_transfers(DMA1, DMA_CH1,NUM_SAMPLES);
dma_set_priority(DMA1, DMA_CH1, DMA_PRIORITY_VERY_HIGH);
dma_enable(DMA1, DMA_CH1);
}
// calibrate ADC1 and ADC2, then set all registers for regular simultaneous dual ADC conversion with DMA transfer
void set_adc() {
adc_set_sample_rate(ADC1, SAMPLE_RATE); // sets sample rate for all channels, all identical (critical in dual mode, even if only pairs sampled together need to be identical)
adc_set_sample_rate(ADC2, SAMPLE_RATE);
adc_calibrate(ADC1);
adc_calibrate(ADC2);
ADC1->regs->CR1 = 1 << 8; // Set scan mode
ADC1->regs->CR1 |= 6 << 16; //Regular simultaneous mode. Required for ADC1 only, ADC2 is slave
ADC1->regs->CR2 = ( ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_EXTSEL | ADC_CR2_EXTTRIG); //0xe0102; cont conversion, DMA, right aligned, disable external; EXTSEL, exttrig=0,jswstart=0
adc_set_reg_seqlen(ADC1, CHANNELS_PER_ADC); // how many channels per ADC
//ADCx->regs->SQR3-1 holds the sequence of channels to convert. A conversion function is provided calc_adc_sequence(ADC1_Sequence) only for SQR3.
//If more than 6 channels are needed, repeat the same for SQR2 and SQR1 (SQR1 only holds 4 sequences)
ADC1->regs->SQR3 |= calc_adc_SQR3(ADC1_Sequence); //200; for IN8 and IN6, on Maple Mini these are D3, D5
ADC2->regs->CR1 = 1 << 8; // Set scan mode
ADC2->regs->CR2 = ( ADC_CR2_CONT | ADC_CR2_EXTSEL | ADC_CR2_EXTTRIG); //0xe0003;
adc_set_reg_seqlen(ADC2, CHANNELS_PER_ADC);
ADC2->regs->SQR3 |= calc_adc_SQR3(ADC2_Sequence); //= 167 forIN7 and IN5, on Maple Mini these are D4, D6 respectively
ADC1->regs->CR2 |= ADC_CR2_ADON; // it is critical to enable ADC (bit 0=1) independently of all other changes to the CR2 register
ADC2->regs->CR2 |= ADC_CR2_ADON; // enabling all at once (i.e. ADC_CR2_ADON | ADC_CR2_CONT | ADC_CR2_EXTSEL ) will cause problems when used with continuous mode
}
// set only the registers that need to be reset before each conversion
void adc_to_ready() {
ADC1->regs->CR2 = ( ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_EXTSEL | ADC_CR2_EXTTRIG); //0xe0102; cont conversion, DMA, right aligned, disable external; EXTSEL, exttrig=0,jswstart=0
ADC2->regs->CR2 = ( ADC_CR2_CONT | ADC_CR2_EXTSEL | ADC_CR2_EXTTRIG); //0xe0002;
ADC1->regs->CR2 |= ADC_CR2_ADON; // it is critical to enable ADC (bit 0=1) independently of all other changes to the CR2 register
ADC2->regs->CR2 |= ADC_CR2_ADON; // enabling all at once (i.e. ADC_CR2_ADON | ADC_CR2_CONT | ADC_CR2_EXTSEL ) will cause problems when used with continuous mode
}
// check for DMA transfer finished, resetting isr bit
uint8 dma_transfer_finished() {
if(dma_get_isr_bits(DMA1,DMA_CH1)==0x07) {
int result=dma_get_irq_cause(DMA1,DMA_CH1);//<--clears isr bits
return 1;
}
return 0;
}
void setup() {
Serial.begin(115200); // Ignored by Maple. But needed by boards using Hardware serial via a USB to Serial Adaptor
pinMode(PA0,INPUT_ANALOG); //set all used pins as INPUT_ANALOG, in the example 3,4,5,6
pinMode(PA1,INPUT_ANALOG);
set_adc(); // initial ADCa and ADC2 settings
}
void loop() {
adc_to_ready(); // it is critical to set ADC before DMA, to avoid partial DMA transfers being stored. If the ADC is in continuous mode while DMA is being set
set_dma(); // the DMA transfer will be triggered and the DMA counter will start from the wrong value
ADC1->regs->CR2 |= ADC_CR2_SWSTART; //start conversion, STM32 will reset this bit immediately. Only ADC1 (master) needs to be started
while(!dma_transfer_finished());
dma_disable(DMA1,DMA_CH1); //stop dma transfer
for(int i=0;i<(NUM_SAMPLES);i++) {
float volts= ((adcbuf[i] & 0xFFFF) / 4095.0)* referenceVolts;
float voltss= (((adcbuf[i] & 0xFFFF0000) >>16) / 4095.0)* referenceVolts;
Serial.print("ADC 1 ");
Serial.print(volts);
/* Serial.println("ADC 2 ");
Serial.print(voltss); */
/*
Serial.print(i);
Serial.print(" ");
Serial.print(adcbuf[i] & 0xFFFF);
Serial.print(" - ");
Serial.println((adcbuf[i] & 0xFFFF0000) >>16); */
}
Serial.println();
delay(750);
}
Thank you for your time