Transfer of values to ArduinoUNO original ports.
Transfer of values to ArduinoUNO original ports.
Hello friends,
I would like to use a shield that I developed for ArduinoUNO on the STM32L476RG board.
In the original program, I transferred integer values to the ports instead of triggering them pin by pin.
As for the ArduinoUNO PORTB, only the first six pins are available (corresponding to digital pins 8 to 13 printed on the ArduinoUNO board, and corresponding to D8 - D13 on the STM32 board). I transfer to this port fixed values depending on the circuits I want to activate on the shield.
PORTB = 4;
As for PORTD, an entire port is available (corresponding to D0 - D7 on the STM32 board). In this port the values can vary more, they are not pre-established.
PORTD = valueA;
Checking the reference https://os.mbed.com/teams/ST/wiki/Use-o ... duino-pins, I realize that I have to change some connections on the board in order to continue using the same shield (pins D0 and D1 are used by the STLink Virtual Comm Port on the STM32 board).
My question is: keeping the program originally developed for ArduinoUNO, when transferring values to ports B and D, will the same pins be kept on the STM32L476RG board?
Note that on the STM32 board, pins D0 - D7 correspond to pins on ports PA_x and PB_x on the L476RG, and pins D8 - D13 correspond to pins on ports PA_x, PB_x and PC_x.
During compilation, will the libraries "mask" the intended pins to use the shield?
I would like to use a shield that I developed for ArduinoUNO on the STM32L476RG board.
In the original program, I transferred integer values to the ports instead of triggering them pin by pin.
As for the ArduinoUNO PORTB, only the first six pins are available (corresponding to digital pins 8 to 13 printed on the ArduinoUNO board, and corresponding to D8 - D13 on the STM32 board). I transfer to this port fixed values depending on the circuits I want to activate on the shield.
PORTB = 4;
As for PORTD, an entire port is available (corresponding to D0 - D7 on the STM32 board). In this port the values can vary more, they are not pre-established.
PORTD = valueA;
Checking the reference https://os.mbed.com/teams/ST/wiki/Use-o ... duino-pins, I realize that I have to change some connections on the board in order to continue using the same shield (pins D0 and D1 are used by the STLink Virtual Comm Port on the STM32 board).
My question is: keeping the program originally developed for ArduinoUNO, when transferring values to ports B and D, will the same pins be kept on the STM32L476RG board?
Note that on the STM32 board, pins D0 - D7 correspond to pins on ports PA_x and PB_x on the L476RG, and pins D8 - D13 correspond to pins on ports PA_x, PB_x and PC_x.
During compilation, will the libraries "mask" the intended pins to use the shield?
- Attachments
-
- placaUno - small1.jpg (84.41 KiB) Viewed 19244 times
-
- nucleo_l476rg_arduino - small.jpg (94.86 KiB) Viewed 19244 times
Re: Transfer of values to ArduinoUNO original ports.
first i need to dissapoint you saying that PORTx are atmega only, it wil not work with STM32
for direct port writing you can use LL driver or direct register access
STM32 have very straight port structure
GPIOA contains all PA0..PA15 ports, GPIOB - PB0..PB15 etc
so if your pins are on the same GPIO you can pack your pins and write them all or write whole port (all 16 pins)
for example
LL_GPIO_SetOutputPin(GPIOD, _Your_LL_BitmaskOfPinsToSet);
LL_GPIO_ResetOutputPin(GPIOD, _Your_LL_BitmaskOfPinsToReset);
where LL_Bitmask should be composed like LL_GPIO_PIN_0 | LL_GPIO_PIN_5 | LL_GPIO_PIN_10 or LL_GPIO_PIN_ALL for all ports;
LL_GPIO_WriteOutputPort(GPIOD, _YourSimpleBitMask);
here you can write whole port state using simple 16bit bitmask, each bit for each port
Upd. Instead of GPIOD here you should use your choosen GPIO port, GPIOA...GPIOZ
for direct port writing you can use LL driver or direct register access
STM32 have very straight port structure
GPIOA contains all PA0..PA15 ports, GPIOB - PB0..PB15 etc
so if your pins are on the same GPIO you can pack your pins and write them all or write whole port (all 16 pins)
for example
LL_GPIO_SetOutputPin(GPIOD, _Your_LL_BitmaskOfPinsToSet);
LL_GPIO_ResetOutputPin(GPIOD, _Your_LL_BitmaskOfPinsToReset);
where LL_Bitmask should be composed like LL_GPIO_PIN_0 | LL_GPIO_PIN_5 | LL_GPIO_PIN_10 or LL_GPIO_PIN_ALL for all ports;
LL_GPIO_WriteOutputPort(GPIOD, _YourSimpleBitMask);
here you can write whole port state using simple 16bit bitmask, each bit for each port
Upd. Instead of GPIOD here you should use your choosen GPIO port, GPIOA...GPIOZ
Re: Transfer of values to ArduinoUNO original ports.
Hi stas2z,
Thanks for the answer.
In fact, due to the silence on this subject in the last days, I realized that I was wrong, relating things that are different (declaration of ports in ArduinoUNO with the ports of STM32).
I took the opportunity to develop some lines of code using bitwise, which would probably solve the problem, although the activation of the port pins is slower and sequential, and not simultaneous, as would be the transfer of an integer value to a port:
I haven't done the tests yet, but it should work!
Thanks for the answer.
You're absolutely right!stas2z wrote: Sun Mar 29, 2020 5:13 am first i need to dissapoint you saying that PORTx are atmega only, it wil not work with STM32
In fact, due to the silence on this subject in the last days, I realized that I was wrong, relating things that are different (declaration of ports in ArduinoUNO with the ports of STM32).
I took the opportunity to develop some lines of code using bitwise, which would probably solve the problem, although the activation of the port pins is slower and sequential, and not simultaneous, as would be the transfer of an integer value to a port:
Code: Select all
//***PORTD ArduinoUNO***
//ArdnuinoUNO pins = STM32L476RG pins
// DO = PA_3
// D1 = PA_2
// D2 = PA_10
// D3 = PB_3
// D4 = PB_5
// D5 = PB_4
// D6 = PB_10
// D7 = PA_8
pinMode(PA3, OUTPUT);
pinMode(PA2, OUTPUT);
pinMode(PA10, OUTPUT);
pinMode(PB3, OUTPUT);
pinMode(PB5, OUTPUT);
pinMode(PB4, OUTPUT);
pinMode(PB10, OUTPUT);
pinMode(PA8, OUTPUT);
int valueA;
//PORTD=valueA;
int mask=0b00000001;
int value_to_port;
void transfer()
{
value_to_port=valueA&mask;
if (value_to_port==mask)
{
digitalWrite(PA3,HIGH);
}
else
{
digitalWrite(PA3,LOW);
}
mask<<1;
value_to_port=valueA&mask;
if (value_to_port==mask)
{
digitalWrite(PA2,HIGH);
}
else
{
digitalWrite(PA2,LOW);
}
mask<<1;
value_to_port=valueA&mask;
if (value_to_port==mask)
{
digitalWrite(PA10,HIGH);
}
else
{
digitalWrite(PA10,LOW);
}
mask<<1;
value_to_port=valueA&mask;
if (value_to_port==mask)
{
digitalWrite(PB3,HIGH);
}
else
{
digitalWrite(PB3,LOW);
}
mask<<1;
value_to_port=valueA&mask;
if (value_to_port==mask)
{
digitalWrite(PB5,HIGH);
}
else
{
digitalWrite(PB5,LOW);
}
mask<<1;
value_to_port=valueA&mask;
if (value_to_port==mask)
{
digitalWrite(PB4,HIGH);
}
else
{
digitalWrite(PB4,LOW);
}
mask<<1;
value_to_port=valueA&mask;
if (value_to_port==mask)
{
digitalWrite(PB10,HIGH);
}
else
{
digitalWrite(PB10,LOW);
}
mask<<1;
value_to_port=valueA&mask;
if (value_to_port==mask)
{
digitalWrite(PA8,HIGH);
}
else
{
digitalWrite(PA8,LOW);
}
mask=0b00000001;
}
Last edited by Fabaum on Thu Apr 02, 2020 8:38 pm, edited 1 time in total.
Re: Transfer of values to ArduinoUNO original ports.
if your output ports are not on the same port sure you need to write it one by one
but much better ti use array, loop and simple bitmath to not write A4 page of almost same copycat parts
sure this piece of code can be optimized much in terms of perfomance, but at least it look much cleaner
but much better ti use array, loop and simple bitmath to not write A4 page of almost same copycat parts
Code: Select all
uint32_t pins[8] = {PA3, PA2, PA10, PB3, PB5, PB4, PB10, PA8};
void setPinsMode(void) {
for (uint8_t counter = 0; counter < 8; counter++) {
pinMode(pins[counter], OUTPUT);
}
}
void writeValueToPins(uint8_t value) {
for (uint8_t counter = 0; counter < 8; counter++) {
digitalWrite(pins[counter], (value & (1U << counter)) ? HIGH : LOW);
}
}
Re: Transfer of values to ArduinoUNO original ports.
Excelent, stas2z, thank you again!
Re: Transfer of values to ArduinoUNO original ports.
Hi, stas2z,
Sorry to ask, but have you tested it?
I tried to apply it, but the operation is quite erratic ...
The code you suggested really looks more elegant.stas2z wrote: Mon Mar 30, 2020 6:02 pm if your output ports are not on the same port sure you need to write it one by one
but much better ti use array, loop and simple bitmath to not write A4 page of almost same copycat parts
sure this piece of code can be optimized much in terms of perfomance, but at least it look much cleanerCode: Select all
uint32_t pins[8] = {PA3, PA2, PA10, PB3, PB5, PB4, PB10, PA8}; void setPinsMode(void) { for (uint8_t counter = 0; counter < 8; counter++) { pinMode(pins[counter], OUTPUT); } } void writeValueToPins(uint8_t value) { for (uint8_t counter = 0; counter < 8; counter++) { digitalWrite(pins[counter], (value & (1U << counter)) ? HIGH : LOW); } }
Sorry to ask, but have you tested it?
I tried to apply it, but the operation is quite erratic ...
Re: Transfer of values to ArduinoUNO original ports.
ive not tested it, but its so basic and shouldn't cause any issue
only if your are trying to use it in the interrupt hadler
only if your are trying to use it in the interrupt hadler
Re: Transfer of values to ArduinoUNO original ports.
That code looks correct. I ran it on a blue pill and it looks like the correct pins are toggling.
You could add a serial print statement to see if the bits are being set the way you expect.
Also, you can simplify the digital write command to eliminate the ternary operator:
You could add a serial print statement to see if the bits are being set the way you expect.
Also, you can simplify the digital write command to eliminate the ternary operator:
Code: Select all
void writeValueToPins(uint8_t value) {
for (uint8_t counter = 0; counter < 8; counter++) {
digitalWrite(pins[counter], (value >> counter) & 1);
}
}
Re: Transfer of values to ArduinoUNO original ports.
Hi, friends,
... Now I will have to order another STM32L476RG board, but my country is restricting imports from China these days ...
stas2z, that is exactly what I am doing, trying to use your suggestion within an interruption routine. The strange thing is that during the execution of this routine, the timer is temporarily stopped ... What is the explanation for why it is not working well?stas2z wrote: Thu Apr 02, 2020 5:46 pm ive not tested it, but its so basic and shouldn't cause any issue
only if your are trying to use it in the interrupt hadler
fredbox, I would like to test this suggestion, but making a change to my ArduinoUNO shield that I am experimenting with on the STM32 board, I was careless and ended up putting 15V on the 3V3 power linefredbox wrote: Thu Apr 02, 2020 8:12 pm That code looks correct. I ran it on a blue pill and it looks like the correct pins are toggling.
You could add a serial print statement to see if the bits are being set the way you expect.
Also, you can simplify the digital write command to eliminate the ternary operator:Code: Select all
void writeValueToPins(uint8_t value) { for (uint8_t counter = 0; counter < 8; counter++) { digitalWrite(pins[counter], (value >> counter) & 1); } }



Re: Transfer of values to ArduinoUNO original ports.
inturrupt handler have to be quick as much as it possible and have some rectrictions also, but digitalWrite is very heavy trying to be beginners friendly with tonns of checks and inits inside
for interrupt handlers it's much better to use direct writing routines, at least digitalWriteFast for official STM32 core
for interrupt handlers it's much better to use direct writing routines, at least digitalWriteFast for official STM32 core