Page 2 of 2

Re: CD74HC4067 MUX example code using STM32F103

Posted: Wed Jul 03, 2024 4:24 am
by ag123
note that if you read the reference manual rm0008
RM0008 Reference manual STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx and STM32F107xx advanced ArmĀ®-based 32-bit MCUs
https://www.st.com/resource/en/referenc ... ronics.pdf

chapter 11 ADC, the ADC has its own mux up to 18 channels, not all of then are on the pins, some of them are used for internal temperature sensor and vrefint.
review rm0008 11.3.3 Channel selection and chapter 11 itself

you could save an external component literally

and it could be as simple as

Code: Select all

pinmode(PAxx, INPUT_ANALOG);
uint16_t value = analogRead(PAxx);
to play with the registers directly, it would take reviewing the ref manual and possibly review the core codes about that.
it is possible to directly read the ADC without using analogRead() at all.

Re: CD74HC4067 MUX example code using STM32F103

Posted: Wed Jul 03, 2024 4:28 am
by STM32ardui
WeActStudio is selling a "Mini Debugger Stlink".

https://github.com/WeActStudio/WeActStu ... ages/1.png
https://github.com/WeActStudio/WeActStu ... ages/2.png

It has both: SWD-pins and UART.
I'm using it for 1 month now and I'm satisfied. I can upload a sketch from ArduinoIDE and afterwards I see output in serial monitor of IDE.

Re: CD74HC4067 MUX example code using STM32F103

Posted: Wed Jul 03, 2024 10:21 am
by justinjools
@ag123

I was interested in finding out how to use the internal multiplexer. I had a look how to do this but only found youtube tutorial of setting up DMA using STCubeMX and looked complex to me. Are they any easy examples to do this anyone knows of? Can you just do it in code or do you have to set it up in STCubeMX?

If there was an easy way to do this I would use it, but setting up a external MUX is easy compared to what I found plus the advantage is I then have 16 MUX ADC on channel plus another 9 normal ADC channels.

For some projects the internal multiplexer would definately fit the bill, if someone could explain to me how to do this, I would be very pleased.

Re: CD74HC4067 MUX example code using STM32F103

Posted: Wed Jul 03, 2024 10:31 am
by justinjools
@STM32ardui

I have an ST-LINKV2 and have a V2.1 and V3MINNIE on the way (V2 doesn't work with later boards like black pill)

So I can do serial monitor with ST-LINKV2?

I have it connected with SWD pins GND/VCC/SWCLK/SWDIO.

What is UART? I don't see any other pins.

When I connect with ST-LINK in Arduino IDE I just get not connected because it is looking for USB port.

Is UART software or hardware thing?

How do I do use for serial monitor?

Update:
I just read something that says STLINKV2 doesn't work and you need V2.1.

https://electronics.stackexchange.com/q ... munication

Update:
My STLINK-V3Minnie and V2.1 arrived :)
Will now see if I do serial monitor.

Re: CD74HC4067 MUX example code using STM32F103

Posted: Wed Jul 03, 2024 12:08 pm
by STM32ardui
HAL_ADC_ConfigChannel() - may be this is the function for selecting a channel?
There is also a struct with the name ADC_ChannelConfTypeDef.


justinjools wrote: Wed Jul 03, 2024 10:31 am @STM32ardui

What is UART? I don't see any other pins.
The RX/TX-pins you need at minimum for a serial connection. On a BluePill it should be PA9/PA10.
You never read something via serial on Arduino UNO, nano etc.?
justinjools wrote: Wed Jul 03, 2024 10:31 am So I can do serial monitor with ST-LINKV2?
No.
I told you about a special debugger, that has SWD and Serial/USB. You need only one USB-C cable to computer. On the other side you have to connect both interfaces.

Re: CD74HC4067 MUX example code using STM32F103

Posted: Wed Jul 03, 2024 1:24 pm
by ag123
justinjools wrote: Wed Jul 03, 2024 10:21 am @ag123

I was interested in finding out how to use the internal multiplexer. I had a look how to do this but only found youtube tutorial of setting up DMA using STCubeMX and looked complex to me. Are they any easy examples to do this anyone knows of? Can you just do it in code or do you have to set it up in STCubeMX?

If there was an easy way to do this I would use it, but setting up a external MUX is easy compared to what I found plus the advantage is I then have 16 MUX ADC on channel plus another 9 normal ADC channels.

For some projects the internal multiplexer would definately fit the bill, if someone could explain to me how to do this, I would be very pleased.
first review the ref manual rm0008 and keep it handy, in particular the ADC chapter
RM0008 Reference manual STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx and STM32F107xx advanced ArmĀ®-based 32-bit MCUs
https://www.st.com/resource/en/referenc ... ronics.pdf
also review the datasheet in particular the pinouts and the alt functions
https://www.st.com/resource/en/datashee ... f103c8.pdf
for example page 28 on you find the pinmap and the alt functions under the 'default' column lets just take a few for the sample
PA0-WKUP WKUP/USART2_CTS(9)/ADC12_IN0/TIM2_CH1_ETR(9)
PA1 USART2_RTS(9)/ADC12_IN1/TIM2_CH2(9)
PA2 USART2_TX(9)/ADC12_IN2/TIM2_CH3(9)
PA3 USART2_RX(9)/ADC12_IN3/TIM2_CH4
so the ADC channels 0 - 3 are on pins PA0 - PA3

DMA is one level 'deeper' and I'd not cover that as DMA involved more 'complications' than just the ADC alone.
the 'proper' way is to use HAL / CMSIS, but that actually nothing prevents you from directly accessing the registers if you want.

to dive below just your 'sketch', you need to find where the core is actually installed
https://support.arduino.cc/hc/en-us/art ... ter#boards
for STM 'official' core
https://github.com/stm32duino/Arduino_Core_STM32
once you are there it is installed in
go into [core folder]/packages/STMicroelectronics/hardware/{version e.g. 2.8.0}
you would find a set of files that are practically similar / same as that in https://github.com/stm32duino/Arduino_Core_STM32
that folder ([core folder]/packages/STMicroelectronics/hardware/{version e.g. 2.8.0}) is where the source for stm32duino core lives.
it is huge runs in 100s of megs as it practically includes the whole bundle of support files HAL etc from ST for the whole STM32 family practically all series

you can take sometime to explore cores/arduino
and libraries/SrcWrapper/src/stm32/
the core proper code

variants lives in variants with subfolders for each series / soc and files for each board

in libraries/SrcWrapper/src/HAL
libraries/SrcWrapper/src/LL
is where HAL for STM32 lives

from this part below, there is no assurance if anything would work or not, it is speculative and may not work
-----------------------------------
and more interestingly
system/Drivers/CMSIS/Device/ST
is where includes files for CMSIS for each series and soc lives
e.g. for stm32f103xb the CMSIS include may be:
system/Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h
in that huge include file, we'd need to dig for structure declarations for the registers
e.g. for ADC it seemed to be
https://github.com/stm32duino/Arduino_C ... 3xb.h#L165

Code: Select all

/**
  * @brief Analog to Digital Converter
  */

typedef struct
{
  __IO uint32_t SR;
  __IO uint32_t CR1;
  __IO uint32_t CR2;
  __IO uint32_t SMPR1;
  __IO uint32_t SMPR2;
  __IO uint32_t JOFR1;
  __IO uint32_t JOFR2;
  __IO uint32_t JOFR3;
  __IO uint32_t JOFR4;
  __IO uint32_t HTR;
  __IO uint32_t LTR;
  __IO uint32_t SQR1;
  __IO uint32_t SQR2;
  __IO uint32_t SQR3;
  __IO uint32_t JSQR;
  __IO uint32_t JDR1;
  __IO uint32_t JDR2;
  __IO uint32_t JDR3;
  __IO uint32_t JDR4;
  __IO uint32_t DR;
} ADC_TypeDef;
Then
https://github.com/stm32duino/Arduino_C ... 3xb.h#L607

Code: Select all

#define ADC1_BASE             (APB2PERIPH_BASE + 0x00002400UL)
#define ADC2_BASE             (APB2PERIPH_BASE + 0x00002800UL)
and
https://github.com/stm32duino/Arduino_C ... 3xb.h#L669

Code: Select all

#define ADC1                ((ADC_TypeDef *)ADC1_BASE)
#define ADC2                ((ADC_TypeDef *)ADC2_BASE)
now go back in the manual review the chapter 11 on ADC
https://www.st.com/resource/en/referenc ... ronics.pdf
take a look at the 11.12 ADC registers section in the manual it should reflect that structure declaration in the include

the ADC is normally initialized by stm32duino core during startup, so life is a little 'easier', but that we still need to setup the pinmux that one is easy

Code: Select all

void setup() {
	pinMode(PA0, INPUT_ANALOG);
	pinMode(PA1, INPUT_ANALOG);	
	pinMode(PA2, INPUT_ANALOG);	
	pinMode(PA3, INPUT_ANALOG);			
}
so with that your pins PA0 - PA3 is pin muxed to the ADC channels 0 - 3, the usual *correct* way is to simply analogRead(PAxx); next

now here are the speculative codes which may not work not tested, no warranty whatsoever

Code: Select all

void setup() {
	pinMode(PA0, INPUT_ANALOG);
	pinMode(PA1, INPUT_ANALOG);	
	pinMode(PA2, INPUT_ANALOG);	
	pinMode(PA3, INPUT_ANALOG);	
	ADC1->CR2 &= ~ADC_CR2_CONT; // make sure it is not continuous, i.e. single conversion mode
}

// this is a rudimentary analogRead();
uint16_t myanalogRead(uint8_t channel) {
	ADC1->SQR3 &= ~ 0x1f; //clear the channel to sample
	ADC1->SQR3 |= channel & 0x1f; //set the channel to sample
	ADC1->SR = 0; // CLEAR the status register	
	ADC1->CR2 |= ADC_CR2_ADON; // start conversion
	while(!(ADC1->SR & ADC_SR_EOC)); // check for end of conversion
	uint16_t value = ADC1->DR; // read the adc converted value
	return value;
}

void loop() {
	uint8_t channel = 1; // note that is PA1, you can set this to whatever channel you want
	uint16_t value = myanalogRead(channel);
	
	Serial.print("adc ch:");
	Serial.println(channel);
	Serial.print("value:");
	Serial.println(value);
	delay(1000);
}
of course, these days this is deemed 'non portable code', you are accessing registers and when the soc changes, this symbol reference / register may be gone or changed.
the channel to sample is stored in the 1st 5 bits of ADCx->SQR3, it is actually a pretty complicated multiplexer, in a sense that it can sample a whole set of channels in sequence controlled by the in-soc hardware. e.g. 1st sample channel 1, 2nd sample channel 2 etc
but there you have it, the ADC has its own multiplexer buiilt right in there.

Re: CD74HC4067 MUX example code using STM32F103

Posted: Wed Jul 03, 2024 4:20 pm
by justinjools
I appreciate your reply and help. That is just too complicated for me, even trying to understand what you wrote. I am just a hobbyist and amateur coder. I get the gist of the code you have written but still looks a bit too abstract to me and I don't have the ability to get something to work that is demonstrating a concept and not guaranteed to work.

I'll stick with using external MUX.

Re: CD74HC4067 MUX example code using STM32F103

Posted: Wed Jul 03, 2024 4:22 pm
by ag123
there is a bunch of 'old' codes based on the libmaple (roger's) core
https://github.com/rogerclarkmelbourne/Arduino_STM32

an 'oscilloscope' based on the 'blue pill' et.al. stm32f103c{8,b}
https://github.com/ag88/GirinoSTM32F103duino
there is a bunch of codes
https://github.com/ag88/GirinoSTM32F103 ... 2f103mm_v3
that 'AdcMgr' class
https://github.com/ag88/GirinoSTM32F103 ... /CAdcMgr.h
https://github.com/ag88/GirinoSTM32F103 ... AdcMgr.cpp
encapsulate a lot of 'ADC' stuff, unfortunately, this is tightly bind to 'libmaple' core, it calls functions in that core
but with that I made a little 'usb oscilloscope' out of a stm32f103c{8,b}