ich versuche gerade, eine 7 Segment Indicator (siehe Bild), die von 
einem MAX7219  gesteuert wird, mit einem STM32F303 via Software SPI 
anzusteuern.
Aber klappt etwas nicht!
 1   
 2 /** 
3  ****************************************************************************** 
4  * @file    main.c 
5  * @author  Ac6 
6  * @version V1.0 
7  * @date    01-December-2013 
8  * @brief   Default main function. 
9  ****************************************************************************** 
10  */ 
11 
 12 #include  "stm32f30x.h" 
13 #include  "stm32f30x_gpio.h" 
14 #include  "stm32f30x_rcc.h" 
15 #include  "stm32f30x_spi.h" 
16 
 17 #define SCK_Pin  GPIO_Pin_10 
18 #define SCK_Pin_Port GPIOC 
19 
 20 #define MOSI_Pin GPIO_Pin_12 
21 #define MOSI_Pin_Port GPIOC 
22 
 23 #define SS_Pin  GPIO_Pin_2 
24 #define SS_Pin_Port GPIOD 
25 
 26 #define cs_set() SS_Pin_Port->BRR = SS_Pin; 
27 #define cs_reset() SS_Pin_Port->BSRR = SS_Pin; 
28 
 29 //OPTIONS 
30 #define SCANLIMIT 7 
31 #define INTENSITY_HIGH 12 
32 #define INTENSITY_MED 7 
33 #define INTENSITY_LOW 3 
34 #define DP 0x80 
35 #define MINUS 0x0a 
36 #define BLANK 0x0f 
37 #define DECODEMODE 0xff 
38 
 39 //OPCODES 
40 #define OP_NOOP   0 
41 #define OP_DIGIT0 1 
42 #define OP_DIGIT1 2 
43 #define OP_DIGIT2 3 
44 #define OP_DIGIT3 4 
45 #define OP_DIGIT4 5 
46 #define OP_DIGIT5 6 
47 #define OP_DIGIT6 7 
48 #define OP_DIGIT7 8 
49 #define OP_DECODEMODE  9 
50 #define OP_INTENSITY   10 
51 #define OP_SCANLIMIT   11 
52 #define OP_SHUTDOWN    12 
53 #define OP_DISPLAYTEST 15 
54 
 55 void  SPISend ( uint8_t  addr ,  uint8_t  data )  { 
56   cs_set () 
 57   ; 
 58   SPI_I2S_SendData16 ( SPI3 ,  ((( uint16_t )  addr  <<  8 )  +  data )); 
 59   cs_reset () 
 60   ; 
 61 
 62 } 
63 
 64 void  SPIInit ( void )  { 
65 
 66   SPI_InitTypeDef  SPIConf ; 
 67   SPIConf . SPI_Direction  =  SPI_Direction_2Lines_FullDuplex ; 
 68   SPIConf . SPI_Mode  =  SPI_Mode_Master ; 
 69   SPIConf . SPI_DataSize  =  SPI_DataSize_8b ; 
 70   SPIConf . SPI_CRCPolynomial  =  7 ; 
 71   SPIConf . SPI_CPOL  =  SPI_CPOL_Low ; 
 72   SPIConf . SPI_CPHA  =  SPI_CPHA_1Edge ; 
 73   SPIConf . SPI_NSS  =  SPI_NSS_Soft ; 
 74   SPIConf . SPI_BaudRatePrescaler  =  SPI_BaudRatePrescaler_8 ; 
 75   SPIConf . SPI_FirstBit  =  SPI_FirstBit_MSB ; 
 76   SPI_Init ( SPI3 ,  & SPIConf ); 
 77   SPI_Cmd ( SPI3 ,  ENABLE ); 
 78 } 
79 
 80 void  GPIOInit ( void )  { 
81   RCC_AHBPeriphClockCmd ( 
 82   RCC_AHBPeriph_GPIOC  |  RCC_AHBPeriph_GPIOD  |  RCC_APB1ENR_SPI3EN ,  ENABLE ); 
 83   GPIO_InitTypeDef  PORT ; 
 84 
 85   PORT . GPIO_Pin  =  GPIO_Pin_10  ; 
 86   PORT . GPIO_Speed  =  GPIO_Speed_2MHz ; 
 87   PORT . GPIO_Mode  =  GPIO_Mode_AF ; 
 88   GPIO_Init ( GPIOC ,  & PORT ); 
 89 
 90   PORT . GPIO_Pin  =  GPIO_Pin_12 ; 
 91   PORT . GPIO_Speed  =  GPIO_Speed_2MHz ; 
 92   PORT . GPIO_Mode  =  GPIO_Mode_AF ; 
 93   GPIO_Init ( GPIOC ,  & PORT ); 
 94 
 95   PORT . GPIO_Pin  =  GPIO_Pin_2 ; 
 96   PORT . GPIO_Speed  =  GPIO_Speed_2MHz ; 
 97   PORT . GPIO_Mode  =  GPIO_Mode_OUT ; 
 98   GPIO_Init ( GPIOD ,  & PORT ); 
 99 } 
100 
 101 int  main ()  { 
102   SystemInit (); 
 103   GPIOInit (); 
 104   SPIInit (); 
 105   for  (;;)  { 
 106     SPISend ( OP_DISPLAYTEST ,  0 ); 
 107     SPISend ( OP_SHUTDOWN ,  1 ); 
 108 
 109 
 110     SPISend ( OP_DECODEMODE ,  DECODEMODE ); 
 111     SPISend ( OP_DIGIT0 ,  7  +  DP ); 
 112     SPISend ( OP_DIGIT1 ,  6 ); 
 113     SPISend ( OP_DIGIT2 ,  5  +  DP ); 
 114     SPISend ( OP_DIGIT3 ,  4 ); 
 115     SPISend ( OP_DIGIT4 ,  3  +  DP ); 
 116     SPISend ( OP_DIGIT5 ,  2 ); 
 117     SPISend ( OP_DIGIT6 ,  1  +  DP ); 
 118     SPISend ( OP_DIGIT7 ,  0 ); 
 119   } 
 120 } 
MOD: bitte Bedienungsanleitung ab "Wichtige Regeln - erst lesen, dann 
posten!" lesen und [c] Tags verwenden. 
   
  
  
 
      
      
  
  
    
      von
      
        :-)  (Gast)
      
      
       
    
    
      25.03.2019 20:57 
    
     
  
  
      ich benutze zwar keinen STM32F...
aber den MAX7219  an PIC  Controllern in Assembler.
Damit er da funktioniert muss ich den Serial Port am PIC  so einstellen, 
dass mit steigender Clockflanke gesendet wird und die Clockpolarität 
auf: Clock Idle State high.
Bei dir dürfte das CPOL (Clock Polarity) und CPHA (Clock Phase) sein. 
   
  
  
 
      
      
  
  
  
  
      Bei dem Code sehe ich nicht wie T_CSW oder T_CSS eingehalten werden 
soll.
Logic high input voltage von mindestens  3,5V sprechen auch eher gegen 
einen STM32 , der nur 3,3V VCC verträgt. Da müsste ein Pegelwandler 
zwischen, falls der STM keine mit 5V befeuerten I/Os hat.
> via Software SPI 
Ich sehe da nur Hardware SPI Zugriffe. 
   
  
  
 
      
      
      
      
  
  
    
      von
      
        SchaumSchläger  (Gast)
      
      
       
    
    
      26.03.2019 10:52 
    
     
  
  
      Jim M. schrieb: > Ich sehe da nur Hardware SPI Zugriffe. 
Also alles in allem betrachtet eine rundum durchdachte Lösung. 
  
  
 
      
      
  
  
    
      von
      
        OhWeia  (Gast)
      
      
       
    
    
      26.03.2019 12:11 
    
     
  
  
      Das habe ich vor ein paar Tagen im Netz gefunden. Soft-SPI und ging auf 
anhieb.
 1 void  max7219_brightness ( char  brightness )  { 
2   brightness  &=  0x0f ;                                  // mask off extra bits 
 3   max7219_write_reg ( REG_INTENSITY ,  brightness );            // set brightness 
 4 
 5 } 
6 
 7 void  max7219_write_reg ( unsigned  char  reg_number ,  unsigned  char  dataout )  { 
8   gpio_clear ( LOAD_PORT ,  LOAD_PIN ); 
 9   max7219_send_byte ( reg_number );                        // write register number to MAX7219 
 10   max7219_send_byte ( dataout );                           // write data to MAX7219 
 11   gpio_set ( LOAD_PORT ,  LOAD_PIN ); 
 12 } 
13 
 14 void  max7219_send_byte ( unsigned  char  dataout )  { 
15   char  i ; 
 16   for  ( i = 8 ;  i > 0 ;  i -- )  { 
 17     unsigned  char  mask  =  1  <<  ( i  -  1 );                 // calculate bitmask 
 18     gpio_clear ( CLK_PORT ,  CLK_PIN ); 
 19     if  ( dataout  &  mask )                                // output one data bit 
 20       gpio_set ( DATA_PORT ,  DATA_PIN ); 
 21     else                                               //  or 
 22       gpio_clear ( DATA_PORT ,  DATA_PIN ); 
 23     gpio_set ( CLK_PORT ,  CLK_PIN ); 
 24   } 
 25 } 
26 
 27 void  init_max7219 ( void )  { 
28   rcc_periph_clock_enable ( RCC_GPIOB );  // TODO: RCC_xxxx aus PORT erzeugen 
 29 
 30     
 31     gpio_set_mode ( GPIOB ,  GPIO_MODE_OUTPUT_2_MHZ ,  GPIO_CNF_OUTPUT_PUSHPULL ,  GPIO12 ); 
 32     gpio_set_mode ( GPIOB ,  GPIO_MODE_OUTPUT_2_MHZ ,  GPIO_CNF_OUTPUT_PUSHPULL ,  GPIO13 ); 
 33     gpio_set_mode ( GPIOB ,  GPIO_MODE_OUTPUT_2_MHZ ,  GPIO_CNF_OUTPUT_PUSHPULL ,  GPIO15 ); 
 34 
 35   max7219_write_reg ( REG_SCAN_LIMIT ,  7 );                    // set up to scan all eight digits 
 36   max7219_write_reg ( REG_DECODE ,  0x00 );                     // set to "no decode" for all digits 
 37   max7219_write_reg ( REG_SHUTDOWN ,  1 );                      // put MAX7219 into "normal" mode 
 38   max7219_write_reg ( REG_DISPLAY_TEST ,  0 );                  // put MAX7219 into "normal" mode 
 39   
 40   max7219_brightness ( 0x00 ); 
 41   
 42 } 
 
  
  
 
      
      
  
  
    
      von
      
        OhWeia  (Gast)
      
      
       
    
    
      26.03.2019 12:12 
    
     
  
  
      Header vergessen. 1 #define DATA_PORT       GPIOB                           // assume "DATA" is on PA7 
2 #define DATA_PIN        GPIO15 
3 #define CLK_PORT        GPIOB                           // assume "CLK" is on PA5 
4 #define CLK_PIN         GPIO13 
5 #define LOAD_PORT       GPIOB                           // assume "LOAD (nCS)" is on PA6 
6 #define LOAD_PIN     GPIO12 
7 
 8 #define REG_NOP           0x00                        // Nop for daisy chaining 
9 #define REG_DIGIT0   0x01 
10 #define REG_DIGIT1   0x02 
11 #define REG_DIGIT2   0x03 
12 #define REG_DIGIT3   0x04 
13 #define REG_DIGIT4   0x05 
14 #define REG_DIGIT5   0x06 
15 #define REG_DIGIT6   0x07 
16 #define REG_DIGIT7       0x08 
17 #define REG_DECODE        0x09                        // "decode mode" register 
18 #define REG_INTENSITY     0x0a                        // "intensity" register 
19 #define REG_SCAN_LIMIT    0x0b                        // "scan limit" register 
20 #define REG_SHUTDOWN      0x0c                        // "shutdown" register 
21 #define REG_DISPLAY_TEST  0x0f                        // "display test" register 
 
  
  
 
      
      
  
  
  
  
      Alles klappt. In main() nicht vergessen zwei Funktion zu schreiben 
Init_SPI();Init_7219();  Dann einfach schreibt: Send_7219(1,1); erste 
Ziffer bedeutet stelle zweite genaue welche ziffer.  Quellcode: 1 #include  "max7219.h" 
2 #include  "stm32f30x.h" 
3 #include  "stm32f30x_gpio.h" 
4 #include  "stm32f30x_rcc.h" 
5 #include  "stm32f30x_spi.h" 
6 
 7 #define cs_ON() GPIO_ResetBits(GPIOD, GPIO_Pin_2); 
8 #define cs_OFF() GPIO_SetBits(GPIOD, GPIO_Pin_2); 
9 
 10 char  dg  =  8 ; 
11 
 12 void  Init_SPI ( void )  { 
13 
 14         RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_GPIOA ,  ENABLE ); 
 15   RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_GPIOB ,  ENABLE ); 
 16   RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_GPIOC ,  ENABLE ); 
 17   RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_GPIOD ,  ENABLE ); 
 18         RCC_APB1PeriphClockCmd ( RCC_APB1Periph_SPI3 ,  ENABLE ); 
 19 
 20   GPIO_InitTypeDef  PORT ; 
 21   PORT . GPIO_Pin  =  GPIO_Pin_10 ;  //10:SCK->CLK 
 22   PORT . GPIO_Speed  =  GPIO_Speed_Level_1 ; 
 23   PORT . GPIO_Mode  =  GPIO_Mode_AF ; 
 24   PORT . GPIO_OType  =  GPIO_OType_PP ; 
 25   PORT . GPIO_PuPd  =  GPIO_PuPd_NOPULL ; 
 26   GPIO_Init ( GPIOC ,  & PORT ); 
 27   GPIO_PinAFConfig ( GPIOC ,  GPIO_PinSource10 ,  GPIO_AF_6 ); 
 28 
 29   PORT . GPIO_Pin  =  GPIO_Pin_12 ;  // 12:MOSI->DIN 
 30   PORT . GPIO_Speed  =  GPIO_Speed_Level_1 ; 
 31   PORT . GPIO_Mode  =  GPIO_Mode_AF ; 
 32   PORT . GPIO_OType  =  GPIO_OType_PP ; 
 33   PORT . GPIO_PuPd  =  GPIO_PuPd_NOPULL ; 
 34   GPIO_Init ( GPIOC ,  & PORT ); 
 35   GPIO_PinAFConfig ( GPIOC ,  GPIO_PinSource12 ,  GPIO_AF_6 ); 
 36 
 37   PORT . GPIO_Pin  =  GPIO_Pin_2 ;  // SS->CS 
 38   PORT . GPIO_Speed  =  GPIO_Speed_Level_1 ; 
 39   PORT . GPIO_Mode  =  GPIO_Mode_OUT ; 
 40   PORT . GPIO_OType  =  GPIO_OType_PP ; 
 41   GPIO_Init ( GPIOD ,  & PORT ); 
 42   GPIO_SetBits ( GPIOD ,  GPIO_Pin_2 ); 
 43 
 44 
 45   SPI_InitTypeDef  SPIConf ; 
 46   SPIConf . SPI_Direction  =  SPI_Direction_1Line_Tx ; 
 47   SPIConf . SPI_Mode  =  SPI_Mode_Master ; 
 48   SPIConf . SPI_DataSize  =  SPI_DataSize_16b ; 
 49   //SPIConf.SPI_CRCPolynomial = 7; 
 50   SPIConf . SPI_CPOL  =  SPI_CPOL_Low ; 
 51   SPIConf . SPI_CPHA  =  SPI_CPHA_1Edge ; 
 52   SPIConf . SPI_NSS  =  SPI_NSS_Soft  |  SPI_NSSInternalSoft_Set ; 
 53   SPIConf . SPI_BaudRatePrescaler  =  SPI_BaudRatePrescaler_4 ; 
 54   SPIConf . SPI_FirstBit  =  SPI_FirstBit_MSB ; 
 55   SPI_Init ( SPI3 ,  & SPIConf ); 
 56   SPI_Cmd ( SPI3 ,  ENABLE ); 
 57   SPI_NSSInternalSoftwareConfig ( SPI3 ,  SPI_NSS_Soft ); 
 58 } 
59 
 60 //------------------------------------------------------ 
61 
 62 void  Send_7219 ( uint8_t  rg ,  uint8_t  dt )  { 
63   cs_ON () 
 64   ; 
 65   while  ( SPI_I2S_GetFlagStatus ( SPI3 ,  SPI_I2S_FLAG_TXE )  ==  RESET ) 
 66     ; 
 67   SPI_I2S_SendData16 ( SPI3 ,  ((( uint16_t )  rg  <<  8 )  +  dt )); 
 68   while  ( SPI_I2S_GetFlagStatus ( SPI3 ,  SPI_I2S_FLAG_BSY )  ==  SET ) 
 69     ; 
 70   cs_OFF () 
 71   ; 
 72 } 
73 
 74 void  Clear_7219 ( void )  { 
75 
 76   Send_7219 ( 0x01 ,  0x00 ); 
 77   Send_7219 ( 0x02 ,  0x00 ); 
 78   Send_7219 ( 0x03 ,  0x00 ); 
 79   Send_7219 ( 0x04 ,  0x00 ); 
 80 } 
81 
 82 void  Number_7219 ( volatile  long  n )  { 
83   uint8_t  ng  =  0 ; 
 84   if  ( n  <  0 )  { 
 85     ng  =  1 ; 
 86     n  *=  - 1 ; 
 87   } 
 88   uint8_t  i  =  0 ; 
 89   do  { 
 90     Send_7219 ( ++ i ,  n  %  10 ); 
 91     n  /=  10 ; 
 92   }  while  ( n ); 
 93   if  ( ng )  { 
 94     Send_7219 ( i  +  1 ,  0x0A ); 
 95   } 
 96 } 
97 
 98 void  Init_7219 ( void )  { 
99   Send_7219 ( 0x0F ,  0x00 ); 
 100   Send_7219 ( 0x0C ,  0x01 ); 
 101   Send_7219 ( 0x0B ,  0x03 ); 
 102   Send_7219 ( 0x0A ,  0x0A ); 
 103   Send_7219 ( 0x09 ,  0xFF ); 
 104   Clear_7219 (); 
 105 } 
106 
 107 void  delay ( uint32_t  us )  { 
108   volatile  uint32_t  nCount ; 
 109   RCC_ClocksTypeDef  RCC_Clocks ; 
 110   RCC_GetClocksFreq ( & RCC_Clocks ); 
 111   nCount  =  ( RCC_Clocks . HCLK_Frequency  /  7200 )  *  us ; 
 112   for  (;  nCount  !=  0 ;  nCount -- ) 
 113     ; 
 114 } 
 
  
  
 
      
      
  
  
    
      von
      
        Christian J.  (Gast)
      
      
       
    
    
      06.10.2019 17:11 
    
     
  
  
      Hi,
ic bin seit 6h an dem gleichen Problem dran. Diese LED  Matrizzen mit 8x8 
und nichts klappt am STM32103. Ja, es tut sich was aber nur Müll. Daten 
laufen richtig raus, am LA geprüft. Aber es reagieren immer mehrere der 
kaskadierten Matrizzen. Nicht mal nacheinander liegen die. Habe 12 in 
Reihe geschaltet. Gibt es als 4er Blocks zu kaufen. Auch eine tut es 
nicht allein.
Ist das sicher, dass der Max719 auch mit 3.3V noch "haarscharf" 
schaltet? Gibt ja auch ESP8266 Videos, wo er es tut. Wenn er es nicht 
tut verstehe ich den zufälligen Müll schon eher.
8 und 16 Bit ausprobiert, beides geht aber wohl. Das Durchschieben lasse 
ich erstmal weg, nur dass 1 Display erstmal läuft, das erste vorne.
 1    /* Die SPI einstellen: Master, 1 Line TX, 8 Bit, Mode 0 */ 
 2     SPI_StructInit ( & SPI_InitStruct ); 
 3     SPI_InitStruct . SPI_Direction  =  SPI_Direction_1Line_Tx ; 
 4     SPI_InitStruct . SPI_Mode       =  SPI_Mode_Master ; 
 5     SPI_InitStruct . SPI_DataSize   =  SPI_DataSize_8b ; 
 6     SPI_InitStruct . SPI_CPOL       =  SPI_CPOL_Low ; 
 7     SPI_InitStruct . SPI_CPHA       =  SPI_CPHA_1Edge ; 
 8     SPI_InitStruct . SPI_NSS        =  SPI_NSS_Soft ; 
 9     SPI_InitStruct . SPI_BaudRatePrescaler  =  SPI_BaudRatePrescaler_16 ;         // 4.5 Mhz 
 10     SPI_InitStruct . SPI_FirstBit   =  SPI_FirstBit_MSB ; 
 11 
 12     SPI_Init ( MAX_SPI ,  & SPI_InitStruct ); 
 13     SPI_Cmd ( MAX_SPI ,  ENABLE ); 
 14 } 
15 
 16 void  SendCmd ( uint8_t  modul ,  uint8_t  cmd ,  uint8_t  val ) 
17 { 
18     if  ( modul  >  11 ) 
 19         return ; 
 20 
 21     CE_LOW (); 
 22     SPI_SendByte ( cmd ); 
 23     SPI_SendByte ( val ); 
 24 
 25 //    for (int i = 0; i < modul; i++) { 
26 //        SPI_SendWord(MAX7219_NOP); 
27 //    } 
28 
 29     CE_HIGH (); 
 30 
 31 } 
32 
 33 /* Init Matrix LED */ 
34 void  InitMatrix () 
35 { 
36     int  v  =  0 ; 
 37 
 38     /* Decode Mode ausschalten */ 
 39     SendCmd ( v , MAX7219_DECODE_MODE , 0 ); 
 40     SendCmd ( v , MAX7219_SCAN_LIMIT , 7 ); 
 41     SendCmd ( v , MAX7219_BRIGHTNESS , 2 ); 
 42     SendCmd ( v , MAX7219_SHUTDOWN , 1 ); 
 43     SendCmd ( v , MAX7219_TEST , 0 ); 
 44 
 45     SendCmd ( v , MAX7219_DIGIT_0 , 6 ); 
 
 
  
  
 
      
      
  
  
    
      von
      
        John Doe  (Gast)
      
      
       
    
    
      06.10.2019 17:28 
    
     
  
  
      Christian J. schrieb: > Ist das sicher, dass der Max719 auch mit 3.3V noch "haarscharf" 
> schaltet? Gibt ja auch ESP8266 Videos, wo er es tut. Wenn er es nicht 
> tut verstehe ich den zufälligen Müll schon eher. 
Warum gibst Du dem Max nicht einfach eine laut Datenblatt vorgegebene 
Spannung und schaust, was passiert?
Bei mir am F446 läuft es übrigens. Heisst aber nix. 
  
  
 
      
      
  
  
    
      von
      
        Christian J.  (Gast)
      
      
       
    
    
      06.10.2019 17:31 
    
     
  
  
      John Doe schrieb: > Warum gibst Du dem Max nicht einfach eine laut Datenblatt vorgegebene 
> Spannung und schaust, was passiert? 
Weil ich die nicht auf dem Lochraster habe? Und einen 74HCT04  dazubauen 
ginge noch aber vorher Klarheit schaffen. 
  
  
 
      
      
  
  
    
      von
      
        Christian J.  (Gast)
      
      
       
    
    
      06.10.2019 19:09 
    
     
      
      hmm.... ein 7404 ist eingebaut, je 2 Inverter in Reihe für die 3 Kanäle 
CS, MOSI und CLK... trotzdem spielt das Teil nicht. Gibt es da noch 
einen Kniff? Daten stimmen jedenfalls. Die Muster die ich einspiele 
erscheinen in allen 4 Displays gleichzeitig und nicht nur in dem ersten. 
   
  
  
 
    
    
        Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.