LCD-BSP.c 文件
#include "lcd/bsp_lcd.h" #include "lcd/ascii.h" /* 私有类型定义 --------------------------------------------------------------*/ /* 私有宏定义 ----------------------------------------------------------------*/ /* 私有变量 ------------------------------------------------------------------*/ __IO uint32_t lcd_id=0; // 保存当前检查到的液晶模块ID SRAM_HandleTypeDef hlcd; // SRAM外设句柄 static int FSMC_LCD_Initialized = 0; // FSMC初始化标志位:0:未初始化;1:已完成初始化 static int FSMC_LCD_DeInitialized = 0; // FSMC反初始化标志位:0:未反初始化;1:已完成反初始化 uint16_t LCD_X_LENGTH = ILI9341_LESS_PIXEL; uint16_t LCD_Y_LENGTH = ILI9341_MORE_PIXEL; uint8_t LCD_SCAN_MODE = 6; /** * @brief 向ILI9341写入命令 * @param usCmd :要写入的命令(表寄存器地址) * @retval 无 */ //__inline void LCD_WRITE_CMD ( uint16_t usCmd ) //{ // * ( __IO uint16_t * ) ( FSMC_LCD_CMD ) = usCmd; // //} ///** // * @brief 向ILI9341写入数据 // * @param usData :要写入的数据 // * @retval 无 // */ //__inline void LCD_WRITE_DATA ( uint16_t usData ) //{ // * ( __IO uint16_t * ) ( FSMC_LCD_DATA ) = usData; // //} ///** // * @brief 从ILI9341读取数据 // * @param 无 // * @retval 读取到的数据 // */ //__inline uint16_t LCD_READ_DATA ( void ) //{ // return ( * ( __IO uint16_t * ) ( FSMC_LCD_DATA) ); // //} /* 扩展变量 ------------------------------------------------------------------*/ /* 私有函数原形 --------------------------------------------------------------*/ /* 函数体 --------------------------------------------------------------------*/ /** * 函数功能: 初始化LCD的IO引脚 * 输入参数: 无 * 返 回 值: 无 * 说 明:LCD控制器ILI9488相当于一个外部SRAM操作 * 该函数被HAL_SRAM_MspInit函数调用 */ static void HAL_FSMC_LCD_MspInit(void) { GPIO_InitTypeDef GPIO_InitStruct; uint16_t LCD_X_LENGTH = ILI9341_LESS_PIXEL; uint16_t LCD_Y_LENGTH = ILI9341_MORE_PIXEL; //液晶屏扫描模式,本变量主要用于方便选择触摸屏的计算参数 //参数可选值为0-7 //调用ILI9341_GramScan函数设置方向时会自动更改 //LCD刚初始化完成时会使用本默认值 uint8_t LCD_SCAN_MODE = 6; /* 如果已经完成初始化就无需初始化第二遍 */ if(FSMC_LCD_Initialized) { return; } FSMC_LCD_Initialized = 1; /* 使能相关端口时钟 */ FSMC_LCD_CS_GPIO_ClK_ENABLE(); FSMC_LCD_DC_GPIO_ClK_ENABLE(); FSMC_LCD_BK_GPIO_ClK_ENABLE(); // __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /* 使能FSMC外设时钟 */ __HAL_RCC_FSMC_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 |GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14 |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4 |GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); GPIO_InitStruct.Pin = ILI9341_RD_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init (ILI9341_RD_PORT, &GPIO_InitStruct ); GPIO_InitStruct.Pin = ILI9341_WR_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(ILI9341_WR_PORT, &GPIO_InitStruct ); GPIO_InitStruct.Pin = FSMC_LCD_CS_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(FSMC_LCD_CS_PORT, &GPIO_InitStruct); GPIO_InitStruct.Pin = FSMC_LCD_DC_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(FSMC_LCD_DC_PORT, &GPIO_InitStruct); GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Pin = ILI9341_RST_PIN; HAL_GPIO_Init ( ILI9341_RST_PORT, &GPIO_InitStruct ); /* 输出低电平:背光不亮 */ HAL_GPIO_WritePin(FSMC_LCD_BK_PORT, FSMC_LCD_BK_PIN, GPIO_PIN_RESET); HAL_GPIO_WritePin(ILI9341_RST_PORT, ILI9341_RST_PIN, GPIO_PIN_SET); /* 液晶背光控制引脚初始化 */ GPIO_InitStruct.Pin = FSMC_LCD_BK_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(FSMC_LCD_BK_PORT, &GPIO_InitStruct); } /** * 函数功能: 初始化FSMC的IO引脚 * 输入参数: hsram:SRAM外设句柄指针 * 返 回 值: 无 * 说 明:该函数被HAL库内部函数调用 */ void HAL_SRAM_MspInit(SRAM_HandleTypeDef* hsram) { HAL_FSMC_LCD_MspInit(); } /** * 函数功能: 反初始化LCD的IO引脚 * 输入参数: 无 * 返 回 值: 无 * 说 明:LCD控制器ILI9488相当于一个外部SRAM操作 * 该函数被HAL_SRAM_MspDeInit函数调用 */ static void HAL_FSMC_LCD_MspDeInit(void) { /* 如果已经完成反初始化就无需初始化第二遍 */ if(FSMC_LCD_DeInitialized) { return; } FSMC_LCD_DeInitialized = 1; /* 禁用FSMC外设时钟 */ __HAL_RCC_FSMC_CLK_DISABLE(); /** FSMC GPIO Configuration PF0 ------> FSMC_A0 PE7 ------> FSMC_D4 PE8 ------> FSMC_D5 PE9 ------> FSMC_D6 PE10 ------> FSMC_D7 PE11 ------> FSMC_D8 PE12 ------> FSMC_D9 PE13 ------> FSMC_D10 PE14 ------> FSMC_D11 PE15 ------> FSMC_D12 PD8 ------> FSMC_D13 PD9 ------> FSMC_D14 PD10 ------> FSMC_D15 PD14 ------> FSMC_D0 PD15 ------> FSMC_D1 PD0 ------> FSMC_D2 PD1 ------> FSMC_D3 PD4 ------> FSMC_NOE PD5 ------> FSMC_NWE PG12 ------> FSMC_NE4 */ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 |GPIO_PIN_15); HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14 |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4 |GPIO_PIN_5); HAL_GPIO_DeInit(FSMC_LCD_DC_PORT, FSMC_LCD_DC_PIN); HAL_GPIO_DeInit(FSMC_LCD_CS_PORT, FSMC_LCD_CS_PIN); } /** * 函数功能: 反初始化FSMC的IO引脚 * 输入参数: hsram:SRAM外设句柄指针 * 返 回 值: 无 * 说 明:该函数被HAL库内部函数调用 */ void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef* hsram) { HAL_FSMC_LCD_MspDeInit(); } /** * 函数功能: LCD FSMC 模式配置 * 输入参数: 无 * 返 回 值: 无 * 说 明:读写使用相同时间配置 */ void MX_FSMC_Init(void) { FSMC_NORSRAM_TimingTypeDef Timing; /* 配置FSMC参数 */ hlcd.Instance = FSMC_NORSRAM_DEVICE; hlcd.Extended = FSMC_NORSRAM_EXTENDED_DEVICE; hlcd.Init.NSBank = FSMC_LCD_BANKx; hlcd.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE; hlcd.Init.MemoryType = FSMC_MEMORY_TYPE_NOR; hlcd.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16; hlcd.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE; hlcd.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW; hlcd.Init.WrapMode = FSMC_WRAP_MODE_DISABLE; hlcd.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS; hlcd.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE; hlcd.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE; hlcd.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE; // hlcd.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE; hlcd.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE; Timing.AddressSetupTime = 0x01; //地址建立时间 Timing.AddressHoldTime = 0x00; //地址保持时间 Timing.DataSetupTime = 0x04; //数据建立时间 Timing.BusTurnAroundDuration = 0x00; Timing.CLKDivision = 0x00; Timing.DataLatency = 0x00; Timing.AccessMode = FSMC_ACCESS_MODE_B; HAL_SRAM_Init(&hlcd, &Timing, &Timing); /* Disconnect NADV */ __HAL_AFIO_FSMCNADV_DISCONNECTED(); } static void LCD_Delay ( __IO uint32_t nCount ) { for ( ; nCount != 0; nCount -- ); } /** * 函数功能: 初始化LCD寄存器 * 输入参数: 无 * 返 回 值: 无 * 说 明:需要配置哪些寄存器,需要设置什么值与液晶厂家生产环境密切相关, * 所以这些参数由厂家提供,不同厂家可能不同。也可以根据ILI9341芯片 * 手册内容参考修改。 */ static void ILI9488_REG_Config ( void ) { LCD_SetDirection(LCD_DIRECTION); DEBUG_DELAY (); LCD_WRITE_CMD ( 0xCF ); LCD_WRITE_DATA ( 0x00 ); LCD_WRITE_DATA ( 0x81 ); LCD_WRITE_DATA ( 0x30 ); /* Power on sequence control (EDh) */ DEBUG_DELAY (); LCD_WRITE_CMD ( 0xED ); LCD_WRITE_DATA ( 0x64 ); LCD_WRITE_DATA ( 0x03 ); LCD_WRITE_DATA ( 0x12 ); LCD_WRITE_DATA ( 0x81 ); /* Driver timing control A (E8h) */ DEBUG_DELAY (); LCD_WRITE_CMD ( 0xE8 ); LCD_WRITE_DATA ( 0x85 ); LCD_WRITE_DATA ( 0x10 ); LCD_WRITE_DATA ( 0x78 ); /* Power control A (CBh) */ DEBUG_DELAY (); LCD_WRITE_CMD ( 0xCB ); LCD_WRITE_DATA ( 0x39 ); LCD_WRITE_DATA ( 0x2C ); LCD_WRITE_DATA ( 0x00 ); LCD_WRITE_DATA ( 0x34 ); LCD_WRITE_DATA ( 0x02 ); /* Pump ratio control (F7h) */ DEBUG_DELAY (); LCD_WRITE_CMD ( 0xF7 ); LCD_WRITE_DATA ( 0x20 ); /* Driver timing control B */ DEBUG_DELAY (); LCD_WRITE_CMD ( 0xEA ); LCD_WRITE_DATA ( 0x00 ); LCD_WRITE_DATA ( 0x00 ); /* Frame Rate Control (In Normal Mode/Full Colors) (B1h) */ DEBUG_DELAY (); LCD_WRITE_CMD ( 0xB1 ); LCD_WRITE_DATA ( 0x00 ); LCD_WRITE_DATA ( 0x1B ); /* Display Function Control (B6h) */ DEBUG_DELAY (); LCD_WRITE_CMD ( 0xB6 ); LCD_WRITE_DATA ( 0x0A ); LCD_WRITE_DATA ( 0xA2 ); /* Power Control 1 (C0h) */ DEBUG_DELAY (); LCD_WRITE_CMD ( 0xC0 ); LCD_WRITE_DATA ( 0x35 ); /* Power Control 2 (C1h) */ DEBUG_DELAY (); LCD_WRITE_CMD ( 0xC1 ); LCD_WRITE_DATA ( 0x11 ); /* VCOM Control 1 (C5h) */ LCD_WRITE_CMD ( 0xC5 ); LCD_WRITE_DATA ( 0x45 ); LCD_WRITE_DATA ( 0x45 ); /* VCOM Control 2 (C7h) */ LCD_WRITE_CMD ( 0xC7 ); LCD_WRITE_DATA ( 0xA2 ); /* Enable 3G (F2h) */ LCD_WRITE_CMD ( 0xF2 ); LCD_WRITE_DATA ( 0x00 ); /* Gamma Set (26h) */ LCD_WRITE_CMD ( 0x26 ); LCD_WRITE_DATA ( 0x01 ); DEBUG_DELAY (); /* Positive Gamma Correction */ LCD_WRITE_CMD ( 0xE0 ); //Set Gamma LCD_WRITE_DATA ( 0x0F ); LCD_WRITE_DATA ( 0x26 ); LCD_WRITE_DATA ( 0x24 ); LCD_WRITE_DATA ( 0x0B ); LCD_WRITE_DATA ( 0x0E ); LCD_WRITE_DATA ( 0x09 ); LCD_WRITE_DATA ( 0x54 ); LCD_WRITE_DATA ( 0xA8 ); LCD_WRITE_DATA ( 0x46 ); LCD_WRITE_DATA ( 0x0C ); LCD_WRITE_DATA ( 0x17 ); LCD_WRITE_DATA ( 0x09 ); LCD_WRITE_DATA ( 0x0F ); LCD_WRITE_DATA ( 0x07 ); LCD_WRITE_DATA ( 0x00 ); /* Negative Gamma Correction (E1h) */ LCD_WRITE_CMD ( 0XE1 ); //Set Gamma LCD_WRITE_DATA ( 0x00 ); LCD_WRITE_DATA ( 0x19 ); LCD_WRITE_DATA ( 0x1B ); LCD_WRITE_DATA ( 0x04 ); LCD_WRITE_DATA ( 0x10 ); LCD_WRITE_DATA ( 0x07 ); LCD_WRITE_DATA ( 0x2A ); LCD_WRITE_DATA ( 0x47 ); LCD_WRITE_DATA ( 0x39 ); LCD_WRITE_DATA ( 0x03 ); LCD_WRITE_DATA ( 0x06 ); LCD_WRITE_DATA ( 0x06 ); LCD_WRITE_DATA ( 0x30 ); LCD_WRITE_DATA ( 0x38 ); LCD_WRITE_DATA ( 0x0F ); /* memory access control set */ DEBUG_DELAY (); LCD_WRITE_CMD ( 0x36 ); LCD_WRITE_DATA ( 0xC8 ); /*竖屏 左上角到 (起点)到右下角 (终点)扫描方式*/ DEBUG_DELAY (); /* column address control set */ LCD_WRITE_CMD ( CMD_SetCoordinateX ); LCD_WRITE_DATA ( 0x00 ); LCD_WRITE_DATA ( 0x00 ); LCD_WRITE_DATA ( 0x00 ); LCD_WRITE_DATA ( 0xEF ); /* page address control set */ DEBUG_DELAY (); LCD_WRITE_CMD ( CMD_SetCoordinateY ); LCD_WRITE_DATA ( 0x00 ); LCD_WRITE_DATA ( 0x00 ); LCD_WRITE_DATA ( 0x01 ); LCD_WRITE_DATA ( 0x3F ); /* Pixel Format Set (3Ah) */ DEBUG_DELAY (); LCD_WRITE_CMD ( 0x3a ); LCD_WRITE_DATA ( 0x55 ); /* Sleep Out (11h) */ LCD_WRITE_CMD ( 0x11 ); LCD_Delay ( 0xAFFf<<2 ); DEBUG_DELAY (); /* Display ON (29h) */ LCD_WRITE_CMD ( 0x29 ); } /** * 函数功能: 读取液晶模组ID * 输入参数: 无 * 返 回 值: 液晶模组的ID * 说 明:这是通过读取04H寄存器获取得到液晶模组ID,该ID值有液晶厂家编程,不同液晶 * 厂家的液晶模组得到的ID值可能不同。这也可以分辨不同型号的液晶模组。 */ static uint32_t LCD_ReadID(void) { uint16_t buf[4]; LCD_WRITE_CMD(0xD3); buf[0] = LCD_READ_DATA(); // 第一个读取数据无效 buf[1] = LCD_READ_DATA()&0x00ff; // 只有低8位数据有效 buf[2] = LCD_READ_DATA()&0x00ff; // 只有低8位数据有效 buf[3] = LCD_READ_DATA()&0x00ff; // 只有低8位数据有效 return (buf[1] << 16) + (buf[2] << 8) + buf[3]; } /** * 函数功能: 液晶模组初始化 * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */ uint32_t BSP_LCD_Init(void) { HAL_FSMC_LCD_MspInit(); MX_FSMC_Init(); lcd_id=LCD_ReadID(); ILI9488_REG_Config(); LCD_Clear(0,0,LCD_DEFAULT_WIDTH,LCD_DEFAULT_HEIGTH,BLACK); HAL_Delay(20); return lcd_id; } /** * 函数功能: 设置LCD的GRAM的扫描方向 * 输入参数: ucOption :选择GRAM的扫描方向 * 可选值:1 :原点在屏幕左上角 X*Y=320*480 * 2 :原点在屏幕右上角 X*Y=480*320 * 3 :原点在屏幕右下角 X*Y=320*480 * 4 :原点在屏幕左下角 X*Y=480*320 * 返 回 值: 无 * 说 明:无 */ void LCD_SetDirection( uint8_t ucOption ) { if(ucOption >7 ) return; //根据模式更新LCD_SCAN_MODE的值,主要用于触摸屏选择计算参数 LCD_SCAN_MODE = ucOption; //根据模式更新XY方向的像素宽度 if(ucOption%2 == 0) { //0 2 4 6模式下X方向像素宽度为240,Y方向为320 LCD_X_LENGTH = ILI9341_LESS_PIXEL; LCD_Y_LENGTH = ILI9341_MORE_PIXEL; } else { //1 3 5 7模式下X方向像素宽度为320,Y方向为240 LCD_X_LENGTH = ILI9341_MORE_PIXEL; LCD_Y_LENGTH = ILI9341_LESS_PIXEL; } //0x36命令参数的高3位可用于设置GRAM扫描方向 LCD_WRITE_CMD ( 0x36 ); LCD_WRITE_DATA ( 0x08 |(ucOption<<5));//根据ucOption的值设置LCD参数,共0-7种模式 LCD_WRITE_CMD ( CMD_SetCoordinateX ); LCD_WRITE_DATA ( 0x00 ); /* x 起始坐标高8位 */ LCD_WRITE_DATA ( 0x00 ); /* x 起始坐标低8位 */ LCD_WRITE_DATA ( ((LCD_X_LENGTH-1)>>8)&0xFF ); /* x 结束坐标高8位 */ LCD_WRITE_DATA ( (LCD_X_LENGTH-1)&0xFF ); /* x 结束坐标低8位 */ LCD_WRITE_CMD ( CMD_SetCoordinateY ); LCD_WRITE_DATA ( 0x00 ); /* y 起始坐标高8位 */ LCD_WRITE_DATA ( 0x00 ); /* y 起始坐标低8位 */ LCD_WRITE_DATA ( ((LCD_Y_LENGTH-1)>>8)&0xFF ); /* y 结束坐标高8位 */ LCD_WRITE_DATA ( (LCD_Y_LENGTH-1)&0xFF ); /* y 结束坐标低8位 */ /* write gram start */ LCD_WRITE_CMD ( CMD_SetPixel ); } /** * 函数功能: 在LCD显示器上开辟一个窗口 * 输入参数: usX :在特定扫描方向下窗口的起点X坐标 * usY :在特定扫描方向下窗口的起点Y坐标 * usWidth :窗口的宽度 * usHeight :窗口的高度 * 返 回 值: 无 * 说 明:无 */ void LCD_OpenWindow(uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight) { LCD_WRITE_CMD(CMD_SetCoordinateX ); /* 设置X坐标 */ LCD_WRITE_DATA(usX>>8); /* 设置起始点:先高8位 */ LCD_WRITE_DATA(usX&0xff); /* 然后低8位 */ LCD_WRITE_DATA((usX+usWidth-1)>>8); /* 设置结束点:先高8位 */ LCD_WRITE_DATA((usX+usWidth-1)&0xff);/* 然后低8位 */ LCD_WRITE_CMD(CMD_SetCoordinateY); /* 设置Y坐标*/ LCD_WRITE_DATA(usY>>8); /* 设置起始点:先高8位 */ LCD_WRITE_DATA(usY&0xff); /* 然后低8位 */ LCD_WRITE_DATA((usY+usHeight-1)>>8); /* 设置结束点:先高8位 */ LCD_WRITE_DATA((usY+usHeight-1)&0xff);/* 然后低8位 */ } /** * 函数功能: 设定LCD的光标坐标 * 输入参数: usX :在特定扫描方向下窗口的起点X坐标 * usY :在特定扫描方向下窗口的起点Y坐标 * 返 回 值: 无 * 说 明:无 */ static void LCD_SetCursor(uint16_t usX,uint16_t usY) { LCD_OpenWindow(usX,usY,1,1); } /** * 函数功能: 在LCD显示器上以某一颜色填充像素点 * 输入参数: ulAmout_Point :要填充颜色的像素点的总数目 * usColor :颜色 * 返 回 值: 无 * 说 明:无 */ #if defined ( __CC_ARM ) // 使用Keil编译环境 static __inline void LCD_FillColor ( uint32_t ulAmout_Point, uint16_t usColor ) { uint32_t i = 0; /* 开始向GRAM写入数据 */ LCD_WRITE_CMD ( CMD_SetPixel); for ( i = 0; i < ulAmout_Point; i ++ ) LCD_WRITE_DATA ( usColor ); } #elif defined ( __ICCARM__ ) // 使用IAR编译环境 #pragma inline static void LCD_FillColor ( uint32_t ulAmout_Point, uint16_t usColor ) { uint32_t i = 0; /* 开始向GRAM写入数据 */ LCD_WRITE_CMD ( 0x2C ); for ( i = 0; i < ulAmout_Point; i ++ ) LCD_WRITE_DATA ( usColor ); } #endif /** * 函数功能: 对LCD显示器的某一窗口以某种颜色进行清屏 * 输入参数: usX :在特定扫描方向下窗口的起点X坐标 * usY :在特定扫描方向下窗口的起点Y坐标 * usWidth :窗口的宽度 * usHeight :窗口的高度 * usColor :颜色 * 返 回 值: 无 * 说 明:无 */ void LCD_Clear(uint16_t usX,uint16_t usY,uint16_t usWidth,uint16_t usHeight,uint16_t usColor) { #if 0 /* 优化代码执行速度 */ uint32_t i; uint32_t n,m; /* 在LCD显示器上开辟一个窗口 */ LCD_OpenWindow(usX,usY,usWidth,usHeight); /* 开始向GRAM写入数据 */ LCD_WRITE_CMD(0x2C); m=usWidth * usHeight; n=m/8; m=m-8*n; for(i=0;i<n;i++) { LCD_WRITE_DATA(usColor); LCD_WRITE_DATA(usColor); LCD_WRITE_DATA(usColor); LCD_WRITE_DATA(usColor); LCD_WRITE_DATA(usColor); LCD_WRITE_DATA(usColor); LCD_WRITE_DATA(usColor); LCD_WRITE_DATA(usColor); } for(i=0;i<m;i++) { LCD_WRITE_DATA(usColor); } #else /* 在LCD显示器上开辟一个窗口 */ LCD_OpenWindow(usX,usY,usWidth,usHeight); /* 在LCD显示器上以某一颜色填充像素点 */ LCD_FillColor(usWidth*usHeight,usColor); #endif } /** * 函数功能: 对LCD显示器的某一点以某种颜色进行填充 * 输入参数: usX :在特定扫描方向下窗口的起点X坐标 * usY :在特定扫描方向下窗口的起点Y坐标 * usColor :颜色 * 返 回 值: 无 * 说 明:无 */ void LCD_SetPointPixel(uint16_t usX,uint16_t usY,uint16_t usColor) { if((usX<LCD_DEFAULT_WIDTH)&&(usY<LCD_DEFAULT_HEIGTH)) { LCD_OpenWindow(usX,usY,1,1); LCD_FillColor(1,usColor); } } /** * 函数功能: 对LCD显示器的某一点以某种颜色进行填充 * 输入参数: 无 * 返 回 值: uint16_t:像素数据RGB565 * 说 明:无 */ static uint16_t LCD_Read_PixelData ( void ) { uint16_t usR=0, usG=0, usB=0 ; LCD_WRITE_CMD ( 0x2E ); /* 读数据 */ usR = LCD_READ_DATA (); /*FIRST READ OUT DUMMY DATA*/ usR = LCD_READ_DATA (); /*READ OUT RED DATA */ usB = LCD_READ_DATA (); /*READ OUT BLUE DATA*/ usG = LCD_READ_DATA (); /*READ OUT GREEN DATA*/ return (((usR>>11)<<11) | ((usG>>10)<<5) | (usB>>11)); } /** * 函数功能: 获取 LCD 显示器上某一个坐标点的像素数据 * 输入参数: usX :在特定扫描方向下窗口的起点X坐标 * usY :在特定扫描方向下窗口的起点Y坐标 * 返 回 值: uint16_t:像素数据RGB565 * 说 明:无 */ uint16_t LCD_GetPointPixel ( uint16_t usX, uint16_t usY ) { uint16_t usPixelData; LCD_SetCursor ( usX, usY ); usPixelData = LCD_Read_PixelData (); return usPixelData; } /** * 函数功能: 在 LCD 显示器上使用 Bresenham 算法画线段 * 输入参数: usX1 :在特定扫描方向下窗口的起点X坐标 * usY1 :在特定扫描方向下窗口的起点Y坐标 * usX2 :在特定扫描方向下线段的另一个端点X坐标 * usY2 :在特定扫描方向下线段的另一个端点Y坐标 * usColor :线段的颜色 * 返 回 值: 无 * 说 明:无 */ void LCD_DrawLine(uint16_t usX1,uint16_t usY1,uint16_t usX2,uint16_t usY2,uint16_t usColor) { uint16_t us; uint16_t usX_Current, usY_Current; int32_t lError_X=0,lError_Y=0,lDelta_X,lDelta_Y,lDistance; int32_t lIncrease_X, lIncrease_Y; lDelta_X=usX2-usX1; //计算坐标增量 lDelta_Y=usY2-usY1; usX_Current = usX1; usY_Current = usY1; if(lDelta_X>0) { lIncrease_X=1; //设置单步方向 } else if(lDelta_X==0) { lIncrease_X=0;//垂直线 } else { lIncrease_X=-1; lDelta_X=-lDelta_X; } if(lDelta_Y>0) { lIncrease_Y=1; } else if(lDelta_Y==0) { lIncrease_Y=0;//水平线 } else { lIncrease_Y=-1; lDelta_Y=-lDelta_Y; } if(lDelta_X>lDelta_Y) { lDistance=lDelta_X; //选取基本增量坐标轴 } else { lDistance=lDelta_Y; } for(us=0;us<=lDistance+1;us++)//画线输出 { LCD_SetPointPixel(usX_Current,usY_Current,usColor);//画点 lError_X+=lDelta_X; lError_Y+=lDelta_Y; if(lError_X>lDistance) { lError_X-=lDistance; usX_Current+=lIncrease_X; } if(lError_Y>lDistance) { lError_Y-=lDistance; usY_Current+=lIncrease_Y; } } } /** * 函数功能: 在LCD显示器上画一个矩形 * 输入参数: usX_Start :在特定扫描方向下窗口的起点X坐标 * usY_Start :在特定扫描方向下窗口的起点Y坐标 * usWidth:矩形的宽度(单位:像素) * usHeight:矩形的高度(单位:像素) * usColor :矩形的颜色 * ucFilled :选择是否填充该矩形 * 可选值:0:空心矩形 * 1:实心矩形 * 返 回 值: 无 * 说 明:无 */ void LCD_DrawRectangle ( uint16_t usX_Start, uint16_t usY_Start, uint16_t usWidth, uint16_t usHeight, uint16_t usColor, uint8_t ucFilled ) { if(ucFilled) { LCD_Clear ( usX_Start, usY_Start, usWidth, usHeight, usColor); } else { LCD_DrawLine ( usX_Start, usY_Start, usX_Start + usWidth - 1, usY_Start, usColor ); LCD_DrawLine ( usX_Start, usY_Start + usHeight - 1, usX_Start + usWidth - 1, usY_Start + usHeight - 1, usColor ); LCD_DrawLine ( usX_Start, usY_Start, usX_Start, usY_Start + usHeight - 1, usColor ); LCD_DrawLine ( usX_Start + usWidth - 1, usY_Start, usX_Start + usWidth - 1, usY_Start + usHeight - 1, usColor ); } } /** * 函数功能: 在 LCD 显示器上使用 Bresenham 算法画圆 * 输入参数: usX_Center :在特定扫描方向下圆心的X坐标 * usY_Center :在特定扫描方向下圆心的Y坐标 * usRadius:圆的半径(单位:像素) * usColor :圆的颜色 * ucFilled :选择是否填充该圆 * 可选值:0:空心圆 * 1:实心圆 * 返 回 值: 无 * 说 明:无 */ void LCD_DrawCircle(uint16_t usX_Center,uint16_t usY_Center,uint16_t usRadius,uint16_t usColor,uint8_t ucFilled) { int16_t sCurrentX, sCurrentY; int16_t sError; sCurrentX=0; sCurrentY=usRadius; sError=3-(usRadius<<1); //判断下个点位置的标志 while(sCurrentX<=sCurrentY) { int16_t sCountY; if(ucFilled) { for(sCountY=sCurrentX;sCountY<=sCurrentY;sCountY++) { LCD_SetPointPixel(usX_Center+sCurrentX,usY_Center+sCountY,usColor); //1,研究对象 LCD_SetPointPixel(usX_Center-sCurrentX,usY_Center+sCountY,usColor); //2 LCD_SetPointPixel(usX_Center-sCountY, usY_Center+sCurrentX,usColor); //3 LCD_SetPointPixel(usX_Center-sCountY, usY_Center-sCurrentX,usColor); //4 LCD_SetPointPixel(usX_Center-sCurrentX,usY_Center-sCountY,usColor); //5 LCD_SetPointPixel(usX_Center+sCurrentX,usY_Center-sCountY,usColor); //6 LCD_SetPointPixel(usX_Center+sCountY, usY_Center-sCurrentX,usColor); //7 LCD_SetPointPixel(usX_Center+sCountY, usY_Center+sCurrentX,usColor); //0 } } else { LCD_SetPointPixel(usX_Center+sCurrentX,usY_Center+sCurrentY,usColor); //1,研究对象 LCD_SetPointPixel(usX_Center-sCurrentX,usY_Center+sCurrentY,usColor); //2 LCD_SetPointPixel(usX_Center-sCurrentY,usY_Center+sCurrentX,usColor); //3 LCD_SetPointPixel(usX_Center-sCurrentY,usY_Center-sCurrentX,usColor); //4 LCD_SetPointPixel(usX_Center-sCurrentX,usY_Center-sCurrentY,usColor); //5 LCD_SetPointPixel(usX_Center+sCurrentX,usY_Center-sCurrentY,usColor); //6 LCD_SetPointPixel(usX_Center+sCurrentY,usY_Center-sCurrentX,usColor); //7 LCD_SetPointPixel(usX_Center+sCurrentY,usY_Center+sCurrentX,usColor); //0 } sCurrentX ++; if(sError<0) { sError+=(4*sCurrentX+6); } else { sError +=(10+4*(sCurrentX-sCurrentY)); sCurrentY--; } } } /** * 函数功能: 在 LCD 显示器上显示一个英文字符 * 输入参数: usX:在特定扫描方向下字符的起始X坐标 * usY :在特定扫描方向下该点的起始Y坐标 * cChar :要显示的英文字符 * usColor_Background :选择英文字符的背景色 * usColor_Foreground :选择英文字符的前景色 * font:字体选择 * 参数:USE_FONT_16 :16号字体 * USE_FONT_24 :24号字体 * 返 回 值: 无 * 说 明:该函数必须与ascii.h内容对应使用 */ void LCD_DispChar_EN( uint16_t usX, uint16_t usY, const char cChar, uint16_t usColor_Background, uint16_t usColor_Foreground,USE_FONT_Typdef font) { uint8_t ucTemp, ucRelativePositon, ucPage, ucColumn; /* 检查输入参数是否合法 */ assert_param(IS_USE_FONT(font)); ucRelativePositon = cChar - ' '; if(font==USE_FONT_16) { LCD_OpenWindow(usX,usY,8,16); LCD_WRITE_CMD(0x2C); for(ucPage=0;ucPage<16;ucPage++) { ucTemp=ucAscii_1608[ucRelativePositon][ucPage]; for(ucColumn=0;ucColumn<8;ucColumn++) { if(ucTemp&0x01) LCD_WRITE_DATA(usColor_Foreground); else LCD_WRITE_DATA(usColor_Background); ucTemp >>= 1; } } } else { LCD_OpenWindow(usX,usY,12,24); LCD_WRITE_CMD(0x2C); for(ucPage=0;ucPage<48;ucPage++) { ucTemp=ucAscii_2412[ucRelativePositon][ucPage]; for(ucColumn=0;ucColumn<8;ucColumn++) { if(ucTemp&0x01) LCD_WRITE_DATA(usColor_Foreground); else LCD_WRITE_DATA(usColor_Background); ucTemp >>= 1; } ucPage++; ucTemp=ucAscii_2412[ucRelativePositon][ucPage]; /* 只显示前面4个位,与上面8位总共12位 */ for(ucColumn=0;ucColumn<4;ucColumn++) { if(ucTemp&0x01) LCD_WRITE_DATA(usColor_Foreground); else LCD_WRITE_DATA(usColor_Background); ucTemp >>= 1; } } } } /** * 函数功能: 在 LCD 显示器上显示英文字符串 * 输入参数: usX:在特定扫描方向下字符的起始X坐标 * usY :在特定扫描方向下该点的起始Y坐标 * pStr :要显示的英文字符串的首地址 * usColor_Background :选择英文字符的背景色 * usColor_Foreground :选择英文字符的前景色 * font:字体选择 * 参数:USE_FONT_16 :16号字体 * USE_FONT_24 :24号字体 * 返 回 值: 无 * 说 明:该函数必须与ascii.h内容对应使用 void LCD_DispString_EN ( uint16_t usX, uint16_t usY, const char * pStr, uint16_t usColor_Background, uint16_t usColor_Foreground,USE_FONT_Typdef font) { /* 检查输入参数是否合法 */ assert_param(IS_USE_FONT(font)); while ( * pStr != '\0' ) { if(font==USE_FONT_16) { if ( ( usX + 8 ) > LCD_DEFAULT_WIDTH ) { usX = 0; usY += 16; } if ( ( usY + 16 ) > LCD_DEFAULT_HEIGTH ) { usX = 0; usY = 0; } LCD_DispChar_EN ( usX, usY, * pStr, usColor_Background, usColor_Foreground,font); pStr ++; usX += 8; } else { if ( ( usX + 12 ) > LCD_DEFAULT_WIDTH ) { usX = 0; usY += 24; } if ( ( usY + 24 ) > LCD_DEFAULT_HEIGTH ) { usX = 0; usY = 0; } LCD_DispChar_EN ( usX, usY, * pStr, usColor_Background, usColor_Foreground,font); pStr ++; usX += 12; } } } */
LCD-BSP.h
#ifndef __LCD_BSP_H__ #define __LCD_BSP_H__ /* 包含头文件 ----------------------------------------------------------------*/ #include "stm32f1xx_hal.h" /* 类型定义 ------------------------------------------------------------------*/ typedef enum { USE_FONT_16=16, USE_FONT_24=24, }USE_FONT_Typdef; #define IS_USE_FONT(FONT) (((FONT) == USE_FONT_16) || ((FONT) == USE_FONT_24)) #define DEBUG_DELAY() #define CMD_SetCoordinateX 0x2A //设置X坐标 #define CMD_SetCoordinateY 0x2B //设置Y坐标 #define CMD_SetPixel 0x2C //填充像素 /* 宏定义 --------------------------------------------------------------------*/ /****************************************************************************** 2^26 =0X0400 0000 = 64MB,每个 BANK 有4*64MB = 256MB 64MB:FSMC_Bank1_NORSRAM1:0X6000 0000 ~ 0X63FF FFFF 64MB:FSMC_Bank1_NORSRAM2:0X6400 0000 ~ 0X67FF FFFF 64MB:FSMC_Bank1_NORSRAM3:0X6800 0000 ~ 0X6BFF FFFF 64MB:FSMC_Bank1_NORSRAM4:0X6C00 0000 ~ 0X6FFF FFFF *******************************************************************************/ /******************************* ILI9341 显示屏的 FSMC 参数定义 ***************/ #define FSMC_LCD_CMD ( ( uint32_t ) 0x60000000 ) //FSMC_Bank1_NORSRAM1用于LCD命令操作的地址 #define FSMC_LCD_DATA ( ( uint32_t ) 0x60020000 ) //FSMC_Bank1_NORSRAM1用于LCD数据操作的地址 #define LCD_WRITE_CMD(x) *(__IO uint16_t *)FSMC_LCD_CMD = x #define LCD_WRITE_DATA(x) *(__IO uint16_t *)FSMC_LCD_DATA = x #define LCD_READ_DATA() *(__IO uint16_t *)FSMC_LCD_DATA #define FSMC_LCD_BANKx FSMC_NORSRAM_BANK1 /************************* ILI9341 显示屏8080通讯引脚定义 *********************/ #define FSMC_LCD_CS_GPIO_ClK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() #define FSMC_LCD_CS_PORT GPIOD #define FSMC_LCD_CS_PIN GPIO_PIN_7 #define FSMC_LCD_DC_GPIO_ClK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() #define FSMC_LCD_DC_PORT GPIOD #define FSMC_LCD_DC_PIN GPIO_PIN_11 #define FSMC_LCD_BK_GPIO_ClK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() #define FSMC_LCD_BK_PORT GPIOD #define FSMC_LCD_BK_PIN GPIO_PIN_12 //写使能 #define ILI9341_WR_CLK __HAL_RCC_GPIOD_CLK_ENABLE() #define ILI9341_WR_PORT GPIOD #define ILI9341_WR_PIN GPIO_PIN_5 //读使能 #define ILI9341_RD_CLK __HAL_RCC_GPIOD_CLK_ENABLE() #define ILI9341_RD_PORT GPIOD #define ILI9341_RD_PIN GPIO_PIN_4 //复位引脚 #define ILI9341_RST_CLK __HAL_RCC_GPIOD_CLK_ENABLE() #define ILI9341_RST_PORT GPIOE #define ILI9341_RST_PIN GPIO_PIN_1 #define LCD_BK_ON() HAL_GPIO_WritePin(FSMC_LCD_BK_PORT, FSMC_LCD_BK_PIN, GPIO_PIN_SET); #define LCD_BK_OFF() HAL_GPIO_WritePin(FSMC_LCD_BK_PORT, FSMC_LCD_BK_PIN, GPIO_PIN_RESET); /**************** 显示方向选择,可选(1,2,3,4)四个方向 *************************/ #define LCD_DIRECTION 6 // 原点在屏幕左上角 X*Y=320*480 //#define LCD_DIRECTION 2 // 原点在屏幕右上角 X*Y=480*320 //#define LCD_DIRECTION 3 // 原点在屏幕右下角 X*Y=320*480 //#define LCD_DIRECTION 4 // 原点在屏幕左下角 X*Y=480*320 /******** ILI934 显示屏全屏默认(扫描方向为1时)最大宽度和最大高度*************/ #if (LCD_DIRECTION==1)||(LCD_DIRECTION==3) #define LCD_DEFAULT_WIDTH 240 // X轴长度 #define LCD_DEFAULT_HEIGTH 320 // Y轴长度 #else #define LCD_DEFAULT_WIDTH 240 // X轴长度 #define LCD_DEFAULT_HEIGTH 320 // Y轴长度 #endif #define ILI9341_LESS_PIXEL 240 //液晶屏较短方向的像素宽度 #define ILI9341_MORE_PIXEL 320 //液晶屏较长方向的像素宽度 /******************************* 定义 ILI9488 显示屏常用颜色 ********************************/ #define BACKGROUND WHITE //默认背景颜色 extern uint8_t LCD_SCAN_MODE; #define WHITE 0xFFFF //白色 #define BLACK 0x0000 //黑色 #define GREY 0xF7DE //灰色 #define BLUE 0x001F //蓝色 #define BLUE2 0x051F //浅蓝色 #define RED 0xF800 //红色 #define MAGENTA 0xF81F //红紫色,洋红色 #define GREEN 0x07E0 //绿色 #define CYAN 0x7FFF //蓝绿色,青色 #define YELLOW 0xFFE0 //黄色 #define BRED 0xF81F #define GRED 0xFFE0 #define GBLUE 0x07FF /* 扩展变量 ------------------------------------------------------------------*/ extern SRAM_HandleTypeDef hlcd; /* 函数声明 ------------------------------------------------------------------*/ uint32_t BSP_LCD_Init(void); void LCD_SetDirection(uint8_t ucOtion); void LCD_OpenWindow(uint16_t usX,uint16_t usY,uint16_t usWidth,uint16_t usHeight); void LCD_Clear(uint16_t usX,uint16_t usY,uint16_t usWidth,uint16_t usHeight,uint16_t usColor); void LCD_SetPointPixel(uint16_t usX,uint16_t usY,uint16_t usColor); uint16_t LCD_GetPointPixel(uint16_t usX,uint16_t usY); void LCD_DrawLine(uint16_t usX1,uint16_t usY1,uint16_t usX2,uint16_t usY2,uint16_t usColor); void LCD_DrawRectangle(uint16_t usX_Start,uint16_t usY_Start, uint16_t usWidth,uint16_t usHeight,uint16_t usColor,uint8_t ucFilled); void LCD_DrawCircle(uint16_t usX_Center,uint16_t usY_Center,uint16_t usRadius,uint16_t usColor,uint8_t ucFilled); void LCD_DispChar_EN(uint16_t usX,uint16_t usY,const char cChar,uint16_t usColor_Background,uint16_t usColor_Foreground,USE_FONT_Typdef font); void LCD_DispString_EN(uint16_t usX,uint16_t usY,const char *pStr,uint16_t usColor_Background,uint16_t usColor_Foreground,USE_FONT_Typdef font); /********************************** 声明 ILI934 函数 ***************************************/ void ILI9341_Init ( void ); void ILI9341_Rst ( void ); void ILI9341_BackLed_Control ( FunctionalState enumState ); void ILI9341_GramScan ( uint8_t ucOtion ); void ILI9341_OpenWindow ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight ); void ILI9341_Clear ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight ); void ILI9341_SetPointPixel ( uint16_t usX, uint16_t usY ); uint16_t ILI9341_GetPointPixel ( uint16_t usX , uint16_t usY ); void ILI9341_DrawLine ( uint16_t usX1, uint16_t usY1, uint16_t usX2, uint16_t usY2 ); void ILI9341_DrawRectangle ( uint16_t usX_Start, uint16_t usY_Start, uint16_t usWidth, uint16_t usHeight,uint8_t ucFilled ); void ILI9341_DrawCircle ( uint16_t usX_Center, uint16_t usY_Center, uint16_t usRadius, uint8_t ucFilled ); void ILI9341_DispChar_EN ( uint16_t usX, uint16_t usY, const char cChar ); void ILI9341_DispStringLine_EN ( uint16_t line, char * pStr ); void ILI9341_DispString_EN ( uint16_t usX, uint16_t usY, char * pStr ); void ILI9341_DispString_EN_YDir ( uint16_t usX,uint16_t usY , char * pStr ); void LCD_ClearLine (uint16_t Line); void LCD_SetBackColor (uint16_t Color); void LCD_SetTextColor (uint16_t Color) ; void LCD_SetColors (uint16_t TextColor, uint16_t BackColor); void LCD_GetColors (uint16_t *TextColor, uint16_t *BackColor); #endif /* __LCD_BSP_H__ */
main.c
#include "stm32f1xx_hal.h" #include "usart/bsp_debug_usart.h" #include "lcd/bsp_lcd.h" #include "stdlib.h" /* 私有类型定义 --------------------------------------------------------------*/ /* 私有宏定义 ----------------------------------------------------------------*/ /* 私有变量 ------------------------------------------------------------------*/ /* 扩展变量 ------------------------------------------------------------------*/ /* 私有函数原形 --------------------------------------------------------------*/ /* 函数体 --------------------------------------------------------------------*/ /** * 函数功能: 系统时钟配置 * 输入参数: 无 * 返 回 值: 无 * 说 明: 无 */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; // 外部晶振,8MHz RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 9倍频,得到72MHz主时钟 HAL_RCC_OscConfig(&RCC_OscInitStruct); RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 系统时钟:72MHz RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // AHB时钟:72MHz RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // APB1时钟:36MHz RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // APB2时钟:72MHz HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); // HAL_RCC_GetHCLKFreq()/1000 1ms中断一次 // HAL_RCC_GetHCLKFreq()/100000 10us中断一次 // HAL_RCC_GetHCLKFreq()/1000000 1us中断一次 HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); // 配置并启动系统滴答定时器 /* 系统滴答定时器时钟源 */ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); /* 系统滴答定时器中断优先级配置 */ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); } /** * 函数功能: 主函数. * 输入参数: 无 * 返 回 值: 无 * 说 明: 无 */ int main(void) { uint32_t lcdid; uint16_t color; /* 复位所有外设,初始化Flash接口和系统滴答定时器 */ // HAL_Init(); /* 配置系统时钟 */ SystemClock_Config(); /* 初始化3.5寸TFT液晶模组,一般优先于调试串口初始化 */ lcdid=BSP_LCD_Init(); /* 调用格式化输出函数打印输出数据 */ // printf("LCD ID=0x%08X\n",lcdid); LCD_Clear(0,0,LCD_DEFAULT_WIDTH,LCD_DEFAULT_HEIGTH,BLUE); /* 开背光 */ // LCD_BK_OFF(); /* 初始化随机种子 */ srand(0xffff); /* 无限循环 */ while (1) { HAL_Delay(1000); /* 获取随机数 */ color=rand(); LCD_Clear(0,0,LCD_DEFAULT_WIDTH,LCD_DEFAULT_HEIGTH,color); } }
用于驱动ILI9341屏幕的HAL库驱动,由标准库ILI9341驱动修改而来,可用于驱动使用FSMC接口8080时序的ILI9341屏幕,以及包含相关的屏幕操作函数,可以方便的在main入口函数中调用,达到显示的效果。