cancel
Showing results for 
Search instead for 
Did you mean: 

Multiplexing with STM32F303

CHae
Associate

Hello !

I really need your help , im working on a project and its a game of luck , random numbers will appear on 4 x 7 Segments , so i must multiplex , i understood the principe but i can't reach some good results , i don't know why ...

only the common segment will always be on and the others off when im trying to test something on main .

example > 1234 only the segment b will be on . i ll be sharing my code and circuits and some photos thank you for your help !

Circuit http://www.fritzler-avr.de/HP/tipps/multi.php first photo

> the 4 Bases are going ofc to ports of the Stm , segments are connected to eachothers and then to stm, Collectors the Common Anodes like in the photo

Code :

#include "stm32f3xx.h"

#include <stdint.h>

void activation();

void showdigit (int digit);

void showdigits1 (int number);

void showdigits2 (int number);

void showdigits3 (int number);

void showdigits4 (int number);

void delay(unsigned int x);

void mode1 () ;

void mode2 () ;

void mode3 () ;

void mode4 () ;

int main(void){

int x = 1234 ;

activation() ;

for(;;){

mode1() ;

showdigits1(x);

delay(1000);

mode2() ;

showdigits2(x);

delay(1000);

mode3() ;

showdigits3(x);

delay(1000);

mode4();

showdigits4(x);

delay(1000);

}

}

//Delay function

volatile _Bool finished;

void delay(unsigned int x){

finished = 0;

RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;

TIM2->DIER = TIM_DIER_UIE; // Update-Interrupt

TIM2->CNT = 0; TIM2->PSC = 7999; // 1 ms

TIM2->ARR = x - 1;

TIM2->CR1 = TIM_CR1_CEN; // Timer on

NVIC_EnableIRQ(TIM2_IRQn);

while (!finished)

__WFI(); TIM2->CR1 = 0;

return;

}

void TIM2_IRQHandler(void) {

finished = 1;

TIM2->SR &= ~TIM_SR_UIF; }

// end Delay Function

// Begin digitsfrom 0

void activation(){

RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // activation PORTS A

RCC->AHBENR |= RCC_AHBENR_GPIOBEN; // activation PORTS B

RCC->AHBENR |= RCC_AHBENR_GPIOCEN; // activation PORTS C

GPIOA->MODER |= 0b01 << 0; // segment d

GPIOA->MODER |= 0b01 << 2; // segment f

GPIOA->MODER |= 0b01 << 8; // segment e

GPIOA->MODER |= 0b01 << 16 ; // segment c

GPIOB->MODER |= 0b01 << 0; // segment g

GPIOC->MODER |= 0b01 << 2; // segment a

GPIOC->MODER |= 0b01 << 0; // segment b

GPIOB->MODER |= 0b01 << 20; // transistor1

GPIOB->MODER |= 0b01 << 10; // transistor2

GPIOB->MODER |= 0b01 << 12; // transistor3

GPIOA->MODER |= 0b01 << 18 ; //transistor4

}

/* PORTS DESCIPTION

Segment a PC1

Segment b PC0

Segment c PA8

Segment d PA0

Segment e PA4

Segment f PA1

Segment g PB0 */

// 0 is active emmeter => +VCC

void digit0 (){ // 0

GPIOB->ODR |= (1<<0);

}

void digit1 (){// 1

GPIOC->ODR |= (1<<1);

GPIOA->ODR |= (1<<1);

GPIOB->ODR |= (1<<0)

GPIOA->ODR |= (1<<4);

GPIOA->ODR |= (1<<0);

}

void digit2 (){// 2

GPIOA->ODR |= (1<<8);

GPIOA->ODR |= (1<<1);

}

void digit3 (){// 3

GPIOA->ODR |= (1<<4);

GPIOA->ODR |= (1<<1);

}

void digit4 (){// 4

GPIOC->ODR |= (1<<1);

GPIOA->ODR |= (1<<4);

GPIOA->ODR |= (1<<0);

}

void digit5 (){// 5

GPIOC->ODR |= (1<<0);

GPIOA->ODR |= (1<<4);

}

void digit6 (){// 6

GPIOC->ODR |= (1<<0);

}

void digit7 (){// 7

GPIOA->ODR |= (1<<4);

GPIOB->ODR |= (1<<0);

GPIOA->ODR |= (1<<1);

GPIOA->ODR |= (1<<0);

}

void digit8 (){// 8

}

void digit9 (){// 9

GPIOA->ODR |= (1<<4);

}

void showdigit (int digit) {

switch (digit)

{

case 0: digit0 ();

break;

case 1: digit1 ();

break;

case 2: digit2 ();

break;

case 3: digit3 ();

break;

case 4: digit4 ();

break;

case 5: digit5 ();

break;

case 6: digit6 ();

break;

case 7: digit7 ();

break;

case 8: digit8 ();

break;

case 9: digit9 ();

break;

default:

break;

};

};

// end digitsdefine from 0 to 9 and showing them

void showdigits1 (int number){

int x = number / 1000 ;

showdigit(x);

}

void showdigits2 (int number){

int y = (number % 1000) / 100 ;

showdigit(y);

}

void showdigits3 (int number){

int z = (number % 100) / 10 ;

showdigit(z);

}

void showdigits4 (int number){

int e = number % 10 ;

showdigit(e);

}

void mode1 () { // transistor 1 ON others OFF

GPIOA->ODR |= (1<<9);

GPIOB->ODR |= (1<<5);

GPIOB->ODR |= (1<<6);

GPIOB->ODR ^= (1<<10);

}

void mode2 () { // transistor 2 ON others OFF

GPIOA->ODR |= (1<<9);

GPIOB->ODR |= (1<<10);

GPIOB->ODR |= (1<<6);

GPIOB->ODR ^= (1<<5);

}

void mode3 () { // transistor 3 ON others OFF

GPIOA->ODR |= (1<<9);

GPIOB->ODR |= (1<<5);

GPIOB->ODR |= (1<<10);

GPIOB->ODR ^= (1<<6);

}

void mode4 () { // transistor 4 ON others OFF

GPIOB->ODR |= (1<<10);

GPIOB->ODR |= (1<<5);

GPIOB->ODR |= (1<<6);

GPIOA->ODR ^= (1<<9);

}

1 REPLY 1

Really don't want to wade into this too deeply

You keep ORing values onto the GPIO pins, at some point they will all be HIGH and never go LOW, you should perhaps mask the bits of interest, and clear them.

Also writing to the register multiple times with RMW is very inefficient

Consider using BSRR to set/clear multiple bits in the GPIO ODR in a single write.

You interrupt routine should be more like this

void TIM2_IRQHandler(void)

{

if (TIM2->SR & TIM_SR_UIF) // Validate source

{

TIM2->SR = ~TIM_SR_UIF; // Clear with a write, not RMW action

finished = 1;

}

}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..