This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430FR4133:使用 SPI 显示 ILI9341

Guru**** 1131400 points
Other Parts Discussed in Thread: MSP430FR4133, MSP430G2553
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1330648/msp430fr4133-ili9341-display-using-spi

器件型号:MSP430FR4133
主题中讨论的其他器件: MSP430G2553

您好、我找到一个使用 MSP430G2553连接 ILI9341 SPI 显示屏的库。 我已经对引脚进行了一些调整、以便将其配置为 MSP430FR4133、但我似乎无法使其正常工作。 我感觉这是与 ILI9341_SPI_init 函数中的中断有关、但通过查看数据表和用户指南、我似乎无法确定我是否正确这么做。 我已经附上了我的代码;如果有任何帮助、我将不胜感激。

#include <msp430.h>
#include <driverlib.h>
#include <stdint.h> 
#include "ili9341.h"


void main(void)
{

    
    WDTCTL = WDTPW + WDTHOLD;  
    PMM_unlockLPM5(); 
  
    PMM_unlockLPM5();
    __bis_SR_register(GIE); // makes timer interrupts work unsure why



  ILI9341_SPI_init();				// init. USCI (SPI)
  ILI9341_Init(ILI9341_RED);			// init. Display
  
   __enable_interrupt(); // enable global interrupts	
   
   
  while(1)
  {  

     __delay_cycles(DELAY_10ms);
     ILI9341_GraphDemo();
  }
}
#include "ili9341.h"
#include "ascii.h"

//####################################################################################################################################################################################
//                                                                      ILI9341_SPI_init()
//
// Initialisiert SPI-UCB0 des Mikrocontrollers MSP430G2553. Beachte der MSP430G2553 besitzt zusätzlich den UCA0 für SPI.
//
void ILI9341_SPI_init(void)
{
  P5DIR &=~   ILI9341_MOSI + ILI9341_SCK;
  P5SEL0  |=  ILI9341_MOSI + ILI9341_SCK;                                        // SCK, MOSI
  P1DIR  |=  ILI9341_RST;                                                        // RST   
  P8DIR |= ILI9341_CS;                                                           // CS
  P5DIR |= ILI9341_DC;                                                           // DC
  P1OUT  &=~ ILI9341_RST;                              
  P8OUT &=~ ILI9341_CS;
  P5OUT &=~ ILI9341_DC;
  
  // SPI settings
  UCB0CTL1 |= UCSWRST;					                         // Reset  
  UCB0CTL0 |=  UCMST + UCSYNC + UCCKPH + UCMSB;		                         // 3-pin, 8-bit SPI master
  UCB0CTL1 |=  UCSSEL_2;					                 // SMCLK
  UCB0CTL1 &=~ UCSWRST;					                         // USCI released for operation
  
  
  __delay_cycles(DELAY_100ms);                                                   // Wait 100ms
  while (!(UCTXIFG0 & UCB0IFG));                                                  // Wait until transmission is complete
  UCB0TXBUF = 0x00;                                                              // Send dummy
}

//####################################################################################################################################################################################
//                                                                     ILI9341_SPI_transmit()
//
// Senden und Empfangen über SPI-UCB0.
//
//                               Variablen
// @ data     : Unsigned 8-Bit-Datensatz der über UCB0 via SPI gesendet werden soll
//
// @ return   : Unsigned 8-Bit-Datensatz der über UCB0 via SPI empfangen wird
//
unsigned char ILI9341_SPI_transmit(unsigned char data)
{   
  UCB0TXBUF = data;                                                              // Sende Datensatz
  while(UCB0STAT & UCBUSY);                                                      // Warte bist übermittelt
  return UCB0RXBUF;                                                              // Gebe empfangenen Datensatz zurück    
} 

//####################################################################################################################################################################################
//                                                                     ILI9341_SendComand()
//
// Sende dem ILI9341 einen Befehl über SPI-UCB0.
//
//                               Variablen
// @ cmd      : Unsigned 8-Bit-Befehl der über UCB0 via SPI gesendet werden soll
//
void ILI9341_SendComand(uint8_t cmd)
{
  P5OUT &=~ ILI9341_DC;			                                         // Signalisiere das ein Befehl gesendet wird. ...
  P8OUT &=~ ILI9341_CS;				                                 // Starte Frame in dem ich !CS auf Low Ziehe. Sende ...
  
  ILI9341_SPI_transmit(cmd);                                                   // sende Befehl ...
  
  P8OUT |= ILI9341_CS;				                                 // Beende den Frame in dem ich !CS wieder auf High setze.-
}

//####################################################################################################################################################################################
//                                                                     ILI9341_SendData8()
//
// Sende dem ILI9341 einen 8-Bit-Datensatz über SPI-UCB0.
//
//                               Variablen
// @ data     : Unsigned 8-Bit-Daten der über UCB0 via SPI gesendet werden soll
//
void ILI9341_SendData8(uint8_t data)
{
  P5OUT |= ILI9341_DC;			                                         // Signalisiere das ein Daten gesendet werden. ...
  P8OUT &=~ ILI9341_CS;				                                 // Starte Frame in dem ich !CS auf Low Ziehe. Sende ...
  
  ILI9341_SPI_transmit(data);                                                    // sende Daten ...
  
  P8OUT |= ILI9341_CS;				                                 // Beende den Frame in dem ich !CS wieder auf High setze.-
}

//####################################################################################################################################################################################
//                                                                     ILI9341_SendData16()
//
// Sende dem ILI9341 einen 16-Bit-Datensatz über SPI-UCB0.
//
//                               Variablen
// @ data     : Unsigned 16-Bit-Daten der über UCB0 via SPI gesendet werden soll
//
void ILI9341_SendData16(uint16_t data)
{ 
  P5OUT |= ILI9341_DC;                                                           // Signalisiere das ein Daten gesendet werden. ...
  P8OUT &=~ ILI9341_CS;	                                                         // Starte Frame in dem ich !CS auf Low Ziehe. Sende ...
  
  ILI9341_SPI_transmit(data >> 8);                                               // Sende Low und High byte über SPI ...
  ILI9341_SPI_transmit(data & 0xff);                                             // .-
  
  P8OUT |= ILI9341_CS;				                                 // Beende den Frame in dem ich !CS wieder auf High setze.-	
}

//####################################################################################################################################################################################
//                                                                   ILI9341_SendPackage()
//
// Sende dem ILI9341 eine Packet aud Daten (Array).
//
//                               Variablen
// @ data     : Unsigned 16-Bit-Daten-Array der über UCB0 via SPI gesendet werden soll
// @ data     : Anzahl der Daten des Arrays die gesendet werden sollen
//
void ILI9341_SendPackage(uint16_t *data, uint8_t howmany)
{
  P5OUT |= ILI9341_DC;                                                           // Signalisiere das ein Daten gesendet werden. ...
  P8OUT &=~ ILI9341_CS;	                                                         // Starte Frame in dem ich !CS auf Low Ziehe. Sende ...
  
  uint8_t count=0;                                                               // Zähler
  for(count=0; count < howmany; count++)                                         // Sänder alle Daten aus Array
  {
    ILI9341_SPI_transmit(data[count]>>8);                                        // Sende Low und High byte über SPI ...
    ILI9341_SPI_transmit(data[count]&0xff);                                      // .-
  } // for
  
  P8OUT |= ILI9341_CS;				                                 // Beende den Frame in dem ich !CS wieder auf High setze.-
}

//####################################################################################################################################################################################
//                                                                       ILI9341_Init()
//
// Initialisiert das Display. Beachte SPI sollte schon vorher initialisiert sein. 
//
// Für die LCD-Initialisierung: * Resete LCD
//                              * Sende Startsequenz zum LCD
//                              * Verlasse Standby und stelle Farbe ein
//                              * Stelle die Ausrichtung vom Display (portrait, landscape, ...)
// 
//
//                               Variablen
// @ color    : Farbauswahl siehe #defines in der ili9341.h
//
void ILI9341_Init(uint16_t color)
{
  uint8_t byte = 0, bit_num = 0, h_index = 0, w_index = 0;                       // Schleifen-Zähler für Daten/Befehls-Arrays

  // 1. LCD Reset
  
  for(char i = 0; i < 3; i++)                                                    // Reset-Sequenz für das Display. Beachte i muss ungerade Zahl sein. ...
  {                                                                              // Ohne Sequenz funktioniert LCD nicht (schon getestet). ...
    P1OUT ^= ILI9341_RST;                                                        // RST-Pin Toggeln ...
    __delay_cycles(DELAY_1ms);                                                   // Warte 1ms.-
  } // for
  
  // 2. Schalte nun die Startsequenz für das Display an
  
  const uint8_t init_cmd[]={0xCB,0xCF,0xE8,0xEA,0xED,0xF7,0xC0,0xC1,0xC5,0xC7,   // Befehls-Array ...
                            0x36,0x3A,0xB1,0xB6,0xF2,0x26,0xE0,0xE1};            // .-
  
  const uint8_t init_data[]={0x39,0x2C,0x00,0x34,0x02,0x00,0xC1,0x30,0x85,0x00,  // Daten-Array ...
                             0x78,0x00,0x00,0x64,0x03,0x12,0x81,0x20,0x23,0x10,  // ...
                             0x3E,0x28,0x86,0x88,0x55,0x00,0x18,0x08,0x82,0x27,  // ...
                             0x00,0x01,0x0F,0x31,0x2B,0x0C,0x0E,0x08,0x4E,0xF1,  // ...
                             0x37,0x07,0x10,0x03,0x0E,0x09,0x00,0x00,0x0E,0x14,  // ...
                             0x03,0x11,0x07,0x31,0xC1,0x48,0x08,0x0F,0x0C,0x31,  // ...
                             0x36,0x0F};                                         // .-
  
  const uint8_t init_data_count[]={5,3,3,2,4,1,1,1,2,1,1,1,2,3,1,1,15,15};
  
  while(byte < sizeof(init_cmd))						 // Für byte < 18 (= Länge vom Array)
  {
    ILI9341_SendComand(init_cmd[byte++]);		                 // Schreibe-Befehl im Register	...
    while(h_index < init_data_count[bit_num])			                 // h_index für Größe von init_data Befels-Zähler ...
    {										 // bit_num für init_data_count Zähler ...
      ILI9341_SendData8(init_data[w_index++]);	                 // w_index für init_data Zähler ...
      h_index++;                                                                 // ...
    } // while
    
    bit_num++;                                                                   // ...
    h_index = 0;                                                                 // ..-
  } // while
  
  // 3. Komme aus dem Standby (Sleep-Mode -> Siehe auch §8.2.12, ILI9341-Datenblatt, Seite 101)

  ILI9341_SendComand(ILI9341_SLPOUT);                                // Komme aus den Sleep-Out ...
  __delay_cycles(2 * DELAY_100ms);                                               // warte mindestens 120ms (sehe description Seite 101).-
  ILI9341_FillScreen(color);                                  // Befülle das ganze Display mit der gewünschten Farbe
  ILI9341_SendComand(ILI9341_DISPON);                                // Mache Dsiplay an
  
  ILI9341_SendComand(ILI9341_RAMWR);                                 // Schreibe-Befehl im Memory Register
  ILI9341_SendComand(ILI9341_RAMWR);                                 // Schreibe-Befehl im Memory Register
  
  ILI9341_Orientation(LCD_ORIENTATION);                                          // Setze Orientations des Display (Portrait oder Landscape)
}

//####################################################################################################################################################################################
//                                                                   ILI9341_Orientation()
//
// Stellt die Ausrichtung vom Display (portrait, landscape, ...). Siehe dazu auch ili9341.h das #define LCD_ORIENTATION. Default ist 0°.
// Siehe auch §8.2.29, ILI9341-Datenblatt, Seite 127.
//
//                               Variablen
// @ deg      : Ausrichtung vom Display  <<LCD_ORIENTATION>> (siehe auch #defines in ili9341.h)
//
void ILI9341_Orientation (int deg)
{
  unsigned dat = 0;                                                              // Variable zum Beschreiben der Adresse MADCTL vom ILI9341

  switch(deg)                                                                    // Anhand der erwünschen Ausrichtung, stelle MEM_X, MEM_Y, MEM_V, MEM_L und MEM_BGR. ...
  {                                                                              // Siehe auch Tabelle auf Seite 127. ...
    case 0:                                                                      // ...
    {                                                                            // ...
      dat = (1 << MEM_X) | (1 << MEM_BGR);                                       // ... 
      break;                                                                     // ...
    } // case                                                                    // ...
    //--------------------------------------------------------------------------
    case 90:                                                                     // ...
    {                                                                            // ...   
      dat = (0<<MEM_Y)  | (0<<MEM_X)  | (1<<MEM_V) | (0<<MEM_L)  | (1<<MEM_BGR); // ...   
      break;                                                                     // ...                                                                     
    } // case                                                                    // ...
    //--------------------------------------------------------------------------
    case 180:                                                                    // ...
    {
      dat = (1 << MEM_Y) | (1 << MEM_BGR);                                       // ...   
      break;                                                                     // ...                                                                     
    } // case                                                                    // ...
    //--------------------------------------------------------------------------
    case 270:                                                                    // ... 
    {                                                                            // ...   
      dat = (1 << MEM_Y) | (1<<MEM_X) | (1<<MEM_V) | (1 << MEM_BGR);             // ...
      break;                                                                     // ...                                                                     
    } // case                                                                    // ...
    //--------------------------------------------------------------------------
    default:                                                                     // ...                                                                     
    {                                                                            // ...
      dat = (1 << MEM_X) | (1 << MEM_BGR);                                       // ...   
    } // default                                                                 // .-
  } // switch   
    
  ILI9341_SendComand (ILI9341_MADCTL);                               // Siehe auch Flow-Chart, Seite 128. Sende Befehl zuerst, dann ...
  ILI9341_SendData8 (dat);                                             // den Datensatz.-
}



//####################################################################################################################################################################################
//                                                                   ILI9341_DisplayINV()
//
// Regelt das Inventieren der Farben des Displays.
//
//                               Variablen
// @ inv      : Variable fürs Inventieren des Displays; TRUE für an - FALSE für aus
//
void ILI9341_DisplayINV(char inv) 
{
  if(inv == TRUE) ILI9341_SendComand (ILI9341_INVON);                            // Display-Farben inventieren
  else ILI9341_SendComand (ILI9341_INVOFF);                                      // Display-Farben NICHT inventieren
}

//####################################################################################################################################################################################
//                                                                   ILI9341_DisplayONorOFF()
//
// Regelt das ein- oder auschalten des Displays.
//
//                               Variablen
// @ ONorOFF  : Variable fürs ein- oder auschalten des Displays; TRUE für an - FALSE für aus
//
void ILI9341_DisplayONorOFF(char ONorOFF) 
{
  if(ONorOFF == TRUE) ILI9341_SendComand (ILI9341_DISPON);                       // Display Anschalten
  else ILI9341_SendComand (ILI9341_DISPOFF);                                     // Display Ausschalten
}

//####################################################################################################################################################################################
//                                                                       ILI9341_SetX()
//
// Die Funktion sollte zusammen mit ILI9341_SetY() genutzt werden. Damit wird im RAM die Pixelposition der Y-Koordinate reserviert (siehe Datenblatt - Seite 110 und 111). Beachte Y 
// sollte auch eingestellt werden. Beachte der Datensatz wird noch nicht mit dem ILI9341_RAMWR-Befehl abgeschlossen.
//
//                               Variablen
// @ x        : X-Position aus kartesischen XY-Koordinatensystem
//
void ILI9341_SetX(uint16_t StartCol,uint16_t EndCol)
{
  ILI9341_SendComand(ILI9341_CASET);                                             // Befehl für die X-Koordinate, siehe Datenblatt - Seite 110 und 111
  ILI9341_SendData16(StartCol);                                                  // Startwert
  ILI9341_SendData16(EndCol);                                                    // Endwert (Beachte kein Abschließen durch ILI9341_RAMWR)
}

//####################################################################################################################################################################################
//                                                                       ILI9341_SetY()
//
// Die Funktion sollte zusammen mit ILI9341_SetX() genutzt werden. Damit wird im RAM die Pixelposition der X-Koordinate reserviert (siehe Datenblatt - Seite 112 und 112). Beachte X 
// sollte auch eingestellt werden. Beachte der Datensatz wird noch nicht mit dem ILI9341_RAMWR-Befehl abgeschlossen.
//
//                               Variablen
// @ y        : Y-Position aus kartesischen XY-Koordinatensystem
//
void ILI9341_SetY(uint16_t StartPage,uint16_t EndPage)
{
  ILI9341_SendComand(ILI9341_PASET);                                             // Befehl für die Y-Koordinate, siehe Datenblatt - Seite 112 und 113
  ILI9341_SendData16(StartPage);                                                 // Startwert
  ILI9341_SendData16(EndPage);                                                   // Endwert (Beachte kein Abschließen durch ILI9341_RAMWR)
}

//####################################################################################################################################################################################
//                                                                       ILI9341_SetXY()
//
// Stellt die X und Y-Koordinaten für das Pixel ein und schreibte es in der Memory (ILI9341_RAMWR). Beachte das Ergebnis ist nicht auf dem Display sichtbar, da noch die Farbe einge-
// stellt werden sollte.
//
//                               Variablen
// @ x        : X-Position aus kartesischen XY-Koordinatensystem
// @ y        : Y-Position aus kartesischen XY-Koordinatensystem
//
void ILI9341_SetXY(uint16_t x, uint16_t y)
{
  ILI9341_SetX(x, x);                                                            // Stelle X- und ...
  ILI9341_SetY(y, y);                                                            // Y-Koordinate ...
  ILI9341_SendComand(ILI9341_RAMWR);                                             // Schreibe es im Memory des ILI9341.-
}

//####################################################################################################################################################################################
//                                                                      ILI9341_SetPixel()
//
// Zeichnet dem Display einzelne Pixels ein.
//
//                               Variablen
// @ x        : X-Position aus kartesischen XY-Koordinatensystem
// @ y        : Y-Position aus kartesischen XY-Koordinatensystem
// @ color    : Farbe für das Pixels
//
void ILI9341_SetPixel(uint16_t poX, uint16_t poY,uint16_t color)
{
  ILI9341_SetXY(poX, poY);                                                       // Wähle Pixel aus XY-Koordinatensystem
  ILI9341_SendData16(color);                                                     // Sende erwünschte Farbe
}

//####################################################################################################################################################################################
//                                                                      ILI9341_DrawPixel()
//
// Zeichnet dem Display einzelne Pixels ein (Funktion ist identisch mit ILI9341_SetPixel(), mache eine logische Trennung).
//
//                               Variablen
// @ x        : X-Position aus kartesischen XY-Koordinatensystem
// @ y        : Y-Position aus kartesischen XY-Koordinatensystem
// @ color    : Farbe für das Pixel
//
void ILI9341_DrawPixel(int16_t x, int16_t y, uint16_t color)
{ 
  ILI9341_SetXY(x, y);                                                           // Wähle Pixel aus XY-Koordinatensystem
  ILI9341_SendData16 (color);                                                    // Sende erwünschte Farbe
}

//####################################################################################################################################################################################
//                                                                      ILI9341_DrawPixelXY()
//
// Zeichnet dem Display mehrere Pixels ein.
//
//                               Variablen
// @ x        : X-Position aus kartesischen XY-Koordinatensystem
// @ y        : Y-Position aus kartesischen XY-Koordinatensystem
// @ sx       : Breite für die X-Komponente einstellen
// @ sy       : Breite für die Y-Komponente einstellen
// @ color    : Farbe für das Pixel
//
void ILI9341_DrawPixelXY(int16_t x, int16_t y, uint8_t sx, uint8_t sy, uint16_t color)
{
  if(sx || sy) ILI9341_FillRectangle(x, x + sx, y, y + sy, color);               // Setze hiermit ganzen Bereich aus Pixel
  else 
  {
    ILI9341_SetX(x, x);                                                          // Setze einzelnt Y und ...
    ILI9341_SetY(y, y);                                                          // Y-Koordinate.-

    ILI9341_SendData16 (color);                                                  // Abschließend erwünschte Farbe senden
  } // else
}

//####################################################################################################################################################################################
//                                                                      ILI9341_DrawChar()
//
// Zeichnet ein einzelnes Zeichen auf ds Display.
//
//                               Variablen
// @ ascii    : Nummer aus der ACII-Tabelle
// @ x        : X-Position auf das Display
// @ y        : Y-Position auf das Display
// @ size     : Breite und Länge des Zeichens
// @ color    : Farbe für das Zeichen
//
void ILI9341_DrawChar(uint8_t ascii, uint16_t x, uint16_t y,uint16_t size, uint16_t color)
{
  if((ascii>=32)&&(ascii<=127)) ;  
  else
  {
    ascii = '?'-32;
  } // else
  
  for (int i =0; i<FONT_X; i++ ) 
  {
    uint8_t temp = simpleFont[ascii-0x20][i];
    for(uint8_t f=0;f<8;f++)
    {
      if((temp>>f)&0x01)
      {
        ILI9341_FillRectangle(x+i*size, y+f*size, size, size, color);
      } // if
    } // for/f
  } // for/i
}

//####################################################################################################################################################################################
//                                                                      ILI9341_DrawString()
//
// Zeichnet ein string (Zeichen-Array) auf ds Display.
//
//                               Variablen
// @ string   : String was auf das Display gezeichnet werden soll
// @ x        : X-Position auf das Display
// @ y        : Y-Position auf das Display
// @ size     : Breite und Länge des Zeichens
// @ color    : Farbe für das Zeichen
//
void ILI9341_DrawString(char *string,uint16_t x, uint16_t y, uint16_t size,uint16_t color)
{
  while(*string)
  {
    ILI9341_DrawChar(*string, x, y, size, color);
    *string++;

    if(x < MAX_X)
    {
      x += FONT_SPACE*size;                                    
    } // if
  } // while
}

//####################################################################################################################################################################################
//                                                                      ILI9341_DrawHLine()
//
// Zeichnet einne horizontale Linie ein.
//
//                               Variablen
// @ x        : X-Position der Linie
// @ y        : Y-Position der Linie
// @ length   : Länge der Linie
// @ color    : Farbe der Linie
//
void ILI9341_DrawHLine(uint16_t x, uint16_t y, uint16_t length,uint16_t color)
{
    ILI9341_SetX(x,x + length);
    ILI9341_SetY(y,y);
    ILI9341_SendComand(ILI9341_RAMWR);
    for(int i=0; i<length; i++) ILI9341_SendData16(color);
}

//####################################################################################################################################################################################
//                                                                      ILI9341_DrawVLine()
//
// Zeichnet einne vertikale Linie ein.
//
//                               Variablen
// @ x        : X-Position der Linie
// @ y        : Y-Position der Linie
// @ length   : Länge der Linie
// @ color    : Farbe der Linie
//
void ILI9341_DrawVLine( uint16_t x, uint16_t y, uint16_t length,uint16_t color)
{
  ILI9341_SetX(x,x);
  ILI9341_SetY(y,y+length);
  ILI9341_SendComand(ILI9341_RAMWR);
  for(int i=0; i<length; i++) ILI9341_SendData16(color);
}

//####################################################################################################################################################################################
//                                                                      ILI9341_DrawLine()
//
// Zeichnet einne Linie ein.
//
//                               Variablen
// @ x0       : X-Startposition der Linie
// @ y0       : Y-Startposition der Linie
// @ x1       : X-Endposition der Linie
// @ y2       : Y-Endposition der Linie
// @ color    : Farbe der Linie
//
void ILI9341_DrawLine(uint16_t x0,uint16_t y0,uint16_t x1, uint16_t y1,uint16_t color)
{
  int x = x1-x0;
  int y = y1-y0;
  int dx = abs(x), sx = x0<x1 ? 1 : -1;
  int dy = -abs(y), sy = y0<y1 ? 1 : -1;
  int err = dx+dy, e2;                                                           // error value e_xy             
  
  for (;;)
  {                                                                              // loop                         
    ILI9341_SetPixel(x0,y0,color);
    e2 = 2*err;
    if (e2 >= dy) {                                                              // e_xy+e_x > 0                 
        if (x0 == x1) break;
        err += dy; x0 += sx;
    } // if
    if (e2 <= dx) {                                                              // e_xy+e_y < 0                 
        if (y0 == y1) break;
        err += dx; y0 += sy;
    } // if
  } // for
}

//####################################################################################################################################################################################
//                                                                      ILI9341_DrawRectangle()
//
// Zeichnet ein Rechteck auf das Display ein.
//
//                               Variablen
// @ x        : X-Position auf das Display
// @ y        : Y-Position auf das Display
// @ length   : Länge des Rechtecks
// @ width    : Breite des Rechtecks
// @ color    : Farbe des Rechtecks
//
void ILI9341_DrawRectangle(uint16_t x, uint16_t y, uint16_t length, uint16_t width,uint16_t color)
{
  ILI9341_DrawHLine(x, y, length, color);
  ILI9341_DrawHLine(x, y+width, length, color);
  ILI9341_DrawVLine(x, y, width,color);
  ILI9341_DrawVLine(x + length, y, width,color);
}

//####################################################################################################################################################################################
//                                                                      ILI9341_DrawCircle()
//
// Zeichnet ein Kreis auf das Display ein.
//
//                               Variablen
// @ pox      : X-Position auf das Display
// @ poy      : Y-Position auf das Display
// @ r        : Radius des Kreises
// @ color    : Farbe des Kreises
//
void ILI9341_DrawCircle(int poX, int poY, int r,uint16_t color)
{
  int x = -r, y = 0, err = 2-2*r, e2;
  do {
      ILI9341_SetPixel(poX-x, poY+y,color);
      ILI9341_SetPixel(poX+x, poY+y,color);
      ILI9341_SetPixel(poX+x, poY-y,color);
      ILI9341_SetPixel(poX-x, poY-y,color);
      
      e2 = err;    
      if (e2 <= y) {
          err += ++y*2+1;
          if (-x == y && e2 <= x) e2 = 0;
      } // if
      
      if (e2 > x) err += ++x*2+1;
  } while (x <= 0);
}

//####################################################################################################################################################################################
//                                                                      ILI9341_FillScreen()
//
// Zeichnet das ganze Display ein
//
//                               Variablen
// @ color    : Farbe für das ganze Display
//
void ILI9341_FillScreen(uint16_t color)
{       
  ILI9341_SetX(0, LCD_WIDTH - 1);                                                // Wähle alle aus der X- und
  ILI9341_SetY(0, LCD_HEIGH - 1);                                                // Y-Koordinate aus.-
  ILI9341_SendComand(ILI9341_RAMWR);                                             // Schreibe die Info in der Memory
                                                                 
  P5OUT |= ILI9341_DC;                                                           // Daten werden nun manuel gesendet ...
  P8OUT &=~ ILI9341_CS;                                                          // Frame startet ...

  uint8_t high = color>>8;                                                       // Farbe in Low und High unterteilen ...
  uint8_t low = color&0xff;                                                      // ...
  for(long int i=0; i < ILI9341_PIXEL; i++)                                      // Für ILI9341_PIXEL = 320 x 240 Pixels ausführen ...
  {     
    ILI9341_SPI_transmit(high);                                                  // Sende High- und ...
    ILI9341_SPI_transmit(low);                                                   // Sende Low-Byte ...
  } // for
  
  P8OUT |= ILI9341_CS;                                                           // Frame endet
}

//####################################################################################################################################################################################
//                                                                      ILI9341_FillRectangle()
//
// Füll ein Rechteck auf das Display ein.
//
//                               Variablen
// @ x        : X-Position auf das Display
// @ y        : Y-Position auf das Display
// @ length   : Länge des Rechtecks
// @ width    : Breite des Rechtecks
// @ color    : Farbe des Rechtecks
//
void ILI9341_FillRectangle(uint16_t x, uint16_t y, uint16_t length, uint16_t width, uint16_t color)
{
  unsigned long  XY=0;
  unsigned long i=0;
  uint16_t XL = x, XR = x+length, YU = y, YD = y+width;
  
  if(XL > XR)
  {
    XL = XL^XR;
    XR = XL^XR;
    XL = XL^XR;
  } // if
  
  if(YU > YD)
  {
    YU = YU^YD;
    YD = YU^YD;
    YU = YU^YD;
  } // if
  
  XY = (XR-XL+1);
  XY = XY*(YD-YU+1);

  ILI9341_SetX(XL,XR);
  ILI9341_SetY(YU, YD);
  ILI9341_SendComand(ILI9341_RAMWR);                                                
       
  P5OUT |= ILI9341_DC;
  P8OUT &=~ ILI9341_CS;

  uint8_t Hcolor = color>>8;
  uint8_t Lcolor = color&0xff;
  for(i=0; i < XY; i++)
  {
    ILI9341_SPI_transmit(Hcolor);
    ILI9341_SPI_transmit(Lcolor);
  }

  P8OUT |= ILI9341_CS;   
}

//####################################################################################################################################################################################
//                                                                      ILI9341_FillCircle()
//
// Füllt ein Kreis auf das Display ein.
//
//                               Variablen
// @ pox      : X-Position auf das Display
// @ poy      : Y-Position auf das Display
// @ r        : Radius des Kreises
// @ color    : Farbe des Kreises
//
void ILI9341_FillCircle(int poX, int poY, int r,uint16_t color)
{
  int x = -r, y = 0, err = 2-2*r, e2;
  do {

     ILI9341_DrawVLine(poX-x, poY-y, 2*y, color);
     ILI9341_DrawVLine(poX+x, poY-y, 2*y, color);

      e2 = err;
      if (e2 <= y) {
          err += ++y*2+1;
          if (-x == y && e2 <= x) e2 = 0;
      } // if
      
      if (e2 > x) err += ++x*2+1;
  } while (x <= 0);
}

//####################################################################################################################################################################################
//                                                                      ILI9341_GraphDemo()
//
// Demo-Funktion zeigt dem Anwender alle wichtigen grafischen Funktionen.
//
void ILI9341_GraphDemo(void)
{
  // 1. Some Colors
  ILI9341_FillScreen(ILI9341_BLACK);
  __delay_cycles(DELAY_10ms);
  ILI9341_FillScreen(ILI9341_RED);
  __delay_cycles(DELAY_10ms);
  ILI9341_FillScreen(ILI9341_GREEN);
  __delay_cycles(DELAY_10ms);
  ILI9341_FillScreen(ILI9341_YELLOW);
  __delay_cycles(DELAY_10ms);
  ILI9341_FillScreen(ILI9341_ORANGE);
  __delay_cycles(DELAY_10ms);
  ILI9341_FillScreen(ILI9341_BLUE);
  __delay_cycles(DELAY_10ms);
  ILI9341_FillScreen(ILI9341_GREY);
  
  // 2. Draw
  for (int i = 0; i < 1000; i++)
  {
    int x = rand() % LCD_WIDTH;
    int y = rand() % LCD_HEIGH;
    
    ILI9341_DrawPixel(x, y, ILI9341_RED);
    __delay_cycles(DELAY_1ms);
  } // for
  
  for (int i = 0; i < 1000; i++)
  {
    int x = rand() % LCD_WIDTH;
    int y = rand() % LCD_HEIGH;
    
    ILI9341_DrawPixel(x, y, ILI9341_BLUE);
    __delay_cycles(DELAY_1ms);
  } // for
  
    for (int i = 0; i < 1000; i++)
  {
    int x = rand() % LCD_WIDTH;
    int y = rand() % LCD_HEIGH;
    
    ILI9341_DrawPixel(x, y, ILI9341_YELLOW);
    __delay_cycles(DELAY_1ms);
  } // for
  
  // 3. Rectangel
  
  ILI9341_FillRectangle(0, 60, 60, 60,ILI9341_YELLOW);
  __delay_cycles(DELAY_100ms);
  ILI9341_FillRectangle(90, 60, 60, 60,ILI9341_BLUE);
  __delay_cycles(DELAY_100ms);
  ILI9341_FillRectangle(180, 60, 60, 60,ILI9341_RED);
  __delay_cycles(DELAY_100ms);
  
  ILI9341_FillCircle(30, 180, 30,ILI9341_YELLOW);
  __delay_cycles(DELAY_100ms);
  ILI9341_FillCircle(120, 180, 30,ILI9341_BLUE);
  __delay_cycles(DELAY_100ms);
  ILI9341_FillCircle(210, 180, 30,ILI9341_RED);
  __delay_cycles(DELAY_100ms);
  
  ILI9341_FillScreen(ILI9341_BLACK);
  ILI9341_DrawString("Follow me",85, 120, 1, ILI9341_BLUE);
  __delay_cycles(DELAY_1s);
  ILI9341_FillScreen(ILI9341_BLACK);
  ILI9341_DrawString("on",117, 120, 1, ILI9341_BLUE);
   __delay_cycles(DELAY_1s);
     
  for(int i = 0; i < 10; i++)
  {
    ILI9341_FillScreen(ILI9341_BLACK);
    __delay_cycles(DELAY_10ms);
    ILI9341_DrawString("www.electrodummies.net",57, 120, 1, ILI9341_BLUE);
    __delay_cycles(DELAY_100ms);
  } // fo


}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我想了解一些其他信息、  
    这是我们刚刚设计的  
    // MSP430FR4133 | ILI9341-TFT-Display 240x320
    //------------------------------------------------------- |-------------------------------------------------------
    // 3.3V |引脚1 - Vcc
    // GND |引脚2 - GND
    //芯片选择- P8.2 |引脚3 - CS
    //复位- P1.6 |引脚4 - RST
    //数据/Cmd - P5.0 |引脚5 - DC
    // MOSI - P5.2 |引脚6 - SDI
    //时钟- P5.1 |引脚7 - SCK
    // Vcc |引脚8 - LED
    // NC |引脚9 - SDO

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我不知道在 SPI_init 中发送该初始0x00字节会引起问题、但我也不知道它有什么作用。 我建议你把它删除。

    ----------------

    > P1OUT &&~ ILI9341_RST;

    这会使器件复位、但我看不到任何将 RST (RESX)设置为高电平的情况;结果是器件永远不会启动。 您应该遵循它(在10us 延迟后)并

    > P1OUT |= ILI9341_RST;  // RESX HIGH ->复位结束

    ----------------

    >  P8OUT &&~ ILI9341_CS;

    同样地、这会在第一次传输之前将/CS 保持为低电平(器件处于活动状态)、甚至可能导致第一个传输丢失。 我建议将其替换为:

    >  P8OUT |= ILI9341_CS;   ///CS 初始高电平(器件空闲)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    感谢您的答复。

    我在显示屏上仍然没有传输任何信息。

    这也是我对函数所做的更改:

    void ILI9341_SPI_init(void)
    {
      P5DIR &=~   ILI9341_MOSI + ILI9341_SCK;
      P5SEL0  |=  ILI9341_MOSI + ILI9341_SCK;                                        // SCK, MOSI
      P1DIR  |=  ILI9341_RST;                                                        // RST   
      P8DIR |= ILI9341_CS;                                                           // CS
      P5DIR |= ILI9341_DC;                                                           // DC
      P1OUT  &=~ ILI9341_RST;  
      __delay_cycles(DELAY_10us);
      P1OUT |=  ILI9341_RST;   // RESX high -> out of reset
      P8OUT |=  ILI9341_CS;     // /CS initially high (device idle)
      P5OUT &=~ ILI9341_DC;
      
      // SPI settings
      UCB0CTL1 |= UCSWRST;					                         // Reset  
      UCB0CTL0 |=  UCMST + UCSYNC + UCCKPH + UCMSB;		                         // 3-pin, 8-bit SPI master
      UCB0CTL1 |=  UCSSEL_2;					                 // SMCLK
      UCB0CTL1 &=~ UCSWRST;					                         // USCI released for operation
      
      
      __delay_cycles(DELAY_100ms);                                                   // Wait 100ms
      while (!(UCTXIFG0 & UCB0IFG));                                                  // Wait until transmission is complete
     // UCB0TXBUF = 0x00;                                                              // Send dummy
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    只是另外一点、

    void ILI9341_SPI_init(void)
    {
      P1SEL  |=  ILI9341_MOSI + ILI9341_SCK;                                         // Spezial Funktion SCK, MOSI und MISO ...
      P1SEL2 |=  ILI9341_MOSI + ILI9341_SCK;                                         // (Falls P1SEL2 unterstützt).-
      
      P1DIR  |=  ILI9341_RST + ILI9341_DC + ILI9341_CS;                              // RST-, DC- und !CS-Leitung  ...
      P1OUT  &=~ ILI9341_RST + ILI9341_DC + ILI9341_CS;                              // .-
      
      UCB0CTL1 |= UCSWRST;					                         // Reset  
      UCB0CTL0 |=  UCMST + UCSYNC + UCCKPH + UCMSB;		                         // 3-pin, 8-bit SPI master
      UCB0CTL1 |=  UCSSEL_2;					                 // SMCLK
      UCB0CTL1 &=~ UCSWRST;					                         // USCI released for operation
      //UCA0MCTL = 0;                                                                // No modulation
      
      __delay_cycles(DELAY_100ms);                                                   // Warte 100ms
      while (!(IFG2 & UCB0TXIFG));                                                   // Warte bist übermittelt
      UCB0TXBUF = 0x00;                                                              // Dummy Senden 
    }

    下面是来自  我 修改的 MSP430G2553库的原始函数:

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    很抱歉、我之前错过了:

      for(char i = 0; i < 3; i++)                                                    // Reset-Sequenz für das Display. Beachte i muss ungerade Zahl sein. ...
      {                                                                              // Ohne Sequenz funktioniert LCD nicht (schon getestet). ...
        P1OUT ^= ILI9341_RST;                                                        // RST-Pin Toggeln ...
        __delay_cycles(DELAY_1ms);                                                   // Warte 1ms.-
      } // for
    

    该参数假定 RST 引脚初始为低电平(因此要求"奇数")。 所以我建议让 RST 保持高电平是不正确的。

    ----------------

    这将使您大致处在开始的位置。 您是否非常确定代码未滞留在某个位置? 如果您在调试器中暂停、您将在哪里执行?

    此外:背光是否打开? 这将指示最小功能测试、因为我希望该块中的命令之一会将其打开。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好  

    背光工作正常。 我已经决定写我自己的图书馆与我在这篇文章中提到的帮助。 在使用我的代码时、它似乎没有在任何地方卡住。

    我认为这可能是由于我的时钟、库说将其设置为8 MHz、所以我是使用 DCO 这样做的、但它仍然没有显示在显示屏上。  

    我已经附上了我的代码。  

    我们将感谢您提供任何帮助。  

    谢谢。

    #include "ili9341.h"
    #include "ascii.h"
    
    void ILI9341_SPI_init(void)
    {
      // selcting pins to MISO, MOSI and SCLK according to datasheet
      P5SEL0 |=  MOSI;
      P5SEL0 |= SCK;
    
      // GPIO for reset chip selct and data/cmd
      P1DIR |=  RST; // RST   
      P8DIR |= CS;  // CS
      P5DIR |= DC;  // DC
    
      P8OUT |= CS; // setting chip select high to intialise
      P1OUT &= ~RST;
      
      // SPI settings
    //  UCB0CTLW0 |= UCSWRST;	// Reset  
    //  UCB0CTLW0 |= UCMST; // SPI master
    //  UCB0CTLW0 |= UCSYNC; // B0 into SPI mode
    //  UCB0CTLW0 |=  UCCKPH; // data captured on first edge then changed on following
    //  UCB0CTLW0 |= UCMSB; // MSB first
    //  UCB0CTLW0 |=  UCSSEL_2; // SMCLK
    //  UCB0CTLW0 |= UCMODE_0; // 3 pin SPI
    //  UCB0BRW = 2;   // Set the clock divider to 2. SMCLK is 16 MHz, want spi max is 8 MHz
    //  UCB0CTLW0 &= ~UCSWRST; // USCI released for operation
    //
    //  UCB0IE |= UCTXIE;
    //  UCB0IFG &= ~UCTXIFG;   
      
      UCB0CTL1 |= UCSWRST;					                         // Reset  
      UCB0CTL0 |=  UCMST + UCSYNC + UCCKPH + UCMSB;		                         // 3-pin, 8-bit SPI master
      UCB0CTL1 |=  UCSSEL_2;					                 // SMCLK
      UCB0CTL1 &=~ UCSWRST;					                         // USCI released for operation
      
      __delay_cycles(DELAY_100ms);                                                   // Warte 100ms
                                            
    }
    
    
    
    unsigned char ILI9341_SPI_transmit(unsigned char data)
    {   
      // UCTXIFG is set when data is written to UCBOTXBUF
      UCB0TXBUF = data;      
      while (!(UCB0IFG & UCTXIFG)); 
      return UCB0RXBUF;
                                                                                                
    } 
    
    void ILI9341_SendCommand(uint8_t cmd)
    {
      P5OUT &= ~DC;			                                        
      P8OUT &= ~CS;				                               
      
      ILI9341_SPI_transmit(cmd);                                                  
      
      P8OUT |= CS;				                               
    }
    
    void ILI9341_SendData8(uint8_t data)
    {
        P8OUT &= ~CS; // active low to send anything
        P5OUT |= DC; // active high to send data 
        
        ILI9341_SPI_transmit(data);    // send the command 
        
        P8OUT |= CS; // stop sending			                                 // Beende den Frame in dem ich !CS wieder auf High setze.-
    }
    
    void ILI9341_SendData16(uint16_t data)
    { 
      P5OUT |= DC;                                                           // Signalisiere das ein Daten gesendet werden. ...
      P8OUT &= ~CS;	                                                         // Starte Frame in dem ich !CS auf Low Ziehe. Sende ...
      
      ILI9341_SPI_transmit(data >> 8);   // shift the the right 8 places to send 8 MSBs
      ILI9341_SPI_transmit(data & 0xff); // AND with 0000 0000 1111 1111 keeping only 8 LSBs
      
      P5OUT |= CS;				                                 // Beende den Frame in dem ich !CS wieder auf High setze.-	
    }
    
    
    
    void ILI9341_Init(void)
    {
      
      // reset has to be held low for at least 10 us 
      // reset is active low so resetting the chip here
      P1OUT |= RST;
      __delay_cycles(DELAY_10ms);
      P1OUT &= ~RST; 
      __delay_cycles(DELAY_10ms);
      P1OUT |= RST;
      __delay_cycles(DELAY_10ms);
      
      P8OUT &= ~CS; // set CS low to prepare to write
      
      ILI9341_SendCommand(0xC5);
      ILI9341_SendData8(0x18);
      ILI9341_SendData8(0x00);
      
      ILI9341_SendCommand(0x36); // memory access control
      // needs to be set with certain parameters
      ILI9341_SendData8(0x40); // BGR
      
      ILI9341_SendCommand(0x3A); // Pixel foramt settings
      ILI9341_SendData8(0x55); //16 bits RGB
      
      ILI9341_SendCommand(0x11); // exiting sleep mode
      __delay_cycles(DELAY_10ms); // need to wait at least 5ms
      
      ILI9341_SendCommand(0x29); // turn display on
      
      ILI9341_SendCommand(0x2C); // pass data from MCU to frame memory
    }
    
    void set_address(uint16_t x1, uint16_t x2, uint16_t y1, uint16_t y2)
    {
      
      // column and page take in 16 bits
      
      ILI9341_SendCommand(0x2b); // column address set
      ILI9341_SendData16(y1);   // send 16 bits
      ILI9341_SendData16(y2);   // send 16 bits
      
      ILI9341_SendCommand(0x2b); // Page address set
      ILI9341_SendData16(x1);   // send 16 bits
      ILI9341_SendData16(x2);   // send 16 bits
      
      ILI9341_SendCommand(0x2c); // write to frame memory
    
    }
    
    void draw_pixel(uint16_t x, uint16_t y, uint16_t colour)
    {
    
      P8OUT &= ~CS; // Active low
      set_address(x, x+1, y, y+1); // set location of pixel
      ILI9341_SendCommand(0x2c); // write to frame memory
      ILI9341_SendData16(colour); // choose 565 RGB colour
      
    }
    #include <msp430.h>
    #include <driverlib.h>
    #include <stdint.h> 
    #include "ili9341.h"
    
    
    void main(void)
    {
    
        
        WDTCTL = WDTPW + WDTHOLD;  
        
        
     // Configure DCO to desired frequency  8 MHz
        CSCTL1 = DCORSEL_5;         // Set DCO frequency range to 8 MHz
        PMM_unlockLPM5(); 
      
        __bis_SR_register(GIE); // makes timer interrupts work unsure why
         __enable_interrupt(); // enable global interrupts	
    
        ILI9341_SPI_init();				// init. USCI (SPI)
      
      
    
        ILI9341_Init();
        for (int i = 50; i < 250; i++){
            draw_pixel(i, 50, ILI9341_WHITE);
            draw_pixel(i, 60, ILI9341_BLUE);
        }  
        
       
      while(1)
      {  
    
      }
      
    }
    
    乌瓦伊斯