Skip to content

Commit 2363e7b

Browse files
committed
F1: fixed STM32ADC example MultiChannelSingleConversion
1 parent 7a7659d commit 2363e7b

File tree

5 files changed

+79
-70
lines changed

5 files changed

+79
-70
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
/*
2-
This example shows how to use the ADC library to sample several
3-
channels/pins in one go.
2+
This example shows how to use the ADC library to sample several channels/pins in one go.
43
This example attaches an interrupt to the DMA completion to notify the user.
5-
The DMA must be set together with the start conversion, so both setDMA and startConversion
6-
Must be called.
74
85
*/
96
#include <STM32ADC.h>
107

11-
#define BOARD_LED D33 //PB0
8+
#define BOARD_LED PC13
129

13-
uint8 pins[] = {11,10,9,8,7,6,5,4};
10+
uint8 pins[] = {PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7};
1411

1512
const int maxSamples = 8; // 8 channels
1613

@@ -21,46 +18,55 @@ volatile static bool dma1_ch1_Active; //flag for interrupt
2118

2219
STM32ADC myADC(ADC1);
2320

24-
void setup() {
25-
//start Serial
26-
Serial.begin(19200);
27-
//Start up blink from Pig-O-Scope
28-
pinMode(BOARD_LED, OUTPUT);
29-
pinMode(D32, INPUT);
30-
digitalWrite(BOARD_LED, HIGH);
31-
delay(1000);
32-
digitalWrite(BOARD_LED, LOW);
33-
delay(1000);
34-
//calibrate ADC.
35-
myADC.calibrate();
36-
37-
myADC.setSampleRate(ADC_SMPR_1_5); //sample ratio
38-
myADC.setPins(pins, maxSamples); //pins to be converted
39-
myADC.setScanMode(); //Set the ADC in Scan Mode
21+
//-----------------------------------------------------------------------------
22+
// Interrupt handler.
23+
//-----------------------------------------------------------------------------
24+
static void DMA1_CH1_Event()
25+
{
26+
dma1_ch1_Active = 0;
4027
}
28+
//-----------------------------------------------------------------------------
29+
void setup()
30+
{
31+
//start Serial
32+
Serial.begin(19200);
33+
pinMode(BOARD_LED, OUTPUT);
34+
digitalWrite(BOARD_LED, HIGH);
4135

42-
void loop(){
43-
//start acquisition on button push.
44-
if(digitalRead(D32) == 1 ) {
45-
Serial.println("begin");
46-
dma1_ch1_Active = 1;
47-
myADC.setDMA(dataPoints, 8, (DMA_MINC_MODE | DMA_TRNS_CMPLT), DMA1_CH1_Event);
48-
myADC.startConversion();
49-
while (dma1_ch1_Active == 1); //wait for DMA to complete.
50-
51-
for(unsigned int i = 0; i < maxSamples; i ++) {
52-
Serial.print("sample[");
53-
Serial.print(i);
54-
Serial.print("] = ");
55-
Serial.println(dataPoints[i]);
56-
}
57-
while(digitalRead(D32) == 1); //stay here. Another button push is required.
58-
}
59-
}; //end loop
36+
while(!Serial); delay(10);
6037

61-
/*
62-
Interrupt handler. eh eh
63-
*/
64-
static void DMA1_CH1_Event() {
65-
dma1_ch1_Active = 0;
38+
Serial.println("MultiChannelSingleConversion demo started\n");
39+
// calibrate ADC.
40+
myADC.calibrate();
41+
// setup ADC
42+
myADC.setSampleRate(ADC_SMPR_1_5); //sample ratio
43+
myADC.setPins(pins, maxSamples); //pins to be converted
44+
myADC.setScanMode(); //Set the ADC in Scan Mode
45+
myADC.setDMA(dataPoints, (DMA_MINC_MODE | DMA_TRNS_CMPLT), DMA1_CH1_Event);
46+
}
47+
//-----------------------------------------------------------------------------
48+
void loop()
49+
{
50+
// blink
51+
digitalWrite(BOARD_LED, HIGH); // turn LED off
52+
delay(1000);
53+
digitalWrite(BOARD_LED, LOW); // turn LED on
54+
55+
// start acquisition
56+
Serial.println("begin");
57+
dma1_ch1_Active = 1;
58+
59+
myADC.startDMA(maxSamples);
60+
myADC.startConversion();
61+
62+
while (dma1_ch1_Active == 1); //wait for DMA to complete.
63+
// print out the sampled values
64+
for(unsigned int i = 0; i < maxSamples; i ++) {
65+
Serial.print("sample[");
66+
Serial.print(i);
67+
Serial.print("] = ");
68+
Serial.println(dataPoints[i]);
69+
}
70+
71+
delay(1000);
6672
}

STM32F1/libraries/STM32ADC/src/STM32ADC.cpp

+18-19
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,8 @@
5252
Polling is being used.
5353
*/
5454
float STM32ADC::readVcc(){
55-
unsigned int result = 0;
56-
float vcc = 0.0;
57-
result = adc_read(_dev, 17);
58-
59-
vcc = (float)result * 1.1; //to be done later...
55+
uint16_t result = adc_read(_dev, 17);
56+
float vcc = (float)result * 1.1; //to be done later...
6057
return vcc;
6158
}
6259

@@ -65,10 +62,9 @@
6562
Polling is being used.
6663
*/
6764
float STM32ADC::readTemp(){
68-
unsigned int result = 0;
69-
float temperature = 0.0;
70-
result = adc_read(_dev, 16);
71-
temperature = (float)((_V25-result)/_AverageSlope)+ 25.0;
65+
uint16_t result = adc_read(_dev, 16);
66+
float Vsense = (3300.0*result)/4096;
67+
float temperature = ((_V25-Vsense)/_AverageSlope) + 25.0;
7268
return temperature;
7369
}
7470

@@ -80,9 +76,8 @@
8076
//convert pins to channels.
8177
uint8 channels[length];
8278
unsigned int records[3] = {0,0,0};
83-
unsigned char i = 0, j = 0;
8479

85-
for (unsigned char i = 0; i < length; i++) { //convert the channels from pins to ch.
80+
for (uint8_t i = 0; i < length; i++) { //convert the channels from pins to ch.
8681
channels[i] = PIN_MAP[pins[i]].adc_channel;
8782
}
8883

@@ -93,7 +88,7 @@
9388
records[2] |= (length - 1) << 20;
9489

9590
//i goes through records, j goes through variables.
96-
for (i = 0, j = 0; i < length; i++) {//go through the channel list.
91+
for (uint8_t i = 0, j = 0; i < length; i++) {//go through the channel list.
9792
if (i!=0 && i%6 == 0) j++;//next variable, please!!
9893
records[j] |= (channels[i] << ((i%6)*5));
9994
}
@@ -162,23 +157,27 @@
162157
The reason why this is a uint16 is that I am not ready for dual mode.
163158
*/
164159

165-
void STM32ADC::setDMA(uint16 * Buf, uint16 BufLen, uint32 dmaFlags, voidFuncPtr func) {
160+
void STM32ADC::setDMA(uint16 * Buf, uint32 dmaFlags, voidFuncPtr func)
161+
{
166162
//initialize DMA
167163
dma_init(DMA1);
164+
dma_disable(DMA1, DMA_CH1);
168165
//if there is an int handler to be called...
169166
if (func != NULL)
170167
dma_attach_interrupt(DMA1, DMA_CH1, func);
171168
//enable ADC DMA transfer
172-
//adc_dma_enable(ADC1);
173-
_dev->regs->CR2 |= ADC_CR2_DMA;
169+
adc_dma_enable(ADC1);
170+
//_dev->regs->CR2 |= ADC_CR2_DMA;
174171
//set it up...
175172
dma_setup_transfer(DMA1, DMA_CH1, &ADC1->regs->DR, DMA_SIZE_16BITS, Buf, DMA_SIZE_16BITS, dmaFlags);// Receive buffer DMA
176-
//how many are we making??
177-
dma_set_num_transfers(DMA1, DMA_CH1, BufLen);
178-
//enable dma.
179-
dma_enable(DMA1, DMA_CH1); // Enable the channel and start the transfer.
180173
}
181174

175+
void STM32ADC::startDMA(uint16 BufLen)
176+
{
177+
dma_disable(DMA1, DMA_CH1);
178+
dma_set_num_transfers(DMA1, DMA_CH1, BufLen);
179+
dma_enable(DMA1, DMA_CH1); // Enable the channel
180+
}
182181
/*
183182
This function is used to setup DMA with the ADC.
184183
It will be independent of the mode used. It will either be used in continuous or scan mode

STM32F1/libraries/STM32ADC/src/STM32ADC.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ class STM32ADC{
3232
3333
The reason why this is a uint16 is that I am not ready for dual mode.
3434
*/
35-
void setDMA(uint16 * Buf, uint16 BufLen, uint32 dmaFlags, voidFuncPtr func);
36-
35+
void setDMA(uint16 * Buf, uint32 dmaFlags, voidFuncPtr func);
36+
void startDMA(uint16 BufLen);
37+
3738
/*
3839
This function is used to setup DMA with the ADC.
3940
It will be independent of the mode used. It will either be used in continuous or scan mode

STM32F1/libraries/STM32ADC/src/utility/util_adc.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@
77
Interrupt function.
88
This handles Analog watchdog and ADC1 and 2.
99
*/
10-
extern volatile unsigned int adc_result;
10+
//extern volatile unsigned int adc_result = 0;
1111

1212
/*
1313
Starts a single conversion in one channel previously defined.
1414
Results must be read through interrupt or polled outside this function.
1515
*/
1616
void start_single_convert(adc_dev* dev, uint8 channel) {
17-
// int pinMapADCin = PIN_MAP[analogInPin].adc_channel;
1817
adc_set_reg_seqlen(dev, 1);
1918
dev->regs->SQR3 = channel;//use channels next time.
2019
dev->regs->CR2 |= ADC_CR2_SWSTART;
@@ -25,7 +24,6 @@ void start_single_convert(adc_dev* dev, uint8 channel) {
2524
Results must be read through interrupt or polled outside this function.
2625
*/
2726
void start_continuous_convert(adc_dev* dev, uint8 channel){
28-
// int pinMapADCin = PIN_MAP[analogInPin].adc_channel;
2927
adc_set_reg_seqlen(dev, 1);
3028
dev->regs->SQR3 = channel;
3129
dev->regs->CR2 |= ADC_CR2_CONT;

STM32F1/libraries/STM32ADC/src/utility/util_adc.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#ifndef UTIL_ADC_H
2+
#define UTIL_ADC_H
3+
14
#ifdef __cplusplus
25
extern "C" {
36
#endif
@@ -34,5 +37,7 @@ uint8 poll_adc_convert(adc_dev *dev);
3437
void adc_dma_enable(adc_dev * dev);
3538

3639
#ifdef __cplusplus
37-
}
40+
} // extern "C"
3841
#endif
42+
43+
#endif // UTIL_ADC_H

0 commit comments

Comments
 (0)