STM32 Blue pill Oled 2,5"

Zestawy developrskie z mikrokontrolerami STM32 innych firm i nie tylko
ODPOWIEDZ
kulfi27
Użytkownik
Posty: 23
Rejestracja: 28 mar 2018, 14:01

STM32 Blue pill Oled 2,5"

Post autor: kulfi27 » 13 gru 2019, 0:02

Witam, jakiś czas temu zakupiłem u chińskich przyjaciół wyświetlacz oled 2,5" z kontrolerem SPD030. Po dotarciu wyświetlaczy na szybko postanowiłem je przetestować na płytce kolegi z uC AVR z gotowym projektem dla OLED 0.96 po I2C i kontrolerem SSD1306. Po podpięciu wyświetlacz zadziałał bez wprowadzania jakichkolwiek poprawek w kodzie. Wyświetlacze trochę poleżały w szufladzie, no ale w końcu przyszedł na nie czas więc padło na Blue Pill.
Bibliotek w necie nie brakuje widziałem takową nawet tutaj na forum więc co tam szybka konfiguracja I2C w QubeMx i odpalam a tu "zonk" oled milczy,

W ruch poszedł analizator i tam ciekawostka po wysłaniu przez mastera adresu brak ack od wyświetlacza, co się na kombinowałem kilka wieczorów kilka szarych komórek z pewnością mniej :D. Wiec jeszcze raz kolegi zestaw i analizator a tam również brak ack, z tym że w jego procedurze obsługi I2C tak się domyślam nie czeka na potwierdzenie od slave ale tak mu to działa, może jakieś podróbki nie wiem. Postanowiłem napisać procedurę obsługi I2C bez ack na tą chwile wybląda to mniej więcej tak;
  1.  
  2.        I2C1->CR1 |=I2C_CR1_START;                         //generuję start
  3.  
  4.       while(  (I2C1->SR1 & I2C_SR1_SB)==RESET   );  // pętla oczekująca na start
  5.  
  6.        I2C1->DR  =(uint8_t)0x78;                              // wysyłam adres
  7.  
  8.        statt=I2C1->SR1;                                           //odczytuję statusy flag
  9.        statt=I2C1->SR2;
  10.  
  11.        Delay(1000);                                                 // tutaj pojawia się pierwszy problem z powodu brak ack niema żadnej flagi potwierdzającej
  12.                                                                                                    stąd ten Delay
  13.  
  14.           //I2C1->DR  =(uint8_t)0x00;  
  15.          I2C1->DR     =(uint8_t)0xAE;                       //  wysłanie jakiej kolwiech wartości powoduje ze peryferial wysyła dwa bajty o tych samych
  16.                                                                                                  wartościach
  17.  
  18.       statt=I2C1->SR1;                                           //odczytuję statusy flag
  19.           statt=I2C1->SR2;
  20.  
  21.           while(  (I2C1->SR1 & I2C_SR1_BTF)==RESET   );  //  czekam aż bajt zostanie wysłany
  22.  
  23.  
  24.          I2C1->CR1 |=I2C_CR1_STOP;                              //generuje stop
  25.  
  26.  
W końcu dotarłem do meritum pytania jak powinna wyglądać taka procedura nadawania, sorki za taki długaśny opis :)

Pozdrawiam

Awatar użytkownika
Nefarious19
Magyster
Posty: 46
Rejestracja: 17 paź 2017, 10:03
Lokalizacja: Łódź

Re: STM32 Blue pill Oled 2,5"

Post autor: Nefarious19 » 13 gru 2019, 12:02

Tu masz obsługę I2C dla STM32F303, dla Twojego będzie b podobnie. Na niej mam b. dobrą komunikację z SH1106 po i2c. Nie szukaj tego kodu w necie bo pisałem go sam na szybko.
  1. /*
  2.  * i2c.c
  3.  *
  4.  *  Created on: 10.01.2019
  5.  *      Author: rafal
  6.  */
  7.  
  8. #include "stm32f3xx.h"
  9. #include "../inc/stm32f303_i2c.h"
  10.  
  11. I2C_deviceFoundCallbackFunctionPtr I2C_addressFoundCallback;
  12.  
  13. void I2C_init(void)
  14. {
  15.     RCC->CFGR3 |= RCC_CFGR3_I2C1SW;
  16.     RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
  17.  
  18.     GPIOB->MODER |= GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1;
  19.     GPIOB->OTYPER |= GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7;
  20.     GPIOB->AFR[0] |= (4<<24) | (4<<28);
  21.  
  22.     I2C1->TIMINGR = (3<<28) |
  23.                     (16<<0)  |
  24.                     (16<<8)  |
  25.                     (2<<20)     |
  26.                     (2<<16)     ;
  27.     I2C1->CR1 |= I2C_CR1_NOSTRETCH;
  28. }
  29.  
  30. void I2C_registerDeviceFoundCallback(I2C_deviceFoundCallbackFunctionPtr funcPtr)
  31. {
  32.     if(funcPtr)
  33.     {
  34.         I2C_addressFoundCallback = funcPtr;
  35.     }
  36. }
  37.  
  38. void I2C_Scanner(void)
  39. {
  40.     uint8_t deviceFound;
  41.  
  42.     for(uint8_t slaveIdx = 0; slaveIdx < 0x7F; slaveIdx++)
  43.     {
  44.         deviceFound = 0;
  45.         I2C1->CR1 |= I2C_CR1_PE;
  46.         I2C1->CR2 = (I2C1->CR2 & 0xFFFFFF00) | (slaveIdx<<1);
  47.         I2C1->CR2 = (I2C1->CR2 & 0xFF00FFFF) | (1<<16);
  48.         I2C1->CR2 &= ~I2C_CR2_RD_WRN;
  49.         I2C1->CR2 |= I2C_CR2_START;
  50.         while(I2C1->CR2 & I2C_CR2_START);
  51.         while((!(I2C1->ISR & I2C_ISR_TXIS)) && (!(I2C1->ISR & I2C_ISR_NACKF)));
  52.         if((I2C1->ISR & I2C_ISR_TXIS))
  53.         {
  54.             deviceFound = 1;
  55.             I2C1->TXDR = 0;
  56.             while(!(I2C1->ISR & I2C_ISR_TXE));
  57.             I2C1->CR2 |= I2C_CR2_STOP;
  58.             while(I2C1->CR2 & I2C_CR2_STOP);
  59.             I2C1->CR1 &= ~I2C_CR1_PE;
  60.         }
  61.         else if(!(I2C1->ISR & I2C_ISR_NACKF))
  62.         {
  63.             I2C1->CR1 &= ~I2C_CR1_PE;
  64.         }
  65.  
  66.         if(deviceFound)
  67.         {
  68.             if(I2C_addressFoundCallback)
  69.             {
  70.                 I2C_addressFoundCallback(slaveIdx<<1);
  71.             }
  72.         }
  73.     }
  74. }
  75.  
  76. void I2C_writeByte(uint8_t slave, uint8_t data)
  77. {
  78.     I2C1->CR1 |= I2C_CR1_PE;
  79.     I2C1->CR2 = (I2C1->CR2 & 0xFFFFFF00) | (slave<<1);
  80.     I2C1->CR2 = (I2C1->CR2 & 0xFF00FFFF) | (1<<16);
  81.     I2C1->CR2 &= ~I2C_CR2_RD_WRN;
  82.     I2C1->CR2 |= I2C_CR2_START;
  83.     while(I2C1->CR2 & I2C_CR2_START);
  84.     I2C1->TXDR = data;
  85.     while(!(I2C1->ISR & I2C_ISR_TXE));
  86.     I2C1->CR2 |= I2C_CR2_STOP;
  87.     while(I2C1->CR2 & I2C_CR2_STOP);
  88.     I2C1->CR1 &= ~I2C_CR1_PE;
  89. }
  90.  
  91. void I2C_writeNBytes(uint8_t slave, uint8_t * data, uint16_t len)
  92. {
  93.  
  94.     if(len > 255)
  95.     {
  96.         uint32_t reloadsRuns = len / 255;
  97.         uint32_t lastRun = (len % 255);
  98.         uint32_t byteCounter = 255;
  99.         I2C1->CR1 |= I2C_CR1_PE;
  100.         I2C1->CR2 = (I2C1->CR2 & 0xFFFFFF00) | (slave);
  101.         I2C1->CR2 = (I2C1->CR2 & 0xFF00FFFF) | (0xFF<<16);
  102.         I2C1->CR2 |= I2C_CR2_RELOAD;
  103.         I2C1->CR2 &= ~(I2C_CR2_RD_WRN | I2C_CR2_AUTOEND);
  104.         I2C1->CR2 |= I2C_CR2_START;
  105.  
  106.         for(uint8_t i = 0; i < reloadsRuns; i++)
  107.         {
  108.             while(byteCounter--)
  109.             {
  110.                 while(!(I2C1->ISR & I2C_ISR_TXIS));
  111.                 I2C1->TXDR = *data++;
  112.             }
  113.             while(!(I2C1->ISR & I2C_ISR_TCR));
  114.             byteCounter = 255;
  115.         }
  116.  
  117.         I2C1->CR2 = (I2C1->CR2 & 0xFF00FFFF) | (lastRun<<16);
  118.         I2C1->CR2 &= ~I2C_CR2_RELOAD;
  119.         I2C1->CR2 |=  I2C_CR2_AUTOEND;
  120.  
  121.         while(lastRun--)
  122.         {
  123.             while(!(I2C1->ISR & I2C_ISR_TXIS));
  124.             I2C1->TXDR = *data++;
  125.         }
  126.  
  127.         while(!(I2C1->ISR & I2C_ISR_TC));
  128.         I2C1->CR1 &= ~I2C_CR1_PE;
  129.  
  130.     }
  131.     else
  132.     {
  133.         I2C1->CR1 |= I2C_CR1_PE;
  134.         I2C1->CR2 = (I2C1->CR2 & 0xFFFFFF00) | (slave);
  135.         I2C1->CR2 = (I2C1->CR2 & 0xFF00FFFF) | (len<<16);
  136.         I2C1->CR2 &= ~I2C_CR2_RD_WRN;
  137.         I2C1->CR2 |= I2C_CR2_START;
  138.         while(!(I2C1->ISR & I2C_ISR_TXIS));
  139.         while(len--)
  140.         {
  141.             while(!(I2C1->ISR & I2C_ISR_TXE));
  142.             I2C1->TXDR = *data++;
  143.         }
  144.         while(!(I2C1->ISR & I2C_ISR_TC));
  145.         I2C1->CR2 |= I2C_CR2_STOP;
  146.         while(I2C1->CR2 & I2C_CR2_STOP);
  147.         I2C1->CR1 &= ~I2C_CR1_PE;
  148.     }
  149. }
  150.  
  151. void I2C_writeNSameBytes(uint8_t slave, uint8_t data, uint8_t len)
  152. {
  153.     I2C1->CR1 |= I2C_CR1_PE;
  154.     I2C1->CR2 = (I2C1->CR2 & 0xFFFFFF00) | (slave<<1);
  155.     I2C1->CR2 = (I2C1->CR2 & 0xFF00FFFF) | (len<<16);
  156.     I2C1->CR2 &= ~I2C_CR2_RD_WRN;
  157.     I2C1->CR2 |= I2C_CR2_START;
  158.     while(I2C1->CR2 & I2C_CR2_START);
  159.     while(len--)
  160.     {
  161.         while(!(I2C1->ISR & I2C_ISR_TXE));
  162.         I2C1->TXDR = data;
  163.     }
  164.  
  165.     while(!(I2C1->ISR & I2C_ISR_TXE));
  166.     I2C1->CR2 |= I2C_CR2_STOP;
  167.     while(I2C1->CR2 & I2C_CR2_STOP);
  168.     I2C1->CR1 &= ~I2C_CR1_PE;
  169. }
  170.  
  171. uint8_t I2C_readByte(uint8_t slave)
  172. {
  173.     uint8_t data = 0;
  174.     I2C1->CR1 |= I2C_CR1_PE;
  175.     I2C1->CR2 = (I2C1->CR2 & 0xFFFFFF00) | (slave<<1);
  176.     I2C1->CR2 = (I2C1->CR2 & 0xFF00FFFF) | (1<<16);
  177.     I2C1->CR2 |= I2C_CR2_RD_WRN;
  178.     I2C1->CR2 |= I2C_CR2_START;
  179.     while(I2C1->CR2 & I2C_CR2_START);
  180.     while(!(I2C1->ISR & I2C_ISR_RXNE));
  181.     data = I2C1->RXDR;
  182.     I2C1->CR2 |= I2C_CR2_STOP;
  183.     while(I2C1->CR2 & I2C_CR2_STOP);
  184.     I2C1->CR1 &= ~I2C_CR1_PE;
  185.     return data;
  186. }
  187.  
  188. uint8_t * I2C_readNBytes(uint8_t slave, uint8_t * buffer, uint8_t len)
  189. {
  190.     uint8_t * data = buffer;
  191.     I2C1->CR1 |= I2C_CR1_PE;
  192.     I2C1->CR2 = (I2C1->CR2 & 0xFFFFFF00) | (slave<<1);
  193.     I2C1->CR2 = (I2C1->CR2 & 0xFF00FFFF) | (len<<16);
  194.     I2C1->CR2 |= I2C_CR2_RD_WRN;
  195.     I2C1->CR2 |= I2C_CR2_START;
  196.  
  197.     while(len--)
  198.     {
  199.         while(!(I2C1->ISR & I2C_ISR_RXNE));
  200.         *data++ = I2C1->RXDR;
  201.     }
  202.     I2C1->CR2 |= I2C_CR2_STOP;
  203.     while(I2C1->CR2 & I2C_CR2_STOP);
  204.     I2C1->CR1 &= ~I2C_CR1_PE;
  205.     return buffer;
  206. }
  207.  
  208.  
  209. uint8_t * I2C_readNBytesFromAddress(uint8_t slave, uint8_t registerAddress, uint8_t * buffer, uint8_t len)
  210. {
  211.     uint8_t * data = buffer;
  212.  
  213.     I2C1->CR1 |= I2C_CR1_PE;
  214.     I2C1->CR2 = (I2C1->CR2 & 0xFFFFFF00) | (slave<<1);
  215.     I2C1->CR2 = (I2C1->CR2 & 0xFF00FFFF) | (1<<16);
  216.     I2C1->CR2 &= ~I2C_CR2_RD_WRN;
  217.     I2C1->CR2 |= I2C_CR2_START;
  218.     while(I2C1->CR2 & I2C_CR2_START);
  219.     while(!(I2C1->ISR & I2C_ISR_TXIS));
  220.     I2C1->TXDR = registerAddress;
  221.     while(!(I2C1->ISR & I2C_ISR_TC));
  222.     I2C1->CR2 |= I2C_CR2_STOP;
  223.     while(I2C1->CR2 & I2C_CR2_STOP);
  224.     I2C1->CR2 = (I2C1->CR2 & 0xFF00FFFF) | (len<<16);
  225.     I2C1->CR2 |= I2C_CR2_RD_WRN;
  226.     I2C1->CR2 |= I2C_CR2_START;
  227.     while(I2C1->CR2 & I2C_CR2_START);
  228.     while(len--)
  229.     {
  230.         while(!(I2C1->ISR & I2C_ISR_RXNE));
  231.         *data++ = I2C1->RXDR;
  232.     }
  233.     I2C1->CR2 |= I2C_CR2_STOP;
  234.     while(I2C1->CR2 & I2C_CR2_STOP);
  235.     I2C1->CR1 &= ~I2C_CR1_PE;
  236.     return buffer;
  237. }

kulfi27
Użytkownik
Posty: 23
Rejestracja: 28 mar 2018, 14:01

Re: STM32 Blue pill Oled 2,5"

Post autor: kulfi27 » 16 gru 2019, 21:58

Dzięki za kod, napiszę jakie efekty i czy udało mi się uruchomić tego oleda. :D

ODPOWIEDZ

Wróć do „STM32 Development BOARD”