[活动专区] 【AT-START-F407测评】+LCD+FATFT+BMP图片显示

[复制链接]
 楼主| qjp1988113 发表于 2021-3-2 12:57 | 显示全部楼层 |阅读模式
手头上有个驱动为HX8347的ardunio接口的LCD屏,今天我们就要ATF407来驱动它。屏幕用SPI方式驱动,同时SD卡也跟屏幕挂在同一路SPI上。
我们通过CS选择,分时使用这2个外设。并移植FATFS,让其显示SD卡里面的BMP图片。
废话不多说,我们先来配置SPI,这里使用SPI1,其中SPI的时钟速度不能太快,要考虑到SD卡的兼容性:
  1. static void SPI1_GPIO_Configuration(void)
  2. {
  3.   GPIO_InitType GPIO_InitStructure;

  4.         RCC_APB2PeriphClockCmd(SPI1_GPIO_CLK|RCC_APB2PERIPH_SPI1|RCC_APB2PERIPH_AFIO, ENABLE);
  5.        
  6.          /* Configure SPI_FLASH pins*/
  7.   GPIO_InitStructure.GPIO_Pins =  SPI1_PIN_MOSI;
  8.   GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_10MHz;
  9.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  10.   GPIO_Init(SPI1_GPIO, &GPIO_InitStructure);

  11.   GPIO_InitStructure.GPIO_Pins = SPI1_PIN_MISO;
  12.   GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_10MHz;  
  13.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  14.   GPIO_Init(SPI1_GPIO, &GPIO_InitStructure);

  15.   GPIO_InitStructure.GPIO_Pins =  SPI1_PIN_SCK;
  16.   GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_10MHz;
  17.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  18.   GPIO_Init(SPI1_GPIO, &GPIO_InitStructure);
  19.        
  20.         //CS
  21.   GPIO_InitStructure.GPIO_Pins = LCD_CS_PIN;
  22.   GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_10MHz;  
  23.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
  24.   GPIO_Init(LCD_CS_GPIO, &GPIO_InitStructure);  
  25.        
  26. }

  27. //SPI1 初始化
  28. void SPI1_Init(void)
  29. {

  30.         SPI_InitType   SPI_InitStructure;
  31.        
  32.         /* Enable SPIy clock and GPIO clock for SPIy and SPIz */
  33.   RCC_APB2PeriphClockCmd(SPI1_CLK , ENABLE);

  34.   /* 1st phase: SPI1 Master */
  35.   /* GPIO configuration ------------------------------------------------------*/
  36.   SPI1_GPIO_Configuration();
  37.        
  38.         //CS 置高
  39.         __LCD_CS_SET();
  40.   
  41.   /* SPI1 Config -------------------------------------------------------------*/
  42.   SPI_DefaultInitParaConfig(&SPI_InitStructure);
  43.   SPI_InitStructure.SPI_TransMode = SPI_TRANSMODE_FULLDUPLEX;
  44.         SPI_InitStructure.SPI_CPHA = SPI_CPHA_2EDGE;
  45.         SPI_InitStructure.SPI_CPOL = SPI_CPOL_HIGH;
  46.         SPI_InitStructure.SPI_CPOLY = 0;
  47.         SPI_InitStructure.SPI_FirstBit = SPI_FIRSTBIT_MSB;
  48.   SPI_InitStructure.SPI_FrameSize = SPI_FRAMESIZE_8BIT;
  49.         SPI_InitStructure.SPI_MCLKP = SPI_MCLKP_8;
  50.        
  51.         //SPI_InitStructure.SPI_MCLKP = SPI_MCLKP_32;
  52.        
  53.        
  54.   SPI_InitStructure.SPI_NSSSEL = SPI_NSSSEL_SOFT;
  55.         SPI_InitStructure.SPI_Mode = SPI_MODE_MASTER;
  56.   
  57.   SPI_Init(SPI1, &SPI_InitStructure);

  58.   
  59.   /* Enable SPI1 */
  60.   SPI_Enable(SPI1, ENABLE);

  61. }
配置好了后,我们单独写一个SPI读写一个字节的函数:
  1. unsigned int SPI1ReadWriteByte(unsigned char tx_data)
  2. {
  3.        
  4.                 /* Wait for SPIy Tx buffer empty */
  5.     while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TE) == RESET);

  6.     /* Send SPIy data */
  7.     SPI_I2S_TxData(SPI1,tx_data);

  8.     /* Wait for SPIy data reception */
  9.     while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RNE) == RESET);
  10.     /* Read SPIy received data */
  11.     return SPI_I2S_RxData(SPI1);
  12.        
  13. }
我们定义LCD的读写,直接调用SPI1的读写函数:
  1. #define __LCD_WRITE_BYTE(__DATA)  SPI1ReadWriteByte(__DATA)
其中LCD的其他几个控制引脚的配置,与JTAG的引脚有冲突,我们remap为SWD调试模式,释放PA15 PB3 PB4 3个引脚作为普通引脚
  1. void lcd_port_init(void)
  2. {

  3.         GPIO_InitType GPIO_InitStructure;

  4.         RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA| RCC_APB2PERIPH_GPIOC||RCC_APB2PERIPH_AFIO , ENABLE);
  5.   //调试仅SWD
  6.         GPIO_PinsRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//释放PA15  PB3  PB4
  7.        
  8.         GPIO_StructInit(&GPIO_InitStructure);
  9.         //LCD-CS  PA15
  10.         GPIO_InitStructure.GPIO_Pins = LCD_CS_PIN;                            
  11.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
  12.         GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  13.         GPIO_Init(LCD_CS_GPIO, &GPIO_InitStructure);
  14.         //LCD-DC  PA8
  15.         GPIO_InitStructure.GPIO_Pins = LCD_DC_PIN;                            
  16.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
  17.         GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  18.         GPIO_Init(LCD_DC_GPIO, &GPIO_InitStructure);
  19.         //LCD-BKL PC7
  20.         GPIO_InitStructure.GPIO_Pins = LCD_BKL_PIN;                           
  21.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
  22.         GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  23.         GPIO_Init(LCD_BKL_GPIO, &GPIO_InitStructure);

  24. }
LCD其他操作函数:
  1. void lcd_write_byte(uint8_t chByte, uint8_t chCmd)
  2. {
  3.     if (chCmd) {
  4.         __LCD_DC_SET();
  5.     } else {
  6.         __LCD_DC_CLR();
  7.     }
  8.    
  9.     __LCD_CS_CLR();
  10.     __LCD_WRITE_BYTE(chByte);
  11.     __LCD_CS_SET();
  12. }

  13. void lcd_write_word(uint16_t hwData)
  14. {
  15.     __LCD_DC_SET();
  16.     __LCD_CS_CLR();
  17.     __LCD_WRITE_BYTE(hwData >> 8);
  18.     __LCD_WRITE_BYTE(hwData & 0xFF);
  19.     __LCD_CS_SET();
  20. }

  21. void lcd_write_register(uint8_t chRegister, uint8_t chValue)
  22. {
  23.         lcd_write_byte(chRegister, LCD_CMD);
  24.         lcd_write_byte(chValue, LCD_DATA);
  25. }

  26. //set the specified position of cursor on lcd.
  27. //hwXpos specify x position
  28. //hwYpos specify y position
  29. void lcd_set_cursor(uint16_t hwXpos, uint16_t hwYpos)
  30. {
  31.         if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
  32.                 return;
  33.         }
  34.    
  35.     lcd_write_register(0x02, hwXpos >> 8);
  36.         lcd_write_register(0x03, hwXpos & 0xFF); //Column Start
  37.         lcd_write_register(0x06, hwYpos >> 8);
  38.         lcd_write_register(0x07, hwYpos & 0xFF); //Row Start
  39. }

  40. //clear the lcd with the specified color.
  41. void lcd_clear_screen(uint16_t hwColor)  
  42. {
  43.         uint32_t i, wCount = LCD_WIDTH;
  44.        
  45.         wCount *= LCD_HEIGHT;
  46.        
  47.         lcd_set_cursor(0, 0);
  48.         lcd_write_byte(0x22, LCD_CMD);
  49.    
  50.     __LCD_DC_SET();
  51.         __LCD_CS_CLR();
  52.         for (i = 0; i < wCount; i ++) {
  53.                 __LCD_WRITE_BYTE(hwColor >> 8);
  54.                 __LCD_WRITE_BYTE(hwColor & 0xFF);
  55.         }
  56.         __LCD_CS_SET();
  57. }

  58. //draw a point on the lcd with the specified color.
  59. //hwXpos specify x position.
  60. //hwYpos specify y position.
  61. //hwColor color of the point.
  62. void lcd_draw_point(uint16_t hwXpos, uint16_t hwYpos, uint16_t hwColor)
  63. {
  64.         if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
  65.                 return;
  66.         }
  67.        
  68.         lcd_set_cursor(hwXpos, hwYpos);
  69.         lcd_write_byte(0x22, LCD_CMD);
  70.     lcd_write_word(hwColor);
  71. }

  72. //display a char at the specified position on lcd.
  73. void lcd_display_char(uint16_t hwXpos, //specify x position.
  74.                          uint16_t hwYpos, //specify y position.
  75.                          uint8_t chChr,   //a char is display.
  76.                          uint8_t chSize,  //specify the size of the char
  77.                          uint16_t hwColor) //specify the color of the char
  78. {             
  79.         uint8_t i, j, chTemp;
  80.         uint16_t hwYpos0 = hwYpos, hwColorVal = 0;

  81.         if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
  82.                 return;
  83.         }

  84.                                           
  85.     for (i = 0; i < chSize; i ++) {   
  86.                 if (FONT_1206 == chSize) {
  87.                         chTemp = c_chFont1206[chChr - 0x20][i];  
  88.                 } else if (FONT_1608 == chSize) {
  89.                         chTemp = c_chFont1608[chChr - 0x20][i];
  90.                 }
  91.                
  92.         for (j = 0; j < 8; j ++) {
  93.                     if (chTemp & 0x80) {
  94.                                 hwColorVal = hwColor;
  95.                                 lcd_draw_point(hwXpos, hwYpos, hwColorVal);
  96.                     }                       
  97.                         chTemp <<= 1;
  98.                         hwYpos ++;
  99.                         if ((hwYpos - hwYpos0) == chSize) {
  100.                                 hwYpos = hwYpos0;
  101.                                 hwXpos ++;
  102.                                 break;
  103.                         }
  104.                 }           
  105.     }
  106. }


  107. //_pow
  108. uint32_t _pow(uint8_t m, uint8_t n)
  109. {
  110.         uint32_t result = 1;
  111.        
  112.         while(n --) result *= m;   
  113.         return result;
  114. }

  115. //display a number at the specified position on lcd.
  116. void lcd_display_num(uint16_t hwXpos,  //specify x position.
  117.                           uint16_t hwYpos, //specify y position.
  118.                           uint32_t chNum,  //a number is display.
  119.                           uint8_t chLen,   //length ot the number
  120.                           uint8_t chSize,  //specify the size of the number
  121.                           uint16_t hwColor) //specify the color of the number
  122. {                
  123.         uint8_t i;
  124.         uint8_t chTemp, chShow = 0;

  125.         if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
  126.                 return;
  127.         }
  128.        
  129.         for(i = 0; i < chLen; i ++) {
  130.                 chTemp = (chNum / _pow(10, chLen - i - 1)) % 10;
  131.                 if(chShow == 0 && i < (chLen - 1)) {
  132.                         if(chTemp == 0) {
  133.                                 lcd_display_char(hwXpos + (chSize / 2) * i, hwYpos, ' ', chSize, hwColor);
  134.                                 continue;
  135.                         } else {
  136.                                 chShow = 1;
  137.                         }         
  138.                 }
  139.                  lcd_display_char(hwXpos + (chSize / 2) * i, hwYpos, chTemp + '0', chSize, hwColor);
  140.         }
  141. }

  142. //display a string at the specified position on lcd.
  143. void lcd_display_string(uint16_t hwXpos, //specify x position.
  144.                          uint16_t hwYpos,   //specify y position.
  145.                          const uint8_t *pchString,  //a pointer to string
  146.                          uint8_t chSize,    // the size of the string
  147.                          uint16_t hwColor)  // specify the color of the string
  148. {

  149.         if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
  150.                 return;
  151.         }
  152.        
  153.     while (*pchString != '\0') {      
  154.         if (hwXpos > (LCD_WIDTH - chSize / 2)) {
  155.                         hwXpos = 0;
  156.                         hwYpos += chSize;
  157.                         if (hwYpos > (LCD_HEIGHT - chSize)) {
  158.                                 hwYpos = hwXpos = 0;
  159.                                 lcd_clear_screen(0x00);
  160.                         }
  161.                 }
  162.                
  163.         lcd_display_char(hwXpos, hwYpos, (uint8_t)*pchString, chSize, hwColor);
  164.         hwXpos += chSize / 2;
  165.         pchString ++;
  166.     }
  167. }

  168. //draw a line at the specified position on lcd.
  169. void lcd_draw_line(uint16_t hwXpos0, //specify x0 position.
  170.                       uint16_t hwYpos0, //specify y0 position.
  171.                       uint16_t hwXpos1, //specify x1 position.
  172.                       uint16_t hwYpos1, //specify y1 position.
  173.                       uint16_t hwColor) //specify the color of the line
  174. {
  175.         int x = hwXpos1 - hwXpos0;
  176.     int y = hwYpos1 - hwYpos0;
  177.     int dx = abs(x), sx = hwXpos0 < hwXpos1 ? 1 : -1;
  178.     int dy = -abs(y), sy = hwYpos0 < hwYpos1 ? 1 : -1;
  179.     int err = dx + dy, e2;

  180.         if (hwXpos0 >= LCD_WIDTH || hwYpos0 >= LCD_HEIGHT || hwXpos1 >= LCD_WIDTH || hwYpos1 >= LCD_HEIGHT) {
  181.                 return;
  182.         }
  183.    
  184.     for (;;){
  185.         lcd_draw_point(hwXpos0, hwYpos0 , hwColor);
  186.         e2 = 2 * err;
  187.         if (e2 >= dy) {     
  188.             if (hwXpos0 == hwXpos1) break;
  189.             err += dy; hwXpos0 += sx;
  190.         }
  191.         if (e2 <= dx) {
  192.             if (hwYpos0 == hwYpos1) break;
  193.             err += dx; hwYpos0 += sy;
  194.         }
  195.     }
  196. }

  197. //draw a circle at the specified position on lcd.
  198. void lcd_draw_circle(uint16_t hwXpos,  //specify x position.
  199.                         uint16_t hwYpos,  //specify y position.
  200.                         uint16_t hwRadius, //specify the radius of the circle.
  201.                         uint16_t hwColor)  //specify the color of the circle.
  202. {
  203.         int x = -hwRadius, y = 0, err = 2 - 2 * hwRadius, e2;

  204.         if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
  205.                 return;
  206.         }
  207.        
  208.     do {
  209.         lcd_draw_point(hwXpos - x, hwYpos + y, hwColor);
  210.         lcd_draw_point(hwXpos + x, hwYpos + y, hwColor);
  211.         lcd_draw_point(hwXpos + x, hwYpos - y, hwColor);
  212.         lcd_draw_point(hwXpos - x, hwYpos - y, hwColor);
  213.         e2 = err;
  214.         if (e2 <= y) {
  215.             err += ++ y * 2 + 1;
  216.             if(-x == y && e2 <= x) e2 = 0;
  217.         }
  218.         if(e2 > x) err += ++ x * 2 + 1;
  219.     } while(x <= 0);
  220. }

  221. //fill a rectangle out at the specified position on lcd.
  222. void lcd_fill_rect(uint16_t hwXpos,  //specify x position.
  223.                    uint16_t hwYpos,  //specify y position.
  224.                    uint16_t hwWidth, //specify the width of the rectangle.
  225.                    uint16_t hwHeight, //specify the height of the rectangle.
  226.                    uint16_t hwColor)  //specify the color of rectangle.
  227. {
  228.         uint16_t i, j;

  229.         if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
  230.                 return;
  231.         }
  232.        
  233.         for(i = 0; i < hwHeight; i ++){
  234.                 for(j = 0; j < hwWidth; j ++){
  235.                         lcd_draw_point(hwXpos + j, hwYpos + i, hwColor);
  236.                 }
  237.         }
  238. }

  239. //draw a vertical line at the specified position on lcd.
  240. void lcd_draw_v_line(uint16_t hwXpos, //specify x position.
  241.                         uint16_t hwYpos, //specify y position.
  242.                         uint16_t hwHeight, //specify the height of the vertical line.
  243.                         uint16_t hwColor)  //specify the color of the vertical line.
  244. {       
  245.         uint16_t i, y1 = MIN(hwYpos + hwHeight, LCD_HEIGHT - 1);

  246.         if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
  247.                 return;
  248.         }
  249.        
  250.     for (i = hwYpos; i < y1; i ++) {
  251.         lcd_draw_point(hwXpos, i, hwColor);
  252.     }
  253. }

  254. //draw a horizonal line at the specified position on lcd.
  255. void lcd_draw_h_line(uint16_t hwXpos, //specify x position.
  256.                         uint16_t hwYpos,  //specify y position.
  257.                         uint16_t hwWidth, //specify the width of the horizonal line.
  258.                         uint16_t hwColor) //specify the color of the horizonal line.
  259. {       
  260.         uint16_t i, x1 = MIN(hwXpos + hwWidth, LCD_WIDTH - 1);

  261.         if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
  262.                 return;
  263.         }
  264.        
  265.     for (i = hwXpos; i < x1; i ++) {
  266.         lcd_draw_point(i, hwYpos, hwColor);
  267.     }
  268. }

  269. void lcd_draw_rect(uint16_t hwXpos,  //specify x position.
  270.                       uint16_t hwYpos,  //specify y position.
  271.                       uint16_t hwWidth, //specify the width of the rectangle.
  272.                       uint16_t hwHeight, //specify the height of the rectangle.
  273.                       uint16_t hwColor)  //specify the color of rectangle.
  274. {
  275.         if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
  276.                 return;
  277.         }

  278.         lcd_draw_h_line(hwXpos, hwYpos, hwWidth, hwColor);
  279.         lcd_draw_h_line(hwXpos, hwYpos + hwHeight, hwWidth, hwColor);
  280.         lcd_draw_v_line(hwXpos, hwYpos, hwHeight, hwColor);
  281.         lcd_draw_v_line(hwXpos + hwWidth, hwYpos, hwHeight + 1, hwColor);
  282. }



  283. //initialize the lcd.
  284. //phwDevId pointer to device ID of lcd
  285. void lcd_init(void)
  286. {
  287. //        __LCD_RST_CLR();
  288. //        delay_ms(100);
  289. //        __LCD_RST_SET();
  290.         __LCD_CS_SET();
  291.         __LCD_BKL_SET();

  292.         //Driving ability Setting
  293.         lcd_write_register(0xEA,0x00); //PTBA[15:8]
  294.         lcd_write_register(0xEB,0x20); //PTBA[7:0]
  295.         lcd_write_register(0xEC,0x0C); //STBA[15:8]
  296.         lcd_write_register(0xED,0xC4); //STBA[7:0]
  297.         lcd_write_register(0xE8,0x38); //OPON[7:0]
  298.         lcd_write_register(0xE9,0x10); //OPON1[7:0]
  299.         lcd_write_register(0xF1,0x01); //OTPS1B
  300.         lcd_write_register(0xF2,0x10); //GEN
  301.         //Gamma 2.2 Setting
  302.         lcd_write_register(0x40,0x01); //
  303.         lcd_write_register(0x41,0x00); //
  304.         lcd_write_register(0x42,0x00); //
  305.         lcd_write_register(0x43,0x10); //
  306.         lcd_write_register(0x44,0x0E); //
  307.         lcd_write_register(0x45,0x24); //
  308.         lcd_write_register(0x46,0x04); //
  309.         lcd_write_register(0x47,0x50); //
  310.         lcd_write_register(0x48,0x02); //
  311.         lcd_write_register(0x49,0x13); //
  312.         lcd_write_register(0x4A,0x19); //
  313.         lcd_write_register(0x4B,0x19); //
  314.         lcd_write_register(0x4C,0x16); //
  315.         lcd_write_register(0x50,0x1B); //
  316.         lcd_write_register(0x51,0x31); //
  317.         lcd_write_register(0x52,0x2F); //
  318.         lcd_write_register(0x53,0x3F); //
  319.         lcd_write_register(0x54,0x3F); //
  320.         lcd_write_register(0x55,0x3E); //
  321.         lcd_write_register(0x56,0x2F); //
  322.         lcd_write_register(0x57,0x7B); //
  323.         lcd_write_register(0x58,0x09); //
  324.         lcd_write_register(0x59,0x06); //
  325.         lcd_write_register(0x5A,0x06); //
  326.         lcd_write_register(0x5B,0x0C); //
  327.         lcd_write_register(0x5C,0x1D); //
  328.         lcd_write_register(0x5D,0xCC); //
  329.         //Power Voltage Setting
  330.         lcd_write_register(0x1B,0x1B); //VRH=4.65V
  331.         lcd_write_register(0x1A,0x01); //BT (VGH~15V,VGL~-10V,DDVDH~5V)
  332.         lcd_write_register(0x24,0x2F); //VMH(VCOM High voltage ~3.2V)
  333.         lcd_write_register(0x25,0x57); //VML(VCOM Low voltage -1.2V)
  334.         //****VCOM offset**///
  335.         lcd_write_register(0x23,0x88); //for Flicker adjust //can reload from OTP
  336.         //Power on Setting
  337.         lcd_write_register(0x18,0x34); //I/P_RADJ,N/P_RADJ, Normal mode 60Hz
  338.         lcd_write_register(0x19,0x01); //OSC_EN='1', start Osc
  339.         lcd_write_register(0x01,0x00); //DP_STB='0', out deep sleep
  340.         lcd_write_register(0x1F,0x88);// GAS=1, VOMG=00, PON=0, DK=1, XDK=0, DVDH_TRI=0, STB=0
  341.         delay_ms(5);
  342.         lcd_write_register(0x1F,0x80);// GAS=1, VOMG=00, PON=0, DK=0, XDK=0, DVDH_TRI=0, STB=0
  343.         delay_ms(5);
  344.         lcd_write_register(0x1F,0x90);// GAS=1, VOMG=00, PON=1, DK=0, XDK=0, DVDH_TRI=0, STB=0
  345.         delay_ms(5);
  346.         lcd_write_register(0x1F,0xD0);// GAS=1, VOMG=10, PON=1, DK=0, XDK=0, DDVDH_TRI=0, STB=0
  347.         delay_ms(5);
  348.         //262k/65k color selection
  349.         lcd_write_register(0x17,0x05); //default 0x06 262k color // 0x05 65k color
  350.         //SET PANEL
  351.         lcd_write_register(0x36,0x00); //SS_P, GS_P,REV_P,BGR_P
  352.         //Display ON Setting
  353.         lcd_write_register(0x28,0x38); //GON=1, DTE=1, D=1000
  354.         delay_ms(40);
  355.         lcd_write_register(0x28,0x3F); //GON=1, DTE=1, D=1100

  356.         lcd_write_register(0x16,0x18);
  357.         //Set GRAM Area
  358.         lcd_write_register(0x02,0x00);
  359.         lcd_write_register(0x03,0x00); //Column Start
  360.         lcd_write_register(0x04,0x00);
  361.         lcd_write_register(0x05,0xEF); //Column End
  362.         lcd_write_register(0x06,0x00);
  363.         lcd_write_register(0x07,0x00); //Row Start
  364.         lcd_write_register(0x08,0x01);
  365.         lcd_write_register(0x09,0x3F); //Row End
  366.    
  367.   lcd_clear_screen(WHITE);
  368.         //lcd_clear_screen(RED);
  369. }
接下来,我们配置SD卡的驱动程序:
SD卡读写一样调用的SPI1的读写函数:
  1. #define __SD_WRITE_BYTE(__DATA)  SPI1ReadWriteByte(__DATA)
SD开的CS端配置,其中触摸芯片XPT2046也挂在这个SPI上面,本例我们先不要,但是定义它的CS引脚,让它处于不选通状态:
  1. void SD_port_init(void)
  2. {
  3.         GPIO_InitType GPIO_InitStructure;
  4.        
  5.         RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB, ENABLE);  
  6.        
  7.         GPIO_StructInit(&GPIO_InitStructure);
  8.         //PB4  PB5
  9.         GPIO_InitStructure.GPIO_Pins = SD_CS_PIN;                            
  10.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
  11.         GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  12.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  13.        
  14.         GPIO_InitStructure.GPIO_Pins = XPT2046_CS_PIN ;                            
  15.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
  16.         //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  17.         GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  18.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  19.        
  20.         __SD_CS_SET();
  21.         __XPT2046_CS_SET();

  22. }
SD其他操作函数:
  1. //data: data to be written to sd card.
  2. //return: data read from sd card.
  3. uint8_t SD_SPI_ReadWriteByte(uint8_t data)
  4. {
  5.         return __SD_WRITE_BYTE(data);
  6. }          

  7. //set spi in low speed mode.
  8. void SD_SPI_SpeedLow(void)
  9. {
  10.         SPI1->CTRL1&=0XFFC7;
  11.         SPI1->CTRL1|=SPI_MCLKP_256;
  12.         SPI_Enable(SPI1, ENABLE);

  13. }


  14. //set spi in high speed mode.
  15. void SD_SPI_SpeedHigh(void)
  16. {
  17.         SPI1->CTRL1&=0XFFC7;
  18.         SPI1->CTRL1|=SPI_MCLKP_32;
  19.         SPI_Enable(SPI1, ENABLE);
  20. }


  21. //released spi bus
  22. void SD_DisSelect(void)
  23. {
  24.         __SD_CS_SET();
  25.         SD_SPI_ReadWriteByte(0xff);//providing extra 8 clocks  
  26. }

  27. //pick sd card and waiting until until it's ready
  28. //return: 0: succed 1: failure
  29. uint8_t SD_Select(void)
  30. {
  31.         __SD_CS_CLR();
  32.         if(SD_WaitReady()==0)return 0;
  33.         SD_DisSelect();
  34.         return 1;
  35. }

  36. //waiting for sd card until it's ready
  37. uint8_t SD_WaitReady(void)
  38. {
  39.         uint32_t t=0;
  40.         do
  41.         {
  42.                 if(SD_SPI_ReadWriteByte(0XFF)==0XFF)return 0;
  43.                 t++;                         
  44.         }while(t<0XFFFFFF);
  45.         return 1;
  46. }

  47. //waiting for response from sd card.
  48. //Response: expect from sd card.
  49. //return: succeed for 0, fail for other else
  50. //return: 0 for success, other for failure.   
  51. uint8_t SD_GetResponse(uint8_t Response)
  52. {
  53.         uint16_t Count=0xFFFF;                                                             
  54.         while ((SD_SPI_ReadWriteByte(0XFF)!=Response)&&Count)Count--;           
  55.         if (Count==0)return MSD_RESPONSE_FAILURE;  
  56.         else return MSD_RESPONSE_NO_ERROR;
  57. }

  58. //read a buffer from sd card.
  59. //*buf: pointer to a buffer.
  60. //len: length of the buffer.
  61. //return: 0 for success, other for failure.   
  62. uint8_t SD_RecvData(uint8_t*buf,uint16_t len)
  63. {                                    
  64.         if(SD_GetResponse(0xFE))return 1;//waiting for start command send back from sd card.
  65.     while(len--)//receiving data...
  66.     {
  67.         *buf=__SD_WRITE_BYTE(0xFF);
  68.         buf++;
  69.     }

  70.     //send 2 dummy write (dummy CRC)
  71.     SD_SPI_ReadWriteByte(0xFF);
  72.     SD_SPI_ReadWriteByte(0xFF);                                                                                                                      
  73.     return 0;
  74. }

  75. //write a buffer containing 512 bytes to sd card.
  76. //buf: data buffer
  77. //cmd: command
  78. //return: 0 for success, other for failure.   
  79. uint8_t SD_SendBlock(uint8_t*buf,uint8_t cmd)
  80. {       
  81.         uint16_t t;                            
  82.         if(SD_WaitReady())return 1;
  83.         SD_SPI_ReadWriteByte(cmd);
  84.         if(cmd!=0XFD)
  85.         {
  86.                 for(t=0;t<512;t++)__SD_WRITE_BYTE(buf[t]);
  87.             SD_SPI_ReadWriteByte(0xFF);//ignoring CRC
  88.             SD_SPI_ReadWriteByte(0xFF);
  89.                 t=SD_SPI_ReadWriteByte(0xFF);
  90.                 if((t&0x1F)!=0x05)return 2;                                                                                                              
  91.         }                                                                                                                                                                       
  92.     return 0;
  93. }


  94. //send a command to sd card
  95. //cmd:command
  96. //arg: parameter
  97. //crc: crc
  98. //return: response sent back from sd card.
  99. uint8_t SD_SendCmd(uint8_t cmd, uint32_t arg, uint8_t crc)
  100. {
  101.     uint8_t r1;       
  102.         uint8_t Retry=0;
  103.         SD_DisSelect();
  104.         if(SD_Select())return 0XFF;

  105.     SD_SPI_ReadWriteByte(cmd | 0x40);
  106.     SD_SPI_ReadWriteByte(arg >> 24);
  107.     SD_SPI_ReadWriteByte(arg >> 16);
  108.     SD_SPI_ReadWriteByte(arg >> 8);
  109.     SD_SPI_ReadWriteByte(arg);          
  110.     SD_SPI_ReadWriteByte(crc);
  111.         if(cmd==CMD12)SD_SPI_ReadWriteByte(0xff); //Skip a stuff byte when stop reading
  112.         Retry=0X1F;
  113.         do
  114.         {
  115.                 r1=SD_SPI_ReadWriteByte(0xFF);
  116.         }while((r1&0X80) && Retry--);         

  117.     return r1;
  118. }


  119. //obtain CID including manufacturer informationfrom sd card  
  120. //*cid_dat: pointer to the buffer storing CID, at least 16 bytes.
  121. //return: 0 no error  1 error
  122. uint8_t SD_GetCID(uint8_t *cid_data)
  123. {
  124.     uint8_t r1;          

  125.     r1=SD_SendCmd(CMD10,0,0x01);
  126.     if(r1==0x00)
  127.         {
  128.                 r1=SD_RecvData(cid_data,16);         
  129.     }
  130.         SD_DisSelect();
  131.         if(r1)return 1;
  132.         else return 0;
  133. }                                                                                                                                                                  

  134. //obtain CSD including storage and speed.
  135. //*csd_data : pointer to the buffer storing CSD, at least 16 bytes.
  136. //return: 0 no error  1 error
  137. uint8_t SD_GetCSD(uint8_t *csd_data)
  138. {
  139.     uint8_t r1;         
  140.     r1=SD_SendCmd(CMD9,0,0x01);//发CMD9命令,读CSD send CMD9 in order to get CSD
  141.     if(r1==0)
  142.         {
  143.             r1=SD_RecvData(csd_data, 16);
  144.     }
  145.         SD_DisSelect();
  146.         if(r1)return 1;
  147.         else return 0;
  148. }  

  149. //obtian the totals of sectors of sd card.
  150. //return: 0 error, other else for storage of sd card.
  151. //numbers of bytes of each sector must be 512, otherwise fail to initialization.  
  152. uint32_t SD_GetSectorCount(void)
  153. {
  154.     uint8_t csd[16];
  155.     uint32_t Capacity;  
  156.     uint8_t n;
  157.         uint16_t csize;                                              
  158.        
  159.     if(SD_GetCSD(csd)!=0) return 0;            
  160.     //calculation for SDHC below
  161.     if((csd[0]&0xC0)==0x40)         //V2.00
  162.     {       
  163.                 csize = csd[9] + ((uint16_t)csd[8] << 8) + 1;
  164.                 Capacity = (uint32_t)csize << 10;  //totals of sectors                   
  165.     }else//V1.XX
  166.     {       
  167.                 n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
  168.                 csize = (csd[8] >> 6) + ((uint16_t)csd[7] << 2) + ((uint16_t)(csd[6] & 3) << 10) + 1;
  169.                 Capacity= (uint32_t)csize << (n - 9);
  170.     }
  171.     return Capacity;
  172. }

  173. //initialize sd card
  174. uint8_t SD_Initialize(void)
  175. {
  176.     uint8_t r1;      
  177.     uint16_t retry;  
  178.     uint8_t buf[4];  
  179.         uint16_t i;
  180.    
  181.     __SD_CS_SET();
  182.         SD_SPI_SpeedLow();       
  183.         for(i=0;i<10;i++)SD_SPI_ReadWriteByte(0XFF);
  184.         retry=20;
  185.         do
  186.         {
  187.                 r1=SD_SendCmd(CMD0,0,0x95);//enter to idle state
  188.         }while((r1!=0X01) && retry--);
  189.         SD_Type=0;
  190.    
  191.         if(r1==0X01)
  192.         {
  193.                 if(SD_SendCmd(CMD8,0x1AA,0x87)==1)//SD V2.0
  194.                 {
  195.                         for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);        //Get trailing return value of R7 resp
  196.                         if(buf[2]==0X01&&buf[3]==0XAA)//is it support of 2.7~3.6V
  197.                         {
  198.                                 retry=0XFFFE;
  199.                                 do
  200.                                 {
  201.                                         SD_SendCmd(CMD55,0,0X01);       
  202.                                         r1=SD_SendCmd(CMD41,0x40000000,0X01);
  203.                                 }while(r1&&retry--);
  204.                                 if(retry&&SD_SendCmd(CMD58,0,0X01)==0) //start to identify the SD2.0 version of sd card.
  205.                                 {
  206.                                         for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);//get OCR
  207.                                         if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC;    //check CCS
  208.                                         else SD_Type=SD_TYPE_V2;   
  209.                                 }
  210.                         }
  211.                 }else//SD V1.x/ MMC        V3
  212.                 {
  213.                         SD_SendCmd(CMD55,0,0X01);               
  214.                         r1=SD_SendCmd(CMD41,0,0X01);       
  215.                         if(r1<=1)
  216.                         {               
  217.                                 SD_Type=SD_TYPE_V1;
  218.                                 retry=0XFFFE;
  219.                                 do //exit idle state
  220.                                 {
  221.                                         SD_SendCmd(CMD55,0,0X01);       
  222.                                         r1=SD_SendCmd(CMD41,0,0X01);
  223.                                 }while(r1&&retry--);
  224.                         }else
  225.                         {
  226.                                 SD_Type=SD_TYPE_MMC;//MMC V3
  227.                                 retry=0XFFFE;
  228.                                 do
  229.                                 {                                                                                            
  230.                                         r1=SD_SendCmd(CMD1,0,0X01);
  231.                                 }while(r1&&retry--);  
  232.                         }
  233.                         if(retry==0||SD_SendCmd(CMD16,512,0X01)!=0)SD_Type=SD_TYPE_ERR;
  234.                 }
  235.         }
  236.         SD_DisSelect();
  237.         SD_SPI_SpeedHigh();
  238.         if(SD_Type)return 0;
  239.         else if(r1)return r1;           
  240.         return 0xaa;
  241. }


  242. //read SD card
  243. //buf: data buffer
  244. //sector: sector
  245. //cnt: totals of sectors]
  246. //return: 0 ok, other for failure
  247. uint8_t SD_ReadDisk(uint8_t*buf,uint32_t sector,uint8_t cnt)
  248. {
  249.         uint8_t r1;
  250.         if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;
  251.         if(cnt==1)
  252.         {
  253.                 r1=SD_SendCmd(CMD17,sector,0X01);
  254.                 if(r1==0)
  255.                 {
  256.                         r1=SD_RecvData(buf,512);   
  257.                 }
  258.         }else
  259.         {
  260.                 r1=SD_SendCmd(CMD18,sector,0X01);
  261.                 do
  262.                 {
  263.                         r1=SD_RecvData(buf,512);
  264.                         buf+=512;  
  265.                 }while(--cnt && r1==0);        
  266.                 SD_SendCmd(CMD12,0,0X01);       
  267.         }   
  268.         SD_DisSelect();
  269.         return r1;//
  270. }


  271. //write sd card
  272. //buf: data buffer
  273. //sector: start sector
  274. //cnt: totals of sectors]
  275. //return: 0 ok, other for failure
  276. uint8_t SD_WriteDisk(uint8_t*buf,uint32_t sector,uint8_t cnt)
  277. {
  278.         uint8_t r1;
  279.         if(SD_Type!=SD_TYPE_V2HC)sector *= 512;
  280.         if(cnt==1)
  281.         {
  282.                 r1=SD_SendCmd(CMD24,sector,0X01);
  283.                 if(r1==0)
  284.                 {
  285.                         r1=SD_SendBlock(buf,0xFE);
  286.                 }
  287.         }else
  288.         {
  289.                 if(SD_Type!=SD_TYPE_MMC)
  290.                 {
  291.                         SD_SendCmd(CMD55,0,0X01);       
  292.                         SD_SendCmd(CMD23,cnt,0X01);       
  293.                 }
  294.                 r1=SD_SendCmd(CMD25,sector,0X01);
  295.                 if(r1==0)
  296.                 {
  297.                         do
  298.                         {
  299.                                 r1=SD_SendBlock(buf,0xFC);
  300.                                 buf+=512;  
  301.                         }while(--cnt && r1==0);
  302.                         r1=SD_SendBlock(0,0xFD);
  303.                 }
  304.         }   
  305.         SD_DisSelect();
  306.         return r1;
  307. }          
下面我们开始移植FATFS,这个主要就是diskio和ff的文件,这里也加载了FATFS常见操作的fatfs_storage文件。
主要修改的就是diskio文件,让我们本例程中的SD具体实现函数来替代FATFS里面的底层操作函数,当然也可在ff_config
头文件里面精简FATFS系统:
  1. /*-----------------------------------------------------------------------*/
  2. /* Inidialize a Drive                                                    */

  3. #define SD_CARD         0  //SD卡,卷标为0

  4. #define FLASH_SECTOR_SIZE         512                          

  5. //初始化磁盘
  6. DSTATUS disk_initialize (
  7.         BYTE drv                                /* Physical drive nmuber (0..) */
  8. )
  9. {       
  10.         uint8_t res=0;            
  11.         switch(drv)
  12.         {
  13.                 case SD_CARD://SD卡
  14.                         res = SD_Initialize();//SD_Initialize()
  15.                          if(res)//STM32 SPI的bug,在sd卡操作失败的时候如果不执行下面的语句,可能导致SPI读写异常
  16.                         {
  17.                                 SD_SPI_SpeedLow();
  18.                                 SD_SPI_ReadWriteByte(0xff);//提供额外的8个时钟
  19.                                 SD_SPI_SpeedHigh();
  20.                         }
  21.                           break;
  22.                 default:
  23.                         res=1;
  24.         }                 
  25.         if(res)return  STA_NOINIT;
  26.         else return 0; //初始化成功
  27. }   
  28. //获得磁盘状态
  29. DSTATUS disk_status (
  30.         BYTE drv                /* Physical drive nmuber (0..) */
  31. )
  32. {                  
  33.     return 0;
  34. }
  35. //读扇区
  36. //drv:磁盘编号0~9
  37. //*buff:数据接收缓冲首地址
  38. //sector:扇区地址
  39. //count:需要读取的扇区数
  40. DRESULT disk_read (
  41.         BYTE drv,                /* Physical drive nmuber (0..) */
  42.         BYTE *buff,                /* Data buffer to store read data */
  43.         DWORD sector,        /* Sector address (LBA) */
  44.         BYTE count                /* Number of sectors to read (1..255) */
  45. )
  46. {
  47.         uint8_t res=0;
  48.     if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误                          
  49.         switch(drv)
  50.         {
  51.                 case SD_CARD://SD卡
  52.                         res=SD_ReadDisk(buff,sector,count);         
  53.                          if(res)//STM32 SPI的bug,在sd卡操作失败的时候如果不执行下面的语句,可能导致SPI读写异常
  54.                         {
  55.                                 SD_SPI_SpeedLow();
  56.                                 SD_SPI_ReadWriteByte(0xff);//提供额外的8个时钟
  57.                                 SD_SPI_SpeedHigh();
  58.                         }
  59.                         break;
  60.                 default:
  61.                         res=1;
  62.         }
  63.    //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
  64.     if(res==0x00)return RES_OK;         
  65.     else return RES_ERROR;          
  66. }  
  67. //写扇区
  68. //drv:磁盘编号0~9
  69. //*buff:发送数据首地址
  70. //sector:扇区地址
  71. //count:需要写入的扇区数            
  72. #if _READONLY == 0
  73. DRESULT disk_write (
  74.         BYTE drv,                        /* Physical drive nmuber (0..) */
  75.         const BYTE *buff,                /* Data to be written */
  76.         DWORD sector,                /* Sector address (LBA) */
  77.         BYTE count                        /* Number of sectors to write (1..255) */
  78. )
  79. {
  80.         uint8_t res=0;  
  81.     if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误                          
  82.         switch(drv)
  83.         {
  84.                 case SD_CARD://SD卡
  85.                         res=SD_WriteDisk((uint8_t*)buff,sector,count);
  86.                         break;
  87.                 default:
  88.                         res=1;
  89.         }
  90.     //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
  91.     if(res == 0x00)return RES_OK;         
  92.     else return RES_ERROR;                 
  93. }
  94. #endif /* _READONLY */

  95. //其他表参数的获得
  96. //drv:磁盘编号0~9
  97. //ctrl:控制代码
  98. //*buff:发送/接收缓冲区指针
  99. DRESULT disk_ioctl (
  100.         BYTE drv,                /* Physical drive nmuber (0..) */
  101.         BYTE ctrl,                /* Control code */
  102.         void *buff                /* Buffer to send/receive control data */
  103. )
  104. {       
  105.         DRESULT res;                                                                               
  106.         if(drv==SD_CARD)//SD卡
  107.         {
  108.             switch(ctrl)
  109.             {
  110.                     case CTRL_SYNC:
  111.                                 __SD_CS_CLR();
  112.                         if(SD_WaitReady()==0)res = RES_OK;
  113.                         else res = RES_ERROR;          
  114.                                 __SD_CS_SET();
  115.                         break;         
  116.                     case GET_SECTOR_SIZE:
  117.                         *(WORD*)buff = 512;
  118.                         res = RES_OK;
  119.                         break;         
  120.                     case GET_BLOCK_SIZE:
  121.                         *(WORD*)buff = 8;
  122.                         res = RES_OK;
  123.                         break;         
  124.                     case GET_SECTOR_COUNT:
  125.                         *(DWORD*)buff = SD_GetSectorCount();
  126.                         res = RES_OK;
  127.                         break;
  128.                     default:
  129.                         res = RES_PARERR;
  130.                         break;
  131.             }
  132.         }else res=RES_ERROR;//其他的不支持
  133.     return res;
  134. }

  135. /*-----------------------------------------------------------------------*/
  136. /* User defined function to give a current time to fatfs module          */
  137. /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */                                                                                                                                                                                                                                          
  138. /* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */                                                                                                                                                                                                                                                
  139. DWORD get_fattime (void)
  140. {
  141.     return 0;
  142. }
  143.        
其他不予多说,在main文件里面添加2个函数,一个是SD挂载FATFS,一个是轮流显示SD卡根目录里面的BMP:
  1. char* pDirectoryFiles[MAX_BMP_FILES];
  2. FATFS microSDFatFs;
  3. uint8_t str[20];

  4. void SDCard_Config(void)
  5. {
  6.   uint32_t counter = 0;
  7.   
  8.   /* Check the mounted device */
  9.   if(f_mount(µSDFatFs, (TCHAR const*)"/", 0) != FR_OK)
  10.   {
  11.       lcd_display_string(0, 16, "FATFS_NOT_MOUNTED", 16, RED);
  12.   }  
  13.   else
  14.   {
  15.     /* Initialize the Directory Files pointers (heap) */
  16.     for (counter = 0; counter < MAX_BMP_FILES; counter++)
  17.     {
  18.       pDirectoryFiles[counter] = malloc(11);
  19.     }
  20.   }
  21. }

  22. static void Display_Images(void)
  23. {   
  24.     uint32_t bmplen = 0x00;
  25.     uint32_t checkstatus = 0x00;
  26.     uint32_t filesnumbers = 0x00;
  27.     uint32_t bmpcounter = 0x00;
  28.     DIR directory;
  29.     FRESULT res;
  30.    
  31.     /* Open directory */
  32.     res= f_opendir(&directory, "/");
  33.     if((res != FR_OK))
  34.     {
  35.       if(res == FR_NO_FILESYSTEM)
  36.       {
  37.         /* Display message: SD card not FAT formated */
  38.         lcd_display_string(0, 32, "SD_CARD_NOT_FORMATTED", 16, RED);  
  39.          
  40.       }
  41.       else
  42.       {
  43.         /* Display message: Fail to open directory */
  44.          lcd_display_string(0, 48, "SD_CARD_OPEN_FAIL", 16, RED);           
  45.       }
  46.     }
  47.    
  48.     /* Get number of bitmap files */
  49.     filesnumbers = Storage_GetDirectoryBitmapFiles ("/", pDirectoryFiles);   
  50.     /* Set bitmap counter to display first image */
  51.     bmpcounter = 1;
  52.    
  53.     while (1)
  54.     {     
  55.         sprintf((char*)str, "%-11.11s", pDirectoryFiles[bmpcounter -1]);
  56.         
  57.         checkstatus = Storage_CheckBitmapFile((const char*)str, &bmplen);
  58.         
  59.         if(checkstatus == 0)
  60.         {
  61.           /* Format the string */
  62.           Storage_OpenReadFile(0, 0, (const char*)str);
  63.         }
  64.         else if (checkstatus == 1)
  65.         {
  66.           /* Display message: SD card does not exist */
  67.            lcd_display_string(0, 64, "SD_CARD_NOT_FOUND", 16, RED);  
  68.         }
  69.         else
  70.         {
  71.           /* Display message: File not supported */
  72.             lcd_display_string(0, 80, "SD_CARD_FILE_NOT_SUPPORTED", 16, RED);
  73.         }
  74.         
  75.         bmpcounter ++;
  76.         if(bmpcounter > filesnumbers)
  77.         {
  78.           bmpcounter = 1;
  79.         }
  80.         
  81.         delay_ms(1000);
  82. //        delay_ms(1000);
  83. //        delay_ms(1000);
  84.     }
  85. }
最终main里面添加:
  1. int main(void)
  2. {
  3.         /*!< At this stage the microcontroller clock setting is already configured,
  4.          this is done through SystemInit() function which is called from startup
  5.          file (startup_at32f403_xx.s) before to branch to application main.
  6.          To reconfigure the default setting of SystemInit() function, refer to
  7.          system_at32f4xx.c file
  8.         */     
  9.          

  10.   
  11.   /* Config LED */
  12.   AT32_Board_Init();
  13.   /* SPIy Config -------------------------------------------------------------*/
  14.   SPI1_Init();

  15.         lcd_port_init();
  16.         lcd_init();
  17.        
  18.         SD_port_init();
  19.         SDCard_Config();
  20.        
  21.        
  22.         lcd_draw_rect(30, 40, 150, 100, RED);
  23.         lcd_draw_circle(120, 160, 50, BLUE);
  24.         lcd_draw_line(30, 40, 180, 140, RED);

  25.         lcd_draw_line(30, 220, 210, 240, RED);
  26.         lcd_draw_line(30, 220, 120, 280, RED);
  27.         lcd_draw_line(120, 280, 210, 240, RED);


  28.         lcd_clear_screen(RED);
  29.         Delay_ms(300);
  30.         lcd_clear_screen(BLUE);
  31.         Delay_ms(300);
  32.         lcd_clear_screen(YELLOW);
  33.         Delay_ms(300);
  34.         lcd_clear_screen(BLACK);
  35.         Delay_ms(300);
  36.         lcd_clear_screen(GRAY);
  37.         Delay_ms(300);
  38.         lcd_clear_screen(GREEN);
  39.         Delay_ms(300);
  40.         lcd_clear_screen(WHITE);
  41.         Delay_ms(300);

  42.         lcd_display_string(60, 120, (const uint8_t *)"Hello, world !", FONT_1608, BLUE);
  43.   lcd_display_string(30, 152, (const uint8_t *)"2.8' TFT Touch Shield", FONT_1608, RED);
  44.         lcd_display_string(30, 152+32, (const uint8_t *)"T want fly high !", FONT_1608, GREEN);
  45.   while (1)
  46.   {
  47. //                AT32_LEDn_Toggle(LED2);
  48. //                AT32_LEDn_Toggle(LED3);
  49. //                Delay_ms(300);       
  50.                 Display_Images();       
  51.                
  52.        
  53.         }
  54. }
编译,下载,查看:
c0 (1).gif
代码(有需要的自取):
SPI_LCD _FATFS_BMP.rar (5.74 MB, 下载次数: 38)


评论

分享的图片无法显示,可否重新上传一下呢?  发表于 2021-3-2 14:46
muyichuan2012 发表于 2021-3-2 13:07 | 显示全部楼层
感谢楼主分享,写的很详细。
 楼主| qjp1988113 发表于 2021-3-2 14:48 | 显示全部楼层
muyichuan2012 发表于 2021-3-2 13:07
感谢楼主分享,写的很详细。

你指什么图片?SD卡里面的BMP图片??
muyichuan2012 发表于 2021-3-2 15:51 | 显示全部楼层
如图
66.png
 楼主| qjp1988113 发表于 2021-3-2 16:06 | 显示全部楼层
jinglixixi 发表于 2021-3-2 19:54 | 显示全部楼层

查了下记录,明白是什么了。
trucyw 发表于 2021-3-3 08:50 | 显示全部楼层
                             不错
单片小菜 发表于 2021-3-3 12:49 | 显示全部楼层
这个LCD驱动,还是比较实用的。
huangcunxiake 发表于 2021-3-3 13:16 | 显示全部楼层
驱动起来。看看。
goyhuan 发表于 2021-3-3 13:53 | 显示全部楼层
谢谢分享
里面有晴雨 发表于 2021-3-3 15:07 | 显示全部楼层
感谢楼主分享,看一下,确实不错的。
渔夫的烟斗 发表于 2021-3-4 23:02 | 显示全部楼层
有没有引脚连接方式的原理图?
zhouyong77 发表于 2021-3-5 08:14 来自手机 | 显示全部楼层
谢谢楼主分享,看下资料。
 楼主| qjp1988113 发表于 2021-3-5 09:16 | 显示全部楼层
渔夫的烟斗 发表于 2021-3-4 23:02
有没有引脚连接方式的原理图?

LCD.jpg
便携手到老 发表于 2021-3-5 16:24 | 显示全部楼层
这个工程确实不错的,给楼主点个赞,比较好的应用哦。
usysm 发表于 2021-3-6 22:22 | 显示全部楼层
如何在LCD上使bmp图片以指定大小显示?
jkl21 发表于 2021-3-6 22:22 | 显示全部楼层
没有演示吗   
wwppd 发表于 2021-3-6 22:22 | 显示全部楼层
这个FATFS自己移植的吗   
maqianqu 发表于 2021-3-6 22:23 | 显示全部楼层
刷屏的速度怎么样   
dspmana 发表于 2021-3-6 22:26 | 显示全部楼层
移植一个ucgui吧   
您需要登录后才可以回帖 登录 | 注册

本版积分规则

111

主题

627

帖子

2

粉丝
快速回复 返回顶部 返回列表