分享

STM32学习笔记

 goodwangLib 2018-03-02

 STM32学习笔记——TFT2.4彩屏显示图片

 

  

 

 

利用彩屏显示图片需要先完成彩屏的驱动程序,然后在驱动程序的基础上再编写应用程序。

彩屏的驱动程序如果写好的话,就可以一直使用了,精力主要集中在应用程序的编写就可以了,但是移植的话,要移植驱动程序。其实移植也只是改变那些很底层的靠近处理器的那部分代码。

 

因为STM32F103C8的片上只有64KFLASH,所以不能存储太多的图片数据,也就不能显示太大的图片。

一下的程序注释的比较详细,看懂了基本上就可以用了。

 

彩屏驱动程序的头文件lcd.h如下:

 

  

 

 

 

 

#define uchar unsigned char 

#define uint unsigned int

 

 

#define Bus_16        //16位数据模式,如果使用8位模式,请注释此语句,如果使用16位模式,请打开此句

#define  LCD_DataPortH P1     //8位数据口,8位模式下只使用高8位 

#define  LCD_DataPortL P0     //8位数据口 ,8位模式下低8位可以不接线

 

 

 

#define LCD_WR    GPIO_Pin_2  //WR  引脚定义 P2^5

#define LCD_RS    GPIO_Pin_1  //RS  引脚定义 P2^6

#define LCD_CS    GPIO_Pin_0  //CS  引脚定义 P2^7

#define LCD_RST   GPIO_Pin_11     //RST 引脚定义 P3^3

#define LCD_RD    GPIO_Pin_8  //RD  引脚定义 P3^2

 

 

#define  LCD_SIZE_X 240

#define  LCD_SIZE_Y 320

 

 

 

extern  uint colors[];

 

extern  void  pic_play(uint xStart, uint xEnd, uint yStart, uint yEnd); //显示图片函数

 

 

 

void delayms(int count) ;

//void LCD_Writ_Bus(char VH,char VL);

void LCD_Init(void);

void LCD_Writ_Bus( uint VH, uint VL);

void LCD_Write_COM(char VH,char VL);

void LCD_Write_DATA(char VH,char VL);

void Pant(char VH,char VL);

void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2);

 

 

 

驱动程序lcd.c文件如下:

 

  

 

 

#include "stm32f10x_lib.h"

#include "Lcd.h"

 

//存储图片数据的头文件

//#include "picture.h"

#include "picture_sara.h"

#include "xiaoqian.h"

#include "yang.h"

 

 

#define    LCD_rest(x) GPIO_SetBits(GPIOA, LCD_RST):   GPIO_ResetBits(GPIOA, LCD_RST) //自己定义位操作函数

#define    LCD_rd(x)   GPIO_SetBits(GPIOA, LCD_RD)   GPIO_ResetBits(GPIOA, LCD_RD)

#define    LCD_rs(x)   GPIO_SetBits(GPIOB, LCD_RS)   GPIO_ResetBits(GPIOB, LCD_RS)

#define    LCD_wr(x)   GPIO_SetBits(GPIOB, LCD_WR)   GPIO_ResetBits(GPIOB, LCD_WR)

#define    LCD_cs(x)   GPIO_SetBits(GPIOB, LCD_CS)   GPIO_ResetBits(GPIOB, LCD_CS)

 

uint colors[]=

{

  0xf800,0x07e0,0x001f,0xffe0,0x0000,0x07ff,0xf81f,0xffff  //颜色数据

};

 

 

 

void LCD_Init(void) //初始化LCD

{

 

    LCD_rest(1);

    delayms(5);

LCD_rest(0);

delayms(5);

LCD_rest(1);

delayms(5);

 

LCD_cs(0);  //打开片选使能

//

LCD_Write_COM(0x00,0xE5); LCD_Write_DATA(0x78,0xF0); // set SRAM internal timing

LCD_Write_COM(0x00,0x01); LCD_Write_DATA(0x01,0x00); // set SS and SM bit

LCD_Write_COM(0x00,0x02); LCD_Write_DATA(0x07,0x00); // set line inversion

LCD_Write_COM(0x00,0x03); LCD_Write_DATA(0x10,0x30); // set GRAM write direction and BGR=1.

LCD_Write_COM(0x00,0x04); LCD_Write_DATA(0x00,0x00); // Resize register

LCD_Write_COM(0x00,0x08); LCD_Write_DATA(0x02,0x07); // set the back porch and front porch

LCD_Write_COM(0x00,0x09); LCD_Write_DATA(0x00,0x00); // set non-display area refresh cycle ISC[3:0]

LCD_Write_COM(0x00,0x0A); LCD_Write_DATA(0x00,0x00); // FMARK function

LCD_Write_COM(0x00,0x0C); LCD_Write_DATA(0x00,0x00); // RGB interface setting

LCD_Write_COM(0x00,0x0D); LCD_Write_DATA(0x00,0x00); // Frame marker Position

LCD_Write_COM(0x00,0x0F); LCD_Write_DATA(0x00,0x00); // RGB interface polarity

//

LCD_Write_COM(0x00,0x10); LCD_Write_DATA(0x00,0x00); // SAP, BT[3:0], AP, DSTB, SLP, STB

LCD_Write_COM(0x00,0x11); LCD_Write_DATA(0x00,0x07); // DC1[2:0], DC0[2:0], VC[2:0]

LCD_Write_COM(0x00,0x12); LCD_Write_DATA(0x00,0x00); // VREG1OUT voltage

LCD_Write_COM(0x00,0x13); LCD_Write_DATA(0x00,0x00); // VDV[4:0] for VCOM amplitude

LCD_Write_COM(0x00,0x07); LCD_Write_DATA(0x00,0x01);

delayms(50); // Dis-charge capacitor power voltage

LCD_Write_COM(0x00,0x10); LCD_Write_DATA(0x10,0x90); // 1490//SAP, BT[3:0], AP, DSTB, SLP, STB

LCD_Write_COM(0x00,0x11); LCD_Write_DATA(0x02,0x27); // DC1[2:0], DC0[2:0], VC[2:0]

delayms(50); // Delay 50ms

LCD_Write_COM(0x00,0x12); LCD_Write_DATA(0x00,0x1F); //001C// Internal reference voltage= Vci;

delayms(50); // Delay 50ms

LCD_Write_COM(0x00,0x13); LCD_Write_DATA(0x15,0x00); //0x1000//1400   Set VDV[4:0] for VCOM amplitude  1A00

LCD_Write_COM(0x00,0x29); LCD_Write_DATA(0x00,0x27); //0x0012 //001a  Set VCM[5:0] for VCOMH  //0x0025  0034

LCD_Write_COM(0x00,0x2B); LCD_Write_DATA(0x00,0x0D); // Set Frame Rate   000C

delayms(50); // Delay 50ms

LCD_Write_COM(0x00,0x20); LCD_Write_DATA(0x00,0x00); // GRAM horizontal Address

LCD_Write_COM(0x00,0x21); LCD_Write_DATA(0x00,0x00); // GRAM Vertical Address

// ----------- Adjust the Gamma Curve ----------//

LCD_Write_COM(0x00,0x30); LCD_Write_DATA(0x00,0x00);

LCD_Write_COM(0x00,0x31); LCD_Write_DATA(0x07,0x07);

LCD_Write_COM(0x00,0x32); LCD_Write_DATA(0x03,0x07);

LCD_Write_COM(0x00,0x35); LCD_Write_DATA(0x02,0x00);

LCD_Write_COM(0x00,0x36); LCD_Write_DATA(0x00,0x08);//0207

LCD_Write_COM(0x00,0x37); LCD_Write_DATA(0x00,0x04);//0306

LCD_Write_COM(0x00,0x38); LCD_Write_DATA(0x00,0x00);//0102

LCD_Write_COM(0x00,0x39); LCD_Write_DATA(0x07,0x07);//0707

LCD_Write_COM(0x00,0x3C); LCD_Write_DATA(0x00,0x02);//0702

LCD_Write_COM(0x00,0x3D); LCD_Write_DATA(0x1D,0x04);//1604

 

//------------------ Set GRAM area ---------------//

LCD_Write_COM(0x00,0x50); LCD_Write_DATA(0x00,0x00); // Horizontal GRAM Start Address

LCD_Write_COM(0x00,0x51); LCD_Write_DATA(0x00,0xEF); // Horizontal GRAM End Address

LCD_Write_COM(0x00,0x52); LCD_Write_DATA(0x00,0x00); // Vertical GRAM Start Address

LCD_Write_COM(0x00,0x53); LCD_Write_DATA(0x01,0x3F); // Vertical GRAM Start Address

LCD_Write_COM(0x00,0x60); LCD_Write_DATA(0xA7,0x00); // Gate Scan Line

LCD_Write_COM(0x00,0x61); LCD_Write_DATA(0x00,0x01); // NDL,VLE, REV

LCD_Write_COM(0x00,0x6A); LCD_Write_DATA(0x00,0x00); // set scrolling line

//-------------- Partial Display Control ---------//

LCD_Write_COM(0x00,0x80); LCD_Write_DATA(0x00,0x00);

LCD_Write_COM(0x00,0x81); LCD_Write_DATA(0x00,0x00);

LCD_Write_COM(0x00,0x82); LCD_Write_DATA(0x00,0x00);

LCD_Write_COM(0x00,0x83); LCD_Write_DATA(0x00,0x00);

LCD_Write_COM(0x00,0x84); LCD_Write_DATA(0x00,0x00);

LCD_Write_COM(0x00,0x85); LCD_Write_DATA(0x00,0x00);

//-------------- Panel Control -------------------//

LCD_Write_COM(0x00,0x90); LCD_Write_DATA(0x00,0x10);

LCD_Write_COM(0x00,0x92); LCD_Write_DATA(0x06,0x00);

LCD_Write_COM(0x00,0x07); LCD_Write_DATA(0x01,0x33); // 262K color and display ON

 

LCD_cs(1);  //关闭片选使能

 

 

 

void delayms(int count)  // 

{

        int i,j;

        for(i=0;i<count;i++)

                for(j=0;j<100;j++);

}

 

#ifdef  Bus_16    //条件编译-16位数据模式   

void LCD_Writ_Bus(uint VH uint VL)   //并行数据写入函数

{

  //LCD_DataPortH=VH;   //高位P1

//屏蔽高8  将数据送到PA0-PA7

GPIOA->BSRR VH 0x00ff;   

    GPIOA->BRR  (~VH) 0x00ff;

   //GPIO_SetBits(GPIOA,  VH 0x00ff);

   //GPIO_ResetBits(GPIOA, (~ VH 0x00ff));

 

    //LCD_DataPortL=VL;   //低位P0

//屏蔽低8  将数据送到PB8-PB15

GPIOB->BSRR (VL)<<8 0xff00;   

    GPIOB->BRR  ((~VL)<<8) 0xff00;

 

LCD_wr(0);

LCD_wr(1);

}

#else //条件编译-8位数据模式 

void LCD_Writ_Bus(char VH,char VL)   //并行数据写入函数

{

     //LCD_DataPortH=VH;  //八位模式都用P0口送数据

     //LCD_wr(0);

//LCD_wr(1);

//LCD_DataPortH=VL; //八位模式都用P0口送数据

//LCD_wr(0);

//LCD_wr(1);

}

#endif

 

 

void LCD_Write_COM(char VH,char VL)  //发送命令

{

    LCD_rs(0);

LCD_Writ_Bus(VH,VL);

}

 

 

void LCD_Write_DATA(char VH,char VL) //发送数据

{

    LCD_rs(1);

LCD_Writ_Bus(VH,VL);

}

 

 

void Pant(char VH,char VL)    //涂满全屏函数

{

int i,j;

LCD_cs(0);  //打开片选使能

Address_set(0,0,239,319);

    for(i=0;i<320;i++)

 {

  for (j=0;j<240;j++)

    {

          LCD_Write_DATA(VH,VL);

    }

 

  }

     LCD_cs(1);  //关闭片选使能

}

 

 

void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2) //设置地址范围函数

{

LCD_Write_COM(0x00,0x20);LCD_Write_DATA(x1>>8,x1);   //设置X坐标位置

    LCD_Write_COM(0x00,0x21);LCD_Write_DATA(y1>>8,y1);   //设置Y坐标位置

    LCD_Write_COM(0x00,0x50);LCD_Write_DATA(x1>>8,x1);   //开始X

LCD_Write_COM(0x00,0x52);LCD_Write_DATA(y1>>8,y1);   //开始Y

    LCD_Write_COM(0x00,0x51);LCD_Write_DATA(x2>>8,x2);   //结束X

LCD_Write_COM(0x00,0x53);LCD_Write_DATA(y2>>8,y2);   //结束Y

    LCD_Write_COM(0x00,0x22);  

}

 

 

 

 

void  pic_play(uint Start_X, uint End_X,uint Start_Y,uint End_Y)

{

   uint m;

   //LCD_CS 0;

   GPIO_ResetBits(GPIOB,LCD_CS);  //打开片选

   Address_set(Start_X,Start_Y,End_X,End_Y) ; //指定图片显示的范围

  // LCD_RS  1; 

   GPIO_SetBits(GPIOB, LCD_RS);   //关闭片选

 

   //循环把图片的所有数据依次写入

 

 

  

 

   Address_set(0,0,141,79);    //用彩屏显示图片时,一定要注意图片长宽比例,如果长宽比例不对的话,显示的图片就会变形

   //例如本幅图片取模软件输出的长宽为(177,100),所以在这里图片的显示范围必须设为(0,0,176,99),即x范围为0~176y的范围为

   //0~99.这样图片才能正常显示,否则图片就会变形。

   for(m=0;m<22728/2;m++)   //这里的35400这个数字指定显示图片的范围,因为该图的数据总共只有35400个,所以这里指定

   //整幅图都显示出来。如果这个数比35400小,则只显示该图的一部分。

   {

       LCD_Write_DATA(gImage_sara[m*2+1],gImage_sara[m*2]);

   }

 

 

Address_set(0,90,65,189);  //一定要注意保持比例

for(m=0;m<13200/2;m++)

{

    LCD_Write_DATA(gImage_xiaoqian[m*2+1],gImage_xiaoqian[m*2]);

}

 

 

    Address_set(75,90,137,189); //一定要注意保持比例

for(m=0;m<12600/2;m++)

{

    LCD_Write_DATA(gImage_yang[m*2+1],gImage_yang[m*2]);

}

  

   //LCD_CS 1;

   GPIO_SetBits(GPIOB, LCD_CS);  //关闭片选

 

}

 

 

 

 

主程序main.c

在主程序中完成对系统的初始化配置,利用彩屏的驱动程序完成图片的显示等功能,程序如下:

  

 

 

#include "stm32f10x_lib.h"

#include "lcd.h"

 

 

GPIO_InitTypeDef GPIO_InitStructure;   //定义GPIO初始化的结构体变量

ErrorStatus HSEStartUpStatus; //定义错误状态变量,为枚举类型

 

 

void RCC_Configuration(void);

void NVIC_Configuration(void);

void Delay(vu32 nCount);

 

 

 

int main(void)

{

#ifdef DEBUG

  debug();  //在线调试使用

#endif

 

 

   RCC_Configuration();      //系统时钟配置函数   

 

   NVIC_Configuration();     //NVIC配置函数

 

    //启动GPIO模块时钟

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA RCC_APB2Periph_GPIOB RCC_APB2Periph_AFIO, ENABLE);

 

    //把调试设置普通IO 禁止SWJ

  GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);  

                            

  GPIO_InitStructure.GPIO_Pin GPIO_Pin_All;  //所有GPIO为同一类型端口

  GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP;  //推挽输出

  GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;  //输出的最大频率为50HZ

  GPIO_Init(GPIOA, &GPIO_InitStructure);   //初始化GPIOA端口

  GPIO_Init(GPIOB, &GPIO_InitStructure);   //初始化GPIOB端口

 

   GPIO_Write(GPIOA,0xffff);  //GPIOA 16个端口全部置为高电平

   GPIO_Write(GPIOB,0xffff);  //GPIOB 16个端口全部置为高电平

 

   LCD_Init();    //初始化LCD

 

   //LCD_clear(6);   //清屏为紫色

   Pant(colors[6]>>8,colors[6]);   //把全屏涂满紫色

   

 

   pic_play(0,173,0,173); //显示图片

 

   //pic_play(7,61,8,74); //显示图片

  // pic_play(68,122,8,74);

  // pic_play(7,61,82,148);

  // pic_play(68,122,82,148);

 

   while(1);

 

}

 

 

void RCC_Configuration(void)

  

 //复位RCC外部设备寄存器到默认值

  RCC_DeInit();

 

  //打开外部高速晶振

  RCC_HSEConfig(RCC_HSE_ON);

 

   //等待外部高速时钟准备好

  HSEStartUpStatus RCC_WaitForHSEStartUp();

 

  if(HSEStartUpStatus == SUCCESS)   //外部高速时钟已经准别好

  {     

    //开启FLASH的预取功能

    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

 

    //FLASH延迟2个周期

    FLASH_SetLatency(FLASH_Latency_2);

 

  //配置AHB(HCLK)时钟=SYSCLK

    RCC_HCLKConfig(RCC_SYSCLK_Div1);  

  

   //配置APB2(PCLK2)=AHB时钟

    RCC_PCLK2Config(RCC_HCLK_Div1); 

 

    //配置APB1(PCLK1)=AHB 1/2时钟

    RCC_PCLK1Config(RCC_HCLK_Div2);

 

     //配置PLL时钟 == 外部高速晶体时钟*9  PLLCLK 8MHz 72 MHz 

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

 

    //使能PLL时钟

    RCC_PLLCmd(ENABLE);

 

   //等待PLL时钟就绪

    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

    {

    }

 

  //配置系统时钟 PLL时钟

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

 

   //检查PLL时钟是否作为系统时钟

    while(RCC_GetSYSCLKSource() != 0x08)

    {

    }

  }

}

 

 

void NVIC_Configuration(void)

{

#ifdef  VECT_TAB_RAM  

   

  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 

#else  

   

  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   

#endif

}

 

 

void Delay(vu32 nCount)

{

  for(; nCount != 0; nCount--);

}

 

 

 

 

 

#ifdef  DEBUG

 

void assert_failed(u8* file, u32 line)

  

 

  

  while (1)

  {

  }

}

#endif

 

 

 

  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多