打印
[应用方案]

基于新唐NANO120的EBI总线的SSD1963的4.3”的480X272的LCD驱动应用

[复制链接]
8362|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
缥缈九哥|  楼主 | 2013-12-6 10:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 缥缈九哥 于 2013-12-8 18:43 编辑

帮助客户调了一个驱动,直接用NANO120的16位总线驱动了神舟III号4.3寸液晶屏,EBI中的ALE配置成GPIO用于写地址和写数据的区别,默认情况是写命令。不用EBI总线中的ALE锁存地址步骤,其余两个GPIO做LCD的复位和背光启动。PLL用到了96M,HCLK用到了48MHZ,感觉 超频了6MHZ了。发出来抛砖引玉,希望大家指正。附件: ssd1963.rar (4.64 KB)
源码如下:

/******************************************************************************
* @file     ssd1963.c
* @brief    The Driver code for 480*272 16-bit Color LCD with NANO120KE3BN
* @version  1.0.0
* @date     05, December, 2013
*
* @note
* Copyright (C) 2000-2013 PM9GZY by yuanxihua@21cn.com. All rights reserved.
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include "nano1xx.h"
#include "nano1xx_gpio.h"
#include "nano1xx_ebi.h"
#include "stdlib.h"
#include "core_cmInstr.h"
#include "rfid.h"
/*
_________________________________________________
| NANO120KE3BN     SSD1963  |
|            |
| EBIAD0- EBIAD15  <--->  DB0-DB15 |
| EBIWR PA10  ---->  WR#   |
| EBIRD PA11  ---->  RD#   |
| EBICS PB7   ---->  CS#   |
| PB6  EBIALE  ---->  D/C#  |
| PA8  EBIPA8  ---->  RESET#  |
| PA9  EBIPA9  ---->  LEDA  |
|_______________________________________________|
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define LCD_LEDA  GPIOA, 9  /* PA9=High,BackLight ON; Low,BackLight OFF */
#define LCD_RESET  GPIOA, 8  /* PA8=Low,LCD Reset;PA8=High,LCD Working   */
#define LCD_DCMD  GPIOB, 6  /* PB6=High,DATA mode; PB6=Low,COMMAND mode */
#define LCD_RESET_DELAY 100    /* LCD_RESET=Low,LCD_RESET_DELAY>=100us  */
#define BLACK         0x0000        /* 黑色:  0  , 0  , 0   */        
#define NAVY          0x000F         /* 深蓝色: 0  , 0  , 128   */        
#define DGREEN        0x03E0          /* 深绿色: 0  , 128, 0     */      
#define DCYAN         0x03EF         /* 深青色: 0  , 128, 128   */      
#define MAROON        0x7800          /* 深红色: 128, 0  , 0     */      
#define PURPLE       0x780F          /* 紫色:  128, 0  , 128   */        
#define OLIVE         0x7BE0         /* 橄榄绿: 128, 128, 0     */     
#define LGRAY         0xC618         /* 灰白色: 192, 192, 192   */      
#define DGRAY         0x7BEF          /* 深灰色: 128, 128, 128   */      
#define BLUE          0x001F          /* 蓝色:  0  , 0  , 255   */         
#define GREEN         0x07E0          /* 绿色:  0  , 255, 0     */         
#define CYAN          0x07FF          /* 青色:  0  , 255, 255   */         
#define RED           0xF800          /* 红色:  255, 0  , 0     */         
#define MAGENTA       0xF81F          /* 品红:  255, 0  , 255   */        
#define YELLOW        0xFFE0         /* 黄色:  255, 255, 0     */      
#define WHITE         0xFFFF          /* 白色:  255, 255, 255  */
#define SSD1963_HDP  0xDF01   /* HDP=479=0x01DF  */
#define SSD1963_HT  0x1302   /* HT =531=0x0213  */
#define SSD1963_HPS  0x2B00   /* HPS=43 =0x002B */
#define SSD1963_LPS  0x0800   /* LPS=8  =0x0008 */
#define SSD1963_HPW  10    /* HPW=10 =0x0A  */
#define SSD1963_VDP  0x0F01   /* VDP=271=0x010F */
#define SSD1963_VT  0x2001   /* VT =288=0x0120  */
#define SSD1963_VPS  0x0C00   /* VPS=12 =0x000C */
#define SSD1963_FPS  0x0100   /* FPS=1  =0x0001 */
#define SSD1963_VPW  10    /* VPW=10 =0x0A  */
/* Private macro -------------------------------------------------------------*/
/*  Command      Hex Code Description */
#define SSD1963_nop      0x00 /* No operation */
#define SSD1963_soft_reset     0x01 /* Software Reset */
#define SSD1963_get_power_mode    0x0A /* Get the current power mode */
#define SSD1963_get_address_mode   0x0B /* Get the frame buffer to the display panel read order */
#define SSD1963_Reserved0c     0x0C /* Reserved */
#define SSD1963_get_display_mode   0x0D /* The SSD1963 returns the Display Image Mode. */
#define SSD1963_get_tear_effect_status  0x0E /* Get the Tear Effect status */
#define SSD1963_Reserved0f     0x0F /* Reserved */
#define SSD1963_enter_sleep_mode   0x10 /* Turn off the panel. This command will pull low the GPIO0. If GPIO0 is configured as normal GPIO or LCD miscellaneous signal with command set_gpio_conf, this command will be ignored. */
#define SSD1963_exit_sleep_mode   0x11 /* Turn on the panel. This command will pull high the GPIO0. If GPIO0 is configured as normal GPIO or LCD miscellaneous signal with command set_gpio_conf, this command will be ignored. */
#define SSD1963_enter_partial_mode   0x12 /* Part of the display area is used for image display. */
#define SSD1963_enter_normal_mode   0x13 /* The whole display area is used for image display. */
#define SSD1963_exit_invert_mode   0x20 /* Displayed image colors are not inverted. */
#define SSD1963_enter_invert_mode   0x21 /* Displayed image colors are inverted. */
#define SSD1963_set_gamma_curve   0x26 /* Selects the gamma curve used by the display panel. */
#define SSD1963_set_display_off   0x28 /* Blanks the display panel */
#define SSD1963_set_display_on    0x29 /* Show the image on the display panel */
#define SSD1963_set_column_address   0x2A /* Set the column address */
#define SSD1963_set_page_address   0x2B /* Set the page address */
#define SSD1963_write_memory_start   0x2C /* Transfer image information from the host processor interface to the SSD1963 starting at the location provided by set_column_address and set_page_address  */
#define SSD1963_read_memory_start   0x2E /* Transfer image data from the SSD1963 to the host processor interface starting at the location provided by set_column_address and set_page_address  */
#define SSD1963_set_partial_area   0x30 /* Defines the partial display area on the display panel */
#define SSD1963_set_scroll_area   0x33 /* Defines the vertical scrolling and fixed area on display area */
#define SSD1963_set_tear_off    0x34 /* Synchronization information is not sent from the SSD1963 to the host processor */
#define SSD1963_set_tear_on    0x35 /* Synchronization information is sent from the SSD1963 to the host processor at the start of VFP */
#define SSD1963_set_address_mode   0x36 /* Set the read order from frame buffer to the display panel */
#define SSD1963_set_scroll_start   0x37 /* Defines the vertical scrolling starting point */
#define SSD1963_exit_idle_mode    0x38 /* Full color depth is used for the display panel */
#define SSD1963_enter_idle_mode   0x39 /* Reduce color depth is used on the display panel. */
#define SSD1963_Reserved3a     0x3A /* Reserved */
#define SSD1963_write_memory_continue  0x3C /* Transfer image information from the host processor interface to the SSD1963 from the last written location */
#define SSD1963_read_memory_continue  0x3E /* Read image data from the SSD1963 continuing after the last read_memory_continue or read_memory_start */
#define SSD1963_set_tear_scanline   0x44 /* Synchronization information is sent from the SSD1963 to the host processor when the display panel refresh reaches the provided scanline  */
#define SSD1963_get_scanline    0x45 /* Get the current scan line */
#define SSD1963_read_ddb     0xA1 /* Read the DDB from the provided location */
#define SSD1963_Reserveda8     0xA8 /* Reserved */
#define SSD1963_set_lcd_mode   0xB0 /* Set the LCD panel mode and resolution */
#define SSD1963_get_lcd_mode    0xB1 /* Get the current LCD panel mode, pad strength and resolution */
#define SSD1963_set_hori_period   0xB4 /* Set front porch */
#define SSD1963_get_hori_period   0xB5 /* Get current front porch settings */
#define SSD1963_set_vert_period   0xB6 /* Set the vertical blanking interval between last scan line and next LFRAME pulse */
#define SSD1963_get_vert_period   0xB7 /* Set the vertical blanking interval between last scan line and next LFRAME pulse */
#define SSD1963_set_gpio_conf    0xB8 /* Set the GPIO configuration. If the GPIO is not used for LCD, set the direction. Otherwise, they are toggled with LCD signals. */
#define SSD1963_get_gpio_conf    0xB9 /* Get the current GPIO configuration */
#define SSD1963_set_gpio_value    0xBA /* Set GPIO value for GPIO configured as output  */
#define SSD1963_get_gpio_status   0xBB /* Read current GPIO status. If the individual GPIO was configured as input, the value is the status of the corresponding pin. Otherwise, it is the programmed value. */
#define SSD1963_set_post_proc    0xBC /* Set the image post processor */
#define SSD1963_get_post_proc    0xBD /* Set the image post processor */
#define SSD1963_set_pwm_conf    0xBE /* Set the image post processor */
#define SSD1963_get_pwm_conf    0xBF /* Set the image post processor */
#define SSD1963_set_lcd_gen0    0xC0 /* Set the rise, fall, period and toggling properties of LCD signal generator 0 */
#define SSD1963_get_lcd_gen0    0xC1 /* Get the current settings of LCD signal generator 0 */
#define SSD1963_set_lcd_gen1    0xC2 /* Set the rise, fall, period and toggling properties of LCD signal generator 1 */
#define SSD1963_get_lcd_gen1    0xC3 /* Get the current settings of LCD signal generator 1 */
#define SSD1963_set_lcd_gen2    0xC4 /* Set the rise, fall, period and toggling properties of LCD signal generator 2 */
#define SSD1963_get_lcd_gen2    0xC5 /* Get the current settings of LCD signal generator 2 */
#define SSD1963_set_lcd_gen3    0xC6 /* Set the rise, fall, period and toggling properties of LCD signal generator 3 */
#define SSD1963_get_lcd_gen3    0xC7 /* Get the current settings of LCD signal generator 3  */
#define SSD1963_set_gpio0_rop    0xC8 /* Set the GPIO0 with respect to the LCD signal generators using ROP operation. No effect if the GPIO0 is configured as general GPIO. */
#define SSD1963_get_gpio0_rop    0xC9 /* Get the GPIO0 properties with respect to the LCD signal generators. */
#define SSD1963_set_gpio1_rop    0xCA /* Set the GPIO1 with respect to the LCD signal generators using ROP operation. No effect if the GPIO1 is configured as general GPIO. */
#define SSD1963_get_gpio1_rop    0xCB /* Get the GPIO1 properties with respect to the LCD signal generators.  */
#define SSD1963_set_gpio2_rop    0xCC /* Set the GPIO2 with respect to the LCD signal generators using ROP operation. No effect if the GPIO2 is configured as general GPIO. */
#define SSD1963_get_gpio2_rop    0xCD /* Get the GPIO2 properties with respect to the LCD signal generators. */
#define SSD1963_set_gpio3_rop    0xCE /* Set the GPIO3 with respect to the LCD signal generators using ROP operation. No effect if the GPIO3 is configured as general GPIO. */
#define SSD1963_get_gpio3_rop    0xCF /* Get the GPIO3 properties with respect to the LCD signal generators. */
#define SSD1963_set_dbc_conf    0xD0 /* Set the dynamic back light configuration 0xD1 get_dbc_conf Get the current dynamic back light configuration  */
#define SSD1963_set_dbc_th     0xD4 /* Set the threshold for each level of power saving */
#define SSD1963_get_dbc_th     0xD5 /* Get the threshold for each level of power saving */
#define SSD1963_set_pll     0xE0 /* Start the PLL. Before the start, the system was operated with the crystal oscillator or clock input */
#define SSD1963_set_pll_mn     0xE2 /* Set the PLL */
#define SSD1963_get_pll_mn     0xE3 /* Get the PLL settings */
#define SSD1963_get_pll_status    0xE4 /* Get the current PLL status */
#define SSD1963_set_deep_sleep    0xE5 /* Set deep sleep mode */
#define SSD1963_set_lshift_freq   0xE6 /* Set the LSHIFT (pixel clock) frequency */
#define SSD1963_get_lshift_freq   0xE7 /* Get current LSHIFT (pixel clock) frequency setting */
#define SSD1963_Reservede8     0xE8 /* Reserved */
#define SSD1963_Reservede9     0xE9 /* Reserved */
#define SSD1963_set_pixel_data_interface 0xF0 /* Set the pixel data format of the parallel host processor interface */
#define SSD1963_get_pixel_data_interface 0xF1 /* Get the current pixel data format settings */
#define SSD1963_Reservedff     0xFF /* Reserved */
/* Private variables ---------------------------------------------------------*/
void SSD1963_Fill(uint16_t color);
extern void SYS_Delay(uint32_t us);
void Delay_ms(uint32_t ms)
{
for(uint32_t i=0;i<ms;i++){SYS_Delay(1000);}
}
// Enable EBI function with 16-bit data width
void NANOEBI_Init(void)
{
EBI_TIMING_T sEBITiming;
UNLOCKREG();
/* Enable EBI clock  */
    CLK->AHBCLK |= CLK_AHBCLK_EBI_EN;
/* EBI function enable */
EBI->EBICON |= EBI_EBICON_ExtEN;
EBI->EBICON |= EBI_EBICON_ExtBW16;
// Enable EBIAD15-0, GPIOPA9-8
GCR->PA_L_MFP = (GCR->PA_L_MFP & 0x0000000f) | 0x22222220; //PA7_MFP-PA1_MFP = EBI AD[6]-EBI AD[12]
GCR->PA_H_MFP = (GCR->PA_H_MFP & 0xf0000000) | 0x02222200; //PA14_MFP-PA12_MFP = EBI AD[15]-EBI AD[13] PA11_MFP-PA10_MFP = EBIWR-EBIRD PA9_MFP-PA8_MFP = PA9-PA8
GCR->PB_L_MFP = (GCR->PB_L_MFP & 0x00ffffff) | 0x20000000; //PB7_MFP-PB6_MFP = EBICS-PB6
GCR->PB_H_MFP = (GCR->PB_H_MFP & 0xff00ffff) | 0x00220000; //PB13_MFP-PB12_MFP = EBI AD[1]-EBI AD[0]
GCR->PC_L_MFP = (GCR->PC_L_MFP & 0x00ffffff) | 0x22000000; //PC15_MFP-PC14_MFP = EBI AD[3]-EBI AD[2]
GCR->PC_H_MFP = (GCR->PC_H_MFP & 0x00ffffff) | 0x22000000; //PC7_MFP-PC6_MFP = EBI AD[5]-EBI AD[4]
sEBITiming.eMCLKDIV = E_EBI_MCLKDIV_1;  //OK!!! 480NS 2.083MHZ
  sEBITiming.u8ExttALE=sEBITiming.u8ExtIR2R=sEBITiming.u8ExtIR2W = 0;
sEBITiming.u8ExtIW2X=sEBITiming.u8ExttAHD=sEBITiming.u8ExttACC = 0;
EBI_SetBusTiming(sEBITiming);
*(volatile uint16_t*)EBI_BASE_ADDR=0xFFFF;  //Set D0-D15 to HIGH

GPIO_Open(GPIOA, GPIO_PMD_PMD8_OUTPUT, GPIO_PMD_PMD8_MASK);
GPIO_Open(GPIOA, GPIO_PMD_PMD9_OUTPUT, GPIO_PMD_PMD9_MASK);
GPIO_Open(GPIOB, GPIO_PMD_PMD6_OUTPUT, GPIO_PMD_PMD6_MASK);

GPIO_SetBit(LCD_LEDA);      //PA9=High,BackLight ON; Low,BackLight OFF
GPIO_SetBit(LCD_DCMD);      //PB6=High,DATA mode; PB6=Low,COMMAND mode
GPIO_SetBit(LCD_RESET);      //PA8=Low,LCD Reset;PA8=High,LCD Working
SYS_Delay(LCD_RESET_DELAY);
GPIO_ClrBit(LCD_RESET);
SYS_Delay(LCD_RESET_DELAY);
GPIO_SetBit(LCD_RESET);
// LOCKREG();
}
static void EBI_test(void) {while(1) {*(volatile uint16_t*)EBI_BASE_ADDR=0x5555;*(volatile uint16_t*)EBI_BASE_ADDR=0xAAAA;}}
static __INLINE void SSD1963_WrPAR(uint8_t *data, uint8_t len){while(len--){EBI_WRITE_DATA16(0, *data++);}}
static __INLINE void SSD1963_WrCMD(uint8_t cmd, uint8_t *data, uint8_t len){GPIO_ClrBit(LCD_DCMD);EBI_WRITE_DATA16(0, cmd);GPIO_SetBit(LCD_DCMD);SSD1963_WrPAR(data, len);}
static __INLINE void SSD1963_WrRAM(uint16_t *data, uint32_t len){while(len--){EBI_WRITE_DATA16(0, *data++);}}
void SSD1963_Init(void)
{
uint32_t Parameter;
Parameter=0x04021d;   //PLL multiplier, set PLL clock to 120M N=0x36 for 6.5M, 0x23 for 10M crystal
SSD1963_WrCMD(SSD1963_set_pll_mn,(uint8_t*)&Parameter, 3);
Parameter=0x01;    //Enable PLL
SSD1963_WrCMD(SSD1963_set_pll,(uint8_t*)&Parameter, 1);
Delay_ms(1);
Parameter=0x03;    //Use PLL output as system clock
SSD1963_WrCMD(SSD1963_set_pll,(uint8_t*)&Parameter, 1);
Delay_ms(5);
SSD1963_WrCMD(SSD1963_soft_reset,(uint8_t*)&Parameter, 0); //software reset
Delay_ms(5);
Parameter=0x16D900;   //PLL setting for PCLK, depends on resolution
SSD1963_WrCMD(SSD1963_set_lshift_freq,(uint8_t*)&Parameter, 3);

Parameter=0x0020;   //LCD SPECIFICATION
SSD1963_WrCMD(SSD1963_set_lcd_mode,(uint8_t*)&Parameter, 2);
Parameter=SSD1963_HDP;  //Set HDP
SSD1963_WrPAR((uint8_t*)&Parameter, 2);
Parameter=SSD1963_VDP;  //Set VDP
SSD1963_WrPAR((uint8_t*)&Parameter, 3);
Parameter=SSD1963_HT;  //Set HT HSYNC
SSD1963_WrCMD(SSD1963_set_hori_period,(uint8_t*)&Parameter, 2);
Parameter=SSD1963_HPS;  //Set HPS
SSD1963_WrPAR((uint8_t*)&Parameter, 2);
Parameter=SSD1963_HPW;  //Set HPW
SSD1963_WrPAR((uint8_t*)&Parameter, 1);
Parameter=SSD1963_LPS;  //Set LPS
SSD1963_WrPAR((uint8_t*)&Parameter, 3);

Parameter=SSD1963_VT;  //Set VT VSYNC
SSD1963_WrCMD(SSD1963_set_vert_period,(uint8_t*)&Parameter, 2);
Parameter=SSD1963_VPS;  //Set VPS
SSD1963_WrPAR((uint8_t*)&Parameter, 2);
Parameter=SSD1963_VPW;  //Set VPW
SSD1963_WrPAR((uint8_t*)&Parameter, 1);
Parameter=SSD1963_FPS;  //Set FPS
SSD1963_WrPAR((uint8_t*)&Parameter, 2);
Parameter=0x05;   //0x000F;    //GPIO[3:0] out 1
SSD1963_WrCMD(SSD1963_set_gpio_value,(uint8_t*)&Parameter, 1);
Parameter=0x0107;   //GPIO0 normal GPIO3=input, GPIO[2:0]=output
SSD1963_WrCMD(SSD1963_set_gpio_conf,(uint8_t*)&Parameter, 2);

Parameter=0x00;   //rotation
SSD1963_WrCMD(SSD1963_set_address_mode,(uint8_t*)&Parameter, 1);
Delay_ms(50);
Parameter=0x8006;  //set PWM for B/L
SSD1963_WrCMD(SSD1963_set_pwm_conf,(uint8_t*)&Parameter, 2);
Parameter=0x0000f001;
SSD1963_WrPAR((uint8_t*)&Parameter, 4);

Parameter=0x0d;   //设置动态背光控制配置
SSD1963_WrCMD(SSD1963_set_dbc_conf,(uint8_t*)&Parameter, 1);
   
Parameter=0x03;   //03:16-bit (565 format)
SSD1963_WrCMD(SSD1963_set_pixel_data_interface,(uint8_t*)&Parameter, 1);
// SSD1963_WrCMD(SSD1963_enter_invert_mode,(uint8_t*)&Parameter, 0); //进入图形颜色翻转模式
// Parameter=0x01808080; //处理机允许  饱和度值  亮度 对比度
// SSD1963_WrCMD(SSD1963_set_post_proc,(uint8_t*)&Parameter, 4);
SSD1963_Fill(BLACK);
SSD1963_WrCMD(SSD1963_set_display_on,(uint8_t*)&Parameter, 0); //display on
Delay_ms(5);
}
void SSD1963_Fill(uint16_t color)
{
uint32_t Parameter;
Parameter=0;
SSD1963_WrCMD(SSD1963_set_column_address,(uint8_t*)&Parameter, 2);
Parameter=SSD1963_HDP;
SSD1963_WrPAR((uint8_t*)&Parameter, 2);
Parameter=0;
SSD1963_WrCMD(SSD1963_set_page_address,(uint8_t*)&Parameter, 2);
Parameter=SSD1963_VDP;
SSD1963_WrPAR((uint8_t*)&Parameter, 2);

SSD1963_WrCMD(SSD1963_write_memory_start,(uint8_t*)&Parameter, 0);
for(uint32_t i=0;i<130560;i++){SSD1963_WrRAM(&color, 1);}
}
void LCD_test(void)
{
uint16_t i=0,color[]={BLACK, NAVY, DGREEN, DCYAN, MAROON, PURPLE, OLIVE, LGRAY, DGRAY, BLUE, GREEN, CYAN, RED, MAGENTA, YELLOW, WHITE};
while(1)
{
  if(i++>(sizeof(color)/sizeof(color[0])))i=0;
  SSD1963_Fill(color);Delay_ms(5000);
}
}
void LCD_Configuration(void)
{
NANOEBI_Init();
SSD1963_Init();
printf("REVSH(0x1234)=0x%04x\n\r",__REVSH(0x1234));
LCD_test();
EBI_test();
}//代码完毕
--缥缈九哥测试

沙发
Regsen| | 2013-12-6 10:34 | 只看该作者
顶起,9G。Up Up

使用特权

评论回复
板凳
haonwing| | 2013-12-6 10:43 | 只看该作者
多谢分享!学习中..

使用特权

评论回复
地板
clyu| | 2013-12-6 11:32 | 只看该作者

使用特权

评论回复
5
xiao4056| | 2013-12-6 12:57 | 只看该作者
老早就想弄个彩屏来玩玩,苦于一直都没时间,先谢谢9G,年后弄个看看

使用特权

评论回复
6
niuyaliang| | 2013-12-6 15:49 | 只看该作者
支持飘渺九哥的分享精神!

使用特权

评论回复
7
bobde163| | 2013-12-7 00:15 | 只看该作者
好长。。。。。

使用特权

评论回复
8
缥缈九哥|  楼主 | 2013-12-7 12:28 | 只看该作者
又有修改。哈哈。总线速度达到了2MHZ,感觉是极限了。有没有人指正一下呀?

使用特权

评论回复
9
mingjiezhong| | 2013-12-10 22:08 | 只看该作者
尽管和九哥有点合不来,但是还是要顶一下

使用特权

评论回复
10
缥缈九哥|  楼主 | 2013-12-11 11:16 | 只看该作者
mingjiezhong 发表于 2013-12-10 22:08
尽管和九哥有点合不来,但是还是要顶一下

肯定是跟我吵架了?有关技术的?请提供点建议呀。

使用特权

评论回复
11
缥缈九哥|  楼主 | 2013-12-16 15:41 | 只看该作者

NANO120KE3BN+W25Q64+SSD1963的EBI驱动的BMP驱动支持

本帖最后由 缥缈九哥 于 2013-12-16 15:45 编辑

人气不行呀。我于发个BMP的驱动上来。LCD是RGB565,16位接口,BMP图片是256色的,SPIFLASH的块是4K,页是256B,型号是W25Q64,从SPI的FLASH地址中读出来显示。目前CPU是NANO120KE3BN,PLL是96MHZ,HCLK是48MHZ,SPICLK是24MHZ。希望大家能帮助指正,谢谢!
代码如下:

void SSD1963_BMP(uint16_t column_start, uint16_t column_end, uint16_t page_start, uint16_t page_end,uint32_t spiaddress)
{
        uint32_t Parameter,pixelsize;
        Parameter=__REVSH(column_start);        SSD1963_WrCMD(SSD1963_set_column_address,(uint8_t*)&Parameter, 2);
        Parameter=__REVSH(column_end);                SSD1963_WrPAR((uint8_t*)&Parameter, 2);
        Parameter=__REVSH(page_start);                SSD1963_WrCMD(SSD1963_set_page_address,(uint8_t*)&Parameter, 2);
        Parameter=__REVSH(page_end);                SSD1963_WrPAR((uint8_t*)&Parameter, 2);
        SSD1963_WrCMD(SSD1963_write_memory_start,(uint8_t*)&Parameter, 0);
        pixelsize=(column_end-column_start)*(page_end-page_start);                                        //要显示的图像像素大小
        
        bmp_picture bmpfile;                                                                                                                 //申请BMP的文件头缓冲
        uint32_t spiflash_address=spiaddress;                                                                                //取文件在FLASH中首地址
        W25Q64_ByteRead(spiflash_address,(uint8_t *)&bmpfile, sizeof(bmpfile));
        DBG_PRINTF("bmpfile.file.bfType=0x%04x\n\r"                ,bmpfile.file.bfType);                //BMP文件标识                 = 0x4d42
        DBG_PRINTF("bmpfile.file.bfSize=0x%08x\n\r"                ,bmpfile.file.bfSize);                //BMP文件大小                 = 0x00020236
        DBG_PRINTF("bmpfile.file.bfOffset=0x%08x\n\r"        ,bmpfile.file.bfOffset);        //像素数据偏移地址         = 0x00000436
        DBG_PRINTF("bmpfile.info.biSize=0x%08x\n\r"                ,bmpfile.info.biSize);                //BMP文件信息大小        = 0x00000028
        DBG_PRINTF("bmpfile.info.biWidth=0x%08x\n\r"        ,bmpfile.info.biWidth);                //图像宽度                        = 0x000001e0
        DBG_PRINTF("bmpfile.info.biHeight=0x%08x\n\r"        ,bmpfile.info.biHeight);        //图像高度                        = 0x00000110
        DBG_PRINTF("bmpfile.info.biBitCount=0x%04x\n\r"        ,bmpfile.info.biBitCount);        //图像像素颜色位数        = 0x0008
        
        uint16_t ColorTable[256];                                                                                                        //申请256色调色板缓冲
        uint32_t ColorLength=bmpfile.file.bfOffset-sizeof(bitmapfile)-sizeof(bitmapinfo);//文件中实际调色板长度
        for(uint32_t i=0;i<(ColorLength/4);i++)                                                                                //取调色板
        {
                uint16_t blue=bmpfile.palette.blue>>3,green=bmpfile.palette.green>>2,red=bmpfile.palette.red>>3;
                ColorTable=(uint16_t)((red<<11)|(green<<5)|(blue<<0));
        }
        uint8_t data[4096];                                                                                                                        //操作每块像素数据缓冲
        uint32_t data_address=spiflash_address+bmpfile.file.bfOffset;                                //图像数据在FLASH中首地址
        uint32_t data_length=(256*5)-bmpfile.file.bfOffset;                                                        //取第一个零散块,以便后面整块读写
        W25Q64_ByteRead(data_address,data,data_length);
        for(uint32_t i=0;i<data_length;i++){EBI_WRITE_DATA16(0,ColorTable[data]);}
        pixelsize=bmpfile.info.biWidth*bmpfile.info.biHeight;                                                //图像大小
        pixelsize-=data_length;data_address+=data_length;                                                        //剩余像素大小和地址偏移
        uint32_t addr,page=pixelsize/4096,rest=pixelsize%4096;                                                //处理整块和不足块整块
        for(addr=data_address;addr<(data_address+(page*4096));addr+=4096)        
        {
                W25Q64_SectorRead(addr,data);
                for(uint32_t i=0;i<4096;i++){EBI_WRITE_DATA16(0,ColorTable[data]);}        //写全部的整块
        }
        if(rest)                                                                                                                        
        {
                W25Q64_ByteRead(addr,data,rest);
                for(uint32_t i=0;i<rest;i++){EBI_WRITE_DATA16(0,ColorTable[data]);}        //写不足整块部分
        }
}

/******************************************************************************
* @file     bmp.c
* @brief    The Driver code for 8-bit 256-color BMP display for SSD1963
* @version  1.0.0
* @date     12, December, 2013
*
* @note
* Copyright (C) 2000-2013 PM9GZY by yuanxihua@21cn.com. All rights reserved.
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifndef __BMP_H__
#define __BMP_H__

#include <stdio.h>
#include <stdint.h>
/* Private typedef -----------------------------------------------------------*/
typedef __packed struct BMP_file
{
        uint16_t bfType;                    //这里恒定等于0x4D42,ASCII字符‘BM’
        uint32_t bfSize;                           //文件大小,以字节为单位
        uint16_t Reserved1;                 //备用,必须为0
        uint16_t reserved2;                 //备用,必须为0
        uint32_t bfOffset;                         //数据区在文件中的位置偏移量,以字节为单位
}bitmapfile;                        //文件头结构体,14 字节
typedef __packed struct BMP_info
{
    uint32_t biSize;                           //位图信息头大小,即本结构所占用字节数=0x28
    uint32_t biWidth;                          //图象宽度,像素单位
    uint32_t biHeight;                         //图象高度,像素单位
    uint16_t biPlanes;                  //位平面树,目标设备的级别,必须为1
    uint16_t biBitCount;                //单位像素的位数,表示BMP图片的颜色位数,必须是1(双色 ),4(16色),8(256色),24位图(真彩色),32位图
    uint32_t biCompression;                    //图片压缩属性,必须为:0(不压缩),1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
    uint32_t biSizeImage;                      //表示图片数据区的大小,当biBompression等于0时,这里的值可以省略
    uint32_t biXpolsPerMeter;                  //水平分辨率,每米像素数,可省略
    uint32_t biYpelsPerMeter;                  //垂直分辨率,每米像素数,可省略
    uint32_t biClrUsed;                        //表示使用了多少个颜色索引表,一般biBitCount属性小于16位才会用到,等于0时表示有2^biBitCount个颜色索引表
    uint32_t biClrImportant;                   //表示有多少个重要的颜色,等于0时表示所有颜色都很重要
}bitmapinfo;                        //位图信息头,40 字节

typedef __packed struct RGB_BMP_type
{
    uint8_t blue;                             //蓝色的亮度(值范围为0-255)
    uint8_t green;                            //绿色的亮度(值范围为0-255)
    uint8_t red;                              //红色的亮度(值范围为0-255)
    uint8_t reserved;                         //保留,必须为0
}RGB_BMP,*RGB_BMP_ptr;              //单个像素颜色结构体,4 字节

typedef __packed struct bmp_picture_type
{
    bitmapfile file;                //位图文件头,14字节
    bitmapinfo info;                //位图信息头,40字节
    RGB_BMP palette[256];           //位图颜色表,1K字节
}bmp_picture, *bmp_picture_ptr;            //位图非数据区结构体  
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
#endif

使用特权

评论回复
12
缥缈九哥|  楼主 | 2013-12-20 13:50 | 只看该作者
提供一个图片增加亮度的算法。用于按键的高亮显示。
#define        RGB565Brightness(c,b)        (((c&0xF800)+((b<<8)&0xF800))|((c&0x07E0)+((b<<3)&0x07E0))|((c&0x001F)+((b>>3)&0x001F)))        /* RGB565 + Brightness         */

使用特权

评论回复
13
骗子的片子| | 2013-12-20 16:40 | 只看该作者
九哥的东西有点看不懂,正在努力学习,争取把你拍在沙滩上

使用特权

评论回复
14
缥缈九哥|  楼主 | 2013-12-24 12:38 | 只看该作者
现在用NANO120的EBI驱动SSD1963的LCD做的菜单,还是很爽的。基本与智能手机的菜单 有得比。

使用特权

评论回复
15
wjsjdeng| | 2014-1-6 15:30 | 只看该作者
顶9哥,,

使用特权

评论回复
16
wjsjdeng| | 2014-1-6 15:31 | 只看该作者
曾经参考9哥的代码,用 nuc140的EBI驱动ILI9341

使用特权

评论回复
17
zxf0168| | 2014-1-20 01:22 | 只看该作者
顶九哥,九哥一直在支持着我

使用特权

评论回复
18
jackem| | 2014-7-18 13:46 | 只看该作者
期待九歌能把整个工程发出来

使用特权

评论回复
19
enjoy21cn| | 2014-7-18 15:08 | 只看该作者
好东西,一直都在学习和应用中

使用特权

评论回复
20
弥勒开怀笑| | 2014-7-18 16:17 | 只看该作者

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:童时不懂世事艰,笑谈学成锦衣还。岁月无声已先过,男儿有泪空自弹。    莫待沾霜愁上发,须嬴吐气喜开颜。拼搏半年誓如愿,不到长城心不甘。

67

主题

1868

帖子

271

粉丝