SRAM
本文展示了STM32 SRAM 内存扩展管理
内容涉及 :
内容涉及对 FSMC 的控制
SRAM 内存扩展管理
FatFs 文件系统移植
SPI函数移植过程
SPI字节数据模拟输出独写 缓存读写
USART串口的识别
IO口输入输出
按键的外部中断处理
32位数据通讯,字符串通讯,单字符通讯
完整代码 : GIT 代码下载
下图为通讯建立的过程:
文章目录
- 前言
- 一、 编程要点
- 二、使用步骤
- --理解原理图
- (注意)Keil 配置状态
- 建立主程序 main.c
- 建立 LCD驱动 管理文件LCD_book.h
- 建立 LCD驱动 管理文件LCD_book.c
- 建立 LCD 绘制函数文件LCD_Draw_book.h
- 建立 LCD 绘制文件LCD_Draw_book.c
- 建立 LCD页面绘制 文件LCD_PageHtml_book.h
- 建立 LCD页面绘制 文件LCD_PageHtml_book.c
- 建立 LCD 文字库 内存管理文件fonts.h
- 建立 LCD 文字库 内存管理文件fonts.c
- 建立 SRAM 内存管理文件SRAM_book.h
- 建立 SRAM 内存管理文件SRAM_book.c
- 整改 系统文件diskio.c
- 修改头文件文件diskio.h
- 建立FatFs传输的 头文件 FatFs_book.h
- 建立FatFs传输的 头文件 FatFs_book.c
- 建立SPI传输的 头文件 SPI_book.h
- 建立SPI传输的 头文件 SPI_book.c
- 建立I2C模拟传输的 头文件 I2C_soft_book.h
- 建立I2C模拟传输的 头文件 I2C_soft_book.c
- 建立I2C硬件传输的 头文件 I2C_book.h
- 建立I2C硬件传输的 头文件 I2C_book.c
- 建立USART传输的 头文件 USART_book.h
- 建立USART传输的C文件 USART_book.c
- 建立DMA传输的 头文件 DMA_book.h
- 建立DMA传输的C文件 DMA_book.c
- 建立EXIT的 头文件 Exit_book.h
- 建立EXIT的C文件 Exit_book.c
- 建立Key传输的 头文件 Key_book.h
- 建立Key的C文件 Key_book.c
前言
STM32F1 系列的芯片由于没有集成液晶控制器到芯片内部, 所以它只能驱动自带控制器的屏幕,
本液晶屏内部包含有一个液晶控制芯片 ILI9341,它的内部结构非常复杂,见图 28-12。 该芯片最主核心部分是位于中间的 GRAM(Graphics RAM),它就是显存。GRAM 中每个存储单元都对应着液晶面板的一个像素点。它右侧的各种模块共同作用把 GRAM 存储单元的数据转化成液晶面板的控制信号,使像素点呈现特定的颜色,而像素点组合起来则成为一幅完整的图像。框图的左上角为 ILI9341 的主要控制信号线和配置引脚,根据其不同状态设置可以使芯片工作在不同的模式,如每个像素点的位数是 6、16 还是 18 位;可配置使用 SPI 接口、8080 接口还是 RGB 接口与 MCU 进行通讯。MCU 通过 SPI、8080 接口或 RGB 接口与ILI9341 进行通讯,从而访问它的控制寄存器(CR)、地址计数器(AC)、及 GRAM。 在 GRAM 的左侧还有一个 LED 控制器(LED Controller)。LCD 为非发光性的显示装置,它需要借助背光源才能达到显示功能,LED 控制器就是用来控制液晶屏中的 LED 背光源。
由图可知,写命令时序由片选信号 CSX 拉低开始,对数据/命令选择信号线 D/CX 也置低电平表示写入的是命令地址(可理解为命令编码,如软件复位命令:0x01),以写信号WRX 为低,读信号 RDX 为高表示数据传输方向为写入,同时,在数据线 D17:0输出命令地址,在第二个传输阶段传送的是命令的参数,所以 D/CX 要置高电平,表示写入的是命令数据,命令数据是某些指令带有的参数,如复位指令编码为 0x01,它后面可以带一个参数,该参数表示多少秒后复位(实际的复位命令不含参数,此处只是为了讲解指令编码与参数的区别)。当需要把像素数据写入 GRAM 时,过程很类似,把片选信号 CSX 拉低后,再把数据/命令选择信号线 D/CX 置为高电平,这时由 D[17:0]传输的数据则会被 ILI9341 保存至它的GRAM 中。
对比 FSMC NOR/PSRAM 中的模式 B 时序与 ILI9341 液晶控制器芯片使用的 8080 时序可发现,这两个时序是十分相似的(除了 FSMC 的地址线 A 和 8080 的 D/CX 线,可以说是完全一样)
对于 FSMC 和 8080 接口,前四种信号线都是完全一样的,仅仅是 FSMC 的地址信号线 A[25:0]与 8080 的数据/命令选择线 D/CX 有区别。而对于 D/CX 线,它为高电平的时候表示数值,为低电平的时候表示命令,如果能使用 FSMC 的 A 地址线根据不同的情况产生对应的电平,那么就完全可以使用 FSMC 来产生 8080 接口需要的时序了。为了模拟出 8080 时序,我们可以把 FSMC 的 A0 地址线(也可以使用其它 A1/A2 等地址线)与 ILI9341 芯片 8080 接口的 D/CX 信号线连接,那么当 A0 为高电平时(即 D/CX 为高电平),数据线 D[15:0]的信号会被 ILI9341 理解为数值,若 A0 为低电平时(即 D/CX 为低电平),传输的信号则会被理解为命令。由于 FSMC 会自动产生地址信号,当使用 FSMC 向 0x6xxx xxx1、0x6xxx xxx3、
0x6xxx xxx5„这些奇数地址写入数据时,地址最低位的值均为 1,所以它会控制地址线A0(D/CX)输出高电平,那么这时通过数据线传输的信号会被理解为数值;若向 0x6xxx xxx0 、0x6xxx xxx2、0x6xxx xxx4„这些偶数地址写入数据时,地址最低位的值均为 0,所 以它会控制地址线 A0(D/CX)输出低电平,因此这时通过数据线传输的信号会被理解为命令,
一、 编程要点
(1) 初始化通讯使用的目标引脚及端口时钟;(2) 使能 FSMC 外设的时钟;
(3) 配置 FSMC 为异步 NOR FLASH 模式以仿真 8080 时序;
(4) 建立机制使用 FSMC 向液晶屏发送命令及数据;
(5) 发送控制命令初始化液晶屏;
(6) 编写液晶屏的绘制像素点函数;
(7) 利用描点函数制作各种不同的液晶显示应用。
二、使用步骤
–理解原理图
液晶排母接口原理图,它说明了配套的 3.2 寸屏幕接入到开发板上时的信号连接关系。其中请着重关注图中液晶屏 LCD_CS 及 LCD_RS(即 DC 引脚) 与 FSMC 存储区选择引脚 FSMC_NE 及地址信号 FSMC_A 的编号,
(注意)Keil 配置状态
我的博客这里有项目配置 设计;
点击链接
(https://blog.csdn.net/u012651389/article/details/119189949)
建立主程序 main.c
代码如下 :
/*******************************************************************************
* @file GPIO/JTAG_Remap/main.c
* @author MCD Application Team
* @version V3.5.0
* @date 08-April-2011
* @brief Main program body
******************************************************************************
* @attention
*
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "PROJ_book.h"
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program.
* @param None
* @retval None
*/
void fn_LED_Flash_Init(void);
void fn_usart_show_Init(void);
void fn_DMA_show_Init(void);
void fn_I2C_EE_Init(void);
void fn_I2C_EE_Soft_Init(void);
void fn_SPI_FLASH_Soft_Init(void);
void fn_FatFs_Document_Init(void);
void fn_SRAM_Init(void);
#define countof(a) (sizeof(a) / sizeof(*(a)))
#define _I2C_BufferSize (countof(writeData)-1)
static uint8_t writeData[_I2C_PageSize]={4,5,6,7,8,9,10,11};
static uint8_t writeData2[_I2C_PageSize]={24,25,26,27,28,29,30,31};
static uint8_t ReadData[_I2C_BufferSize]={0};
#define _SPI_BufferSize SPI_PAGE_SIZE //(countof(write_SPI_Data)-1)
static uint8_t write_SPI_Data[_SPI_BufferSize]={0};
static uint8_t Read_SPI_Data[_SPI_BufferSize]={0};
int main(void)
{
__IO int16_t int_check;
//*************系统接口初始化**************
fn_RCC_Init(); //CPU 倍频
fn_Led_Init(); //LED 输出初始化
fn_Key_Init(); //按键 输入初始化
//*************显示系统初始化**************
int_check = (__IO int16_t)ILI9341_Init();
fn_USART_Init(); //串口输出初始化
printf("\n\n\r\n********** IC系统开始运行 **********\r\n");
switch(int_check){
case 0x05:
printf("\n-->LCD 运行正常");
break;
default:
printf("\n-->LCD 运行异常");
}
//*************功能系统初始化**************
fn_LED_Flash_Init(); //RGB 输出测试
fn_usart_show_Init(); //串口输出测试
fn_EXTI_GPIO_Config(); //外部中断入口
fn_DMA_show_Init(); //初始化DMA数据链路
fn_I2C_EE_Init(); //初始化硬件I2C数据链路
fn_I2C_EE_Soft_Init(); //初始化软件I2C数据链路
fn_SPI_FLASH_Soft_Init(); //SPI测试通讯
fn_FatFs_Document_Init(); //FatFs文件读取测试
fn_SRAM_Init(); //SRAM文件读取测试
//************* LCD页面初始化**************
Display_Char_test();
fn_Lcd_Page1();
while(1){
fn_LED_ALL_OFF();
fn_Systick_Delay(500,_Systick_ms);
__G_OUT__;
fn_Systick_Delay(500,_Systick_ms);
}
}
//======================================================================
//======================================================================
void fn_LED_Flash_Init(void){
uint16_t count_Init = 2;
printf("\n ---> LED开始运行 \n");
while(count_Init-->0){
fn_LED_ALL_OFF();
__R_OUT__;
fn_Systick_Delay(500,_Systick_ms);
fn_LED_ALL_OFF();
__G_OUT__;
fn_Systick_Delay(500,_Systick_ms);
fn_LED_ALL_OFF();
__B_OUT__;
fn_Systick_Delay(500,_Systick_ms);
fn_LED_ALL_OFF();
__R_OUT__;
}
}
//======================================================================
//======================================================================
void fn_usart_show_Init(void){
fn_Usart_Send_Byte(_DEBUG_USARTx,'\r');
printf("-->串口通信指测试完毕 \n");
fn_Usart_SendString(_DEBUG_USARTx," : wangqi \n");
}
//======================================================================
//======================================================================
void fn_DMA_show_Init(void){
printf("\n ---> DMA开始运行 \n");
_DMA_ROM_TO_RAM(Map_BUFFER_SIZE ,aSRC_Cont_Buffer , aDST_Buffer);
_DMA_RAM_TO_USART(Map_BUFFER_SIZE ,USART_Source_ADDR , aDST_Buffer);
printf("---> DMA运行完毕 \n");
}
//======================================================================
//======================================================================
void fn_I2C_EE_Init(void){
printf("\n-->I2C_函数写入开始 \n");
_I2C_EE_Init();
I2C_Write_fun(writeData ,EEP_Firstpage ,_I2C_BufferSize);
I2C_Read_fun(ReadData ,EEP_Firstpage ,_I2C_BufferSize);
printf("--->I2C_函数写入完毕\n\r");
}
//======================================================================
//======================================================================
void fn_I2C_EE_Soft_Init(void){
printf("\n-->I2C_软件函数写入开始 \n");
I2C_Soft_Init();
I2C_Soft_Write_fun(writeData2 ,EEP_Firstpage ,_I2C_BufferSize);
I2C_Soft_Read_fun(ReadData ,EEP_Firstpage ,_I2C_BufferSize);
printf("\n--->I2C_软件函数写入完毕\n\r");
}
//======================================================================
//======================================================================
void fn_SPI_FLASH_Soft_Init(void){
uint16_t i,FlashID;
printf("-->SPI通信指测试开始 \n");
SPI_FLASH_Init();
FlashID = SPI_Read_ID() ;
if(FlashID == _SPI_FLASH_ID){
printf("-->SPI 0x%x \n",FlashID);
}
SPI_Erase_Sector(0); //清除一个页的空间
printf("\n\n-->SPI清空开始 \n");
SPI_Read_Data(Read_SPI_Data , 0, SPI_PAGE_SIZE);
SPI_Show_Data(Read_SPI_Data , SPI_PAGE_SIZE);
printf("\n\n-->SPI清空完成 \n");
for(i=0 ; i < _SPI_BufferSize ; i++){
write_SPI_Data[i] = 0xA7;
}
SPI_Show_Data(write_SPI_Data , SPI_PAGE_SIZE);
SPI_BufferWrite_Data(write_SPI_Data ,0x000000,_SPI_BufferSize);
printf("\n\n-->SPI输入完成 \n");
SPI_Read_Data(Read_SPI_Data , 0x000000, _SPI_BufferSize);
SPI_Show_Data(Read_SPI_Data , _SPI_BufferSize);
printf("-->SPI通信指测试完毕 \n");
}
//======================================================================
//======================================================================
void fn_FatFs_Document_Init(void){
/*----------------------- 格式化测试 -----------------*/
FatFs_equipment_flash("1:");
/*----------------------- 文件系统读写测试 -------------------*/
FatFs_document_Text(FileTest_ADDR_Buffer_Document, "Wangqi加油!\n" );
/*----------------------- 文件具体内容识别 -------------------*/
file_check(FileTest_ADDR_Buffer_Document);
/*----------------------- 文件目录更改测试 -------------------*/
FatFs_document_set_content(FileTest_ADDR_Buffer_Document , FileTest_ADDR_Buffer_path , FileTest_ADDR_Buffer_NewDocument2);
/*----------------------- 文件具体内容识别 -------------------*/
file_check(FileTest_ADDR_Buffer_NewDocument2);
/*----------------------- 文件目录查找识别 -------------------*/
Scan_file_Check("1:");
/*----------------------- 完成操作 -------------------*/
FatFs_Close_flash("1:");
}
//======================================================================
//======================================================================
void fn_SRAM_Init(void){ //SRAM文件读取测试
printf("********** SRAM_扩展内存测试 ********** \n");
printf("-->外部SRAM_内存函数初始化开始 \n");
SRAM_Init();
printf("\n-->外部SRAM_内存函数测试开始 \n");
SRAM_Test();
printf("\n-->外部SRAM_内存函数写入开始 \n");
SRAM_Write();
}
//======================================================================
//======================================================================
void delay(int x){
int y = 0xFFFFF;
while((x--)>0){
while((y--)>0){
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
}
}
}
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
建立 LCD驱动 管理文件LCD_book.h
代码如下 :
#ifndef __LCD_BOOK_H
#define __LCD_BOOK_H
#include "stm32f10x.h"
/***************************************************************************************
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
选择BANK1-BORSRAM4 连接 TFT,地址范围为0X6C00 0000 ~ 0X6FFF FFFF
FSMC_A23 接LCD的DC(寄存器/数据选择)脚
寄存器基地址 = 0X6C00 0000
RAM基地址 = 0X6D00 0000 = 0X6C00 0000+2^23*2 = 0X6C00 0000 + 0X100 0000 = 0X6D00 0000
当选择不同的地址线时,地址要重新计算
****************************************************************************************/
/******************************* ILI9341 显示屏的 FSMC 参数定义 ***************************/
//FSMC_Bank1_NORSRAM用于LCD命令操作的地址
#define FSMC_Addr_ILI9341_CMD ( ( uint32_t ) 0x6C000000 )
//FSMC_Bank1_NORSRAM用于LCD数据操作的地址
#define FSMC_Addr_ILI9341_DATA ( ( uint32_t ) 0x6D000000 )
//由片选引脚决定的NOR/SRAM块
#define FSMC_Bank1_NORSRAMx FSMC_Bank1_NORSRAM4
/******************************* ILI9341 显示屏8080通讯引脚定义 ***************************/
/******控制信号线******/
//片选,选择NOR/SRAM块
#define ILI9341_CS_CLK RCC_APB2Periph_GPIOG
#define ILI9341_CS_PORT GPIOG
#define ILI9341_CS_PIN GPIO_Pin_12
//DC引脚,使用FSMC的地址信号控制,本引脚决定了访问LCD时使用的地址
//PE2为FSMC_A23
#define ILI9341_DC_CLK RCC_APB2Periph_GPIOE
#define ILI9341_DC_PORT GPIOE
#define ILI9341_DC_PIN GPIO_Pin_2
//写使能
#define ILI9341_WR_CLK RCC_APB2Periph_GPIOD
#define ILI9341_WR_PORT GPIOD
#define ILI9341_WR_PIN GPIO_Pin_5
//读使能
#define ILI9341_RD_CLK RCC_APB2Periph_GPIOD
#define ILI9341_RD_PORT GPIOD
#define ILI9341_RD_PIN GPIO_Pin_4
//复位引脚
#define ILI9341_RST_CLK RCC_APB2Periph_GPIOG
#define ILI9341_RST_PORT GPIOG
#define ILI9341_RST_PIN GPIO_Pin_11
//背光引脚
#define ILI9341_BK_CLK RCC_APB2Periph_GPIOG
#define ILI9341_BK_PORT GPIOG
#define ILI9341_BK_PIN GPIO_Pin_6
/********数据信号线***************/
#define ILI9341_D0_CLK RCC_APB2Periph_GPIOD
#define ILI9341_D0_PORT GPIOD
#define ILI9341_D0_PIN GPIO_Pin_14
#define ILI9341_D1_CLK RCC_APB2Periph_GPIOD
#define ILI9341_D1_PORT GPIOD
#define ILI9341_D1_PIN GPIO_Pin_15
#define ILI9341_D2_CLK RCC_APB2Periph_GPIOD
#define ILI9341_D2_PORT GPIOD
#define ILI9341_D2_PIN GPIO_Pin_0
#define ILI9341_D3_CLK RCC_APB2Periph_GPIOD
#define ILI9341_D3_PORT GPIOD
#define ILI9341_D3_PIN GPIO_Pin_1
#define ILI9341_D4_CLK RCC_APB2Periph_GPIOE
#define ILI9341_D4_PORT GPIOE
#define ILI9341_D4_PIN GPIO_Pin_7
#define ILI9341_D5_CLK RCC_APB2Periph_GPIOE
#define ILI9341_D5_PORT GPIOE
#define ILI9341_D5_PIN GPIO_Pin_8
#define ILI9341_D6_CLK RCC_APB2Periph_GPIOE
#define ILI9341_D6_PORT GPIOE
#define ILI9341_D6_PIN GPIO_Pin_9
#define ILI9341_D7_CLK RCC_APB2Periph_GPIOE
#define ILI9341_D7_PORT GPIOE
#define ILI9341_D7_PIN GPIO_Pin_10
#define ILI9341_D8_CLK RCC_APB2Periph_GPIOE
#define ILI9341_D8_PORT GPIOE
#define ILI9341_D8_PIN GPIO_Pin_11
#define ILI9341_D9_CLK RCC_APB2Periph_GPIOE
#define ILI9341_D9_PORT GPIOE
#define ILI9341_D9_PIN GPIO_Pin_12
#define ILI9341_D10_CLK RCC_APB2Periph_GPIOE
#define ILI9341_D10_PORT GPIOE
#define ILI9341_D10_PIN GPIO_Pin_13
#define ILI9341_D11_CLK RCC_APB2Periph_GPIOE
#define ILI9341_D11_PORT GPIOE
#define ILI9341_D11_PIN GPIO_Pin_14
#define ILI9341_D12_CLK RCC_APB2Periph_GPIOE
#define ILI9341_D12_PORT GPIOE
#define ILI9341_D12_PIN GPIO_Pin_15
#define ILI9341_D13_CLK RCC_APB2Periph_GPIOD
#define ILI9341_D13_PORT GPIOD
#define ILI9341_D13_PIN GPIO_Pin_8
#define ILI9341_D14_CLK RCC_APB2Periph_GPIOD
#define ILI9341_D14_PORT GPIOD
#define ILI9341_D14_PIN GPIO_Pin_9
#define ILI9341_D15_CLK RCC_APB2Periph_GPIOD
#define ILI9341_D15_PORT GPIOD
#define ILI9341_D15_PIN GPIO_Pin_10
/*************************************** 调试预用 ******************************************/
#define DEBUG_DELAY()
/******************************* 定义 ILI934 常用命令 ********************************/
#define CMD_SetCoordinateX 0x2A //设置X坐标
#define CMD_SetCoordinateY 0x2B //设置Y坐标
#define CMD_SetPixel 0x2C //填充像素
/***************************** ILI934 显示区域的起始坐标和总行列数 ***************************/
#define ILI9341_DispWindow_X_Star 0 //起始点的X坐标
#define ILI9341_DispWindow_Y_Star 0 //起始点的Y坐标
#define ILI9341_LESS_PIXEL 240 //液晶屏较短方向的像素宽度
#define ILI9341_MORE_PIXEL 320 //液晶屏较长方向的像素宽度
//根据液晶扫描方向而变化的XY像素宽度
//调用ILI9341_GramScan函数设置方向时会自动更改
extern uint16_t LCD_X_LENGTH,LCD_Y_LENGTH;
//液晶屏扫描模式
//参数可选值为0-7
typedef enum {
LCD_SCAN_MODE_1 = 1,
LCD_SCAN_MODE_2 = 2,
LCD_SCAN_MODE_3 = 3,
LCD_SCAN_MODE_4 = 4,
LCD_SCAN_MODE_5 = 5,
LCD_SCAN_MODE_6 = 6,
} LCD_SCAN_MODE_enum;
extern uint8_t LCD_SCAN_MODE ;
void ILI9341_Write_Cmd ( uint16_t usCmd );
void ILI9341_Write_Data ( uint16_t usData );
__IO uint16_t ILI9341_Read_Data ( void );
__IO uint16_t ILI9341_Init (void);
#endif /* __BSP_ILI9341_ILI9341_H */
建立 LCD驱动 管理文件LCD_book.c
代码如下 :
/**
******************************************************************************
* @file bsp_ili9341_lcd.c
* @version V1.0
* @date 2013-xx-xx
* @brief ili9341液晶屏驱动
******************************************************************************
* @attention
*
* 实验平台:野火 F103-霸道 STM32 开发板
* 论坛 :http://www.firebbs.cn
* 淘宝 :https://fire-stm32.taobao.com
*
******************************************************************************
*/
#include "stm32f10x.h"
#include "LCD_book.h"
//根据液晶扫描方向而变化的XY像素宽度
//调用ILI9341_GramScan函数设置方向时会自动更改
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;
/**
* @brief 初始化ILI9341的IO引脚
* @param 无
* @retval 无
*/
static void ILI9341_GPIO_Config ( void ){
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能FSMC对应相应管脚时钟*/
RCC_APB2PeriphClockCmd (
/*控制信号*/
ILI9341_CS_CLK|ILI9341_DC_CLK|ILI9341_WR_CLK|
ILI9341_RD_CLK |ILI9341_BK_CLK|ILI9341_RST_CLK|
/*数据信号*/
ILI9341_D0_CLK|ILI9341_D1_CLK| ILI9341_D2_CLK |
ILI9341_D3_CLK | ILI9341_D4_CLK|ILI9341_D5_CLK|
ILI9341_D6_CLK | ILI9341_D7_CLK|ILI9341_D8_CLK|
ILI9341_D9_CLK | ILI9341_D10_CLK|ILI9341_D11_CLK|
ILI9341_D12_CLK | ILI9341_D13_CLK|ILI9341_D14_CLK|
ILI9341_D15_CLK , ENABLE );
/* 配置FSMC相对应的数据线,FSMC-D0~D15 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = ILI9341_D0_PIN;
GPIO_Init ( ILI9341_D0_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D1_PIN;
GPIO_Init ( ILI9341_D1_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D2_PIN;
GPIO_Init ( ILI9341_D2_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D3_PIN;
GPIO_Init ( ILI9341_D3_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D4_PIN;
GPIO_Init ( ILI9341_D4_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D5_PIN;
GPIO_Init ( ILI9341_D5_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D6_PIN;
GPIO_Init ( ILI9341_D6_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D7_PIN;
GPIO_Init ( ILI9341_D7_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D8_PIN;
GPIO_Init ( ILI9341_D8_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D9_PIN;
GPIO_Init ( ILI9341_D9_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D10_PIN;
GPIO_Init ( ILI9341_D10_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D11_PIN;
GPIO_Init ( ILI9341_D11_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D12_PIN;
GPIO_Init ( ILI9341_D12_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D13_PIN;
GPIO_Init ( ILI9341_D13_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D14_PIN;
GPIO_Init ( ILI9341_D14_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_D15_PIN;
GPIO_Init ( ILI9341_D15_PORT, & GPIO_InitStructure );
/* 配置FSMC相对应的控制线
* FSMC_NOE :LCD-RD
* FSMC_NWE :LCD-WR
* FSMC_NE1 :LCD-CS
* FSMC_A16 :LCD-DC
*/
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = ILI9341_RD_PIN;
GPIO_Init (ILI9341_RD_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_WR_PIN;
GPIO_Init (ILI9341_WR_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_CS_PIN;
GPIO_Init ( ILI9341_CS_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = ILI9341_DC_PIN;
GPIO_Init ( ILI9341_DC_PORT, & GPIO_InitStructure );
/* 配置LCD复位RST控制管脚*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = ILI9341_RST_PIN;
GPIO_Init ( ILI9341_RST_PORT, & GPIO_InitStructure );
/* 配置LCD背光控制管脚BK*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = ILI9341_BK_PIN;
GPIO_Init ( ILI9341_BK_PORT, & GPIO_InitStructure );
}
/**
* @brief LCD FSMC 模式配置
* @param 无
* @retval 无
*/
static void ILI9341_FSMC_Config ( void )
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef readWriteTiming;
/* 使能FSMC时钟*/
RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_FSMC, ENABLE );
//地址建立时间(ADDSET)为1个HCLK 2/72M=28ns
readWriteTiming.FSMC_AddressSetupTime = 0x01; //地址建立时间
//数据保持时间(DATAST)+ 1个HCLK = 5/72M=70ns
readWriteTiming.FSMC_DataSetupTime = 0x06; //数据建立时间
//选择控制的模式
//模式B,异步NOR FLASH模式,与ILI9341的8080时序匹配
readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_B;
/*以下配置与模式B无关*/
//地址保持时间(ADDHLD)模式A未用到
readWriteTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间
//设置总线转换周期,仅用于复用模式的NOR操作
readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
//设置时钟分频,仅用于同步类型的存储器
readWriteTiming.FSMC_CLKDivision = 0x00;
//数据保持时间,仅用于同步型的NOR
readWriteTiming.FSMC_DataLatency = 0x00;
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAMx;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &readWriteTiming;
FSMC_NORSRAMInit ( & FSMC_NORSRAMInitStructure );
/* 使能 FSMC_Bank1_NORSRAM4 */
FSMC_NORSRAMCmd ( FSMC_Bank1_NORSRAMx, ENABLE );
}
//==================================================================================
//==============================命令初始化==========================================
//==================================================================================
/**
* @brief 向ILI9341写入命令
* @param usCmd :要写入的命令(表寄存器地址)
* @retval 无
*/
__inline void ILI9341_Write_Cmd ( uint16_t usCmd ){
* ( __IO uint16_t * ) ( FSMC_Addr_ILI9341_CMD ) = usCmd;
}
/**
* @brief 向ILI9341写入数据
* @param usData :要写入的数据
* @retval 无
*/
__inline void ILI9341_Write_Data ( uint16_t usData ){
* ( __IO uint16_t * ) ( FSMC_Addr_ILI9341_DATA ) = usData;
}
/**
* @brief 从ILI9341读取数据
* @param 无
* @retval 读取到的数据
*/
__inline __IO uint16_t ILI9341_Read_Data ( void ){
return ( * ( __IO uint16_t * ) ( FSMC_Addr_ILI9341_DATA ) );
}
/**
* @brief 用于 ILI9341 简单延时函数
* @param nCount :延时计数值
* @retval 无
*/
static void ILI9341_Delay ( __IO uint32_t nCount ){
for ( ; nCount != 0; nCount -- );
}
/**
* @brief ILI9341背光LED控制
* @param enumState :决定是否使能背光LED
* 该参数为以下值之一:
* @arg ENABLE :使能背光LED
* @arg DISABLE :禁用背光LED
* @retval 无
*/
void ILI9341_BackLed_Control ( FunctionalState enumState )
{
if ( enumState )
GPIO_ResetBits ( ILI9341_BK_PORT, ILI9341_BK_PIN );
else
GPIO_SetBits ( ILI9341_BK_PORT, ILI9341_BK_PIN );
}
/**
* @brief ILI9341 软件复位
* @param 无
* @retval 无
*/
void ILI9341_Rst ( void )
{
GPIO_ResetBits ( ILI9341_RST_PORT, ILI9341_RST_PIN ); //低电平复位
ILI9341_Delay ( 0xAFF );
GPIO_SetBits ( ILI9341_RST_PORT, ILI9341_RST_PIN );
ILI9341_Delay ( 0xAFF );
}
//==================================================================================
//============================== 显示屏幕 初始化========================================
//==================================================================================
/**
* @brief 初始化ILI9341寄存器
* @param 无
* @retval 无
*/
static void ILI9341_REG_Config ( void )
{
/* Power control B (CFh) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xCF );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x81 );
ILI9341_Write_Data ( 0x30 );
/* Power on sequence control (EDh) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xED );
ILI9341_Write_Data ( 0x64 );
ILI9341_Write_Data ( 0x03 );
ILI9341_Write_Data ( 0x12 );
ILI9341_Write_Data ( 0x81 );
/* Driver timing control A (E8h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xE8 );
ILI9341_Write_Data ( 0x85 );
ILI9341_Write_Data ( 0x10 );
ILI9341_Write_Data ( 0x78 );
/* Power control A (CBh) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xCB );
ILI9341_Write_Data ( 0x39 );
ILI9341_Write_Data ( 0x2C );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x34 );
ILI9341_Write_Data ( 0x02 );
/* Pump ratio control (F7h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xF7 );
ILI9341_Write_Data ( 0x20 );
/* Driver timing control B */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xEA );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x00 );
/* Frame Rate Control (In Normal Mode/Full Colors) (B1h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xB1 );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x1B );
/* Display Function Control (B6h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xB6 );
ILI9341_Write_Data ( 0x0A );
ILI9341_Write_Data ( 0xA2 );
/* Power Control 1 (C0h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xC0 );
ILI9341_Write_Data ( 0x35 );
/* Power Control 2 (C1h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xC1 );
ILI9341_Write_Data ( 0x11 );
/* VCOM Control 1 (C5h) */
ILI9341_Write_Cmd ( 0xC5 );
ILI9341_Write_Data ( 0x45 );
ILI9341_Write_Data ( 0x45 );
/* VCOM Control 2 (C7h) */
ILI9341_Write_Cmd ( 0xC7 );
ILI9341_Write_Data ( 0xA2 );
/* Enable 3G (F2h) */
ILI9341_Write_Cmd ( 0xF2 );
ILI9341_Write_Data ( 0x00 );
/* Gamma Set (26h) */
ILI9341_Write_Cmd ( 0x26 );
ILI9341_Write_Data ( 0x01 );
DEBUG_DELAY ();
/* Positive Gamma Correction */
ILI9341_Write_Cmd ( 0xE0 ); //Set Gamma
ILI9341_Write_Data ( 0x0F );
ILI9341_Write_Data ( 0x26 );
ILI9341_Write_Data ( 0x24 );
ILI9341_Write_Data ( 0x0B );
ILI9341_Write_Data ( 0x0E );
ILI9341_Write_Data ( 0x09 );
ILI9341_Write_Data ( 0x54 );
ILI9341_Write_Data ( 0xA8 );
ILI9341_Write_Data ( 0x46 );
ILI9341_Write_Data ( 0x0C );
ILI9341_Write_Data ( 0x17 );
ILI9341_Write_Data ( 0x09 );
ILI9341_Write_Data ( 0x0F );
ILI9341_Write_Data ( 0x07 );
ILI9341_Write_Data ( 0x00 );
/* Negative Gamma Correction (E1h) */
ILI9341_Write_Cmd ( 0XE1 ); //Set Gamma
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x19 );
ILI9341_Write_Data ( 0x1B );
ILI9341_Write_Data ( 0x04 );
ILI9341_Write_Data ( 0x10 );
ILI9341_Write_Data ( 0x07 );
ILI9341_Write_Data ( 0x2A );
ILI9341_Write_Data ( 0x47 );
ILI9341_Write_Data ( 0x39 );
ILI9341_Write_Data ( 0x03 );
ILI9341_Write_Data ( 0x06 );
ILI9341_Write_Data ( 0x06 );
ILI9341_Write_Data ( 0x30 );
ILI9341_Write_Data ( 0x38 );
ILI9341_Write_Data ( 0x0F );
/* memory access control set */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0x36 );
ILI9341_Write_Data ( 0xC8 ); /*竖屏 左上角到 (起点)到右下角 (终点)扫描方式*/
DEBUG_DELAY ();
/* column address control set */
ILI9341_Write_Cmd ( CMD_SetCoordinateX );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0xEF );
/* page address control set */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( CMD_SetCoordinateY );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x01 );
ILI9341_Write_Data ( 0x3F );
/* Pixel Format Set (3Ah) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0x3a );
ILI9341_Write_Data ( 0x55 );
/* Sleep Out (11h) */
ILI9341_Write_Cmd ( 0x11 );
ILI9341_Delay ( 0xAFFf<<2 );
DEBUG_DELAY ();
/* Display ON (29h) */
ILI9341_Write_Cmd ( 0x29 );
}
/**
* @brief uint16_t ILI9341_Read_Pixel_Pormat(void)
* @param 无
* @retval 读取到的数据
*/
static __IO uint16_t ILI9341_Read_Pixel_Pormat(void){
ILI9341_Write_Cmd(0x0C);
ILI9341_Read_Data();
return (__IO uint16_t) ILI9341_Read_Data();
}
/**
* @brief 设置ILI9341的GRAM的扫描方向
* @param ucOption :选择GRAM的扫描方向
* @arg 0-7 :参数可选值为0-7这八个方向
*
* !!!其中0、3、5、6 模式适合从左至右显示文字,
* 不推荐使用其它模式显示文字 其它模式显示文字会有镜像效果
*
* 其中0、2、4、6 模式的X方向像素为240,Y方向像素为320
* 其中1、3、5、7 模式下X方向像素为320,Y方向像素为240
*
* 其中 6 模式为大部分液晶例程的默认显示方向
* 其中 3 模式为摄像头例程使用的方向
* 其中 0 模式为BMP图片显示例程使用的方向
*
* @retval 无
* @note 坐标图例:A表示向上,V表示向下,<表示向左,>表示向右
X表示X轴,Y表示Y轴
------------------------------------------------------------
模式0: . 模式1: . 模式2: . 模式3:
A . A . A . A
| . | . | . |
Y . X . Y . X
0 . 1 . 2 . 3
<--- X0 o . <----Y1 o . o 2X---> . o 3Y--->
------------------------------------------------------------
模式4: . 模式5: . 模式6: . 模式7:
<--- X4 o . <--- Y5 o . o 6X---> . o 7Y--->
4 . 5 . 6 . 7
Y . X . Y . X
| . | . | . |
V . V . V . V
---------------------------------------------------------
LCD屏示例
|-----------------|
| 野火Logo |
| |
| |
| |
| |
| |
| |
| |
| |
|-----------------|
屏幕正面(宽240,高320)
*******************************************************/
void ILI9341_GramScan ( uint8_t ucOption ){
//参数检查,只可输入0-7
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扫描方向
ILI9341_Write_Cmd ( 0x36 );
ILI9341_Write_Data ( 0x08 |(ucOption<<5));//根据ucOption的值设置LCD参数,共0-7种模式
ILI9341_Write_Cmd ( CMD_SetCoordinateX );
ILI9341_Write_Data ( 0x00 ); /* x 起始坐标高8位 */
ILI9341_Write_Data ( 0x00 ); /* x 起始坐标低8位 */
ILI9341_Write_Data ( ((LCD_X_LENGTH-1)>>8)&0xFF ); /* x 结束坐标高8位 */
ILI9341_Write_Data ( (LCD_X_LENGTH-1)&0xFF ); /* x 结束坐标低8位 */
ILI9341_Write_Cmd ( CMD_SetCoordinateY );
ILI9341_Write_Data ( 0x00 ); /* y 起始坐标高8位 */
ILI9341_Write_Data ( 0x00 ); /* y 起始坐标低8位 */
ILI9341_Write_Data ( ((LCD_Y_LENGTH-1)>>8)&0xFF ); /* y 结束坐标高8位 */
ILI9341_Write_Data ( (LCD_Y_LENGTH-1)&0xFF ); /* y 结束坐标低8位 */
/* write gram start */
ILI9341_Write_Cmd ( CMD_SetPixel );
}
//==================================================================================
//============================== 主程序初始化========================================
//==================================================================================
/**
* @brief ILI9341初始化函数,如果要用到lcd,一定要调用这个函数
* @param 无
* @retval 无
*/
__IO uint16_t ILI9341_Init (void){
ILI9341_GPIO_Config ();
ILI9341_FSMC_Config ();
ILI9341_Rst ();
ILI9341_BackLed_Control ( ENABLE ); //点亮LCD背光灯
ILI9341_REG_Config();
//设置默认扫描方向,其中 6 模式为大部分液晶例程的默认显示方向
ILI9341_GramScan(LCD_SCAN_MODE_6 );
return (__IO uint16_t)ILI9341_Read_Pixel_Pormat();
}
建立 LCD 绘制函数文件LCD_Draw_book.h
代码如下 :
#ifndef __LCD_DRAW_BOOK_H
#define __LCD_DRAW_BOOK_H
#include "stm32f10x.h"
#include "USART_book.h"
#include "LCD_book.h"
#include "fonts.h"
/******************************* 定义 ILI934 显示屏常用颜色 ********************************/
#define BACKGROUND BLACK //默认背景颜色
#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
//1110 1100 1101 0101 1010 1111
//11101 110101 10101
//GB565(Rh,Gh,Bh) (((Rh&0xf8)<<8)|((Gh&0xfc)<<3)|((Bh&0xf8)>>3))
//GB888(RGB) ((((RGB&0xf80000)) | ((RGB&0x00fc00)<<3)| ((RGB&0x0000f8)<<5))>>8)
#define GB565(Rh,Gh,Bh) (((Rh&0xf8)<<8)|((Gh&0xfc)<<3)|((Bh&0xf8)>>3))
#define GB888(RGB) ((((RGB&0xf80000)) | ((RGB&0x00fc00)<<3)| ((RGB&0x0000f8)<<5))>>8)
extern sFONT *LCD_Currentfonts ; //英文字体
extern uint16_t CurrentForecolor ;//前景色
extern uint16_t CurrentBackColor ;//背景色
//================================ 接口函数=======================================
/**
* @brief 在ILI9341显示器上开辟一个窗口
* @param usX :在特定扫描方向下窗口的起点X坐标
* @param usY :在特定扫描方向下窗口的起点Y坐标
* @param usWidth :窗口的宽度
* @param usHeight :窗口的高度
* @retval 无
*/
void ILI9341_OpenWindow (
uint16_t usX,
uint16_t usY,
uint16_t usWidth,
uint16_t usHeight
);
/**
* @brief 设定ILI9341的光标坐标
* @param usX :在特定扫描方向下光标的X坐标
* @param usY :在特定扫描方向下光标的Y坐标
* @retval 无
*/
static void ILI9341_SetCursor (
uint16_t usX,
uint16_t usY,
uint16_t usW
);
/**
* @brief 在ILI9341显示器上以某一颜色填充像素点
* @param ulAmout_Point :要填充颜色的像素点的总数目
* @param usColor :颜色
* @retval 无
*/
static __inline void ILI9341_FillColor ( uint32_t ulAmout_Point, uint16_t usColor );
/**
* @brief 对ILI9341显示器的某一窗口以某种颜色进行清屏
* @param usX :在特定扫描方向下窗口的起点X坐标
* @param usY :在特定扫描方向下窗口的起点Y坐标
* @param usWidth :窗口的宽度
* @param usHeight :窗口的高度
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_Clear (
uint16_t usX,
uint16_t usY,
uint16_t usWidth,
uint16_t usHeight
);
//================================ 颜色状态函数=======================================
/**
* @brief 设置LCD的前景(字体)及背景颜色,RGB565
* @param TextColor: 指定前景(字体)颜色
* @param BackColor: 指定背景颜色
* @retval None
*/
void LCD_SetColors(uint16_t TextColor, uint16_t BackColor);
/**
* @brief 设置LCD的前景(字体)颜色,RGB565
* @param Color: 指定前景(字体)颜色
* @retval None
*/
void LCD_SetForeColor(uint16_t Color);
/**
* @brief 设置LCD的背景颜色,RGB565
* @param Color: 指定背景颜色
* @retval None
*/
void LCD_SetBackColor(uint16_t Color);
//================================ 形状绘制应用函数=======================================
/**
* @brief 对ILI9341显示器的某一点以某种颜色进行填充
* @param usX :在特定扫描方向下该点的X坐标
* @param usY :在特定扫描方向下该点的Y坐标
* @param usW :在特定扫描宽度
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_SetPointPixel (
uint16_t usX,
uint16_t usY,
uint16_t usW
);
/**
* @brief 在 ILI9341 显示器上使用 Bresenham 算法画线段
* @param usX1 :在特定扫描方向下线段的一个端点X坐标
* @param usY1 :在特定扫描方向下线段的一个端点Y坐标
* @param usX2 :在特定扫描方向下线段的另一个端点X坐标
* @param usY2 :在特定扫描方向下线段的另一个端点Y坐标
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DrawLine (
uint16_t usX1,
uint16_t usY1,
uint16_t usX2,
uint16_t usY2,
uint16_t usW
);
/**
* @brief 在 ILI9341 显示器上画一个矩形
* @param usX_Start :在特定扫描方向下矩形的起始点X坐标
* @param usY_Start :在特定扫描方向下矩形的起始点Y坐标
* @param usWidth:矩形的宽度(单位:像素)
* @param usHeight:矩形的高度(单位:像素)
* @param ucFilled :选择是否填充该矩形
* 该参数为以下值之一:
* @arg 0 :空心矩形
* @arg 1 :实心矩形
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DrawRectangle (
uint16_t usX_Start, //X坐标
uint16_t usY_Start, //Y坐标
uint16_t usWidth, //X宽度
uint16_t usHeight, //Y宽度
uint8_t ucFilled , //填充类型
uint16_t usW //填充线宽度
);
/**
* @brief 在 ILI9341 显示器上使用 Bresenham 算法画圆
* @param usX_Center :在特定扫描方向下圆心的X坐标
* @param usY_Center :在特定扫描方向下圆心的Y坐标
* @param usRadius:圆的半径(单位:像素)
* @param ucFilled :选择是否填充该圆
* 该参数为以下值之一:
* @arg 0 :空心圆
* @arg 1 :实心圆
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DrawCircle (
uint16_t usX_Center,
uint16_t usY_Center,
uint16_t usRadius,
uint8_t ucFilled ,
uint16_t usW
);
//================================ 文字颜色状态绘制应用函数=======================================
/**
* @brief 设置英文字体类型
* @param fonts: 指定要选择的字体
* 参数为以下值之一
* @arg:Font24x32;
* @arg:Font16x24;
* @arg:Font8x16;
* @retval None
*/
void LCD_SetFont(sFONT *fonts);
/**
* @brief 在 ILI9341 显示器上显示一个英文字符
* @param usX :在特定扫描方向下字符的起始X坐标
* @param usY :在特定扫描方向下该点的起始Y坐标
* @param cChar :要显示的英文字符
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DispChar_EN ( uint16_t usX, uint16_t usY, const char cChar );
/**
* @brief 在 ILI9341 显示器上显示英文字符串
* @param line :在特定扫描方向下字符串的起始Y坐标
* 本参数可使用宏LINE(0)、LINE(1)等方式指定文字坐标,
* 宏LINE(x)会根据当前选择的字体来计算Y坐标值。
* 显示中文且使用LINE宏时,需要把英文字体设置成Font8x16
* @param pStr :要显示的英文字符串的首地址
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DispStringLine_EN ( uint16_t line, char * pStr );
/**
* @brief 在 ILI9341 显示器上显示英文字符串
* @param usX :在特定扫描方向下字符的起始X坐标
* @param usY :在特定扫描方向下字符的起始Y坐标
* @param pStr :要显示的英文字符串的首地址
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DispString_EN ( uint16_t usX ,uint16_t usY, char * pStr );
/**
* @brief 在 ILI9341 显示器上显示英文字符串(沿Y轴方向)
* @param usX :在特定扫描方向下字符的起始X坐标
* @param usY :在特定扫描方向下字符的起始Y坐标
* @param pStr :要显示的英文字符串的首地址
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DispString_EN_YDir ( uint16_t usX,uint16_t usY , char * pStr );
#endif /* __BSP_ILI9341_ILI9341_H */
建立 LCD 绘制文件LCD_Draw_book.c
代码如下 :
#include "LCD_Draw_book.h"
#include "USART_book.h"
sFONT *LCD_Currentfonts = &Font8x16; //英文字体
uint16_t CurrentForecolor = BLACK;//前景色
uint16_t CurrentBackColor = BACKGROUND;//背景色
//================================ 接口函数=======================================
/**
* @brief 在ILI9341显示器上开辟一个窗口
* @param usX :在特定扫描方向下窗口的起点X坐标
* @param usY :在特定扫描方向下窗口的起点Y坐标
* @param usWidth :窗口的宽度
* @param usHeight :窗口的高度
* @retval 无
*/
void ILI9341_OpenWindow ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight )
{
ILI9341_Write_Cmd ( CMD_SetCoordinateX ); /* 设置X坐标 */
ILI9341_Write_Data ( (usX & 0xFF00) >> 8 ); /* 先高8位,然后低8位 */
ILI9341_Write_Data ( usX & 0xff ); /* 设置起始点和结束点*/
ILI9341_Write_Data ( ( usX + usWidth - 1 ) >> 8 );
ILI9341_Write_Data ( ( usX + usWidth - 1 ) & 0xff );
ILI9341_Write_Cmd ( CMD_SetCoordinateY ); /* 设置Y坐标*/
ILI9341_Write_Data ( (usY & 0xFF00 )>> 8 );
ILI9341_Write_Data ( usY & 0xff );
ILI9341_Write_Data ( ( usY + usHeight - 1 ) >> 8 );
ILI9341_Write_Data ( ( usY + usHeight - 1) & 0xff );
}
/**
* @brief 设定ILI9341的光标坐标
* @param usX :在特定扫描方向下光标的X坐标
* @param usY :在特定扫描方向下光标的Y坐标
* @retval 无
*/
static void ILI9341_SetCursor (
uint16_t usX,
uint16_t usY,
uint16_t usW
){
ILI9341_OpenWindow ( usX, usY, usW, usW );
}
/**
* @brief 在ILI9341显示器上以某一颜色填充像素点
* @param ulAmout_Point :要填充颜色的像素点的总数目
* @param usColor :颜色
* @retval 无
*/
static __inline void ILI9341_FillColor ( uint32_t ulAmout_Point, uint16_t usColor ){
uint32_t i = 0;
/* memory write */
ILI9341_Write_Cmd ( CMD_SetPixel );
for ( i = 0; i < ulAmout_Point; i ++ )
ILI9341_Write_Data ( usColor );
}
/**
* @brief 对ILI9341显示器的某一窗口以某种颜色进行清屏
* @param usX :在特定扫描方向下窗口的起点X坐标
* @param usY :在特定扫描方向下窗口的起点Y坐标
* @param usWidth :窗口的宽度
* @param usHeight :窗口的高度
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_Clear (
uint16_t usX,
uint16_t usY,
uint16_t usWidth,
uint16_t usHeight
){
ILI9341_OpenWindow ( usX, usY, usWidth, usHeight );
ILI9341_FillColor ( usWidth * usHeight, CurrentBackColor );
}
//================================ 颜色状态函数=======================================
/**
* @brief 设置LCD的前景(字体)及背景颜色,RGB565
* @param TextColor: 指定前景(字体)颜色
* @param BackColor: 指定背景颜色
* @retval None
*/
void LCD_SetColors(uint16_t TextColor, uint16_t BackColor){
CurrentForecolor = TextColor;
CurrentBackColor = BackColor;
}
/**
* @brief 设置LCD的前景(字体)颜色,RGB565
* @param Color: 指定前景(字体)颜色
* @retval None
*/
void LCD_SetForeColor(uint16_t Color){
CurrentForecolor = Color;
}
/**
* @brief 设置LCD的背景颜色,RGB565
* @param Color: 指定背景颜色
* @retval None
*/
void LCD_SetBackColor(uint16_t Color){
CurrentBackColor = Color;
}
//================================ 形状绘制应用函数=======================================
/**
* @brief 对ILI9341显示器的某一点以某种颜色进行填充
* @param usX :在特定扫描方向下该点的X坐标
* @param usY :在特定扫描方向下该点的Y坐标
* @param usW :在特定扫描宽度
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_SetPointPixel (
uint16_t usX,
uint16_t usY,
uint16_t usW
){
if ( ( usX < LCD_X_LENGTH ) && ( usY < LCD_Y_LENGTH ) ){
ILI9341_SetCursor ( usX, usY ,usW);
ILI9341_FillColor ( usW*usW, CurrentForecolor );
}
}
/**
* @brief 在 ILI9341 显示器上使用 Bresenham 算法画线段
* @param usX1 :在特定扫描方向下线段的一个端点X坐标
* @param usY1 :在特定扫描方向下线段的一个端点Y坐标
* @param usX2 :在特定扫描方向下线段的另一个端点X坐标
* @param usY2 :在特定扫描方向下线段的另一个端点Y坐标
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DrawLine (
uint16_t usX1,
uint16_t usY1,
uint16_t usX2,
uint16_t usY2,
uint16_t usW
){
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 ++ ){//画线输出
ILI9341_SetPointPixel ( usX_Current, usY_Current , usW );//画点
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;
}
}
}
/**
* @brief 在 ILI9341 显示器上画一个矩形
* @param usX_Start :在特定扫描方向下矩形的起始点X坐标
* @param usY_Start :在特定扫描方向下矩形的起始点Y坐标
* @param usWidth:矩形的宽度(单位:像素)
* @param usHeight:矩形的高度(单位:像素)
* @param ucFilled :选择是否填充该矩形
* 该参数为以下值之一:
* @arg 0 :空心矩形
* @arg 1 :实心矩形
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DrawRectangle (
uint16_t usX_Start, //X坐标
uint16_t usY_Start, //Y坐标
uint16_t usWidth, //X宽度
uint16_t usHeight, //Y宽度
uint8_t ucFilled , //填充类型
uint16_t usW //填充线宽度
){
if ( ucFilled ){
ILI9341_OpenWindow ( usX_Start, usY_Start, usWidth, usHeight );
ILI9341_FillColor ( usWidth * usHeight ,CurrentForecolor);
}
else {
ILI9341_DrawLine ( usX_Start, usY_Start, usX_Start + usWidth - 1, usY_Start ,usW);
ILI9341_DrawLine ( usX_Start, usY_Start + usHeight - 1, usX_Start + usWidth - 1, usY_Start + usHeight - 1 ,usW);
ILI9341_DrawLine ( usX_Start, usY_Start, usX_Start, usY_Start + usHeight - 1 ,usW);
ILI9341_DrawLine ( usX_Start + usWidth - 1, usY_Start, usX_Start + usWidth - 1, usY_Start + usHeight - 1 ,usW);
}
}
/**
* @brief 在 ILI9341 显示器上使用 Bresenham 算法画圆
* @param usX_Center :在特定扫描方向下圆心的X坐标
* @param usY_Center :在特定扫描方向下圆心的Y坐标
* @param usRadius:圆的半径(单位:像素)
* @param ucFilled :选择是否填充该圆
* 该参数为以下值之一:
* @arg 0 :空心圆
* @arg 1 :实心圆
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DrawCircle (
uint16_t usX_Center,
uint16_t usY_Center,
uint16_t usRadius,
uint8_t ucFilled ,
uint16_t usW
){
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 ++ )
{
ILI9341_SetPointPixel ( usX_Center + sCurrentX, usY_Center + sCountY ,usW ); //1,研究对象
ILI9341_SetPointPixel ( usX_Center - sCurrentX, usY_Center + sCountY ,usW); //2
ILI9341_SetPointPixel ( usX_Center - sCountY, usY_Center + sCurrentX ,usW); //3
ILI9341_SetPointPixel ( usX_Center - sCountY, usY_Center - sCurrentX ,usW); //4
ILI9341_SetPointPixel ( usX_Center - sCurrentX, usY_Center - sCountY ,usW); //5
ILI9341_SetPointPixel ( usX_Center + sCurrentX, usY_Center - sCountY ,usW); //6
ILI9341_SetPointPixel ( usX_Center + sCountY, usY_Center - sCurrentX ,usW); //7
ILI9341_SetPointPixel ( usX_Center + sCountY, usY_Center + sCurrentX ,usW); //0
}
else
{
ILI9341_SetPointPixel ( usX_Center + sCurrentX, usY_Center + sCurrentY ,usW ); //1,研究对象
ILI9341_SetPointPixel ( usX_Center - sCurrentX, usY_Center + sCurrentY ,usW ); //2
ILI9341_SetPointPixel ( usX_Center - sCurrentY, usY_Center + sCurrentX ,usW ); //3
ILI9341_SetPointPixel ( usX_Center - sCurrentY, usY_Center - sCurrentX ,usW ); //4
ILI9341_SetPointPixel ( usX_Center - sCurrentX, usY_Center - sCurrentY ,usW ); //5
ILI9341_SetPointPixel ( usX_Center + sCurrentX, usY_Center - sCurrentY ,usW ); //6
ILI9341_SetPointPixel ( usX_Center + sCurrentY, usY_Center - sCurrentX ,usW ); //7
ILI9341_SetPointPixel ( usX_Center + sCurrentY, usY_Center + sCurrentX ,usW ); //0
}
sCurrentX ++;
if ( sError < 0 ) sError += 4 * sCurrentX + 6;
else{
sError += 10 + 4 * ( sCurrentX - sCurrentY );
sCurrentY --;
}
}
}
//================================ 文字颜色状态绘制应用函数=======================================
/**
* @brief 设置英文字体类型
* @param fonts: 指定要选择的字体
* 参数为以下值之一
* @arg:Font24x32;
* @arg:Font16x24;
* @arg:Font8x16;
* @retval None
*/
void LCD_SetFont(sFONT *fonts)
{
LCD_Currentfonts = fonts;
}
/**
* @brief 获取当前字体类型
* @param None.
* @retval 返回当前字体类型
*/
sFONT *LCD_GetFont(void)
{
return LCD_Currentfonts;
}
//================================ 文字绘制应用函数=======================================
/**
* @brief 在 ILI9341 显示器上显示一个英文字符
* @param usX :在特定扫描方向下字符的起始X坐标
* @param usY :在特定扫描方向下该点的起始Y坐标
* @param cChar :要显示的英文字符
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DispChar_EN ( uint16_t usX, uint16_t usY, const char cChar )
{
uint8_t byteCount, bitCount,fontLength;
uint16_t ucRelativePositon;
uint8_t *Pfont;
//对ascii码表偏移(字模表不包含ASCII表的前32个非图形符号)
ucRelativePositon = cChar - ' ';
//每个字模的字节数
fontLength = (LCD_Currentfonts->Width*LCD_Currentfonts->Height)/8;
//字模首地址
/*ascii码表偏移值乘以每个字模的字节数,求出字模的偏移位置*/
Pfont = (uint8_t *)&LCD_Currentfonts->table[ucRelativePositon * fontLength];
//设置显示窗口
ILI9341_OpenWindow ( usX, usY, LCD_Currentfonts->Width, LCD_Currentfonts->Height);
ILI9341_Write_Cmd ( CMD_SetPixel );
//按字节读取字模数据
//由于前面直接设置了显示窗口,显示数据会自动换行
for ( byteCount = 0; byteCount < fontLength; byteCount++ )
{
//一位一位处理要显示的颜色
for ( bitCount = 0; bitCount < 8; bitCount++ )
{
if ( Pfont[byteCount] & (0x80>>bitCount) )
ILI9341_Write_Data ( CurrentForecolor );
else
ILI9341_Write_Data ( CurrentBackColor );
}
}
}
/**
* @brief 在 ILI9341 显示器上显示英文字符串
* @param line :在特定扫描方向下字符串的起始Y坐标
* 本参数可使用宏LINE(0)、LINE(1)等方式指定文字坐标,
* 宏LINE(x)会根据当前选择的字体来计算Y坐标值。
* 显示中文且使用LINE宏时,需要把英文字体设置成Font8x16
* @param pStr :要显示的英文字符串的首地址
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DispStringLine_EN ( uint16_t line, char * pStr ){
uint16_t usX = 0;
while ( * pStr != '\0' )
{
if ( ( usX - ILI9341_DispWindow_X_Star + LCD_Currentfonts->Width ) > LCD_X_LENGTH )
{
usX = ILI9341_DispWindow_X_Star;
line += LCD_Currentfonts->Height;
}
if ( ( line - ILI9341_DispWindow_Y_Star + LCD_Currentfonts->Height ) > LCD_Y_LENGTH )
{
usX = ILI9341_DispWindow_X_Star;
line = ILI9341_DispWindow_Y_Star;
}
ILI9341_DispChar_EN ( usX, line, * pStr);
pStr ++;
usX += LCD_Currentfonts->Width;
}
}
/**
* @brief 在 ILI9341 显示器上显示英文字符串
* @param usX :在特定扫描方向下字符的起始X坐标
* @param usY :在特定扫描方向下字符的起始Y坐标
* @param pStr :要显示的英文字符串的首地址
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DispString_EN ( uint16_t usX ,uint16_t usY, char * pStr ){
while ( * pStr != '\0' )
{
if ( ( usX - ILI9341_DispWindow_X_Star + LCD_Currentfonts->Width ) > LCD_X_LENGTH )
{
usX = ILI9341_DispWindow_X_Star;
usY += LCD_Currentfonts->Height;
}
if ( ( usY - ILI9341_DispWindow_Y_Star + LCD_Currentfonts->Height ) > LCD_Y_LENGTH )
{
usX = ILI9341_DispWindow_X_Star;
usY = ILI9341_DispWindow_Y_Star;
}
ILI9341_DispChar_EN ( usX, usY, * pStr);
pStr ++;
usX += LCD_Currentfonts->Width;
}
}
/**
* @brief 在 ILI9341 显示器上显示英文字符串(沿Y轴方向)
* @param usX :在特定扫描方向下字符的起始X坐标
* @param usY :在特定扫描方向下字符的起始Y坐标
* @param pStr :要显示的英文字符串的首地址
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9341_DispString_EN_YDir ( uint16_t usX,uint16_t usY , char * pStr )
{
while ( * pStr != '\0' )
{
if ( ( usY - ILI9341_DispWindow_Y_Star + LCD_Currentfonts->Height ) >LCD_Y_LENGTH )
{
usY = ILI9341_DispWindow_Y_Star;
usX += LCD_Currentfonts->Width;
}
if ( ( usX - ILI9341_DispWindow_X_Star + LCD_Currentfonts->Width ) > LCD_X_LENGTH)
{
usX = ILI9341_DispWindow_X_Star;
usY = ILI9341_DispWindow_Y_Star;
}
ILI9341_DispChar_EN ( usX, usY, * pStr);
pStr ++;
usY += LCD_Currentfonts->Height;
}
}
建立 LCD页面绘制 文件LCD_PageHtml_book.h
代码如下 :
#ifndef __LCD_PAGEHTML_BOOK_H
#define __LCD_PAGEHTML_BOOK_H
#include "stm32f10x.h"
#include "LCD_book.h"
#include "LCD_Draw_book.h"
#include "fonts.h"
void Display_Char_test(void);
void fn_Lcd_Page1(void);
#endif
建立 LCD页面绘制 文件LCD_PageHtml_book.c
代码如下 :
#include "LCD_PageHtml_book.h"
/// 自模 设计 字宽 16 字高 16
// 阴码 逐行 24 24 顺向 16进制
//uint8_t test_modu[] ={
// 0x00,0x00,0x7F,0xFC,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
// 0x00,0x01,0x00,0x3F,0xF8,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00 ,
// 0x01,0x00,0x01,0x00,0xFF,0xFE,0x00,0x00};/*"王",0*/
//#define _row_count 16
//#define _byte_count 2
//#define _bit_count 8
/// 自模 设计 字宽 32 字高 32
// 阴码 逐行 24 24 顺向 16进制
uint8_t test_modu2[] ={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xC0 ,
0x04,0x03,0xC0,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xC0,0x00,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x00 ,
0x03,0x03,0xC0,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xC0,0x00,0x1F,0xFF,0xFC,0x00,0x3F,0xFF,0xFF,0xFE ,
0x7F,0x80,0x7F,0xFE,0x60,0x00,0x03,0xFC,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/*"王",0*/
#define _row_count 32
#define _byte_count 4
#define _bit_count 8
void Display_Char_test(void){
uint8_t row_count , byte_count , bit_count ;
for(row_count = 0 ;row_count< _row_count; row_count++){
printf("\n");
for(byte_count = 0 ;byte_count< _byte_count ; byte_count++){
for( bit_count = 0;bit_count < _bit_count ; bit_count++){
if(test_modu2[row_count*_byte_count+byte_count] &(0x80 >>bit_count)){
printf("*");
}else{
printf(" ");
}
}
}
}
}
//================================ 页面设计函数=======================================
/**
* @brief 在ILI9341显示器上开辟一个窗口
* @param usX :在特定扫描方向下窗口的起点X坐标
* @param usY :在特定扫描方向下窗口的起点Y坐标
* @param usWidth :窗口的宽度
* @param usHeight :窗口的高度
* @retval 无
*/
void fn_Lcd_Page1(void){
// printf("\n-->LCD %x",GB565(255, 193 ,98));
// printf("\n-->LCD %x",GB888(0xFFC162));
LCD_SetColors( GB888(0x589447), GB888(0xFFC162));
ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH); /* 清屏,显示 黄色的界面 */
LCD_SetForeColor(GB888(0x589447)); //标题绿色的框
ILI9341_DrawRectangle( 0,0,LCD_X_LENGTH,25,1,1);
LCD_SetForeColor(GB888(0x797979));//阴影框
ILI9341_DrawLine(0,25,LCD_X_LENGTH,25,2);
LCD_SetForeColor(GB888(0xCDCDCD));
ILI9341_DrawLine(0,27,LCD_X_LENGTH,27,1);
LCD_SetForeColor(WHITE);//Wifi设计
ILI9341_DrawLine(LCD_X_LENGTH-20,19,LCD_X_LENGTH-15,19,3);
ILI9341_DrawLine(LCD_X_LENGTH-25,12,LCD_X_LENGTH-10,12,3);
ILI9341_DrawLine(LCD_X_LENGTH-28,5,LCD_X_LENGTH-7,5,3);
LCD_SetFont(&Font8x16);
LCD_SetColors(GB888(0xE8E5C4), GB888(0x589447)); //白色文字,绿色背景
/********显示字符串示例*******/
ILI9341_DispStringLine_EN(LINE(0),"Wangqi Telephone:");
LCD_SetFont(&Font8x16); //制作对话框
LCD_SetColors( GB888(0x000000), GB888(0xFFC162));
ILI9341_DispStringLine_EN(LINE(3)," Personnal News:");
LCD_SetForeColor(GB888(0x589447)); //灰色的框
ILI9341_DrawRectangle( 10,65,(LCD_X_LENGTH-20),30,0,1);
LCD_SetForeColor(GB888(0xC3C09C)); //里面的
ILI9341_DrawRectangle( 11,66,(LCD_X_LENGTH-20-1),30-1,1,1);
LCD_SetFont(&Font8x16);
LCD_SetColors(GB888(0xE8E5C4), GB888(0x589447));
LCD_SetForeColor(GB888(0x589447)); //绿色的按钮
ILI9341_DrawRectangle( 180,110,(50),30,1,1);
LCD_SetForeColor(WHITE); //白色阴影
ILI9341_DrawRectangle( 180,110,(50),30,0,1);
//-------------------------
LCD_SetFont(&Font8x16); //制作对话框
LCD_SetColors( GB888(0xC90000), GB888(0xFFC162)); //红色文字
ILI9341_DispStringLine_EN(LINE(9)," Have Girlfriend?");
//-------------------------
LCD_SetColors( GB888(0xF0A0A1), GB888(0xFFC162)); //红色文字
ILI9341_DrawCircle(210,180,10,1,1);
LCD_SetForeColor(GB888(0x797979));//阴影框
ILI9341_DrawCircle(210,180,10,0,1);
LCD_SetColors( GB888(0x34BDD5), GB888(0xFFC162)); //红色文字
ILI9341_DrawCircle(210,205,10,1,1);
LCD_SetForeColor(GB888(0x797979));//阴影框
ILI9341_DrawCircle(210,205,10,0,1);
//-------------------------
LCD_SetFont(&Font16x24); //制作对话框
LCD_SetColors( GB888(0xBB3756), GB888(0xFFC162)); //红色文字
ILI9341_DispStringLine_EN(LINE(7)," Yes!");
LCD_SetColors( GB888(0x310F29), GB888(0xFFC162)); //红色文字
ILI9341_DispStringLine_EN(LINE(8)," NO!");
//-------------------------
LCD_SetForeColor(GB888(0xA6A6A6));//阴影框
ILI9341_DrawLine(0,230,LCD_X_LENGTH,230,1);
LCD_SetColors( GB888(0xBF5BBA), GB888(0xFFC162)); //红色文字
ILI9341_DispStringLine_EN(LINE(10)," My LOVE ");
LCD_SetColors( GB888(0x2369FC) , GB888(0xFFC162)); //白色文字
ILI9341_DispStringLine_EN(LINE(12)," Hi 2021-8-14 ");
}
建立 LCD 文字库 内存管理文件fonts.h
代码如下 :
#ifndef __FONT_H
#define __FONT_H
#include "stm32f10x.h"
#define LINE(x) ((x) * (((sFONT *)LCD_GetFont())->Height))
#define LINEY(x) ((x) * (((sFONT *)LCD_GetFont())->Width))
/** @defgroup FONTS_Exported_Types
* @{
*/
typedef struct _tFont
{
const uint8_t *table;
uint16_t Width;
uint16_t Height;
} sFONT;
extern sFONT Font24x32;
extern sFONT Font16x24;
extern sFONT Font8x16;
//要支持中文需要实现本函数,可参考“液晶显示中英文(字库在外部FLASH)”例程
#define GetGBKCode( ucBuffer, usChar )
#endif /*end of __FONT_H */
建立 LCD 文字库 内存管理文件fonts.c
代码如下 :
/**
******************************************************************************
* @file bsp_ili9341_lcd.c
* @version V1.0
* @date 2013-xx-xx
* @brief 液晶屏字模相关(仅支持英文)
******************************************************************************
* @attention
*
* 实验平台:野火 F103-霸道 STM32 开发板
* 论坛 :http://www.firebbs.cn
* 淘宝 :https://fire-stm32.taobao.com
*
******************************************************************************
*/
#include "./fonts.h"
/*
* 常用ASCII表,偏移量32,大小:16(高度)* 8 (宽度)
*/
const uint8_t ASCII8x16_Table [ ] = { //@conslons字体,阴码点阵格式,逐行顺向取摸
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x08,0x00,0x08,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x34,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x16,0x24,0x7f,0x24,0x24,0x24,0x7e,0x24,0x24,0x00,0x00,0x00,
0x00,0x00,0x00,0x08,0x3e,0x68,0x48,0x68,0x1c,0x16,0x12,0x12,0x7c,0x10,0x10,0x00,
0x00,0x00,0x00,0x61,0xd2,0x96,0x74,0x08,0x10,0x16,0x29,0x49,0xc6,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3c,0x64,0x64,0x38,0x72,0x4a,0xce,0x46,0x7f,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x04,0x08,0x18,0x10,0x30,0x30,0x30,0x30,0x10,0x10,0x18,0x0c,0x04,
0x00,0x00,0x00,0x20,0x10,0x08,0x08,0x0c,0x04,0x04,0x04,0x0c,0x08,0x18,0x10,0x20,
0x00,0x00,0x00,0x08,0x0a,0x34,0x1c,0x6a,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x7f,0x18,0x18,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x08,0x30,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x02,0x06,0x04,0x0c,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x00,0x00,
0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x47,0x5b,0x73,0x42,0x66,0x3c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x78,0x48,0x08,0x08,0x08,0x08,0x08,0x7e,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3c,0x46,0x06,0x06,0x04,0x08,0x10,0x20,0x7e,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7c,0x06,0x06,0x04,0x3c,0x02,0x02,0x06,0x7c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x0c,0x1c,0x14,0x24,0x64,0x44,0xff,0x04,0x04,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7e,0x60,0x60,0x60,0x7e,0x02,0x02,0x06,0x7c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x1e,0x30,0x60,0x48,0x76,0x42,0x42,0x62,0x3c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7e,0x02,0x06,0x04,0x0c,0x08,0x18,0x10,0x30,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3c,0x62,0x42,0x36,0x1c,0x66,0x42,0x42,0x3c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x42,0x66,0x1a,0x02,0x04,0x78,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x08,0x30,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x18,0x30,0x60,0x10,0x0c,0x06,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x18,0x04,0x06,0x0c,0x10,0x20,0x00,0x00,0x00,
0x00,0x00,0x00,0x30,0x1c,0x06,0x06,0x06,0x18,0x10,0x00,0x10,0x10,0x00,0x00,0x00,
0x00,0x00,0x00,0x1c,0x22,0x41,0x41,0xdd,0xb5,0xa5,0xa5,0xaf,0x94,0xc0,0x40,0x3c,
0x00,0x00,0x00,0x00,0x18,0x1c,0x34,0x24,0x26,0x62,0x7e,0x43,0xc1,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7c,0x46,0x42,0x46,0x7c,0x42,0x42,0x42,0x7c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x1e,0x20,0x40,0x40,0x40,0x40,0x40,0x60,0x3e,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7c,0x46,0x42,0x43,0x43,0x43,0x42,0x46,0x78,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7e,0x60,0x60,0x60,0x7e,0x60,0x60,0x60,0x7e,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7e,0x60,0x60,0x60,0x7e,0x60,0x60,0x60,0x60,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x1e,0x60,0x40,0x40,0xce,0x42,0x42,0x62,0x3e,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x7e,0x42,0x42,0x42,0x42,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7c,0x04,0x04,0x04,0x04,0x04,0x04,0x44,0x78,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x42,0x44,0x48,0x50,0x70,0x58,0x4c,0x44,0x42,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3e,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x62,0x66,0x67,0x5f,0x5b,0x5b,0xc1,0xc1,0xc1,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x62,0x62,0x72,0x52,0x5a,0x4a,0x4e,0x46,0x46,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3c,0x62,0x43,0xc3,0xc3,0xc3,0x43,0x62,0x3c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7c,0x46,0x42,0x42,0x46,0x78,0x40,0x40,0x40,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3c,0x62,0x43,0xc3,0xc3,0xc3,0x43,0x62,0x3c,0x18,0x0f,0x00,
0x00,0x00,0x00,0x00,0x7c,0x66,0x62,0x66,0x7c,0x6c,0x64,0x66,0x62,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3e,0x60,0x40,0x60,0x1c,0x06,0x02,0x02,0x7c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x62,0x3c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xc1,0x43,0x42,0x62,0x26,0x24,0x34,0x1c,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xc1,0xc1,0x41,0x49,0x5b,0x5b,0x76,0x66,0x66,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x43,0x66,0x34,0x18,0x18,0x1c,0x24,0x66,0xc3,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xc1,0x42,0x66,0x34,0x1c,0x18,0x18,0x18,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7e,0x02,0x04,0x0c,0x18,0x10,0x20,0x60,0x7e,0x00,0x00,0x00,
0x00,0x00,0x00,0x1c,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1c,
0x00,0x00,0x00,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x0c,0x04,0x06,0x02,0x00,0x00,
0x00,0x00,0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,
0x00,0x00,0x00,0x00,0x18,0x1c,0x24,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
0x00,0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x06,0x02,0x3e,0x42,0x46,0x7a,0x00,0x00,0x00,
0x00,0x00,0x00,0x40,0x40,0x40,0x5c,0x62,0x42,0x42,0x42,0x42,0x7c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x20,0x60,0x40,0x60,0x20,0x3e,0x00,0x00,0x00,
0x00,0x00,0x00,0x02,0x02,0x02,0x3e,0x62,0x42,0x42,0x42,0x66,0x3a,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x62,0x42,0x7e,0x40,0x60,0x3e,0x00,0x00,0x00,
0x00,0x00,0x00,0x0f,0x18,0x10,0x10,0x7e,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x66,0x42,0x66,0x58,0x40,0x3e,0x43,0x42,0x3c,
0x00,0x00,0x00,0x40,0x40,0x40,0x5c,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x18,0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x7e,0x00,0x00,0x00,
0x00,0x00,0x00,0x04,0x0c,0x00,0x7c,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x0c,0x78,
0x00,0x00,0x00,0x60,0x60,0x60,0x62,0x6c,0x78,0x70,0x68,0x64,0x62,0x00,0x00,0x00,
0x00,0x00,0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x7e,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x5c,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x62,0x42,0x43,0x42,0x62,0x3c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x5c,0x62,0x42,0x42,0x42,0x42,0x7c,0x40,0x40,0x40,
0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x62,0x42,0x42,0x42,0x66,0x3a,0x02,0x02,0x02,
0x00,0x00,0x00,0x00,0x00,0x00,0x6e,0x72,0x63,0x60,0x60,0x60,0x60,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x20,0x20,0x3c,0x06,0x02,0x7c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x10,0xfe,0x10,0x10,0x10,0x10,0x10,0x1e,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x66,0x3a,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x42,0x66,0x24,0x34,0x18,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xc1,0xc1,0x5b,0x5a,0x5e,0x66,0x66,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x26,0x1c,0x18,0x1c,0x26,0x62,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x42,0x66,0x24,0x34,0x1c,0x18,0x18,0x30,0xe0,
0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x06,0x0c,0x18,0x10,0x20,0x7e,0x00,0x00,0x00,
0x00,0x00,0x00,0x0e,0x18,0x10,0x10,0x10,0x30,0x70,0x10,0x10,0x10,0x10,0x18,0x0e,
0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
0x00,0x00,0x00,0x30,0x18,0x08,0x08,0x08,0x0c,0x0e,0x08,0x08,0x08,0x08,0x18,0x30,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x71,0x4b,0x06,0x00,0x00,0x00,0x00,0x00,
};
/*
* 常用ASCII表,偏移量32,大小:24(高度)* 16 (宽度)
*/
const uint8_t ASCII16x24_Table [ ] = { //@conslons字体,阴码点阵格式,逐行顺向取摸
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x01,0x80,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,
0x00,0x00,0x03,0xc0,0x03,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x70,0x0e,0x70,0x0e,0x70,
0x0c,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x18,0x06,0x38,
0x06,0x30,0x7f,0xfe,0x0c,0x30,0x0c,0x30,0x0c,0x30,0x0c,0x30,0x7f,0xfe,0x0c,0x60,
0x1c,0x60,0x18,0x60,0x18,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0xc0,0x0f,0xf8,0x3c,0xc8,
0x31,0xc0,0x31,0x80,0x3d,0x80,0x1f,0x80,0x03,0xf0,0x01,0xf8,0x03,0x1c,0x03,0x0c,
0x03,0x1c,0x3f,0xf8,0x3f,0xe0,0x07,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x00,0x7e,0x0e,0x63,0x0c,0x63,0x18,
0x63,0x30,0x7e,0x60,0x00,0xc0,0x01,0x80,0x03,0x00,0x07,0x7c,0x0e,0xe6,0x1c,0xc6,
0x18,0xc6,0x30,0xc6,0x60,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xe0,0x1c,0xf0,0x38,0x70,
0x38,0x70,0x1c,0x60,0x1f,0xc0,0x0f,0x00,0x3f,0x8c,0x71,0xcc,0x60,0xec,0x60,0x7c,
0x70,0x38,0x3c,0xfc,0x1f,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xc0,0x01,0x80,0x01,0x80,
0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0xe0,0x01,0xc0,0x01,0x80,
0x03,0x00,0x07,0x00,0x06,0x00,0x06,0x00,0x0e,0x00,0x0e,0x00,0x0e,0x00,0x0e,0x00,
0x06,0x00,0x07,0x00,0x03,0x00,0x03,0x80,0x01,0xc0,0x00,0xe0,0x00,0x30,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0x00,0x03,0x80,0x01,0x80,
0x01,0xc0,0x00,0xe0,0x00,0x60,0x00,0x60,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x60,
0x00,0x60,0x00,0xe0,0x00,0xc0,0x01,0x80,0x03,0x80,0x06,0x00,0x0c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x11,0x88,0x1d,0xb8,
0x03,0xc0,0x07,0xe0,0x3d,0xbc,0x01,0x88,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x7f,0xfe,0x01,0x80,0x01,0x80,
0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x03,0xc0,0x03,0xc0,0x01,0xc0,0x01,0xc0,0x03,0x80,0x1f,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x03,0xc0,0x03,0xc0,0x03,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x38,0x00,0x30,
0x00,0x60,0x00,0xe0,0x00,0xc0,0x01,0xc0,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,
0x0e,0x00,0x0c,0x00,0x1c,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x0f,0xf0,0x1c,0x38,
0x38,0x1c,0x30,0x1c,0x70,0x7e,0x70,0xee,0x73,0x8e,0x7e,0x0e,0x7c,0x0c,0x30,0x0c,
0x38,0x1c,0x1e,0x78,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xc0,0x1f,0xc0,
0x39,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,
0x01,0xc0,0x3f,0xfc,0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x1f,0xf0,0x18,0x38,
0x00,0x38,0x00,0x18,0x00,0x38,0x00,0x38,0x00,0x70,0x01,0xe0,0x03,0x80,0x07,0x00,
0x1c,0x00,0x3f,0xfc,0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x1f,0xf0,0x00,0x38,
0x00,0x38,0x00,0x38,0x00,0x30,0x07,0xe0,0x07,0xf0,0x00,0x38,0x00,0x1c,0x00,0x1c,
0x00,0x18,0x20,0xf8,0x3f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x01,0xb0,
0x03,0x30,0x07,0x30,0x0e,0x30,0x1c,0x30,0x38,0x30,0x70,0x30,0x7f,0xfe,0x7f,0xfe,
0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xf8,0x18,0x00,
0x18,0x00,0x18,0x00,0x18,0x00,0x1f,0xe0,0x00,0xf8,0x00,0x1c,0x00,0x1c,0x00,0x1c,
0x00,0x38,0x00,0xf0,0x1f,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xf8,0x0f,0x00,
0x1c,0x00,0x18,0x00,0x30,0x00,0x37,0xf8,0x3c,0x3c,0x30,0x0c,0x30,0x0c,0x38,0x0c,
0x38,0x1c,0x1e,0x38,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xfc,0x00,0x1c,
0x00,0x18,0x00,0x38,0x00,0x70,0x00,0x60,0x00,0xe0,0x01,0xc0,0x01,0x80,0x03,0x80,
0x07,0x00,0x06,0x00,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xc0,0x1f,0xf8,0x38,0x1c,
0x38,0x1c,0x38,0x1c,0x1c,0x38,0x0f,0xf0,0x07,0xf0,0x1c,0x78,0x38,0x1c,0x30,0x0c,
0x38,0x1c,0x3c,0x38,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x1f,0xf0,0x38,0x38,
0x30,0x1c,0x70,0x1c,0x70,0x0c,0x38,0x0c,0x1f,0xfc,0x0f,0xcc,0x00,0x1c,0x00,0x18,
0x00,0x70,0x1f,0xe0,0x1f,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x03,0xc0,0x03,0xc0,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x03,0xc0,0x03,0xc0,0x03,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x03,0xc0,0x03,0xc0,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x03,0xc0,0x03,0xc0,0x01,0xc0,0x01,0xc0,0x03,0x80,0x0f,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x38,0x00,0xf0,0x01,0xc0,0x07,0x00,0x1e,0x00,0x38,0x00,0x0e,0x00,0x07,0x80,
0x01,0xc0,0x00,0x70,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xfc,0x00,0x00,0x00,0x00,0x3f,0xfc,0x3f,0xfc,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x1c,0x00,0x0f,0x00,0x03,0x80,0x01,0xe0,0x00,0x78,0x00,0x1c,0x00,0x70,0x01,0xe0,
0x03,0x80,0x0e,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xc0,0x00,0xf0,0x00,0x38,
0x00,0x38,0x00,0x38,0x00,0x38,0x03,0xf0,0x03,0x80,0x03,0x00,0x03,0x00,0x00,0x00,
0x00,0x00,0x07,0x80,0x07,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x07,0xf8,0x0c,0x0c,0x18,0x06,
0x30,0x06,0x70,0x03,0x63,0xf3,0x66,0x33,0xc6,0x73,0xcc,0x63,0xcc,0x62,0xcc,0x66,
0xcc,0xe6,0xc7,0xfc,0xe0,0x00,0x60,0x00,0x70,0x00,0x38,0x10,0x1f,0xf0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xc0,0x07,0xe0,
0x06,0xe0,0x0e,0x70,0x0e,0x70,0x0c,0x30,0x1c,0x38,0x18,0x18,0x3f,0xfc,0x3f,0xfc,
0x70,0x0e,0x60,0x0e,0xe0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xf0,0x38,0x38,
0x38,0x1c,0x38,0x1c,0x38,0x38,0x3f,0xf0,0x3f,0xf8,0x38,0x1c,0x38,0x0c,0x38,0x0c,
0x38,0x1c,0x3f,0xf8,0x3f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x07,0xfc,0x1e,0x04,
0x38,0x00,0x38,0x00,0x30,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x30,0x00,0x38,0x00,
0x3c,0x00,0x1f,0x9c,0x07,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xf0,0x30,0x78,
0x30,0x1c,0x30,0x0c,0x30,0x0e,0x30,0x0e,0x30,0x0e,0x30,0x0e,0x30,0x0e,0x30,0x1c,
0x30,0x38,0x3f,0xf0,0x3f,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xf8,0x18,0x00,
0x18,0x00,0x18,0x00,0x18,0x00,0x1f,0xf8,0x1f,0xf8,0x18,0x00,0x18,0x00,0x18,0x00,
0x18,0x00,0x1f,0xf8,0x1f,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xf8,0x18,0x00,
0x18,0x00,0x18,0x00,0x18,0x00,0x1f,0xf8,0x1f,0xf8,0x18,0x00,0x18,0x00,0x18,0x00,
0x18,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x07,0xfc,0x1e,0x04,
0x38,0x00,0x30,0x00,0x70,0x00,0x70,0x00,0x70,0xfc,0x70,0x0c,0x70,0x0c,0x30,0x0c,
0x38,0x0c,0x1f,0x1c,0x07,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x0c,0x30,0x0c,
0x30,0x0c,0x30,0x0c,0x30,0x0c,0x3f,0xfc,0x3f,0xfc,0x30,0x0c,0x30,0x0c,0x30,0x0c,
0x30,0x0c,0x30,0x0c,0x30,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xfc,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,
0x01,0x80,0x3f,0xfc,0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xf0,0x00,0x30,
0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,
0x00,0x70,0x1d,0xe0,0x1f,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x1c,0x38,0x70,
0x38,0xe0,0x39,0xc0,0x3b,0x80,0x3f,0x00,0x3f,0x00,0x3b,0x80,0x39,0xc0,0x38,0xe0,
0x38,0x70,0x38,0x38,0x38,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x00,0x1c,0x00,
0x1c,0x00,0x1c,0x00,0x1c,0x00,0x1c,0x00,0x1c,0x00,0x1c,0x00,0x1c,0x00,0x1c,0x00,
0x1c,0x00,0x1f,0xfc,0x1f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x1c,0x7c,0x3c,
0x6c,0x3e,0x6e,0x6e,0x66,0x6e,0x66,0xce,0x63,0xc6,0x63,0x86,0x61,0x86,0x60,0x06,
0x60,0x06,0x60,0x06,0x60,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x0c,0x3c,0x0c,
0x3e,0x0c,0x36,0x0c,0x33,0x0c,0x33,0x8c,0x31,0x8c,0x31,0xcc,0x30,0xec,0x30,0x6c,
0x30,0x7c,0x30,0x3c,0x30,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xc0,0x0f,0xf8,0x1c,0x3c,
0x38,0x1c,0x70,0x0e,0x70,0x0e,0x60,0x06,0x60,0x06,0x70,0x0e,0x70,0x0e,0x70,0x0c,
0x38,0x1c,0x1e,0x78,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xf0,0x38,0x3c,
0x38,0x1c,0x38,0x0c,0x38,0x0c,0x38,0x1c,0x38,0x78,0x3f,0xe0,0x38,0x00,0x38,0x00,
0x38,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xc0,0x0f,0xf8,0x1c,0x3c,
0x38,0x1c,0x70,0x0e,0x70,0x0e,0x60,0x06,0x60,0x06,0x70,0x0e,0x70,0x0e,0x70,0x0c,
0x38,0x1c,0x1e,0x78,0x0f,0xe0,0x01,0x80,0x01,0xc0,0x00,0xff,0x00,0x3c,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xf0,0x38,0x38,
0x38,0x18,0x38,0x18,0x38,0x38,0x38,0xf0,0x3f,0xc0,0x38,0xe0,0x38,0x70,0x38,0x38,
0x38,0x38,0x38,0x1c,0x38,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe0,0x0f,0xf8,0x38,0x00,
0x38,0x00,0x38,0x00,0x3c,0x00,0x1f,0x80,0x03,0xf0,0x00,0x78,0x00,0x1c,0x00,0x1c,
0x00,0x1c,0x38,0x78,0x3f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xfe,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x0c,0x30,0x0c,
0x30,0x0c,0x30,0x0c,0x30,0x0c,0x30,0x0c,0x30,0x0c,0x30,0x0c,0x30,0x0c,0x30,0x0c,
0x38,0x1c,0x1c,0x38,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x06,0x70,0x0e,
0x70,0x0e,0x38,0x1c,0x38,0x1c,0x1c,0x18,0x1c,0x38,0x0c,0x30,0x0e,0x70,0x06,0x60,
0x07,0xe0,0x03,0xc0,0x03,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x06,0x60,0x06,
0x60,0x06,0x60,0x06,0x61,0x86,0x63,0x86,0x73,0xc6,0x73,0xce,0x76,0x6c,0x36,0x6c,
0x3c,0x3c,0x3c,0x3c,0x38,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x1c,0x38,0x18,
0x1c,0x38,0x0e,0x70,0x07,0xe0,0x03,0xc0,0x03,0xc0,0x07,0xe0,0x0e,0x70,0x1c,0x38,
0x18,0x38,0x38,0x1c,0x70,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x0e,0x70,0x0c,
0x38,0x1c,0x1c,0x38,0x0e,0x70,0x06,0x60,0x07,0xe0,0x03,0xc0,0x01,0x80,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xfc,0x00,0x1c,
0x00,0x38,0x00,0x70,0x00,0xe0,0x01,0xc0,0x03,0x80,0x07,0x00,0x0e,0x00,0x0c,0x00,
0x18,0x00,0x3f,0xfc,0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xf0,0x07,0xf0,0x06,0x00,0x06,0x00,
0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,
0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x07,0xf0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x1c,0x00,0x0c,0x00,
0x06,0x00,0x07,0x00,0x03,0x00,0x03,0x80,0x01,0x80,0x01,0xc0,0x00,0xc0,0x00,0x60,
0x00,0x70,0x00,0x30,0x00,0x38,0x00,0x18,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xe0,0x0f,0xe0,0x00,0x60,0x00,0x60,
0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,
0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x0f,0xe0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xc0,0x06,0xc0,
0x06,0x60,0x0c,0x30,0x18,0x18,0x30,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x00,0x03,0x80,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x1f,0xf0,0x10,0x38,0x00,0x1c,0x00,0x1c,0x0f,0xfc,0x1c,0x1c,0x38,0x1c,
0x38,0x1c,0x3c,0xfc,0x1f,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x38,0x00,
0x38,0x00,0x3b,0xf8,0x3e,0x1c,0x3c,0x1c,0x38,0x0c,0x38,0x0c,0x38,0x0c,0x38,0x0c,
0x38,0x1c,0x3c,0x78,0x1f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x07,0xf8,0x0e,0x00,0x1c,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,
0x1c,0x00,0x0f,0x18,0x07,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x00,0x1c,0x00,0x1c,
0x00,0x1c,0x0f,0xfc,0x1c,0x1c,0x38,0x1c,0x30,0x1c,0x30,0x1c,0x30,0x1c,0x30,0x1c,
0x38,0x3c,0x1c,0xfc,0x0f,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0f,0xf0,0x1c,0x38,0x38,0x1c,0x30,0x0c,0x3f,0xfc,0x30,0x00,0x30,0x00,
0x38,0x00,0x1e,0x0c,0x07,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x01,0xfe,0x03,0x80,0x03,0x00,
0x03,0x00,0x03,0x00,0x7f,0xfc,0x7f,0xfc,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,
0x03,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0f,0xfe,0x1c,0x38,0x38,0x18,0x38,0x18,0x18,0x38,0x1f,0xf0,0x3b,0x80,
0x30,0x00,0x3f,0xf0,0x1f,0xfc,0x30,0x0e,0x70,0x0e,0x38,0x1c,0x1f,0xf8,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x38,0x00,
0x38,0x00,0x3b,0xf8,0x3e,0x38,0x3c,0x1c,0x38,0x1c,0x38,0x1c,0x38,0x1c,0x38,0x1c,
0x38,0x1c,0x38,0x1c,0x38,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0xc0,0x03,0xc0,0x00,0x00,
0x00,0x00,0x1f,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,
0x01,0xc0,0x01,0xc0,0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x70,0x00,0x70,0x00,0x00,
0x00,0x00,0x3f,0xf0,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,
0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x20,0xe0,0x3f,0xc0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x18,0x00,
0x18,0x00,0x18,0x3c,0x18,0x70,0x18,0xe0,0x1b,0x80,0x1f,0x00,0x1b,0x80,0x19,0xe0,
0x18,0x70,0x18,0x38,0x18,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xc0,0x01,0xc0,0x01,0xc0,
0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,
0x01,0xc0,0x01,0xc0,0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x6f,0x3c,0x79,0xee,0x71,0xce,0x71,0x8e,0x71,0x8e,0x71,0x8e,0x71,0x8e,
0x71,0x8e,0x71,0x8e,0x71,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x3b,0xf8,0x3e,0x38,0x3c,0x1c,0x38,0x1c,0x38,0x1c,0x38,0x1c,0x38,0x1c,
0x38,0x1c,0x38,0x1c,0x38,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0f,0xf0,0x1c,0x3c,0x38,0x1c,0x70,0x0e,0x70,0x0e,0x70,0x0e,0x70,0x0c,
0x38,0x1c,0x1e,0x78,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x3b,0xf8,0x3e,0x1c,0x3c,0x1c,0x38,0x0c,0x38,0x0c,0x38,0x0c,0x38,0x0c,
0x38,0x1c,0x3c,0x78,0x3f,0xe0,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0f,0xfc,0x1c,0x1c,0x38,0x1c,0x30,0x1c,0x30,0x1c,0x30,0x1c,0x30,0x1c,
0x38,0x3c,0x1c,0xfc,0x0f,0x9c,0x00,0x1c,0x00,0x1c,0x00,0x1c,0x00,0x1c,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x19,0xf8,0x1f,0x1c,0x1c,0x0c,0x18,0x0e,0x18,0x00,0x18,0x00,0x18,0x00,
0x18,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0f,0xf8,0x1c,0x00,0x18,0x00,0x1e,0x00,0x0f,0xc0,0x01,0xf8,0x00,0x18,
0x00,0x18,0x18,0x38,0x1f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x06,0x00,
0x06,0x00,0x7f,0xfc,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,
0x07,0x00,0x07,0x84,0x01,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x1c,0x38,0x1c,0x38,0x1c,0x38,0x1c,0x38,0x1c,0x38,0x1c,0x38,0x1c,
0x38,0x3c,0x1c,0xfc,0x0f,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x70,0x0c,0x38,0x1c,0x38,0x18,0x1c,0x38,0x0c,0x30,0x0e,0x70,0x06,0x60,
0x07,0xe0,0x03,0xc0,0x03,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x60,0x06,0x60,0x06,0x61,0x86,0x73,0x8e,0x73,0xcc,0x33,0xcc,0x36,0x6c,
0x36,0x6c,0x3c,0x3c,0x3c,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x1c,0x1c,0x38,0x0e,0x70,0x07,0xe0,0x03,0xc0,0x03,0xc0,0x07,0xe0,
0x0e,0x70,0x1c,0x38,0x38,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x70,0x0c,0x38,0x1c,0x38,0x18,0x1c,0x38,0x0c,0x30,0x0e,0x70,0x06,0x60,
0x07,0xe0,0x03,0xc0,0x03,0xc0,0x03,0x80,0x07,0x00,0x0e,0x00,0x7c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x1f,0xf8,0x00,0x38,0x00,0x70,0x00,0xe0,0x01,0xc0,0x03,0x80,0x07,0x00,
0x0c,0x00,0x1f,0xfc,0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x01,0xf8,0x03,0x80,0x03,0x80,
0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x3f,0x00,0x3e,0x00,0x03,0x00,0x03,0x80,
0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x01,0xc0,0x00,0xf8,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,
0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x00,0x1f,0x80,0x01,0x80,0x01,0xc0,
0x01,0xc0,0x01,0xc0,0x01,0xc0,0x00,0xc0,0x00,0xfc,0x00,0x7c,0x00,0xc0,0x01,0xc0,
0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x03,0x80,0x1f,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x00,0x3f,0x06,0x71,0xce,0x60,0xfc,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
/*
* 常用ASCII表,偏移量32,大小:32(高度)* 24 (宽度)
*/
const uint8_t ASCII24x32_Table [ ] = { //@conslons字体,阴码点阵格式,逐行顺向取摸
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,
0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,
0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x3c,0x00,0x00,0x7e,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x03,0xc3,0xe0,0x03,0xc3,0xe0,0x03,0xc3,0xc0,0x03,0xc3,0xc0,0x03,0xc3,
0xc0,0x03,0xc3,0xc0,0x03,0xc1,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe0,0xe0,0x01,0xc0,0xe0,0x01,0xc0,
0xe0,0x01,0xc0,0xe0,0x3f,0xff,0xfe,0x3f,0xff,0xfe,0x03,0xc1,0xc0,0x03,0x81,0xc0,
0x03,0x81,0xc0,0x03,0x81,0xc0,0x7f,0xff,0xfc,0x7f,0xff,0xfc,0x07,0x83,0x80,0x07,
0x03,0x80,0x07,0x03,0x80,0x07,0x03,0x80,0x07,0x07,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x07,0x00,0x00,0x0f,0x00,0x00,0x0e,0x00,0x01,0xff,0xf0,0x07,0xff,0xf0,0x1f,0x0e,
0x00,0x1e,0x1e,0x00,0x1e,0x1c,0x00,0x1e,0x1c,0x00,0x0f,0xdc,0x00,0x07,0xfc,0x00,
0x00,0xff,0x80,0x00,0x3f,0xf0,0x00,0x38,0xf8,0x00,0x38,0x78,0x00,0x78,0x3c,0x00,
0x70,0x78,0x30,0x71,0xf8,0x3f,0xff,0xe0,0x1f,0xff,0x00,0x00,0xe0,0x00,0x00,0xe0,
0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0f,0x80,0x0f,0x3f,0xe0,0x1e,0x78,0x70,0x3c,0x70,0x70,0x70,0x70,0x70,
0xe0,0x70,0x71,0xc0,0x3f,0xe3,0x80,0x1f,0xc7,0x00,0x00,0x0e,0x00,0x00,0x1c,0x00,
0x00,0x78,0x00,0x00,0xf0,0xf0,0x01,0xe7,0xfc,0x03,0xcf,0x0e,0x07,0x8e,0x0e,0x0f,
0x0e,0x0e,0x1e,0x0e,0x0e,0x3c,0x07,0xbc,0x70,0x03,0xf8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0xff,0x00,0x07,0xff,0x80,0x0f,0x03,0xc0,0x0f,0x03,
0xc0,0x0f,0x03,0xc0,0x0f,0x07,0x80,0x07,0x9f,0x00,0x03,0xfe,0x00,0x03,0xf0,0x00,
0x0f,0xf8,0x3c,0x3e,0x7c,0x3c,0x3c,0x1f,0x3c,0x78,0x0f,0xf8,0x78,0x07,0xf8,0x7c,
0x01,0xf0,0x3e,0x03,0xf8,0x1f,0xff,0xfc,0x07,0xfe,0x1f,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x3e,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,
0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x80,0x00,0x01,0xc0,0x00,0x07,0x80,0x00,0x0f,0x00,0x00,0x1e,0x00,0x00,0x3c,
0x00,0x00,0x78,0x00,0x00,0xf0,0x00,0x00,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,
0x01,0xc0,0x00,0x03,0xc0,0x00,0x03,0xc0,0x00,0x01,0xc0,0x00,0x01,0xe0,0x00,0x01,
0xe0,0x00,0x00,0xf0,0x00,0x00,0xf0,0x00,0x00,0x78,0x00,0x00,0x3c,0x00,0x00,0x1e,
0x00,0x00,0x0f,0x00,0x00,0x07,0xc0,0x00,0x01,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x03,0xc0,0x00,0x01,0xe0,0x00,0x00,0xf0,0x00,0x00,0x7c,0x00,0x00,0x3e,
0x00,0x00,0x1e,0x00,0x00,0x0f,0x00,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x03,0x80,
0x00,0x03,0xc0,0x00,0x03,0xc0,0x00,0x03,0xc0,0x00,0x03,0xc0,0x00,0x03,0x80,0x00,
0x07,0x80,0x00,0x07,0x80,0x00,0x0f,0x00,0x00,0x1e,0x00,0x00,0x3c,0x00,0x00,0x78,
0x00,0x00,0xf0,0x00,0x01,0xe0,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x1c,0x00,0x00,0x1c,0x00,0x00,0x18,0x00,0x0f,0x18,0xf0,0x07,0xdb,
0xe0,0x00,0x7f,0x00,0x00,0xff,0x00,0x07,0xdb,0xe0,0x0e,0x18,0x70,0x00,0x18,0x00,
0x00,0x1c,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,
0x00,0x3c,0x00,0x3f,0xff,0xfc,0x3f,0xff,0xfc,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,
0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x7c,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x3e,0x00,0x00,0x1e,0x00,0x00,0x3c,
0x00,0x00,0xf8,0x00,0x07,0xe0,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0xff,0xe0,0x03,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x7c,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x78,0x00,0x00,0xf0,0x00,0x00,0xe0,0x00,0x01,0xe0,0x00,0x03,
0xc0,0x00,0x03,0x80,0x00,0x07,0x80,0x00,0x0f,0x00,0x00,0x0e,0x00,0x00,0x1e,0x00,
0x00,0x3c,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0xf0,0x00,0x00,0xe0,0x00,0x01,
0xc0,0x00,0x03,0xc0,0x00,0x07,0x80,0x00,0x07,0x00,0x00,0x0f,0x00,0x00,0x1e,0x00,
0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xc0,0x07,0xff,0xe0,0x0f,0x00,
0xf0,0x1e,0x00,0x78,0x1e,0x00,0x3c,0x3c,0x00,0xfc,0x3c,0x07,0xfc,0x3c,0x1f,0xbc,
0x3c,0x7c,0x1c,0x3d,0xf0,0x3c,0x3f,0xc0,0x3c,0x3f,0x00,0x3c,0x1e,0x00,0x38,0x1e,
0x00,0x78,0x0f,0x80,0xf0,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x03,0xfe,0x00,0x1f,0xde,
0x00,0x0e,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,
0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,
0x1e,0x00,0x00,0x1e,0x00,0x0f,0xff,0xf8,0x0f,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0x80,0x0f,0xff,0xe0,0x0e,0x01,
0xf0,0x00,0x00,0xf0,0x00,0x00,0xf0,0x00,0x00,0xf0,0x00,0x00,0xf0,0x00,0x01,0xe0,
0x00,0x03,0xc0,0x00,0x0f,0x80,0x00,0x3e,0x00,0x00,0x7c,0x00,0x01,0xf0,0x00,0x03,
0xc0,0x00,0x0f,0x80,0x00,0x1f,0xff,0xfc,0x1f,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0x80,0x0f,0xff,0xe0,0x00,0x01,
0xe0,0x00,0x00,0xf0,0x00,0x00,0xf0,0x00,0x01,0xe0,0x00,0x03,0xc0,0x01,0xff,0x00,
0x01,0xff,0xc0,0x00,0x03,0xf0,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,
0x00,0x78,0x00,0x01,0xf0,0x0f,0xff,0xc0,0x0f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xc0,0x00,0x1f,0xc0,0x00,0x3f,
0xc0,0x00,0x7b,0xc0,0x00,0xf3,0xc0,0x01,0xe3,0xc0,0x03,0xc3,0xc0,0x07,0x83,0xc0,
0x0f,0x03,0xc0,0x1c,0x03,0xc0,0x38,0x03,0xc0,0x7f,0xff,0xfe,0x7f,0xff,0xfe,0x00,
0x03,0xc0,0x00,0x03,0xc0,0x00,0x03,0xc0,0x00,0x03,0xc0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xe0,0x0f,0xff,0xe0,0x0f,0x00,
0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0xff,0x80,
0x0f,0xff,0xe0,0x00,0x00,0xf0,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,
0x00,0xf0,0x00,0x03,0xe0,0x0f,0xff,0xc0,0x0f,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xf0,0x01,0xff,0xf0,0x03,0xe0,
0x00,0x07,0x80,0x00,0x0f,0x00,0x00,0x1e,0x00,0x00,0x1e,0x1f,0x00,0x1f,0xff,0xe0,
0x1f,0xc1,0xf8,0x1e,0x00,0x78,0x1e,0x00,0x3c,0x1e,0x00,0x3c,0x1e,0x00,0x3c,0x0f,
0x00,0x78,0x0f,0x80,0xf8,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0xfc,0x1f,0xff,0xfc,0x00,0x00,
0x78,0x00,0x00,0xf0,0x00,0x00,0xe0,0x00,0x01,0xe0,0x00,0x03,0xc0,0x00,0x07,0x80,
0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x1e,0x00,0x00,0x3c,0x00,0x00,0x78,0x00,0x00,
0xf0,0x00,0x01,0xf0,0x00,0x01,0xe0,0x00,0x03,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xe0,0x0f,0xe3,0xf0,0x0f,0x00,
0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x0f,0x00,0xf0,0x07,0xe3,0xe0,0x01,0xff,0x80,
0x01,0xff,0x80,0x07,0xe7,0xe0,0x0f,0x00,0xf8,0x1e,0x00,0x78,0x1e,0x00,0x3c,0x1e,
0x00,0x7c,0x1f,0x00,0xf8,0x0f,0xff,0xf0,0x03,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0x80,0x0f,0xc7,0xe0,0x1e,0x00,
0xf0,0x1e,0x00,0x78,0x3c,0x00,0x78,0x3c,0x00,0x78,0x3c,0x00,0x38,0x1e,0x00,0x78,
0x0f,0xef,0xf8,0x07,0xff,0xb8,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0xf0,0x00,
0x01,0xe0,0x00,0x0f,0xc0,0x0f,0xff,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x18,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x3c,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x18,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x3e,0x00,0x00,0x7e,0x00,0x00,0x7f,0x00,0x00,0x1f,0x00,0x00,0x1e,0x00,0x00,0x1e,
0x00,0x00,0xfc,0x00,0x07,0xf0,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x40,0x00,0x01,0xe0,0x00,0x07,0xc0,0x00,0x1f,0x00,0x00,0x7e,0x00,0x01,0xf8,0x00,
0x03,0xe0,0x00,0x0f,0x80,0x00,0x0f,0x80,0x00,0x03,0xe0,0x00,0x00,0xf8,0x00,0x00,
0x3e,0x00,0x00,0x0f,0x80,0x00,0x03,0xe0,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0xf8,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0xf8,0x1f,0xff,0xf8,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x07,0x80,0x00,0x03,0xe0,0x00,0x00,0xf8,0x00,0x00,0x3e,0x00,0x00,0x0f,0x80,
0x00,0x03,0xe0,0x00,0x00,0xf8,0x00,0x01,0xf0,0x00,0x07,0xc0,0x00,0x1f,0x00,0x00,
0x7c,0x00,0x01,0xf0,0x00,0x07,0xc0,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0xc0,0x00,0x01,0xfe,0x00,0x00,0x7f,0x80,0x00,0x07,0xc0,0x00,0x01,
0xe0,0x00,0x00,0xf0,0x00,0x00,0xf0,0x00,0x01,0xf0,0x00,0x03,0xe0,0x00,0x7f,0xc0,
0x00,0x7e,0x00,0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xf8,0x00,0x00,0xf8,0x00,0x00,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x1f,0x80,0x00,0xff,0xf0,0x03,0xc0,0x78,0x07,0x80,0x1c,0x0e,0x00,
0x0e,0x1c,0x00,0x0e,0x3c,0x00,0x0f,0x38,0x3f,0xc7,0x78,0xff,0xc7,0x70,0xe3,0xc7,
0x71,0xc3,0xc7,0xf3,0xc3,0x87,0xe3,0xc3,0x87,0xe3,0x87,0x8e,0xe3,0x87,0x8e,0xe3,
0xcf,0x8e,0xe3,0xff,0xfc,0x71,0xf9,0xf0,0x70,0x00,0x00,0x70,0x00,0x00,0x38,0x00,
0x00,0x3c,0x00,0x00,0x0f,0x01,0xc0,0x07,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7f,0x00,0x00,0xff,
0x00,0x00,0xe7,0x80,0x01,0xe7,0x80,0x03,0xc3,0xc0,0x03,0xc3,0xc0,0x07,0x81,0xe0,
0x07,0x81,0xe0,0x0f,0x00,0xf0,0x0f,0x00,0xf8,0x1f,0xff,0xf8,0x1f,0xff,0xfc,0x3c,
0x00,0x3c,0x3c,0x00,0x1e,0x78,0x00,0x1e,0xf0,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0xc0,0x1f,0xff,0xf0,0x1e,0x00,
0xf0,0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0xf0,0x1e,0x01,0xf0,0x1f,0xff,0xc0,
0x1f,0xff,0xe0,0x1e,0x01,0xf8,0x1e,0x00,0x78,0x1e,0x00,0x3c,0x1e,0x00,0x3c,0x1e,
0x00,0x78,0x1e,0x00,0xf8,0x1f,0xff,0xe0,0x1f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xf8,0x03,0xff,0xf8,0x07,0xc0,
0x00,0x0f,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,
0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3e,0x00,0x00,0x1e,0x00,0x00,0x0f,
0x00,0x00,0x0f,0xc0,0x08,0x03,0xff,0xf8,0x00,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x00,0x3f,0xff,0xe0,0x3c,0x01,
0xf0,0x3c,0x00,0x78,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x1e,
0x3c,0x00,0x1e,0x3c,0x00,0x1e,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x78,0x3c,
0x00,0xf8,0x3c,0x07,0xe0,0x3f,0xff,0xc0,0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xf0,0x0f,0xff,0xf0,0x0f,0x00,
0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0xff,0xf0,
0x0f,0xff,0xf0,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,
0x00,0x00,0x0f,0x00,0x00,0x0f,0xff,0xf0,0x0f,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xf0,0x0f,0xff,0xf0,0x0f,0x00,
0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0xff,0xf0,
0x0f,0xff,0xf0,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,
0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xfc,0x03,0xff,0xfc,0x0f,0xc0,
0x04,0x1f,0x00,0x00,0x1e,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x78,0x0f,0xfc,
0x78,0x0f,0xfc,0x78,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3e,0x00,0x3c,0x1f,
0x00,0x3c,0x0f,0xc0,0x3c,0x03,0xff,0xfc,0x00,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,
0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3f,0xff,0xfc,
0x3f,0xff,0xfc,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,
0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xf8,0x0f,0xff,0xf8,0x00,0x3c,
0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,
0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,
0x3c,0x00,0x00,0x3c,0x00,0x0f,0xff,0xf8,0x0f,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xe0,0x0f,0xff,0xe0,0x00,0x01,
0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,
0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,
0x03,0xc0,0x0c,0x07,0xc0,0x0f,0xff,0x80,0x07,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x00,0x78,0x1e,0x01,0xf0,0x1e,0x03,
0xc0,0x1e,0x07,0x80,0x1e,0x1f,0x00,0x1e,0x3c,0x00,0x1e,0x78,0x00,0x1e,0xf0,0x00,
0x1f,0xf0,0x00,0x1e,0xf8,0x00,0x1e,0x3c,0x00,0x1e,0x1e,0x00,0x1e,0x0f,0x80,0x1e,
0x07,0xc0,0x1e,0x01,0xe0,0x1e,0x00,0xf8,0x1e,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,
0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,
0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,
0x80,0x00,0x07,0x80,0x00,0x07,0xff,0xf8,0x07,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x7c,0x3f,0x00,0xfc,0x3f,0x81,
0xdc,0x3b,0x81,0xdc,0x3b,0xc3,0x9c,0x39,0xc3,0x9c,0x38,0xe7,0x1c,0x38,0xef,0x1c,
0x38,0x7e,0x1c,0x38,0x7c,0x1e,0x38,0x3c,0x1e,0x78,0x00,0x1e,0x78,0x00,0x1e,0x78,
0x00,0x1e,0x78,0x00,0x1e,0x78,0x00,0x1e,0x78,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x00,0x3c,0x1f,0x80,0x3c,0x1f,0xc0,
0x3c,0x1d,0xc0,0x3c,0x1d,0xe0,0x3c,0x1c,0xf0,0x3c,0x1c,0x78,0x3c,0x1c,0x78,0x3c,
0x1c,0x3c,0x3c,0x1c,0x1e,0x3c,0x1c,0x0f,0x3c,0x1c,0x0f,0x3c,0x1c,0x07,0xbc,0x1c,
0x03,0xfc,0x1c,0x01,0xfc,0x1c,0x00,0xfc,0x1c,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xc0,0x07,0xff,0xf0,0x0f,0x00,
0xf8,0x1e,0x00,0x7c,0x3c,0x00,0x3c,0x3c,0x00,0x1e,0x78,0x00,0x1e,0x78,0x00,0x1e,
0x78,0x00,0x1e,0x78,0x00,0x1e,0x78,0x00,0x1e,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x1e,
0x00,0x78,0x1f,0x00,0xf0,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0x80,0x1f,0xff,0xf0,0x1e,0x00,
0xf8,0x1e,0x00,0x7c,0x1e,0x00,0x3c,0x1e,0x00,0x3c,0x1e,0x00,0x3c,0x1e,0x00,0x78,
0x1e,0x03,0xf0,0x1f,0xff,0xc0,0x1f,0xfe,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,
0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xc0,0x07,0xff,0xf0,0x0f,0x00,
0xf8,0x1e,0x00,0x7c,0x3c,0x00,0x3c,0x3c,0x00,0x1e,0x78,0x00,0x1e,0x78,0x00,0x1e,
0x78,0x00,0x1e,0x78,0x00,0x1e,0x78,0x00,0x1e,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x1e,
0x00,0x78,0x1f,0x80,0xf0,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x3c,0x00,0x00,0x3c,
0x00,0x00,0x1f,0x06,0x00,0x0f,0xff,0x00,0x01,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0x80,0x0f,0xff,0xe0,0x0e,0x01,
0xf0,0x0e,0x00,0xf0,0x0e,0x00,0xf0,0x0e,0x00,0xf0,0x0e,0x01,0xf0,0x0f,0xff,0xc0,
0x0f,0xff,0x00,0x0e,0x1f,0x00,0x0e,0x07,0x80,0x0e,0x03,0xc0,0x0e,0x01,0xe0,0x0e,
0x00,0xf0,0x0e,0x00,0xf8,0x0e,0x00,0x78,0x0e,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xf0,0x0f,0xff,0xf0,0x1f,0x00,
0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1f,0x00,0x00,0x0f,0xc0,0x00,0x07,0xfc,0x00,
0x00,0xff,0x80,0x00,0x0f,0xf0,0x00,0x01,0xf8,0x00,0x00,0x78,0x00,0x00,0x78,0x00,
0x00,0x78,0x20,0x00,0xf8,0x3f,0xff,0xe0,0x3f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xfc,0x3f,0xff,0xfc,0x00,0x3c,
0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,
0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,
0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,
0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,
0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x1e,
0x00,0x78,0x1f,0x00,0xf8,0x0f,0xff,0xe0,0x03,0xff,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x00,0x0f,0x78,0x00,0x1e,0x3c,0x00,
0x1e,0x3c,0x00,0x3c,0x1e,0x00,0x38,0x1e,0x00,0x78,0x0f,0x00,0x70,0x0f,0x00,0xf0,
0x07,0x81,0xe0,0x07,0x81,0xe0,0x03,0xc3,0xc0,0x03,0xe3,0xc0,0x01,0xe7,0x80,0x00,
0xf7,0x80,0x00,0xff,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x0e,0x78,0x00,0x0e,0x78,0x00,
0x0e,0x78,0x00,0x1e,0x38,0x00,0x1e,0x38,0x00,0x1e,0x38,0x3c,0x1c,0x38,0x3c,0x1c,
0x38,0x7e,0x1c,0x38,0x7f,0x1c,0x3c,0xe7,0x1c,0x3c,0xe7,0x9c,0x3d,0xc3,0x9c,0x1d,
0xc3,0xdc,0x1f,0x81,0xdc,0x1f,0x80,0xf8,0x1f,0x00,0xf8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x3c,0x1e,0x00,0x78,0x0f,0x00,
0xf0,0x07,0x81,0xe0,0x03,0xc3,0xc0,0x01,0xe7,0x80,0x00,0xff,0x00,0x00,0x7e,0x00,
0x00,0x7e,0x00,0x00,0xff,0x00,0x01,0xff,0x80,0x03,0xe7,0xc0,0x07,0xc3,0xe0,0x0f,
0x81,0xf0,0x1f,0x00,0xf8,0x3e,0x00,0x7c,0x7c,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x1f,0x3c,0x00,0x3e,0x1e,0x00,
0x7c,0x1f,0x00,0x78,0x0f,0x80,0xf0,0x07,0xc1,0xe0,0x03,0xe3,0xc0,0x01,0xe7,0x80,
0x00,0xff,0x00,0x00,0x7e,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,
0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0xfc,0x1f,0xff,0xfc,0x00,0x00,
0xf8,0x00,0x01,0xe0,0x00,0x03,0xc0,0x00,0x07,0x80,0x00,0x0f,0x00,0x00,0x1e,0x00,
0x00,0x3c,0x00,0x00,0x78,0x00,0x00,0xf0,0x00,0x03,0xe0,0x00,0x07,0xc0,0x00,0x0f,
0x80,0x00,0x1f,0x00,0x00,0x3f,0xff,0xfc,0x3f,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0xff,0xc0,0x01,0xff,0xc0,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,
0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,
0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,
0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,
0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0e,0x00,0x00,0x0f,0x00,0x00,0x07,0x00,0x00,0x03,0x80,0x00,0x03,0xc0,
0x00,0x01,0xe0,0x00,0x00,0xe0,0x00,0x00,0xf0,0x00,0x00,0x78,0x00,0x00,0x38,0x00,
0x00,0x3c,0x00,0x00,0x1e,0x00,0x00,0x0e,0x00,0x00,0x0f,0x00,0x00,0x07,0x80,0x00,
0x03,0x80,0x00,0x01,0xc0,0x00,0x01,0xe0,0x00,0x00,0xe0,0x00,0x00,0x70,0x00,0x00,
0x78,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x03,0xff,0x80,0x03,0xff,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,
0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,
0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,
0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x00,0x07,
0x80,0x00,0x07,0x80,0x00,0x07,0x80,0x03,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x00,0x7e,0x00,0x00,0xe7,
0x00,0x01,0xc3,0x80,0x03,0x81,0xc0,0x07,0x00,0xe0,0x0e,0x00,0xf0,0x1e,0x00,0x78,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0f,0x80,0x00,0x03,0xe0,0x00,0x00,0xf8,0x00,0x00,0x3c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x07,0xff,0xc0,0x07,0xe7,0xf0,0x00,0x00,0xf0,0x00,0x00,0x78,
0x00,0x00,0x78,0x00,0xff,0xf8,0x07,0xff,0xf8,0x0f,0x00,0x78,0x1e,0x00,0x78,0x1e,
0x00,0x78,0x1e,0x03,0xf8,0x0f,0xff,0xf8,0x07,0xfc,0x78,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,
0x00,0x1e,0x00,0x00,0x1e,0x7f,0xe0,0x1e,0xff,0xf0,0x1f,0xc0,0x78,0x1f,0x00,0x78,
0x1e,0x00,0x3c,0x1e,0x00,0x3c,0x1e,0x00,0x3c,0x1e,0x00,0x3c,0x1e,0x00,0x38,0x1e,
0x00,0x78,0x1e,0x00,0xf0,0x1f,0xff,0xe0,0x07,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xff,0xf0,0x03,0xff,0xf0,0x07,0xc0,0x00,0x0f,0x80,0x00,
0x0f,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x0f,0x00,0x00,0x0f,
0x80,0x00,0x07,0xc0,0x00,0x03,0xff,0xf0,0x00,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,
0x78,0x00,0x00,0x78,0x01,0xff,0xf8,0x07,0xff,0xf8,0x0f,0x00,0x78,0x1e,0x00,0x78,
0x1e,0x00,0x78,0x3c,0x00,0x78,0x3c,0x00,0x78,0x3c,0x00,0x78,0x1c,0x00,0x78,0x1e,
0x01,0xf8,0x1f,0x03,0xf8,0x0f,0xff,0x78,0x03,0xfc,0x78,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0xff,0xc0,0x07,0xe3,0xf0,0x0f,0x00,0xf8,0x1e,0x00,0x78,
0x1e,0x00,0x3c,0x1f,0xff,0xfc,0x1f,0xff,0xfc,0x1c,0x00,0x00,0x1e,0x00,0x00,0x1e,
0x00,0x00,0x0f,0x80,0x00,0x07,0xff,0xf8,0x01,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0xfc,0x00,0x1f,0xfe,0x00,0x3e,0x00,0x00,0x78,0x00,0x00,0x78,
0x00,0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x70,0x00,0x3f,0xff,0xfc,0x3f,0xff,0xfc,
0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x70,0x00,0x00,
0x70,0x00,0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x03,0xff,0xfc,0x07,0xc3,0xfc,0x0f,0x00,0xf0,0x1e,0x00,0xf0,
0x1e,0x00,0xf0,0x0f,0x00,0xf0,0x0f,0x83,0xe0,0x0f,0xff,0xc0,0x1e,0x7c,0x00,0x1c,
0x00,0x00,0x1f,0x00,0x00,0x0f,0xff,0xf0,0x0f,0xff,0xfc,0x1e,0x00,0x3c,0x3c,0x00,
0x3c,0x3c,0x00,0x3c,0x1f,0x81,0xf8,0x0f,0xff,0xe0,0x00,0x38,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,
0x00,0x1e,0x00,0x00,0x1e,0x7f,0xe0,0x1e,0xff,0xf0,0x1f,0xc0,0xf0,0x1f,0x00,0x78,
0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,
0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x3c,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x3c,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x0f,0xfe,0x00,0x0f,0xfe,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,
0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,
0x1e,0x00,0x00,0x1e,0x00,0x0f,0xff,0xf8,0x0f,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0x80,0x00,0x07,0xe0,0x00,0x07,0xe0,0x00,0x03,0x80,0x00,0x00,
0x00,0x00,0x00,0x00,0x0f,0xff,0xc0,0x0f,0xff,0xc0,0x00,0x03,0xc0,0x00,0x03,0xc0,
0x00,0x03,0xc0,0x00,0x03,0xc0,0x00,0x03,0xc0,0x00,0x03,0xc0,0x00,0x03,0xc0,0x00,
0x03,0xc0,0x00,0x03,0xc0,0x00,0x03,0xc0,0x00,0x03,0xc0,0x00,0x03,0xc0,0x00,0x03,
0xc0,0x00,0x07,0x80,0x1e,0x3f,0x00,0x1f,0xfe,0x00,0x01,0xc0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,
0x00,0x0f,0x00,0x00,0x0f,0x00,0xf8,0x0f,0x01,0xe0,0x0f,0x07,0xc0,0x0f,0x1f,0x00,
0x0f,0x3c,0x00,0x0f,0xf8,0x00,0x0f,0xf8,0x00,0x0f,0x3e,0x00,0x0f,0x1f,0x00,0x0f,
0x07,0xc0,0x0f,0x03,0xe0,0x0f,0x00,0xf8,0x0f,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0f,0xfe,0x00,0x0f,0xfe,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,
0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,
0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,
0x1e,0x00,0x00,0x1e,0x00,0x0f,0xff,0xf8,0x0f,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x39,0xf9,0xf8,0x3b,0xbb,0xbc,0x3e,0x3e,0x1c,0x3c,0x3e,0x1c,
0x38,0x3c,0x1c,0x38,0x3c,0x1c,0x38,0x3c,0x1c,0x38,0x3c,0x1c,0x38,0x3c,0x1c,0x38,
0x3c,0x1c,0x38,0x3c,0x1c,0x38,0x3c,0x1c,0x38,0x3c,0x1c,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x1e,0x7f,0xe0,0x1e,0xff,0xf0,0x1f,0xc0,0xf0,0x1f,0x00,0x78,
0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,
0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0xff,0xc0,0x07,0xe7,0xf0,0x0f,0x00,0xf8,0x1e,0x00,0x3c,
0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x3c,0x00,0x3c,0x1e,
0x00,0x78,0x1f,0x00,0xf0,0x07,0xff,0xe0,0x01,0xff,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x1e,0x7f,0xe0,0x1e,0xff,0xf0,0x1f,0xc0,0x78,0x1f,0x00,0x78,
0x1e,0x00,0x3c,0x1e,0x00,0x3c,0x1e,0x00,0x3c,0x1e,0x00,0x3c,0x1e,0x00,0x38,0x1e,
0x00,0x78,0x1e,0x00,0xf0,0x1f,0xff,0xe0,0x1f,0xff,0x00,0x1e,0x00,0x00,0x1e,0x00,
0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0xff,0xf8,0x07,0xf7,0xf8,0x0f,0x00,0x78,0x1e,0x00,0x78,
0x1e,0x00,0x78,0x3c,0x00,0x78,0x3c,0x00,0x78,0x3c,0x00,0x78,0x1c,0x00,0x78,0x1e,
0x01,0xf8,0x1f,0x03,0xf8,0x0f,0xff,0x78,0x03,0xfc,0x78,0x00,0x00,0x78,0x00,0x00,
0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x0f,0x1f,0xf0,0x0f,0x7f,0xf8,0x0f,0xe0,0x3c,0x0f,0x80,0x3c,
0x0f,0x00,0x3c,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,
0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0xff,0xe0,0x07,0xe1,0xe0,0x0f,0x00,0x00,0x0f,0x00,0x00,
0x07,0x80,0x00,0x03,0xfc,0x00,0x00,0xff,0xc0,0x00,0x0f,0xf0,0x00,0x00,0xf0,0x00,
0x00,0x78,0x00,0x00,0xf0,0x0f,0xff,0xe0,0x0f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,
0x00,0x01,0xe0,0x00,0x7f,0xff,0xf8,0x7f,0xff,0xf8,0x01,0xe0,0x00,0x01,0xe0,0x00,
0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,0xe0,0x00,0x01,
0xe0,0x00,0x00,0xf0,0x00,0x00,0x7f,0xf8,0x00,0x3f,0xf8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,
0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x1e,0x00,0x78,0x0e,
0x00,0xf8,0x0f,0x03,0xf8,0x07,0xff,0x78,0x03,0xfc,0x78,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3c,0x00,0x3c,0x1e,0x00,0x7c,0x1e,0x00,0x78,0x0f,0x00,0xf0,
0x0f,0x80,0xf0,0x07,0x81,0xe0,0x03,0xc3,0xc0,0x03,0xc3,0xc0,0x01,0xe7,0x80,0x00,
0xe7,0x00,0x00,0xff,0x00,0x00,0x7e,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x78,0x00,0x0e,0x78,0x00,0x1e,0x78,0x00,0x1e,0x38,0x3c,0x1e,
0x38,0x3c,0x1c,0x3c,0x7e,0x1c,0x3c,0x7e,0x3c,0x1c,0xe7,0x3c,0x1c,0xe7,0xb8,0x1d,
0xc3,0xb8,0x1f,0xc3,0xf8,0x0f,0x81,0xf8,0x0f,0x81,0xf0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x1f,0x00,0x7c,0x0f,0x80,0xf0,0x07,0xc1,0xe0,0x03,0xe3,0xc0,
0x00,0xf7,0x80,0x00,0x7f,0x00,0x00,0x3e,0x00,0x00,0xff,0x00,0x01,0xe7,0x80,0x03,
0xc3,0xc0,0x07,0x81,0xf0,0x1f,0x00,0xf8,0x3e,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3c,0x00,0x3c,0x1e,0x00,0x3c,0x1e,0x00,0x78,0x0f,0x00,0xf0,
0x07,0x80,0xf0,0x07,0x81,0xe0,0x03,0xc1,0xc0,0x03,0xc3,0xc0,0x01,0xe7,0x80,0x00,
0xf7,0x80,0x00,0xff,0x00,0x00,0x7e,0x00,0x00,0x3e,0x00,0x00,0x3c,0x00,0x00,0x78,
0x00,0x01,0xf0,0x00,0x7f,0xe0,0x00,0x7f,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x0f,0xff,0xf0,0x0f,0xff,0xf0,0x00,0x01,0xe0,0x00,0x07,0xc0,
0x00,0x0f,0x80,0x00,0x1e,0x00,0x00,0x3c,0x00,0x00,0xf8,0x00,0x01,0xe0,0x00,0x03,
0xc0,0x00,0x07,0x80,0x00,0x0f,0xff,0xf8,0x0f,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x07,0xe0,0x00,0x1f,0xe0,0x00,0x3c,0x00,0x00,0x38,0x00,0x00,0x38,
0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,
0x1f,0xf0,0x00,0x1f,0x80,0x00,0x01,0xf0,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,
0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x38,
0x00,0x00,0x3c,0x00,0x00,0x1f,0x80,0x00,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,
0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,
0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,
0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,
0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,
0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x07,0xe0,0x00,0x07,0xf8,0x00,0x00,0x3c,0x00,0x00,0x1e,0x00,0x00,0x1e,
0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x0e,0x00,
0x00,0x0f,0xf8,0x00,0x01,0xf8,0x00,0x0f,0x80,0x00,0x0e,0x00,0x00,0x1e,0x00,0x00,
0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,0x00,0x00,0x1e,
0x00,0x00,0x3c,0x00,0x00,0xfc,0x00,0x07,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xc0,0x00,
0x1f,0xf0,0x1e,0x3c,0x7c,0x1e,0x38,0x1f,0xfc,0x78,0x07,0xf8,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
sFONT Font8x16 = {
ASCII8x16_Table,
8, /* Width */
16, /* Height */
};
sFONT Font16x24 = {
ASCII16x24_Table,
16, /* Width */
24, /* Height */
};
sFONT Font24x32 = {
ASCII24x32_Table,
24, /* Width */
32, /* Height */
};
/*----------------------------end of file--------------------------*/
建立 SRAM 内存管理文件SRAM_book.h
代码如下 :
#ifndef __SRAM_BOOK_H_
#define __SRAM_BOOK_H_
#include "stm32f10x.h"
//定义基础地址 因为我们的芯片是1M字节的
#define SRAM_BASE_ADDR (0x68000000)
#define SRAM_CHIP (1) //1M
#define SRAM_SIZE (SRAM_CHIP*1024*1024)
#define SRAM_END_ADDR (SRAM_BASE_ADDR + SRAM_SIZE)
/*A地址信号线*/
#define FSMC_A0_GPIO_PORT GPIOF
#define FSMC_A0_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A0_GPIO_PIN GPIO_Pin_0
#define FSMC_A1_GPIO_PORT GPIOF
#define FSMC_A1_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A1_GPIO_PIN GPIO_Pin_1
#define FSMC_A2_GPIO_PORT GPIOF
#define FSMC_A2_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A2_GPIO_PIN GPIO_Pin_2
#define FSMC_A3_GPIO_PORT GPIOF
#define FSMC_A3_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A3_GPIO_PIN GPIO_Pin_3
#define FSMC_A4_GPIO_PORT GPIOF
#define FSMC_A4_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A4_GPIO_PIN GPIO_Pin_4
#define FSMC_A5_GPIO_PORT GPIOF
#define FSMC_A5_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A5_GPIO_PIN GPIO_Pin_5
#define FSMC_A6_GPIO_PORT GPIOF
#define FSMC_A6_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A6_GPIO_PIN GPIO_Pin_12
#define FSMC_A7_GPIO_PORT GPIOF
#define FSMC_A7_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A7_GPIO_PIN GPIO_Pin_13
#define FSMC_A8_GPIO_PORT GPIOF
#define FSMC_A8_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A8_GPIO_PIN GPIO_Pin_14
#define FSMC_A9_GPIO_PORT GPIOF
#define FSMC_A9_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A9_GPIO_PIN GPIO_Pin_15
#define FSMC_A10_GPIO_PORT GPIOG
#define FSMC_A10_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A10_GPIO_PIN GPIO_Pin_0
#define FSMC_A11_GPIO_PORT GPIOG
#define FSMC_A11_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A11_GPIO_PIN GPIO_Pin_1
#define FSMC_A12_GPIO_PORT GPIOG
#define FSMC_A12_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A12_GPIO_PIN GPIO_Pin_2
#define FSMC_A13_GPIO_PORT GPIOG
#define FSMC_A13_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A13_GPIO_PIN GPIO_Pin_3
#define FSMC_A14_GPIO_PORT GPIOG
#define FSMC_A14_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A14_GPIO_PIN GPIO_Pin_4
#define FSMC_A15_GPIO_PORT GPIOG
#define FSMC_A15_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A15_GPIO_PIN GPIO_Pin_5
#define FSMC_A16_GPIO_PORT GPIOD
#define FSMC_A16_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_A16_GPIO_PIN GPIO_Pin_11
#define FSMC_A17_GPIO_PORT GPIOD
#define FSMC_A17_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_A17_GPIO_PIN GPIO_Pin_12
#define FSMC_A18_GPIO_PORT GPIOD
#define FSMC_A18_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_A18_GPIO_PIN GPIO_Pin_13
/*D 数据信号线*/
#define FSMC_D0_GPIO_PORT GPIOD
#define FSMC_D0_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D0_GPIO_PIN GPIO_Pin_14
#define FSMC_D1_GPIO_PORT GPIOD
#define FSMC_D1_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D1_GPIO_PIN GPIO_Pin_15
#define FSMC_D2_GPIO_PORT GPIOD
#define FSMC_D2_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D2_GPIO_PIN GPIO_Pin_0
#define FSMC_D3_GPIO_PORT GPIOD
#define FSMC_D3_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D3_GPIO_PIN GPIO_Pin_1
#define FSMC_D4_GPIO_PORT GPIOE
#define FSMC_D4_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D4_GPIO_PIN GPIO_Pin_7
#define FSMC_D5_GPIO_PORT GPIOE
#define FSMC_D5_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D5_GPIO_PIN GPIO_Pin_8
#define FSMC_D6_GPIO_PORT GPIOE
#define FSMC_D6_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D6_GPIO_PIN GPIO_Pin_9
#define FSMC_D7_GPIO_PORT GPIOE
#define FSMC_D7_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D7_GPIO_PIN GPIO_Pin_10
#define FSMC_D8_GPIO_PORT GPIOE
#define FSMC_D8_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D8_GPIO_PIN GPIO_Pin_11
#define FSMC_D9_GPIO_PORT GPIOE
#define FSMC_D9_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D9_GPIO_PIN GPIO_Pin_12
#define FSMC_D10_GPIO_PORT GPIOE
#define FSMC_D10_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D10_GPIO_PIN GPIO_Pin_13
#define FSMC_D11_GPIO_PORT GPIOE
#define FSMC_D11_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D11_GPIO_PIN GPIO_Pin_14
#define FSMC_D12_GPIO_PORT GPIOE
#define FSMC_D12_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D12_GPIO_PIN GPIO_Pin_15
#define FSMC_D13_GPIO_PORT GPIOD
#define FSMC_D13_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D13_GPIO_PIN GPIO_Pin_8
#define FSMC_D14_GPIO_PORT GPIOD
#define FSMC_D14_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D14_GPIO_PIN GPIO_Pin_9
#define FSMC_D15_GPIO_PORT GPIOD
#define FSMC_D15_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D15_GPIO_PIN GPIO_Pin_10
/*控制信号线*/
/*CS片选*/
/*NE3 ,对应的基地址0x68000000*/
// 这里一定要注意 那个地址用哪个地址
#define FSMC_CS_GPIO_PORT GPIOG
#define FSMC_CS_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_CS_GPIO_PIN GPIO_Pin_10
/*WE写使能*/
#define FSMC_WE_GPIO_PORT GPIOD
#define FSMC_WE_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_WE_GPIO_PIN GPIO_Pin_5
/*OE读使能*/
#define FSMC_OE_GPIO_PORT GPIOD
#define FSMC_OE_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_OE_GPIO_PIN GPIO_Pin_4
/*UB数据掩码*/
#define FSMC_UDQM_GPIO_PORT GPIOE
#define FSMC_UDQM_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_UDQM_GPIO_PIN GPIO_Pin_1
/*LB数据掩码*/
#define FSMC_LDQM_GPIO_PORT GPIOE
#define FSMC_LDQM_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_LDQM_GPIO_PIN GPIO_Pin_0
void SRAM_Init(void);
uint8_t SRAM_Test(void);
void SRAM_Write(void);
#endif
建立 SRAM 内存管理文件SRAM_book.c
代码如下 :
#include "SRAM_book.h"
#include "Systick_book.h"
#include "USART_book.h"
/**
* @brief 初始化控制SRAM的IO
* @param 无
* @retval 无
*/
static void SRAM_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能SRAM相关的GPIO时钟 */
/*地址信号线*/
RCC_APB2PeriphClockCmd(FSMC_A0_GPIO_CLK | FSMC_A1_GPIO_CLK | FSMC_A2_GPIO_CLK |
FSMC_A3_GPIO_CLK | FSMC_A4_GPIO_CLK | FSMC_A5_GPIO_CLK |
FSMC_A6_GPIO_CLK | FSMC_A7_GPIO_CLK | FSMC_A8_GPIO_CLK |
FSMC_A9_GPIO_CLK | FSMC_A10_GPIO_CLK| FSMC_A11_GPIO_CLK|
FSMC_A12_GPIO_CLK| FSMC_A13_GPIO_CLK|FSMC_A14_GPIO_CLK|
FSMC_A15_GPIO_CLK|FSMC_A16_GPIO_CLK|FSMC_A17_GPIO_CLK|FSMC_A18_GPIO_CLK|
/*数据信号线*/
FSMC_D0_GPIO_CLK | FSMC_D1_GPIO_CLK | FSMC_D2_GPIO_CLK |
FSMC_D3_GPIO_CLK | FSMC_D4_GPIO_CLK | FSMC_D5_GPIO_CLK |
FSMC_D6_GPIO_CLK | FSMC_D7_GPIO_CLK | FSMC_D8_GPIO_CLK |
FSMC_D9_GPIO_CLK | FSMC_D10_GPIO_CLK| FSMC_D11_GPIO_CLK|
FSMC_D12_GPIO_CLK| FSMC_D13_GPIO_CLK| FSMC_D14_GPIO_CLK|
FSMC_D15_GPIO_CLK|
/*控制信号线*/
FSMC_CS_GPIO_CLK | FSMC_WE_GPIO_CLK | FSMC_OE_GPIO_CLK |
FSMC_UDQM_GPIO_CLK|FSMC_LDQM_GPIO_CLK, ENABLE);
//UDQM UB引脚
/*-- GPIO 配置 -----------------------------------------------------*/
/* 通用 GPIO 配置 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //配置为复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //都是复用推完功能因为这个是数据手册的规定
/*A地址信号线 针对引脚配置*/
GPIO_InitStructure.GPIO_Pin = FSMC_A0_GPIO_PIN;
GPIO_Init(FSMC_A0_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A1_GPIO_PIN;
GPIO_Init(FSMC_A1_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A2_GPIO_PIN;
GPIO_Init(FSMC_A2_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A3_GPIO_PIN;
GPIO_Init(FSMC_A3_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A4_GPIO_PIN;
GPIO_Init(FSMC_A4_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A5_GPIO_PIN;
GPIO_Init(FSMC_A5_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A6_GPIO_PIN;
GPIO_Init(FSMC_A6_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A7_GPIO_PIN;
GPIO_Init(FSMC_A7_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A8_GPIO_PIN;
GPIO_Init(FSMC_A8_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A9_GPIO_PIN;
GPIO_Init(FSMC_A9_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A10_GPIO_PIN;
GPIO_Init(FSMC_A10_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A11_GPIO_PIN;
GPIO_Init(FSMC_A11_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A12_GPIO_PIN;
GPIO_Init(FSMC_A12_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A13_GPIO_PIN;
GPIO_Init(FSMC_A13_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A14_GPIO_PIN;
GPIO_Init(FSMC_A14_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A15_GPIO_PIN;
GPIO_Init(FSMC_A15_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A16_GPIO_PIN;
GPIO_Init(FSMC_A16_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A17_GPIO_PIN;
GPIO_Init(FSMC_A17_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A18_GPIO_PIN;
GPIO_Init(FSMC_A18_GPIO_PORT, &GPIO_InitStructure);
/*DQ数据信号线 针对引脚配置*/
GPIO_InitStructure.GPIO_Pin = FSMC_D0_GPIO_PIN;
GPIO_Init(FSMC_D0_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D1_GPIO_PIN;
GPIO_Init(FSMC_D1_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D2_GPIO_PIN;
GPIO_Init(FSMC_D2_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D3_GPIO_PIN;
GPIO_Init(FSMC_D3_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D4_GPIO_PIN;
GPIO_Init(FSMC_D4_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D5_GPIO_PIN;
GPIO_Init(FSMC_D5_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D6_GPIO_PIN;
GPIO_Init(FSMC_D6_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D7_GPIO_PIN;
GPIO_Init(FSMC_D7_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D8_GPIO_PIN;
GPIO_Init(FSMC_D8_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D9_GPIO_PIN;
GPIO_Init(FSMC_D9_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D10_GPIO_PIN;
GPIO_Init(FSMC_D10_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D11_GPIO_PIN;
GPIO_Init(FSMC_D11_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D12_GPIO_PIN;
GPIO_Init(FSMC_D12_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D13_GPIO_PIN;
GPIO_Init(FSMC_D13_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D14_GPIO_PIN;
GPIO_Init(FSMC_D14_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D15_GPIO_PIN;
GPIO_Init(FSMC_D15_GPIO_PORT, &GPIO_InitStructure);
/*控制信号线*/
GPIO_InitStructure.GPIO_Pin = FSMC_CS_GPIO_PIN;
GPIO_Init(FSMC_CS_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_WE_GPIO_PIN;
GPIO_Init(FSMC_WE_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_OE_GPIO_PIN;
GPIO_Init(FSMC_OE_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_UDQM_GPIO_PIN;
GPIO_Init(FSMC_UDQM_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_LDQM_GPIO_PIN;
GPIO_Init(FSMC_LDQM_GPIO_PORT, &GPIO_InitStructure);
}
// 写时钟周期
//ADDSET +1 + DATAST +1 > 55ns;
//DATAST +1 >40ns
//ADDSET +1 > 0 ns
// 读的时钟
//ADDSET +1 > 25ns
//DATAST +1 > 0 ns
/时钟单位 1.38*10-8S = 13.8ns
//写时序
//ADDSET
//DATAST
//
//读时序
//ADDSET = 0
//DATAST = 2
//
//ADDSET +1 + DATAST +1 = (0+1+2+1)(13.8)=55.2> 55ns;
//DATAST +1 >=2+1*(13.8 = 41.4)40ns
//ADDSET +1 = 0+1*(13.8) = 13.8>0 ns
static void FSMC_ModleConfig(void){
//对寄存器进行配置
FSMC_NORSRAMTimingInitTypeDef readTimingInitStruct ; //读时序
FSMC_NORSRAMTimingInitTypeDef writeTimingInitStruct ; //写时序
FSMC_NORSRAMInitTypeDef SRAMInitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE); //注意时钟使能
//读
readTimingInitStruct.FSMC_AccessMode = FSMC_AccessMode_A ;/*设置访问模式 */
readTimingInitStruct.FSMC_AddressHoldTime = 0; //SRAM 没有用到
readTimingInitStruct.FSMC_BusTurnAroundDuration = 0;//SRAM 没有用到
readTimingInitStruct.FSMC_CLKDivision = 0;//SRAM 没有用到
readTimingInitStruct.FSMC_DataLatency = 0;//SRAM 没有用到
readTimingInitStruct.FSMC_AddressSetupTime = 0; //代表ADDSET单位13.8ns
readTimingInitStruct.FSMC_DataSetupTime =2;//代表DATAST单位13.8ns
//写
writeTimingInitStruct.FSMC_AccessMode = FSMC_AccessMode_A ;/*设置访问模式 */
writeTimingInitStruct.FSMC_AddressHoldTime = 0; //SRAM 没有用到
writeTimingInitStruct.FSMC_BusTurnAroundDuration = 0;//SRAM 没有用到
writeTimingInitStruct.FSMC_CLKDivision = 0;//SRAM 没有用到
writeTimingInitStruct.FSMC_DataLatency = 0;//SRAM 没有用到
writeTimingInitStruct.FSMC_AddressSetupTime = 0; //代表ADDSET单位13.8ns
writeTimingInitStruct.FSMC_DataSetupTime =2;//代表DATAST单位13.8ns
//到此读时序结构体完成
SRAMInitStruct.FSMC_Bank = FSMC_Bank1_NORSRAM3;
SRAMInitStruct.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; //读写时序
SRAMInitStruct.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
SRAMInitStruct.FSMC_MemoryType = FSMC_MemoryType_SRAM;
//SRAM 没有用到
SRAMInitStruct.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable ;
SRAMInitStruct.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
SRAMInitStruct.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
SRAMInitStruct.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
SRAMInitStruct.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
SRAMInitStruct.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
SRAMInitStruct.FSMC_WrapMode = FSMC_WrapMode_Disable;
SRAMInitStruct.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
SRAMInitStruct.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
//读写操作结构化评估
SRAMInitStruct.FSMC_ReadWriteTimingStruct = &readTimingInitStruct;//读
SRAMInitStruct.FSMC_WriteTimingStruct = &writeTimingInitStruct;//写
//写操作 注意FSMC_ExtendedMode 配置成 FSMC_ExtendedMode_Enable 时候有用
// 吧配置写入寄存器
FSMC_NORSRAMInit(&SRAMInitStruct);
//使能FSMC
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3,ENABLE);
}
/**
* @brief 测试SRAM是否正常
* @param None
* @retval 正常返回1,异常返回0
*/
uint8_t SRAM_Test(void){
/*写入数据计数器*/
uint32_t counter=0;
/* 8位的数据 */
uint8_t ubWritedata_8b = 0, ubReaddata_8b = 0;
/* 16位的数据 */
uint16_t uhWritedata_16b = 0, uhReaddata_16b = 0;
printf("正在检测SRAM,以8位、16位的方式读写sram...");
/*按8位格式读写数据,并校验*/
/* 把SRAM数据全部重置为0 ,IS62WV51216_SIZE是以8位为单位的 */
for (counter = 0x00; counter < SRAM_SIZE; counter++)
{
*(__IO uint8_t*) (SRAM_BASE_ADDR + counter) = (uint8_t)0x0;
}
/* 向整个SRAM写入数据 8位 */
for (counter = 0; counter < SRAM_SIZE; counter++)
{
*(__IO uint8_t*) (SRAM_BASE_ADDR + counter) = (uint8_t)(ubWritedata_8b + counter);
}
/* 读取 SRAM 数据并检测*/
for(counter = 0; counter<SRAM_SIZE;counter++ )
{
ubReaddata_8b = *(__IO uint8_t*)(SRAM_BASE_ADDR + counter); //从该地址读出数据
if(ubReaddata_8b != (uint8_t)(ubWritedata_8b + counter)) //检测数据,若不相等,跳出函数,返回检测失败结果。
{
printf("8位数据读写错误!");
return 0;
}
}
/*按16位格式读写数据,并检测*/
/* 把SRAM数据全部重置为0 */
for (counter = 0x00; counter < SRAM_SIZE/2; counter++)
{
*(__IO uint16_t*) (SRAM_BASE_ADDR + 2*counter) = (uint16_t)0x00;
}
/* 向整个SRAM写入数据 16位 */
for (counter = 0; counter < SRAM_SIZE/2; counter++)
{
*(__IO uint16_t*) (SRAM_BASE_ADDR + 2*counter) = (uint16_t)(uhWritedata_16b + counter);
}
/* 读取 SRAM 数据并检测*/
for(counter = 0; counter<SRAM_SIZE/2;counter++ )
{
uhReaddata_16b = *(__IO uint16_t*)(SRAM_BASE_ADDR + 2*counter); //从该地址读出数据
if(uhReaddata_16b != (uint16_t)(uhWritedata_16b + counter)) //检测数据,若不相等,跳出函数,返回检测失败结果。
{
printf("16位数据读写错误!\n");
return 0;
}
}
printf("SRAM读写测试正常!\n");
/*检测正常,return 1 */
return 1;
}
/**
* @brief void SRAM_Init(void)
* @param 初始化
* @retval
*/
void SRAM_Init(void){
SRAM_GPIO_Config();
FSMC_ModleConfig();
}
static uint8_t testSRAM_Value __attribute__ ((at (SRAM_BASE_ADDR)));
/**
* @brief void SRAM_Write(void)
* @param None
* @retval
*/
void SRAM_Write(void){
uint8_t* SRAM_P ;
uint16_t* SRAM_P16 ;
float* SRAM_Pf ;
//---------------------------------
SRAM_P = (uint8_t*)SRAM_BASE_ADDR;
*SRAM_P = 0xA2;
printf("读出的数据为1: 0x%x\n",*SRAM_P);
//---------------------------------
SRAM_P16 = (uint16_t*)SRAM_BASE_ADDR;
*SRAM_P16 = 0x2AA2;
printf("读出的数据为2: 0x%x\n",*SRAM_P16);
//---------------------------------
SRAM_Pf = (float*)SRAM_BASE_ADDR;
*SRAM_Pf = 83.65;
printf("读出的数据为3: 0x%.2f\n",*SRAM_Pf);
//-----------利用常量来设计----------------------
testSRAM_Value = 0x6A;
printf("读出的数据为1: 0x%x\n",testSRAM_Value);
}
整改 系统文件diskio.c
代码如下 :
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2014 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include "diskio.h" /* FatFs lower layer API */
#include "ff.h"
#include "SPI_book.h"
//#include "usbdisk.h" /* Example: Header file of existing USB MSD control module */
//#include "atadrive.h" /* Example: Header file of existing ATA harddisk control module */
//#include "sdcard.h" /* Example: Header file of existing MMC/SDC contorl module */
/* Definitions of physical drive number for each drive */
#define ATA 0 /* Example: Map ATA harddisk to physical drive 0 */
#define MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
#define USB 2 /* Example: Map USB MSD to physical drive 2 */
#define SD_CARD 0
#define SPI_FLASH 1
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat = STA_NOINIT;
// int result;
switch (pdrv) {
case SD_CARD : break;
case SPI_FLASH :
if(SPI_Read_ID() == _SPI_FLASH_ID){
stat = RES_OK;
}else{
stat = RES_ERROR;
}
break;
default:
stat = STA_NOINIT;
}
return stat;
}
//disk_status 函数只有一个参数 pdrv,表示物理编号。一般我们都是使用 switch 函数实
//现对 pdrv 的分支判断。对于 SD 卡只是预留接口,留空即可。对于 SPI Flash 芯片,我们直
//接调用在 SPI_FLASH_ReadID()获取设备 ID,
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat = STA_NOINIT;
// int result;
switch (pdrv) {
case SD_CARD : break;
case SPI_FLASH :
SPI_FLASH_Init();
SPI_Flash_WAKEUP();
stat = disk_status(SPI_FLASH);
break;
default:
stat = STA_NOINIT;
}
return stat;
}
//disk_initialize 函数也是有一个参数 pdrv,用来指定设备物理编号。对于 SPI Flash 芯片
//我们调用 SPI_FLASH_Init()函数实现对 SPI Flash 芯片引脚 GPIO 初始化配置以及 SPI 通信
//参数配置。SPI_Flash_WAKEUP()函数唤醒 SPI Flash 芯片,当 SPI Flash 芯片处于睡眠模式
//时需要唤醒芯片才可以进行读写操作。
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to read */
)
{
DRESULT res = RES_PARERR;
//int result;
switch (pdrv) {
case SD_CARD : break;
case SPI_FLASH :
// 扇区偏移2MB 外部Flash 文件系统空间放在 SPI_FLAH后面的6MB空间
sector += 512;
SPI_Read_Data(buff,(sector << 12),(count << 12));
res = RES_OK ;
break;
default:
res = RES_PARERR;
}
return res;
}
//SPI Flash 芯片型号为 W25Q64FV,每个扇区大小为 4096 个字节(4KB),
//总共有 8M 字节空间,为兼容后面实验程序,我们只将后部分 6MB 空间分配给 FatFs 使用,
//前部分 2MB 空间用于其他实验需要,即 FatFs 是从 2MB 空间开始,为实现这个效果需要
//将所有的读写地址都偏移 512 个扇区空间
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if _USE_WRITE
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */
)
{
DRESULT res = RES_PARERR;
//int result;
if(!count){return res;}
switch (pdrv) {
case SD_CARD : break;
case SPI_FLASH :
// 扇区偏移2MB 外部Flash 文件系统空间放在 SPI_FLAH后面的6MB空间
sector += 512;
SPI_Erase_Sector(sector << 12);
SPI_BufferWrite_Data((uint8_t *)buff ,sector << 12,count << 12);
res = RES_OK ;
break;
default:
res = RES_PARERR;
}
return res;
}
#endif
//disk_write 函数有四个形参,pdrv 为设备物理编号。buff 指向待写入扇区数据的首地址。
//sector,指定要写入数据的扇区首地址。count 指定扇区数量。对于 SPI Flash 芯片,在写入
//数据之前需要先擦除,所以用到扇区擦除函数(SPI_FLASH_SectorErase)。然后就是在调用
//数据写入函数(SPI_FLASH_BufferWrite)把数据写入到指定位置内。
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
#if _USE_IOCTL
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res = RES_PARERR;
// int result;
switch (pdrv) {
case SD_CARD : break;
case SPI_FLASH :{
switch(cmd){
//返回 扇区的个数 1280*4096/1024/1024 = 5MB
case GET_SECTOR_COUNT:
*(DWORD * )buff = 1280;
break;
//返回每一个扇区的大小
case GET_SECTOR_SIZE:
*(DWORD * )buff = 4096;
break;
case GET_BLOCK_SIZE:
*(DWORD * )buff = 1;
break;
default:
return RES_PARERR;
}
res = RES_OK;
break;
}
default:
res = RES_PARERR;
}
return res;
}
#endif
DWORD get_fattime(void) {
/* 返回当前时间戳 */
return ((DWORD)(2015 - 1980) << 25) /* Year 2015 */
| ((DWORD)1 << 21) /* Month 1 */
| ((DWORD)1 << 16) /* Mday 1 */
| ((DWORD)0 << 11) /* Hour 0 */
| ((DWORD)0 << 5) /* Min 0 */
| ((DWORD)0 >> 1); /* Sec 0 */
}
修改头文件文件diskio.h
代码如下 :
/*---------------------------------------------------------------------------/
/ FatFs - FAT file system module configuration file R0.11a (C)ChaN, 2015
/---------------------------------------------------------------------------*/
#define _FFCONF 64180 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Function Configurations
/---------------------------------------------------------------------------*/
#define _FS_READONLY 0
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ and optional writing functions as well. */
#define _FS_MINIMIZE 0
/* This option defines minimization level to remove some basic API functions.
/
/ 0: All basic functions are enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(),
/ f_truncate() and f_rename() function are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */
#define _USE_STRFUNC 1
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
/ f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define _USE_FIND 0
/* This option switches filtered directory read feature and related functions,
/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
#define _USE_MKFS 1
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
//格式化功能选择,为使用 FatFs 格式化功能,需要把它设置为 1
#define _USE_FASTSEEK 0
/* This option switches fast seek feature. (0:Disable or 1:Enable) */
#define _USE_LABEL 0
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define _USE_FORWARD 0
/* This option switches f_forward() function. (0:Disable or 1:Enable)
/ To enable it, also _FS_TINY need to be set to 1. */
/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/---------------------------------------------------------------------------*/
#define _CODE_PAGE 936
//语言功能选择
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure.
/
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
/ 771 - KBL
/ 775 - Baltic
/ 850 - Latin 1
/ 852 - Latin 2
/ 855 - Cyrillic
/ 857 - Turkish
/ 860 - Portuguese
/ 861 - Icelandic
/ 862 - Hebrew
/ 863 - Canadian French
/ 864 - Arabic
/ 865 - Nordic
/ 866 - Russian
/ 869 - Greek 2
/ 932 - Japanese (DBCS)
/ 936 - Simplified Chinese (DBCS)
/ 949 - Korean (DBCS)
/ 950 - Traditional Chinese (DBCS)
*/
#define _USE_LFN 2
//2: Enable LFN with dynamic working buffer on the STACK.
//长文件名支持
#define _MAX_LFN 255
/* The _USE_LFN option switches the LFN feature.
/
/ 0: Disable LFN feature. _MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP.
/
/ When enable the LFN feature, Unicode handling functions (option/unicode.c) must
/ be added to the project. The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes.
/ When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree(), must be added to the project. */
#define _LFN_UNICODE 0
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:Unicode)
/ To use Unicode string for the path name, enable LFN feature and set _LFN_UNICODE
/ to 1. This option also affects behavior of string I/O functions. */
#define _STRF_ENCODE 3
/* When _LFN_UNICODE is 1, this option selects the character encoding on the file to
/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
/
/ 0: ANSI/OEM
/ 1: UTF-16LE
/ 2: UTF-16BE
/ 3: UTF-8
/
/ When _LFN_UNICODE is 0, this option has no effect. */
#define _FS_RPATH 0
/* This option configures relative path feature.
/
/ 0: Disable relative path feature and remove related functions.
/ 1: Enable relative path feature. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1.
/
/ Note that directory items read via f_readdir() are affected by this option. */
/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define _VOLUMES 2
/* Number of volumes (logical drives) to be used. */
//包括预留 SD 卡和 SPI Flash 芯片
#define _STR_VOLUME_ID 0
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
/* _STR_VOLUME_ID option switches string volume ID feature.
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for
/ the drive ID strings are: A-Z and 0-9. */
#define _MULTI_PARTITION 0
/* This option switches multi-partition feature. By default (0), each logical drive
/ number is bound to the same physical drive number and only an FAT volume found on
/ the physical drive will be mounted. When multi-partition feature is enabled (1),
/ each logical drive number is bound to arbitrary physical drive and partition
/ listed in the VolToPart[]. Also f_fdisk() funciton will be available. */
#define _MIN_SS 512
#define _MAX_SS 4096
//SPI Flash 芯片扇区大小一般设置为 4096 字节
/* These options configure the range of sector size to be supported. (512, 1024,
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
/ disk_ioctl() function. */
#define _USE_TRIM 0
/* This option switches ATA-TRIM feature. (0:Disable or 1:Enable)
/ To enable Trim feature, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */
#define _FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO.
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
/*---------------------------------------------------------------------------/
/ System Configurations
/---------------------------------------------------------------------------*/
#define _FS_TINY 0
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS
/ bytes. Instead of private sector buffer eliminated from the file object,
/ common sector buffer in the file system object (FATFS) is used for the file
/ data transfer. */
#define _FS_NORTC 0
#define _NORTC_MON 1
#define _NORTC_MDAY 1
#define _NORTC_YEAR 2015
/* The _FS_NORTC option switches timestamp feature. If the system does not have
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR.
/ When timestamp feature is enabled (_FS_NORTC == 0), get_fattime() function need
/ to be added to the project to read current time form RTC. _NORTC_MON,
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
/ These options have no effect at read-only configuration (_FS_READONLY == 1). */
#define _FS_LOCK 0
/* The _FS_LOCK option switches file lock feature to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
/ is 1.
/
/ 0: Disable file lock feature. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock feature. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock feature is independent of re-entrancy. */
#define _FS_REENTRANT 0
#define _FS_TIMEOUT 1000
#define _SYNC_t HANDLE
/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this feature.
/
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function, must be added to the project. Samples are available in
/ option/syscall.c.
/
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.c. */
#define _WORD_ACCESS 0
/* The _WORD_ACCESS option is an only platform dependent option. It defines
/ which access method is used to the word data on the FAT volume.
/
/ 0: Byte-by-byte access. Always compatible with all platforms.
/ 1: Word access. Do not choose this unless under both the following conditions.
/
/ * Address misaligned memory access is always allowed to ALL instructions.
/ * Byte order on the memory is little-endian.
/
/ If it is the case, _WORD_ACCESS can also be set to 1 to reduce code size.
/ Following table shows allowable settings of some type of processors.
/
/ ARM7TDMI 0 *2 ColdFire 0 *1 V850E 0 *2
/ Cortex-M3 0 *3 Z80 0/1 V850ES 0/1
/ Cortex-M0 0 *2 x86 0/1 TLCS-870 0/1
/ AVR 0/1 RX600(LE) 0/1 TLCS-900 0/1
/ AVR32 0 *1 RL78 0 *2 R32C 0 *2
/ PIC18 0/1 SH-2 0 *1 M16C 0/1
/ PIC24 0 *2 H8S 0 *1 MSP430 0 *2
/ PIC32 0 *1 H8/300H 0 *1 8051 0/1
/
/ *1:Big-endian.
/ *2:Unaligned memory access is not supported.
/ *3:Some compilers generate LDM/STM for mem_cpy function.
*/
建立FatFs传输的 头文件 FatFs_book.h
代码如下 :
#ifndef __FATFS_BOOK_H_
#define __FATFS_BOOK_H_
#include "ff.h" /* Declarations of FatFs API */
extern FATFS fs; /* FatFs 文件系统对象 */
extern FIL fnew; /* 文件对象 */
extern FRESULT res_flash; /* 文件操作结果 */
extern UINT fnum; /* 文件成功读写数量 */
extern BYTE FATFS_buffer[0]; /* 读缓冲区 */
extern BYTE textFile_Buffer[];
extern BYTE textFile_Buffer2[];
extern BYTE File_Read_Buffer[1024];
#define textFile_Buffer "欢迎自己完成第一阶段回国隔离任务,后面加油 今天是个好日子,新建文件系统测试文件\r\n"
#define FileTest_ADDR_Buffer_Document "1:Wangqi.txt"
#define FileTest_ADDR_Buffer_NewDocument "1:Wangqi/Wangqi.txt"
#define FileTest_ADDR_Buffer_path "1:test"
#define FileTest_ADDR_Buffer_NewDocument2 "1:test/testdir.txt"
FRESULT FatFs_equipment_flash(
const TCHAR* path
);
FRESULT FatFs_Close_flash(
const TCHAR* path
);
BYTE* FatFs_document_Text(
const TCHAR* _File_ADDR ,
BYTE* Text_Buffer
);
void FatFs_document_set_content(
const TCHAR* _File_ADDR ,
const TCHAR* _File_OldPath ,
const TCHAR* _File_NewPath
);
FRESULT file_check(const TCHAR* FileTest_ADDR);
FRESULT Scan_file_Check(const TCHAR* File_ADDR);
#endif
建立FatFs传输的 头文件 FatFs_book.c
代码如下 :
#include "FatFs_book.h"
#include "Systick_book.h"
#include "USART_book.h"
#include "string.h"
FATFS fs; /* FatFs 文件系统对象 */
FIL fnew; /* 文件对象 */
FRESULT res_flash; /* 文件操作结果 */
UINT fnum; /* 文件成功读写数量 */
BYTE FATFS_buffer[0]; /* 读缓冲区 */
/**************************************************************
* @brief
* FRESULT FatFs_equipment_flash(const TCHAR* path )
* @param
*
*FatFs 的第一步工作就是使用 f_mount 函数挂载工作区。f_mount 函数有三个形参,第
*一个参数是指向 FATFS 变量指针,如果赋值为 NULL 可以取消物理设备挂载。第二个参数
*为逻辑设备编号,使用设备根路径表示,与物理设备编号挂钩,在代码清单 26-1 中我们定
*义 SPI Flash 芯片物理编号为 1,所以这里使用“1:”。第三个参数可选 0 或 1,1 表示立
*即挂载,0 表示不立即挂载,延迟挂载。 f_mount 函数会返回一个 FRESULT 类型值,指示
*运行情况。
*如果 f_mount 函数返回值为 FR_NO_FILESYSTEM,说明没有 FAT 文件系统,比如新
*出厂的 SPI Flash 芯片就没有 FAT 文件系统。我们就必须对物理设备进行格式化处理。使用
*f_mkfs 函数可以实现格式化操作。f_mkfs 函数有三个形参,第一个参数为逻辑设备编号;
*第二参数可选 0 或者 1,0 表示设备为一般硬盘,1 表示设备为软盘。第三个参数指定扇区
*大小,如果为 0,表示通过代码清单 26-6 中 disk_ioctl 函数获取。格式化成功后需要先取消
*挂载原来设备,再重新挂载设备。
*
*/
FRESULT FatFs_equipment_flash(
const TCHAR* path
){
//在外部 SPI Flash 挂载文件系统,文件系统挂载时会对 SPI 设备初始化
//初始化函数调用流程如下
//f_mount()->find_volume()->disk_initialize->SPI_FLASH_Init()
DIR dir;
FATFS *pfs;
DWORD fre_clust , fre_sect , tot_sect ;
printf("\n********** 外部SPIFlash挂载文件系统 **********\r\n");
printf(" 在外部SPI Flash挂载文件系统,文件系统挂载时会对SPI设备初始化\r\n");
res_flash = f_mount(&fs ,path,1); //SPI Flash 芯片物理编号为 1,所以这里使用“1:”。
/* Pointer to the file system object (NULL:unmount)*/
/* Logical drive number to be mounted/unmounted */
/* 0:Do not mount (delayed mount), 1:Mount immediately */
/*----------------------- 格式化测试 -----------------*/
/* 如果没有文件系统就格式化创建创建文件系统 */
if(res_flash == FR_NO_FILESYSTEM ){
printf("》FLASH 还没有文件系统,即将进行Flash FatFS 格式化...\r\n");
/* 格式化 */
res_flash=f_mkfs(path,0,0);/* Create a file system on the volume */
/* Logical drive number */
/* Partitioning rule 0:FDISK, 1:SFD */
/* Size of allocation unit in unit of byte or sector */
//格式完成,先取消挂载
if(res_flash == FR_OK ){
printf("》FLASH 已成功格式化文件系统。\r\n");
res_flash = f_mount(NULL ,path ,1);
//重新挂载
res_flash = f_mount(&fs ,path ,1);
}else{
printf("》格式化失败。 \r\n");
return res_flash;
}
}
else if(res_flash != FR_OK){
printf("!外部 Flash 挂载文件系统失败。(%d)\r\n",res_flash);
printf("!可能原因:SPI Flash 初始化不成功。\r\n");
return res_flash;
}
else{
printf("》文件系统挂载成功,可以进行读写测试\r\n");
}
//获取设备信息和空间的大小
res_flash = f_getfree(path ,&fre_clust ,&pfs );
//计算得到的总扇区个数和空扇区个数
tot_sect = (pfs->n_fatent-2)*pfs->csize ;
fre_sect = fre_clust * pfs->csize ;
/* 打印信息(4096 字节/扇区) */
printf("》设备总空间:%10lu KB。\n》可用空间: %10lu KB。\r\n", tot_sect<<2, fre_sect<<2);
return FR_OK;
}
/**************************************************************
* @brief
* FRESULT FatFs_Close_flash( const TCHAR* path )
* @param
* 关闭Flash操作
**************************************************************/
FRESULT FatFs_Close_flash(
const TCHAR* path
){
res_flash=f_mkfs(path,0,0);
/* 不再使用文件系统,取消挂载文件系统 */
return f_mount(NULL ,path ,1);
}
/**************************************************************
* @brief
* void FatFs_document_Text(
* const TCHAR* _File_ADDR , 文件的目录
* BYTE* Text_Buffer 需要写入的内容
*)
* @param
* 关闭Flash文件的读写操作
**************************************************************/
BYTE* FatFs_document_Text(
const TCHAR* _File_ADDR ,
BYTE* Text_Buffer
){
BYTE File_Read_Buffer[1024]={0} ;
printf("\n******** 文件%s定位和格式化写入功能测试 ********\r\n",File_Read_Buffer);
res_flash = f_open(&fnew , _File_ADDR, FA_OPEN_ALWAYS|FA_WRITE|FA_READ );
if( res_flash == FR_OK ){
//res_flash = f_write(&fnew,Text_Buffer ,sizeof(Text_Buffer), &fnum); 这个函数有点问题:sizeof(Text_Buffer)
//f_printf(&fnew ,Text_Buffer );
printf("******** 文件定位追加内容 ********\r\n");
res_flash = f_lseek(&fnew , f_size(&fnew)); //文件定位到 文件的末尾 Move file pointer of a file object
if( res_flash == FR_OK ){
//格式化写入 参数格式类似printf函数
f_printf(&fnew ,Text_Buffer );
res_flash = f_lseek(&fnew,0);
res_flash = f_read(&fnew , File_Read_Buffer , f_size(&fnew),&fnum );
if(res_flash == FR_OK){
printf("> 文件内容:\n%s\n" ,File_Read_Buffer );
}
}
}
else{
printf("!! 打开文件失败:%d\n",res_flash);
printf("!! 或许需要再次运行“FatFs移植与读写测试”工程\n");
}
f_close(&fnew);
return File_Read_Buffer;
}
/**************************************************************
* @brief
*void FatFs_document_set_content(
* const TCHAR* _File_ADDR , //文件原始名字路径
* const TCHAR* _File_OldPath ,//建立新的文件夹目录
* const TCHAR* _File_NewPath //文件移动以后的文件目录
*)
* @param
* 文件目录的更改
**************************************************************/
void FatFs_document_set_content(
const TCHAR* _File_ADDR ,
const TCHAR* _File_OldPath ,
const TCHAR* _File_NewPath
){
DIR dir;
//尝试打开目录、
printf("\n********** 目录创建和重命名功能测试 **********\r\n");
res_flash = f_opendir(&dir,_File_OldPath);
if(res_flash != FR_OK){
printf("!! 打开目录%s 失败开始尝试创建新的目录\n",_File_OldPath);
res_flash = f_mkdir(_File_OldPath);
res_flash = f_opendir(&dir,_File_OldPath);
if(res_flash != FR_OK){
printf("!! 创建新的目录还是失败(%d) \n",res_flash);
return;
}
}
else{
printf("!! 如果目录已经存在,关闭它\n");
res_flash = f_closedir(&dir);
//删除文件
f_unlink(_File_NewPath);
}
//重命名并移动文件
res_flash=f_rename(_File_ADDR , _File_NewPath);
printf("> 重命名并移动文件%d完成 \n",res_flash);
}
/**************************************************************
* @brief
* FRESULT file_check(const TCHAR* File_ADDR)
* @param
* 文件属性的查看
**************************************************************/
FRESULT file_check(const TCHAR* File_ADDR){
static FILINFO fno;
printf("\n********** file_check 测试 **********\r\n");
/* 获取文件信息,必须确保文件存在*/
res_flash = f_stat(File_ADDR,&fno);
if(res_flash==FR_OK){
printf("%s 文件信息:\n",File_ADDR);
printf("》文件大小: %ld(字节)\n", fno.fsize);
printf("》时间戳: %u/%02u/%02u, %02u:%02u\n",
(fno.fdate >> 9) + 1980, fno.fdate >> 5 & 15, fno.fdate & 31,
fno.ftime >> 11, fno.ftime >> 5 & 63);
printf("》属性: %c%c%c%c%c\n\n",
(fno.fattrib & AM_DIR) ? 'D' : '-', // 是一个目录
(fno.fattrib & AM_RDO) ? 'R' : '-', // 只读文件
(fno.fattrib & AM_HID) ? 'H' : '-', // 隐藏文件
(fno.fattrib & AM_SYS) ? 'S' : '-', // 系统文件
(fno.fattrib & AM_ARC) ? 'A' : '-'); // 档案文件
}
else{
printf("》错误 %ld(字节)\n",res_flash);
}
return res_flash;
}
/**************************************************************
* @brief
* FRESULT scan_file(char* File_ADDR)
* @param
* 文件目录内容的查看
**************************************************************/
static FRESULT scan_file(char* File_ADDR){
FRESULT res; //部分在递归过程被修改的变了
FILINFO fno;
DIR dir;
int i;
TCHAR* fn;
#if _USE_LFN
//长文件名支持
//简体中文需要2个字节保存一个字
static char lfn[_MAX_LFN*2 + 1];
fno.lfname = lfn;
fno.lfsize = sizeof(lfn);
#endif
//打开目录
res = f_opendir(&dir, File_ADDR);
if(res == FR_OK){
i = strlen(File_ADDR);
while(1){
//读取 目录下的内容,再读会自动读取下一个文件
res = f_readdir(&dir , &fno);
//为空时候表示读取完毕
if((res != FR_OK) || (fno.fname[0] == 0 )){
break;}
#if _USE_LFN
fn = *fno.lfname ?fno.lfname : fno.fname ;
#else
fn = fno.fname;
#endif
//表示当前目录跳过
if(*fn == '.'){continue;}
//目录 递归读取
if( fno.fattrib & AM_DIR ){
//合成完整目录名
sprintf(&File_ADDR[i], "/%s", fn);
//递归遍历
res = scan_file(File_ADDR);
//打开失败,跳出循环
File_ADDR[i] = 0;
if(res != FR_OK ){break;}
}else{
printf( "%s/%s\r\n" , File_ADDR , fn);
}
}
}
else{
printf("》错误 %d \n",res);
}
return res;
}
/**************************************************************
* @brief
* FRESULT Scan_file_Check(const TCHAR* File_ADDR)
* @param
* 文件目录内容的查看
**************************************************************/
FRESULT Scan_file_Check(const TCHAR* File_ADDR){
BYTE fpath[100]; /* 保存当前扫描路径 */
printf("\n********** file_路径测试 **********\r\n");
strcpy(fpath,File_ADDR);
return scan_file(fpath);
}
建立SPI传输的 头文件 SPI_book.h
代码如下 :
#ifndef __SPI_BOOK_H_
#define __SPI_BOOK_H_
#include "stm32f10x.h"
//#define _SPI_FLASH_ID 0xEF3015 //W25X16
//#define _SPI_FLASH_ID 0xEF4015 //W25Q16
//#define _SPI_FLASH_ID 0XEF4018 //W25Q128
#define _SPI_FLASH_ID 0XEF4017 //W25Q64
//---------------- 这里封装了 I2C 通讯配置信息 -------------------
#define _FLASH_SPIx SPI1
#define _FLASH_SPI_APBxClock_FUN RCC_APB2PeriphClockCmd
#define _FLASH_SPI_CLK RCC_APB2Periph_SPI1
#define _FLASH_SPI_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define _FLASH_SPI_GPIO_CLK RCC_APB2Periph_GPIOA
#define _FLASH_SPI_SCL_PORT GPIOA
#define _FLASH_SPI_SCL_PIN GPIO_Pin_5
#define _FLASH_SPI_MISO_PORT GPIOA
#define _FLASH_SPI_MISO_PIN GPIO_Pin_6
#define _FLASH_SPI_MOSI_PORT GPIOA
#define _FLASH_SPI_MOSI_PIN GPIO_Pin_7
#define _FLASH_SPI_CSS_PORT GPIOA
#define _FLASH_SPI_CSS_PIN GPIO_Pin_4
//FLASH_SPI 引脚配置
#define _FLASH_CSS_HIGH() _FLASH_SPI_CSS_PORT->BSRR = _FLASH_SPI_CSS_PIN
#define _FLASH_CSS_LOW() _FLASH_SPI_CSS_PORT->BRR = _FLASH_SPI_CSS_PIN
/*通讯等待超时时间*/
#define FLASH_SPI_TIMEOUT ((uint32_t)0x6000)
#define FLASH_SPI_LONG_TIMEOUT ((uint32_t)(10*FLASH_SPI_TIMEOUT))
//信息输出
#define FLASH_ERROR(fmt,arg...) printf("<<-FLASH-ERROR->> "fmt"\n",##arg)
//
#define SPI_PAGE_SIZE 4096
#define SPI_PAGE_Write_SIZE 256
//FLASH 指令
#define FLASH_SPI_DUMMY 0x00
#define FLASH_SPI_READ_JEDEC_ID 0x9f
#define FLASH_SPI_REASE_SECTOR 0x20
#define FLASH_SPI_READ_STATUS 0x05
#define FLASH_SPI_READ_DATA 0x03
#define FLASH_SPI_WRITE_ENABLE 0x06
#define FLASH_SPI_WRITE_DATA 0x02
#define FLASH_SPI_ChipErase 0xC7
void SPI_FLASH_Init(void);
uint32_t SPI_Read_ID(void);
uint32_t SPI_Read_DeviceID(void);
void SPI_Erase_Sector(uint32_t addr);
void SPI_FLASH_BulkErase(void);
void SPI_Read_Data(uint8_t *readBuffer , uint32_t addr ,uint16_t numByteToRead );
void SPI_BufferRead_Data(uint8_t *writeBuffer , uint32_t WriteAddr ,uint16_t numByteToWrite );
void SPI_Write_Data(uint8_t *writeBuffer , uint32_t addr ,uint16_t numByteToRead );
void SPI_BufferWrite_Data(uint8_t *writeBuffer , uint32_t WriteAddr ,uint16_t numByteToWrite );
void SPI_Show_Data(uint8_t *readBuffer , uint16_t numByteToRead);
#endif
建立SPI传输的 头文件 SPI_book.c
代码如下 :
#include "SPI_book.h"
#include "Systick_book.h"
static __IO uint32_t SPITimeout = FLASH_SPI_LONG_TIMEOUT;
/**
* @brief SPII/O配置
* @param 无
* @retval 无
*/
static void SPI_GPIO_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
//使能与SPI 有关的时钟
_FLASH_SPI_APBxClock_FUN(_FLASH_SPI_CLK , ENABLE);
_FLASH_SPI_GPIO_APBxClock_FUN(_FLASH_SPI_GPIO_CLK , ENABLE);
//MISO MOSI SCK
GPIO_InitStructure.GPIO_Pin = _FLASH_SPI_SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(_FLASH_SPI_SCL_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = _FLASH_SPI_MISO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(_FLASH_SPI_SCL_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = _FLASH_SPI_MOSI_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(_FLASH_SPI_SCL_PORT,&GPIO_InitStructure);
//初始化CSS引脚,使能软件控制,所以直接设置为推挽输出
GPIO_InitStructure.GPIO_Pin = _FLASH_SPI_CSS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(_FLASH_SPI_SCL_PORT,&GPIO_InitStructure);
_FLASH_CSS_HIGH();
}
/**
* @brief static void SPI_Mode_Config(void) 配置
* @param 无
* @retval 无
*/
static void SPI_Mode_Config(void){
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2 ; //波特率预分频值为 2
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge ; //数据捕获于第二个时钟沿
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //时钟悬空高
SPI_InitStructure.SPI_CRCPolynomial = 0; //不使用CRC功能,数值随便写
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI 发送接收 8 位帧结构
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex ; //双线全双工
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从 MSB 位开始
SPI_InitStructure.SPI_Mode = SPI_Mode_Master ; //设置为主 SPI
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //内部 NSS 信号有 SSI 位控制
SPI_Init(_FLASH_SPIx , &SPI_InitStructure ); //写入配置到寄存器
SPI_Cmd(_FLASH_SPIx , ENABLE); //使能SPI
}
/**
* @brief void SPI_FLASH_Init(void) 初始化
* @param 无
* @retval 无
*/
void SPI_FLASH_Init(void){
SPI_GPIO_Config();
SPI_Mode_Config();
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// 通讯建立操作
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/**
* @brief Basic management of the timeout situation.
* @param errorCode:错误代码,可以用来定位是哪个环节出错.
* @retval 返回0,表示SPI读取失败.
*/
static uint32_t SPI_TIMEOUT_UserCallback(uint8_t errorCode)
{
/* Block communication and all processes */
FLASH_ERROR("SPI 等待超时!errorCode = %d",errorCode);
return 0;
}
/**
* @brief uint8_t SPI_FLASH_Send_Byte(uint8_t data) 初始化
* @param 发送并且接收一个字节
* @retval 无
*/
static uint8_t SPI_FLASH_Send_Byte(uint8_t data){
SPITimeout = FLASH_SPI_TIMEOUT;
//检查并等待至TX缓冲区
while(SPI_I2S_GetFlagStatus(_FLASH_SPIx,SPI_I2S_FLAG_TXE) == RESET){//发送缓存空标志位
if(SPITimeout--==0) {return SPI_TIMEOUT_UserCallback(0);}
}
//判断程序已经为空
SPI_I2S_SendData(_FLASH_SPIx , data);
//判断接受缓存非空
SPITimeout = FLASH_SPI_TIMEOUT;
while(SPI_I2S_GetFlagStatus(_FLASH_SPIx,SPI_I2S_FLAG_RXNE) == RESET){//接受缓存非空标志位标志位
if(SPITimeout--==0) {return SPI_TIMEOUT_UserCallback(1);}
}
//程序发送完毕.并且需要接收一个字节
return SPI_I2S_ReceiveData(_FLASH_SPIx);
}
/**
* @brief uint8_t SPI_FLASH_Send_Byte(uint8_t data) 初始化
* @param 发送并且接收一个字节
* @retval 无
*/
static uint8_t SPI_FLASH_SendHalf_Byte(uint16_t Halfdata){
SPITimeout = FLASH_SPI_TIMEOUT;
//检查并等待至TX缓冲区
while(SPI_I2S_GetFlagStatus(_FLASH_SPIx,SPI_I2S_FLAG_TXE) == RESET){//发送缓存空标志位
if(SPITimeout--==0) {return SPI_TIMEOUT_UserCallback(2);}
}
//判断程序已经为空
SPI_I2S_SendData(_FLASH_SPIx , Halfdata);
//判断接受缓存非空
SPITimeout = FLASH_SPI_TIMEOUT;
while(SPI_I2S_GetFlagStatus(_FLASH_SPIx,SPI_I2S_FLAG_RXNE) == RESET){//接受缓存非空标志位标志位
if(SPITimeout--==0) {return SPI_TIMEOUT_UserCallback(3);}
}
//程序发送完毕.并且需要接收一个字节
return SPI_I2S_ReceiveData(_FLASH_SPIx);
}
/**
* @brief uint32_t SPI_Read_ID(void)
* @param 读取ID号
* @retval
*/
uint32_t SPI_Read_ID(void){
uint32_t flash_id;
//片选使能
_FLASH_CSS_LOW();
SPI_FLASH_Send_Byte(FLASH_SPI_READ_JEDEC_ID);
flash_id = SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY);//Memory typeID
flash_id<<=8;
flash_id|=SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY);//Capcity typeID
flash_id<<=8;
flash_id|=SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY);//Capcity typeID
_FLASH_CSS_HIGH();
return flash_id;
}
/**
* @brief uint32_t SPI_Read_ID(void)
* @param 读取ID号
* @retval
*/
//uint32_t SPI_Read_DeviceID(void){
// uint32_t flash_id;
// //片选使能
// _FLASH_CSS_LOW();
// SPI_FLASH_Send_Byte(FLASH_SPI_READ_JEDEC_ID);
// SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY);//Memory typeID
// SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY);//Capcity typeID
// SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY);//Capcity typeID
// flash_id = SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY);//Capcity typeID
// _FLASH_CSS_HIGH();
// return flash_id;
//}
/**
* @brief void SPI_Write_Enable(void)
* @param 写入使能
* @retval
*/
static void SPI_Write_Enable(void){
//片选使能
_FLASH_CSS_LOW();
SPI_FLASH_Send_Byte(FLASH_SPI_WRITE_ENABLE);
_FLASH_CSS_HIGH();
}
/**
* @brief static void SPI_WaitForWriteEnd(void);
* @param //等待FLASH内部时序操作完成
* @retval
*/
static SPI_WaitForWriteEnd(void){
uint8_t status_reg = 0; //判断最低位S0 erse or write in progress
// 片选指令
_FLASH_CSS_LOW();
SPI_FLASH_Send_Byte(FLASH_SPI_READ_STATUS);
do{
status_reg = SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY); //想要读取数据需要继续发送
}while((status_reg & 0x01)==1); //校验最低位进行校验
_FLASH_CSS_HIGH();
}
/**
* @brief svoid SPI_Erase_Sector(uint32_t addr)
* @param 擦除FLASH指定扇区
* @retval
*/
void SPI_Erase_Sector(uint32_t addr){
SPI_Write_Enable();
/* 擦除扇区 */
/* 选择FLASH: CS低电平 */
_FLASH_CSS_LOW();
/* 发送扇区擦除指令*/
SPI_FLASH_Send_Byte(FLASH_SPI_REASE_SECTOR);
/*发送擦除扇区地址的高位*/
SPI_FLASH_Send_Byte((addr & 0xFF0000) >> 16);
/* 发送擦除扇区地址的中位 */
SPI_FLASH_Send_Byte((addr & 0xFF00) >> 8);
/* 发送擦除扇区地址的低位 */
SPI_FLASH_Send_Byte(addr & 0xFF);
/* 停止信号 FLASH: CS 高电平 */
_FLASH_CSS_HIGH();
/* 等待擦除完毕*/
SPI_WaitForWriteEnd();
}
/**
* @brief 擦除FLASH扇区,整片擦除
* @param 无
* @retval 无
*/
void SPI_FLASH_BulkErase(void){
//发送FLASH 写使能命令
SPI_Write_Enable();
//整块Erase
//选择FLASH :CS 低电平
_FLASH_CSS_LOW();
SPI_FLASH_Send_Byte(FLASH_SPI_ChipErase);
/* 停止信号 FLASH: CS 高电平 */
_FLASH_CSS_HIGH();
/* 等待擦除完毕*/
SPI_WaitForWriteEnd();
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// 读写操作
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/**
* @brief void SPI_Read_Data(uint8_t *readBuffer , uint32_t addr ,uint32_t numByteToRead ));
* @param 读取FLASH的内容
* @retval
*/
void SPI_Read_Data(uint8_t *readBuffer , uint32_t addr ,uint16_t numByteToRead ){
//片选使能
_FLASH_CSS_LOW();
//发送地址
/* 发送 读 指令 */
SPI_FLASH_Send_Byte(FLASH_SPI_READ_DATA);
/* 发送 读 地址高位 */
SPI_FLASH_Send_Byte((addr>>16)&0xff);
/* 发送 读 地址中位 */
SPI_FLASH_Send_Byte((addr>>8)&0xff);
/* 发送 读 地址低位 */
SPI_FLASH_Send_Byte(addr&0xff);
// if(numByteToRead > SPI_PAGE_SIZE){
// numByteToRead = SPI_PAGE_SIZE;
// printf("SPI_FLASH_PageWrite too large!\n");
// }
/* 读取数据 */
while(numByteToRead--){
/* 读取一个字节*/
*readBuffer = SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY);
/* 指向下一个字节缓冲区 */
readBuffer++;
}
/* 停止信号 FLASH: CS 高电平 */
_FLASH_CSS_HIGH();
}
/**
* @brief void SPI_Write_Data(uint8_t *readBuffer , uint32_t addr ,uint32_t numByteToRead ));
* @param 读取FLASH的内容
* @retval
*/
void SPI_Write_Data(uint8_t *writeBuffer , uint32_t addr ,uint16_t numByteToRead ){
SPI_Write_Enable();
//片选使能
_FLASH_CSS_LOW();
/* 写页写指令*/
SPI_FLASH_Send_Byte(FLASH_SPI_WRITE_DATA);
/*发送写地址的高位*/
SPI_FLASH_Send_Byte((addr&0xff0000)>>16);
/*发送写地址的中位*/
SPI_FLASH_Send_Byte((addr&0xff00)>>8);
/*发送写地址的低位*/
SPI_FLASH_Send_Byte(addr&0xff);
if(numByteToRead > SPI_PAGE_SIZE){
numByteToRead = SPI_PAGE_SIZE;
printf("SPI_FLASH_PageWrite too large!\n");
}
//写入数据
while(numByteToRead--){
//发送当前要写入的字节数据
SPI_FLASH_Send_Byte(*writeBuffer);
//指向先亿字节数据
writeBuffer++;
}
/* 停止信号 FLASH: CS 高电平 */
_FLASH_CSS_HIGH();
/* 等待写入完毕*/
SPI_WaitForWriteEnd();
}
/**
* @brief SPI_Write_Data(uint8_t *writeBuffer , uint32_t addr ,uint32_t numByteToRead ){
* @param 读取FLASH的内容
* @retval
*/
void SPI_BufferWrite_Data(uint8_t *writeBuffer , uint32_t WriteAddr ,uint16_t numByteToWrite ){
uint32_t NumOfPage , NumOfSingle , BufferAddr ,count , temp;
if(numByteToWrite == 0){printf("SPI_FLASH_PageWrite too small!\n"); return;}
BufferAddr = WriteAddr % SPI_PAGE_Write_SIZE;
/*地址对应页的前方对齐数量*/
count = SPI_PAGE_Write_SIZE - BufferAddr;
/*当前页剩下的全部地址数量*/
if(count >= numByteToWrite){
//剩下的内容可以一行写完
SPI_Write_Data(writeBuffer ,WriteAddr ,numByteToWrite );
return;
}
SPI_Write_Data(writeBuffer ,WriteAddr ,(uint16_t)count );//分割写入单独页面
temp = numByteToWrite - count ; //排除多余部分
WriteAddr += count;
writeBuffer+=count;
NumOfPage = temp / SPI_PAGE_Write_SIZE ; //对大面积分割输入
NumOfSingle = temp % SPI_PAGE_Write_SIZE ;
if(NumOfPage == 0){
SPI_Write_Data(writeBuffer ,WriteAddr ,(uint16_t)NumOfSingle );
return;
}else{
while(NumOfPage--){
SPI_Write_Data(writeBuffer ,WriteAddr ,SPI_PAGE_Write_SIZE );
WriteAddr += SPI_PAGE_Write_SIZE;
writeBuffer += SPI_PAGE_Write_SIZE;
}
SPI_Write_Data(writeBuffer ,WriteAddr ,(uint16_t)NumOfSingle );
return;
}
}
/**
* @brief void SPI_Show_Data(uint8_t *readBuffer);
* @param 读取FLASH的内容
* @retval
*/
void SPI_Show_Data(uint8_t *readBuffer , uint16_t numByteToRead){
uint32_t i;
for(i=0 ;i<numByteToRead ;i++ ){
if(i%SPI_PAGE_Write_SIZE == 0){ //每隔256字节换行
printf("\r\n ");
}
printf("0x%x ",readBuffer[i]);
}
}
与所有使用到 GPIO 的外设一样,都要先把使用到的 GPIO 引脚模式初始化,配置好复 用功能。GPIO 初始化流程如下:(1) 使用 GPIO_InitTypeDef定义 GPIO初始化结构体变量,以便下面用于存储 GPIO 配置;
(2) 调用库函数 RCC_APB2PeriphClockCmd 来使能 SPI 引脚使用的 GPIO 端口时钟。
(3) 向 GPIO 初始化结构体赋值,把 SCK/MOSI/MISO 引脚初始化成复用推挽模式。而 CS(NSS)引脚由于使用软件控制,我们把它配置为普通的推挽输出模式。
(4) 使用以上初始化结构体的配置,调用 GPIO_Init 函数向寄存器写入参数,完成 GPIO 的 初始化
SPI_FLASH_SendByte 函数实现了前面讲解的“SPI 通讯过程”: (1) 本函数中不包含 SPI 起始和停止信号,只是收发的主要过程,所以在调用本函数 前后要做好起始和停止信号的操作;
(2) 对 SPITimeout 变量赋值为宏 SPIT_FLAG_TIMEOUT。这个 SPITimeout 变量在下 面的 while 循环中每次循环减 1,该循环通过调用库函数 SPI_I2S_GetFlagStatus 检 测事件,若检测到事件,则进入通讯的下一阶段,若未检测到事件则停留在此处 一直检测,当检测 SPIT_FLAG_TIMEOUT 次都还没等待到事件则认为通讯失败, 调用的 SPI_TIMEOUT_UserCallback 输出调试信息,并退出通讯;
(3) 通过检测 TXE 标志,获取发送缓冲区的状态,若发送缓冲区为空,则表示可能存 在的上一个数据已经发送完毕;
(4) 等待至发送缓冲区为空后,调用库函数 SPI_I2S_SendData 把要发送的数据“byte” 写入到 SPI 的数据寄存器 DR,写入 SPI 数据寄存器的数据会存储到发送缓冲区, 由 SPI 外设发送出去;
(5) 写入完毕后等待 RXNE 事件,即接收缓冲区非空事件。由于 SPI 双线全双工模式 下 MOSI 与 MISO 数据传输是同步的(请对比“SPI 通讯过程”阅读),当接收缓冲 区非空时,表示上面的数据发送完毕,且接收缓冲区也收到新的数据;
(6) 等待至接收缓冲区非空时,通过调用库函数 SPI_I2S_ReceiveData 读取 SPI 的数据 寄存器 DR,就可以获取接收缓冲区中的新数据了。代码中使用关键字“return” 把接收到的这个数据作为 SPI_FLASH_SendByte 函数的返回值,所以我们可以看 到在下面定义的 SPI 接收数据函数 SPI_FLASH_ReadByte,它只是简单地调用了 SPI_FLASH_SendByte 函数发送数据“Dummy_Byte”,然后获取其返回值(因为 不关注发送的数据,所以此时的输入参数“Dummy_Byte”可以为任意值)。可以 这样做的原因是 SPI 的接收过程和发送过程实质是一样的,收发同步进行,关键 在于我们的上层应用中,关注的是发送还是接收的数据。
建立I2C模拟传输的 头文件 I2C_soft_book.h
代码如下 :
#ifndef __I2C_SOFT_BOOK_H_
#define __I2C_SOFT_BOOK_H_
#include "stm32f10x.h"
//---------------- 这里封装了 I2C 通讯配置信息 -------------------
#define _Soft_I2C_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define _Soft_I2C_GPIO_CLK RCC_APB2Periph_GPIOB
#define _Soft_I2C_SCL_PORT GPIOB
#define _Soft_I2C_SCL_PIN GPIO_Pin_6
#define _Soft_I2C_SDA_PORT GPIOB
#define _Soft_I2C_SDA_PIN GPIO_Pin_7
#define _I2C_SCL_1() _Soft_I2C_SCL_PORT->BSRR = _Soft_I2C_SCL_PIN
#define _I2C_SCL_0() _Soft_I2C_SCL_PORT->BRR = _Soft_I2C_SCL_PIN
#define _I2C_SDA_1() _Soft_I2C_SCL_PORT->BSRR = _Soft_I2C_SDA_PIN
#define _I2C_SDA_0() _Soft_I2C_SCL_PORT->BRR = _Soft_I2C_SDA_PIN
#define _I2C_SDA_READ() ((_Soft_I2C_SCL_PORT->IDR & _Soft_I2C_SDA_PIN)!=0)
#define I2C_WR 0 /* 写控制bit */
#define I2C_RD 1 /* 读控制bit */
//----------------器件地址--------------------
/*
* AT24C02 2kb = 2048bit = 2048/8 B = 256 B
* 32 pages of 8 bytes each
*
* Device Address
* 1 0 1 0 A2 A1 A0 R/W
* 1 0 1 0 0 0 0 0 = 0XA0
* 1 0 1 0 0 0 0 1 = 0XA1
*/
/* EEPROM Addresses defines */
#define Soft_EEPROM_ADDRESS 0xA0 /* E2 = 0 */
//#define EEPROM_ADDRESS 0xA2 /* E2 = 0 */
//#define EEPROM_ADDRESS 0xA4 /* E2 = 0 */
//#define EEPROM_ADDRESS 0xA6 /* E2 = 0 */
/*读取数据的格式以及字符数量*/
#define _I2C_Soft_PageSize 8
#define _I2C_Soft_SIZE 256 /* 24xx02总容量 */
/*I2C 存储地址*/
#define EEP_Soft_Firstpage 0x90
void I2C_Soft_Init(void);
void EE_Soft_Trase(void);
uint8_t I2C_Soft_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
uint8_t I2C_Soft_Read_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
#endif
建立I2C模拟传输的 头文件 I2C_soft_book.c
代码如下 :
#include "I2C_soft_book.h"
#include "Systick_book.h"
static I2C_GPIO_Soft_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
_Soft_I2C_GPIO_APBxClock_FUN(_Soft_I2C_GPIO_CLK , ENABLE);
GPIO_InitStructure.GPIO_Pin = _Soft_I2C_SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出
GPIO_Init(_Soft_I2C_SCL_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = _Soft_I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出
GPIO_Init(_Soft_I2C_SDA_PORT,&GPIO_InitStructure);
}
/**
* @brief I2C_EE_Init 程序初始化
* @param 无
* @retval 无
*/
static void I2C_Start(void){
// 当SCL高电平时候SDA 出现一个下降沿编号位I2C 总线启动信号
_I2C_SCL_1();
_I2C_SDA_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SDA_0();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
}
/**
* @brief I2C_Stop 程序初始化
* @param 无
* @retval 无
*/
static void I2C_Stop(void){
// 当SCL高电平,SDA出现上升沿表示I2C总线停止信号
_I2C_SDA_0();
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SDA_1();
}
/**
* @brief I2C_SendByte 程序初始化
* @param 无
* @retval 无
*/
static void I2C_SendByte(uint8_t _ucByte){
uint8_t i;
//发送字节的高位
for( i=0; i<8;i++ ){
if(_ucByte & 0x80){
_I2C_SDA_1();
}else{
_I2C_SDA_0();
}
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_0();
_ucByte <<=1; //------注意这里不太一样
fn_Systick_Delay(50,_Systick_us);
}
_I2C_SDA_1();// 释放总线
}
/**
* @brief I2C_ReadByte 程序初始化
* @param 无
* @retval 无
*/
static uint8_t I2C_ReadByte(void){
uint8_t i;
uint8_t value;
//读到第1个bit 为数据的bit7
value = 0;
for(i=0 ;i<8 ;i++ ){
value <<=1;
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
if(_I2C_SDA_READ()){
value++;
}
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
}
return value;
}
/**
* @brief I2C_WaitAck
* @param 无
* @retval 无
*/
static uint8_t I2C_WaitAck(void){
uint8_t re;
_I2C_SDA_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
if(_I2C_SDA_READ()){
re = 1;
}else{
re = 0;
}
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
return re;
}
/**
* @brief I2C_ACK
* @param 无
* @retval 无
*/
static void I2C_ACK(void){
_I2C_SDA_0(); //CPU 驱动SDA = 0;
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_1(); //CPU 产生1个时钟
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
_I2C_SDA_1(); //CPU 释放SDA总线
}
/**
* @brief I2C_ACK
* @param 无
* @retval 无
*/
static void I2C_NACK(void){
_I2C_SDA_1(); //CPU 驱动SDA = 1;
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_1(); //CPU 产生1个时钟
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
}
static uint8_t I2C_CheckDevice(uint8_t _Address){
uint8_t ucAck;
I2C_GPIO_Soft_Config();
I2C_Start();
I2C_SendByte(_Address | I2C_WR);
ucAck = I2C_WaitAck(); /* 检测设备的ACK应答 */
I2C_Stop(); /* 发送停止信号 */
return ucAck;
}
//----------------------I2C 独写操作--------------------
//------------------------------------------------------
/**
* @brief EE_Soft_Check_State
* @param 判断串行EERPOM是否正常
* @retval 无
*/
static uint8_t EE_Soft_Check_State(void){
if(I2C_CheckDevice(Soft_EEPROM_ADDRESS)==0){return 1;}
else{I2C_Stop(); /* 发送停止信号 */ return 0;}
}
/**
* @brief uint8_t I2C_Soft_BufferRead(uint8_t* pBuffer,
* uint8_t ReadAddr, uint16_t NumByteToRead)
* @param 判断串行EERPOM是否正常
* @retval 无
*/
static uint8_t I2C_Soft_BufferRead(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead){
uint16_t i ;
//连续取得若干个字节
// 发起I2C总线启动信号
I2C_Start();
//发送控制字节地址和读取数据信号
I2C_SendByte(Soft_EEPROM_ADDRESS | I2C_WR);
//等待应答状态
if(I2C_WaitAck()!=0){printf("EEPROM 错误 1 !\r\n"); goto CMD_Fail;}
//发送数据读取位置信息信号
I2C_SendByte((uint8_t)ReadAddr);
//等待应答状态
if(I2C_WaitAck()!=0){printf("EEPROM 错误 2 !\r\n");goto CMD_Fail;}
//--------------
//重新启动I2C总线
I2C_Start();
//发送器件地址
I2C_SendByte(Soft_EEPROM_ADDRESS| I2C_RD);
//等待应答状态
if(I2C_WaitAck()!=0){printf("EEPROM 错误3 !\r\n"); goto CMD_Fail;}
for(i=0 ;i<NumByteToRead ;i++ ){
pBuffer[i] = I2C_ReadByte();
if(i!=NumByteToRead-1){
I2C_ACK();
}else{
I2C_NACK();
}
}
I2C_Stop();
return 1;
CMD_Fail:
I2C_Stop();
return 0;
}
/**
* @brief uint8_t EE_Soft_WriteBytes(uint8_t* pBuffer,
* uint8_t ReadAddr, uint16_t NumByteToRead)
* @param 判断串行EERPOM是否正常
* @retval 无
*/
static uint8_t EE_Soft_WriteBytes(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead){
uint16_t i , m;
uint16_t usAddr;
/*
写串行EEPROM 不像读操作可以连续读取很多字节每次写操作只能在同一个page
对于24C page size = 8
简单的处理方法为 按字节写操作模式,写一个字节都发送地址
为了提高连续写的效率 笨函数采用Page write操作
*/
usAddr = ReadAddr;
for(i=0 ;i<NumByteToRead;i++ ){
// 当发送第一个字节或者页面首地址时,需要重新发起启动信号和地址
if((i==0)||(usAddr)&(_I2C_Soft_PageSize-1)==0){
// 发送停止信号
I2C_Stop();
//通过检测器判断内存写入是否成功
m = 100;
for (m = 0; m < 100; m++){
//启动I2C总线
I2C_Start();
//发送器件地址
I2C_SendByte(Soft_EEPROM_ADDRESS| I2C_WR);
//等待应答状态
if(I2C_WaitAck()==0){break;}
}
if(m==100){printf("EEPROM 错误 4 !\r\n"); goto CMD_FAIL_bytes ; }
I2C_SendByte((uint8_t)usAddr);
if(I2C_WaitAck()!=0){printf("EEPROM 错误 5 !\r\n"); goto CMD_FAIL_bytes;}
}
// 开始写入数据
I2C_SendByte(pBuffer[i]);
//等待应答状态
if(I2C_WaitAck()!=0){printf("EEPROM 错误 7 !\r\n"); goto CMD_FAIL_bytes;}
usAddr++;
}
// 发送停止信号
I2C_Stop();
return 1;
CMD_FAIL_bytes:
// 发送停止信号
I2C_Stop();
return 0;
}
/**
* @brief void EE_Soft_Trase(void)
* @param 判断串行EERPOM是否正常
* @retval 无
*/
void EE_Soft_Trase(void){
uint16_t i ;
uint8_t buf[_I2C_Soft_SIZE]={0};
// 填充缓冲区
for(i=0 ;i<_I2C_Soft_SIZE ;i++ ){
buf[i] = 0xFF;
}
//写EEPROM 起始地址= 0 数据长度为256
if(EE_Soft_WriteBytes(buf,0,_I2C_Soft_SIZE)==0){
printf("擦除EEPROM出错!\r\n");
return;
}else{
printf("擦除EEPROM出错!\r\n");
}
}
/**
* @brief void I2C_Soft_Init(void)
* @param
* @retval 无
*/
void I2C_Soft_Init(void){
if(EE_Soft_Check_State()==0){
/* 没有检测到EEPROM */
printf("没有检测到串行EEPROM!\r\n");
}
}
/**
* @brief void I2C_Soft_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite)
* @param 判断串行EERPOM是否正常
* @retval 无
*/
uint8_t I2C_Soft_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
uint16_t i;
//-------------------------------
if(EE_Soft_Check_State()==0){
/* 没有检测到EEPROM */
printf("没有检测到串行EEPROM!\r\n");
return 1;
}
//------------写入I2C-------------------
if(EE_Soft_WriteBytes(pBuffer,WriteAddr ,NumByteToWrite)==0){
/* 没有检测到EEPROM */
printf("写EEPROM错误!\r\n");
return 1;
}else{
/* 没有检测到EEPROM */
printf("写EEPROM成功!\r\n");
}
fn_Systick_Delay(150,_Systick_us);
//--------------数据检查--------------
printf("EEPROM写入数据检查检查\r\n");
for(i=0 ;i<NumByteToWrite ;i++ ){
printf(" %d ",pBuffer[i]);
if((i & 15)==15){
printf("\r\n");
}
}
return 0;
}
uint8_t I2C_Soft_Read_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
uint16_t i;
//-------------读取I2C------------------
if(I2C_Soft_BufferRead(pBuffer,WriteAddr,NumByteToWrite)==0){
/* 没有检测到EEPROM */
printf("读EEPROM错误!\r\n");
return 1;
}else{
/* 没有检测到EEPROM */
printf("\n读EEPROM成功!\r\n");
}
//--------------数据检查--------------
printf("EEPROM读取数据数据检查 \r\n");
for(i=0 ;i<NumByteToWrite ;i++ ){
printf(" %d ",pBuffer[i]);
if((i & 15)==15){
printf("\r\n");
}
}
return 1;
}
/*********************END OF FILE**********************/
建立I2C硬件传输的 头文件 I2C_book.h
代码如下 :
#ifndef __I2C_BOOK_H_
#define __I2C_BOOK_H_
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "USART_book.h"
//---------------- 这里封装了 I2C 通讯配置信息 -------------------
#define _EEPROM_I2Cx I2C1
#define _EEPROM_I2C_APBxClock_FUN RCC_APB1PeriphClockCmd
#define _EEPROM_I2C_CLK RCC_APB1Periph_I2C1
#define _EEPROM_I2C_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define _EEPROM_I2C_GPIO_CLK RCC_APB2Periph_GPIOB
#define _EEPROM_I2C_SCL_PORT GPIOB
#define _EEPROM_I2C_SCL_PIN GPIO_Pin_6
#define _EEPROM_I2C_SDA_PORT GPIOB
#define _EEPROM_I2C_SDA_PIN GPIO_Pin_7
/*STM32 I2C 速度模式 */
#define _I2C_Speed 400000
/* I2C 器件地址 */
#define _I2Cx_OWN_ADDRESS7 0x5f
/*读取数据的格式以及字符数量*/
#define _I2C_PageSize 8
/*I2C 存储地址*/
#define EEP_Firstpage 0x90
#define EEP_SIZE 0xFF
//----------------器件地址--------------------
/*
* AT24C02 2kb = 2048bit = 2048/8 B = 256 B
* 32 pages of 8 bytes each
*
* Device Address
* 1 0 1 0 A2 A1 A0 R/W
* 1 0 1 0 0 0 0 0 = 0XA0
* 1 0 1 0 0 0 0 1 = 0XA1
*/
/* EEPROM Addresses defines */
#define EEPROM_ADDRESS 0xA0 /* E2 = 0 */
//#define EEPROM_ADDRESS 0xA2 /* E2 = 0 */
//#define EEPROM_ADDRESS 0xA4 /* E2 = 0 */
//#define EEPROM_ADDRESS 0xA6 /* E2 = 0 */
//----------------函数声明--------------------
//I2C 应用函数
void _I2C_EE_Init(void);
void I2C_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
void I2C_Read_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
#endif
建立I2C硬件传输的 头文件 I2C_book.c
代码如下 :
#include "I2C_book.h"
#include "Systick_book.h"
/**
* @brief I2C_EE_Init 程序初始化
* @param 无
* @retval 无
*/
static void I2C_GPIO_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
// 初始化 I2C 相关时钟
_EEPROM_I2C_APBxClock_FUN(_EEPROM_I2C_CLK,ENABLE);
_EEPROM_I2C_GPIO_APBxClock_FUN(_EEPROM_I2C_GPIO_CLK,ENABLE);
// 初始化I2C_SCL SDA
GPIO_InitStructure.GPIO_Pin = _EEPROM_I2C_SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //开漏输出
GPIO_Init(_EEPROM_I2C_SCL_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = _EEPROM_I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //开漏输出
GPIO_Init(_EEPROM_I2C_SDA_PORT,&GPIO_InitStructure);
}
/**
* @brief I2C_EE_Init 程序初始化
* @param 无
* @retval 无
*/
static void I2C_Mode_Config(void){
I2C_InitTypeDef I2C_InitStructure;
/* i2C 配置 */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
// 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = _I2Cx_OWN_ADDRESS7;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
//I2C 寻址模式
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
//通讯频率
I2C_InitStructure.I2C_ClockSpeed = _I2C_Speed;
//I2C 初始化
I2C_Init(_EEPROM_I2Cx,&I2C_InitStructure);
//使能I2C
I2C_Cmd(_EEPROM_I2Cx,ENABLE);
}
/**************************************/
static uint32_t I2C_TIMEOUT_UserCallback(uint8_t errorCode){
fn_Usart_SendString(_DEBUG_USARTx,"I2C 等待超时!errorCode =");
printf("%d\n",errorCode);
return 0;
}
/**************************************/
/*通讯等待超时时间*/
#define I2CT_FLAG_TIMEOUT ((uint32_t)0x6000)
#define I2CT_LONG_TIMEOUT ((uint32_t)(10*I2CT_FLAG_TIMEOUT))
static uint16_t I2CTimeout;
/**************************************/
/**
* @brief 写一个字节到 I2C EEPROM 中
* @param pBuffer:缓冲区指针
* @param WriteAddr:写地址
* @retval 正常返回 1,异常返回 0
*/
static uint32_t I2C_EE_ByteWrite(u8* pBuffer, uint8_t WriteAddr ){
I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_GetFlagStatus(_EEPROM_I2Cx , ENABLE)){
if((I2CTimeout--) == 0){return I2C_TIMEOUT_UserCallback(4);}
}
//产生I2C起始信号
I2C_GenerateSTART(_EEPROM_I2Cx , ENABLE);
I2CTimeout = I2CT_LONG_TIMEOUT; //这个变量是延时异常时间
//检测EV5 事件并清除标识位
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_MODE_SELECT)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(5);}
}
//发送EEPROM 设备地址
I2C_Send7bitAddress(_EEPROM_I2Cx,EEPROM_ADDRESS,I2C_Direction_Transmitter);
I2CTimeout = I2CT_LONG_TIMEOUT; //这个变量是延时异常时间
//检测EV6 事件并清除标识位
while(I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(6);}
}
//发送要写入的EEPROM 内部地址(即EEPROM内部存储其地址);
I2C_SendData(_EEPROM_I2Cx,WriteAddr);
I2CTimeout = I2CT_LONG_TIMEOUT;
//检测EV8 事件清除标志位
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(2);}
}
//发送要写入的EEPROM 内部的数据;
I2C_SendData(_EEPROM_I2Cx,*pBuffer);
I2CTimeout = I2CT_LONG_TIMEOUT;
//检测EV8 事件清除标志位
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(3);}
}
//发送要写入的EEPROM 内部的数据;
I2C_SendData(_EEPROM_I2Cx,ENABLE);
return 1;
}
/**
* @brief 将缓冲区中的数据写到 I2C EEPROM 中,采用单字节写入的方式,速度比页写入慢
* @param pBuffer:缓冲区指针
* @param WriteAddr:写地址
* @param NumByteToWrite:写的字节数
*/
static void I2C_EE_WaitEepromStandbyState(void){
vu16 SR1_Tmp = 0;
do{
//产生I2C起始信号
I2C_GenerateSTART(_EEPROM_I2Cx,ENABLE);
//读取I2C1 SR1 寄存器
SR1_Tmp = I2C_ReadRegister(_EEPROM_I2Cx, I2C_Register_SR1);
//发送EEPROM 地址+ 方向
I2C_Send7bitAddress(_EEPROM_I2Cx,EEPROM_ADDRESS,I2C_Direction_Transmitter);
}while(!(I2C_ReadRegister(_EEPROM_I2Cx, I2C_Register_SR1) & 0x0002));
/* 清除 AF 位 */
I2C_ClearFlag(_EEPROM_I2Cx, I2C_FLAG_AF);
//发送停止位信号
I2C_GenerateSTOP(_EEPROM_I2Cx , ENABLE);
}
//zuozuo04-30
/**
* @brief 在 EEPROM 的一个写循环中可以写多个字节,但一次写入的字节数
* 不能超过 EEPROM 页的大小,AT24C02 每页有 8 个字节
* @param
* @param pBuffer:缓冲区指针
* @param WriteAddr:写地址
* @param NumByteToWrite:要写的字节数要求 NumByToWrite 小于页大小
* @retval 正常返回 1,异常返回 0
*/
static uint8_t I2C_EE_PageWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_GetFlagStatus(_EEPROM_I2Cx , ENABLE)){
if((I2CTimeout--) == 0){return I2C_TIMEOUT_UserCallback(4);}
}
//产生I2C起始信号
I2C_GenerateSTART(_EEPROM_I2Cx , ENABLE);
I2CTimeout = I2CT_LONG_TIMEOUT; //这个变量是延时异常时间
//检测EV5 事件并清除标识位
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_MODE_SELECT)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(5);}
}
//发送EEPROM 设备地址
I2C_Send7bitAddress(_EEPROM_I2Cx,EEPROM_ADDRESS,I2C_Direction_Transmitter);
I2CTimeout = I2CT_LONG_TIMEOUT; //这个变量是延时异常时间
//检测EV6 事件并清除标识位
while(I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(6);}
}
//发送要写入的EEPROM内部地址(EEPROM内部存储器地址)
I2C_SendData(_EEPROM_I2Cx,WriteAddr);
I2CTimeout = I2CT_LONG_TIMEOUT; //这个变量是延时异常时间
//检测EV7 事件并清除标识位
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTING)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(7);}
}
//循环发送 NumByteToWrite个数据
while(NumByteToWrite--){
//发送缓冲区的数据
I2C_SendData(_EEPROM_I2Cx,*pBuffer++);
I2CTimeout = I2CT_FLAG_TIMEOUT; //这个变量是延时异常时间
//检测EV8 事件并清除标识位
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(8);}
}
}
//发送停止信号
I2C_GenerateSTOP(_EEPROM_I2Cx,ENABLE);
return 1;
}
/** 快速写入一页
* @brief 将缓冲区中的数据写到 I2C EEPROM 中
* @param
* @arg pBuffer:缓冲区指针
* @arg WriteAddr:写地址
* @arg NumByteToWrite:写的字节数
* @retval 无
*/
#define I2C_PageSize 8 //AT24C01 02 每页有8个字节
static void I2C_EE_BufferWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
u8 NumOfPage = 0, NumOfSingle = 0 , Addr = 0 , count = 0,temp = 0;
//Mod 求余运算,如果writeAddr 是 I2C_PageSize 整书倍,运算结果位Addr为0
Addr = WriteAddr % I2C_PageSize;
//差count个数值,刚好可以对齐到页面地址
count = I2C_PageSize - Addr;
//计算出要写多少整书页
NumOfPage = NumByteToWrite / I2C_PageSize;
//mod运算求余计算出不满一页的字节数
NumOfSingle = NumByteToWrite % I2C_PageSize;
// Addr = 0,则WriteAddr 刚好按页对齐aligned
// 这样就很简单了,直接写就可以写完整页后
// 把剩下的不满一页的写完即可
if(Addr == 0){
//如果 NumByteToWrite < I2C_PageSize
if(NumOfPage==0){
I2C_EE_PageWrite(pBuffer , WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}//如果NumByteToWrite > I2C_PageSize
else{
//先把整数页写了
while(NumOfPage--){
I2C_EE_PageWrite(pBuffer , WriteAddr, I2C_PageSize);
I2C_EE_WaitEepromStandbyState();
WriteAddr += I2C_PageSize ;
pBuffer += I2C_PageSize ;
}
//若有多余的不满一页的数据,把它写完
if(NumOfSingle != 0){
I2C_EE_PageWrite(pBuffer , WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
}
}
//如果 WriteAddr 不是按 I2C_PageSize 对齐
//那就算出对齐到页地址还需要多少数据,然后先把这几个数据写完,剩下开始的地址就已经对齐
//到页地址了,代码重复上面的即可
else{
//如果NumByteToWrite < I2C_PageSize
if(NumOfPage == 0){
//若NumOfSingle > count,当前面写不完,要写下一页
if(NumOfSingle > count){
temp = NumOfSingle - count;
I2C_EE_PageWrite(pBuffer , WriteAddr, count);
I2C_EE_WaitEepromStandbyState();
WriteAddr += count ;
pBuffer += count ;
I2C_EE_PageWrite(pBuffer , WriteAddr, temp);
I2C_EE_WaitEepromStandbyState();
}else{//若count 比 NumOfSingle大
I2C_EE_PageWrite(pBuffer , WriteAddr, NumByteToWrite);
I2C_EE_WaitEepromStandbyState();
}
}
//如果 NumByteToWrite > I2C_PageSize
else{
//地址不对齐多出的Count 分开处理,不加入这个运算
NumByteToWrite -= count;
NumOfPage = NumByteToWrite / I2C_PageSize ;
NumOfSingle = NumByteToWrite % I2C_PageSize;
//先把 WriteAddr 所在页的剩余字节写了
if(count!=0){
I2C_EE_PageWrite(pBuffer , WriteAddr, count);
I2C_EE_WaitEepromStandbyState();
//加上 count 后,地址就对齐到页了
WriteAddr += count ;
pBuffer += count ;
}
//把整页都写了
while(NumOfPage--){
I2C_EE_PageWrite(pBuffer , WriteAddr, I2C_PageSize);
I2C_EE_WaitEepromStandbyState();
WriteAddr += I2C_PageSize ;
pBuffer += I2C_PageSize ;
}
//若多余的不满足一页,就把它写完
if(NumOfSingle !=0){
I2C_EE_PageWrite(pBuffer , WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
}
}
}
/* EEPROM 读取
* @brief 从 EEPROM 里面读取一块数据
* @param pBuffer:存放从 EEPROM 读取的数据的缓冲区指针
* @param ReadAddr:接收数据的 EEPROM 的地址
* @param NumByteToRead:要从 EEPROM 读取的字节数
* @retval 正常返回 1,异常返回 0
*/
static uint8_t I2C_EE_BufferRead(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead){
I2CTimeout = I2CT_LONG_TIMEOUT ;
while(I2C_GetFlagStatus(_EEPROM_I2Cx , I2C_FLAG_BUSY)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(9);}
}
//产生I2C起始信号
I2C_GenerateSTART(_EEPROM_I2Cx , ENABLE);
I2CTimeout = I2CT_FLAG_TIMEOUT;
//检测EV10 事件并清除标注
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_MODE_SELECT)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(10);}
}
//发送EEPROM 设备地址
I2C_Send7bitAddress(_EEPROM_I2Cx , EEPROM_ADDRESS , I2C_Direction_Transmitter);
I2CTimeout = I2CT_FLAG_TIMEOUT;
//检测EV11 事件并清除
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(11);}
}
//通过重新设置PE位清除EV12事件
I2C_Cmd(_EEPROM_I2Cx ,ENABLE );
//发送要读取的EEPROM内部地址(即EEPROM内部存储器地址)
I2C_SendData(_EEPROM_I2Cx, ReadAddr);
I2CTimeout = I2CT_FLAG_TIMEOUT ;
//检测EV12 事件并清除
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(12);}
}
//产生第二次I2C起始信号
I2C_GenerateSTART(_EEPROM_I2Cx , ENABLE);
I2CTimeout = I2CT_FLAG_TIMEOUT;
//检测EV13 事件并清除
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_MODE_SELECT)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(13);}
}
//发送EEPROM 设备地址
I2C_Send7bitAddress(_EEPROM_I2Cx , EEPROM_ADDRESS , I2C_Direction_Receiver);
I2CTimeout = I2CT_FLAG_TIMEOUT;
//检测EV14 事件并清除
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(14);}
}
//读取NumByteToRead个数据
while(NumByteToRead){
//如果 NumByteToRead=1,表示已经收到最后一个数据了
//发送应答信号结束输出
if(NumByteToRead == 1){
//发送非应答信号
I2C_AcknowledgeConfig(_EEPROM_I2Cx , DISABLE);
}
I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_BYTE_RECEIVED)==0){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(3);}
}
//通过I2C,从设备中读取一个字节的数据
*pBuffer = I2C_ReceiveData(_EEPROM_I2Cx);
//存储数据的指针指以下地址
pBuffer++;
//接受数据自减
NumByteToRead--;
}
//发送停止信号
I2C_GenerateSTOP(_EEPROM_I2Cx , ENABLE);
//使能大应,方便一下I2C输出
I2C_AcknowledgeConfig(_EEPROM_I2Cx , ENABLE);
return 1;
}
//--------------------------------------------------------
/**
* @brief void _I2C_EE_Init(void)
* @param 无
* @retval 正常返回 1 ,不正常返回 0
*/
void _I2C_EE_Init(void){
I2C_GPIO_Config();
I2C_Mode_Config();
}
/**
* @brief I2C_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite)
* @param 无
* @retval 正常返回 1 ,不正常返回 0
*/
void I2C_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
u16 i;
printf("I2C_写入数据 \n");
I2C_EE_WaitEepromStandbyState();
I2C_EE_PageWrite(pBuffer,WriteAddr, NumByteToWrite);
for(i=0 ;i<NumByteToWrite ;i++ ){
printf("%d ", *pBuffer++);
if(i%16 == 15)
printf("\n\r");
}
printf("\nI2C_写入数据完成 \n");
I2C_EE_WaitEepromStandbyState();
for(i=0 ;i<NumByteToWrite ;i++ ){
printf("%d ", pBuffer[i]);
if(i%16 == 15)
printf("\n\r");
}
}
/**
* @brief I2C(void I2C_Read_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite))读写测试
* @param 无
* @retval EEP_SIZE
*/
void I2C_Read_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
u16 i;
printf("I2C_数据检测 \n");
I2C_EE_BufferRead(pBuffer,WriteAddr,NumByteToWrite);
printf("\nI2C_数据读取完毕 \n");
for(i=0 ;i<NumByteToWrite ;i++ ){
printf("%d ", pBuffer[i]);
if(i%16 == 15)
printf("\n\r");
}
printf("\n--->I2C_数据检测完成\n");
}
建立USART传输的 头文件 USART_book.h
代码如下 :
#ifndef __USART_BOOK_H_
#define __USART_BOOK_H_
#include "stm32f10x.h"
#include <stdio.h>
#include "stm32f10x_usart.h"
#include "stm32f10x_rcc.h"
//串口的宏定义 不同的串口挂在的总线和IO不一样
//串口1
#define _DEBUG_USARTx USART1
#define _DEBUG_USART_CLK RCC_APB2Periph_USART1
#define _DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
#define _DEBUG_USART_BAUDRATE 115200
// USART GPIO 引脚定义
#define _DEBUG_USART_GPIO_CLK RCC_APB2Periph_GPIOA
#define _DEBUG_USART_GPIO_APBxCLKCmd RCC_APB2PeriphClockCmd
#define _DEBUG_USART_TX_GPIO_PORT GPIOA
#define _DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
#define _DEBUG_USART_TX_GPIO_MODE GPIO_Mode_AF_PP
#define _DEBUG_USART_RX_GPIO_PORT GPIOA
#define _DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10
#define _DEBUG_USART_RX_GPIO_MODE GPIO_Mode_IN_FLOATING
#define _DEBUG_NVIC_USART_IRQ USART1_IRQn
#define _DRBUG_USART_IRQHandler USART1_IRQHandler
void fn_USART_IO_Config(void);
void fn_USART_Config(void);
void fn_USART_Init(void);
void fn_Usart_Send_Byte(USART_TypeDef * pUSARTx , uint8_t ch );
void fn_Usart_SendString(USART_TypeDef *pUSARTx , char * str);
void Usart_SendHalf_32_Word( USART_TypeDef * pUSARTx, uint32_t ch);
int fputc (int ch , FILE *f);
int fgetc(FILE *f);
void _DRBUG_USART_IRQHandler(void);
#endif
建立USART传输的C文件 USART_book.c
代码如下 :
#include "USART_book.h"
/**************************************************************
* @brief
* void fn_LED_Corporate(GPIO_TypeDef* _GPIO_x , uint16_t _GPIO_Pin_x ,
* LED_Corporate_state_t _LED_Corporate_state_t );
* @param
* //串口1
* #define _DEBUG_NVIC_USART_IRQ USART1_IRQn
* #define _DRBUG_NVIC_USART_IRQHandler USART1_IRQHandler
* @retval
*************************************************************/
static void NVIC_Configuration(void){
NVIC_InitTypeDef NVIC_InitStructure;
/* 嵌套向量中断控制寄存器组选择*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 配置 USART 为中断源 */
NVIC_InitStructure.NVIC_IRQChannel = _DEBUG_NVIC_USART_IRQ;
/* 抢断优先级为 1 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 子优先级为 1 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 初始化配置 NVIC */
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************
* @brief
* void fn_LED_Corporate(GPIO_TypeDef* _GPIO_x , uint16_t _GPIO_Pin_x ,
* LED_Corporate_state_t _LED_Corporate_state_t );
* @param
* //串口1
* // USART GPIO 引脚定义
* #define _DEBUG_USART_GPIO_CLK RCC_APB2Periph_GPIOA
* #define _DEBUG_USART_GPIO_APBxCLKCmd RCC_APB2PeriphClockCmd
*
* #define _DEBUG_USART_TX_GPIO_PORT GPIOA
* #define _DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
* #define _DEBUG_USART_TX_GPIO_MODE GPIO_Mode_AF_PP
* #define _DEBUG_USART_RX_GPIO_PORT GPIOA
* #define _DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10
* #define _DEBUG_USART_RX_GPIO_MODE GPIO_Mode_AF_FLOATING
* @retval
*************************************************************/
void fn_USART_IO_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
// 打开串口 GPIO 的时钟
_DEBUG_USART_GPIO_APBxCLKCmd(_DEBUG_USART_GPIO_CLK , ENABLE);
//将USART TX 的GPIO配置为推挽模式
GPIO_InitStructure.GPIO_Pin = _DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = _DEBUG_USART_TX_GPIO_MODE;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(_DEBUG_USART_TX_GPIO_PORT,&GPIO_InitStructure);
//将USART RX 的GPIO配置为浮空输入
GPIO_InitStructure.GPIO_Pin = _DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = _DEBUG_USART_RX_GPIO_MODE;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(_DEBUG_USART_RX_GPIO_PORT,&GPIO_InitStructure);
}
/**************************************************************
* @brief
* void fn_LED_Corporate(GPIO_TypeDef* _GPIO_x , uint16_t _GPIO_Pin_x ,
* LED_Corporate_state_t _LED_Corporate_state_t );
* @param
* //串口1
* #define _DEBUG_USARTx USART1
* #define _DEBUG_USART_CLK RCC_APB2Periph_USART1
* #define _DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
* #define _DEBUG_USART_BAUDRATE 115200
* @retval
*************************************************************/
void fn_USART_Config(void){
USART_InitTypeDef USART_InitStructure;
// 打开串口外设的时钟
_DEBUG_USART_APBxClkCmd(_DEBUG_USART_CLK , ENABLE);
//配置串口的工作参数
USART_InitStructure.USART_BaudRate = _DEBUG_USART_BAUDRATE;
//配置波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// 配置 针数据字长
USART_InitStructure.USART_StopBits = USART_StopBits_1;
// 配置停止位
USART_InitStructure.USART_Parity = USART_Parity_No;
// 配置校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
// 配置硬件流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx ;
// 配置工作模式,收发一起
USART_Init(_DEBUG_USARTx , &USART_InitStructure);// 完成串口的初始化配置
NVIC_Configuration();// 串口中断优先级配置
USART_ITConfig(_DEBUG_USARTx , USART_IT_RXNE , ENABLE);// 使能串口接收中断
USART_Cmd(_DEBUG_USARTx , ENABLE);// 使能串口
}
/**************************************************************
* @brief
* void fn_Usart_Send_Byte(USART_TypeDef * pUSARTx , uint8_t ch );
* @param
* //串口1
* #define _DEBUG_USARTx USART1
* #define _DEBUG_USART_CLK RCC_APB2Periph_USART1
* #define _DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
* #define _DEBUG_USART_BAUDRATE 115200
* @retval
*************************************************************/
void fn_Usart_Send_Byte(USART_TypeDef * pUSARTx , uint8_t ch ){
/*发送一个字节数据到USART*/
USART_SendData(pUSARTx , ch);
/*等待发送数据寄存器为空*/
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE)==RESET);
}
/**************************************************************
* @brief
* void fn_Usart_SendString(USART_TypeDef *pUSARTx , char * str);
* @param
* //串口1
* #define _DEBUG_USARTx USART1
* #define _DEBUG_USART_CLK RCC_APB2Periph_USART1
* #define _DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
* #define _DEBUG_USART_BAUDRATE 115200
* @retval
*************************************************************/
void fn_Usart_SendString(USART_TypeDef *pUSARTx , char * str){
unsigned int k = 0;
do{
fn_Usart_Send_Byte(pUSARTx,*(str + k++));
}while(*(str + k)!='\0');
/*等待发送完成*/
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC));
}
/**************************************************************
* @brief
* void Usart_SendHalf_32_Word( USART_TypeDef * pUSARTx, uint32_t ch);
* @param
* @retval
*************************************************************/
void Usart_SendHalf_32_Word( USART_TypeDef * pUSARTx, uint32_t ch){
uint32_t temp_Half32;
uint8_t temp_Half=0,i_Half=4;
temp_Half32 =ch;
while(i_Half-->0){
temp_Half=(temp_Half32 & 0xFF000000)>>24;
temp_Half32<<=8;
fn_Usart_Send_Byte(pUSARTx,temp_Half);
}
/*等待发送完成*/
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC));
}
/**************************************************************
* @brief
* void fn_USART_Init(void);
* @param
* @retval
*************************************************************/
void fn_USART_Init(void){
fn_USART_IO_Config();
fn_USART_Config();
}
//须在 MDK 的工程选项把“Use MicroLIB”勾选上,MicoroLIB 是缺省 C 库的备选库,它对
//标准 C 库进行了高度优化使代码更少,占用更少资源。
/**************************************************************
* @brief
* int fputc (int ch , FILE *f)
* @param 重新定向C库函数Printf 到USART1
* @retval
*************************************************************/
int fputc (int ch , FILE *f){
/*发送一个字节数据到USART*/
USART_SendData(_DEBUG_USARTx , (uint8_t)ch);
/*等待发送数据寄存器为空*/
while(USART_GetFlagStatus(_DEBUG_USARTx,USART_FLAG_TXE)==RESET);
return (ch);
}
/**************************************************************
* @brief
* int fgetc(FILE *f);
* @param 重新定向C库函数Printf 到USART1
* @retval
*************************************************************/
int fgetc(FILE *f){
//等待串口1输入数据
while(USART_GetITStatus(_DEBUG_USARTx,USART_IT_RXNE)==RESET);
return (int)USART_ReceiveData(_DEBUG_USARTx);
}
/**************************************************************
* @brief
* void USART1_IRQHandler(void); 中断服务
* @param
* @retval
*************************************************************/
void _DRBUG_USART_IRQHandler(void){
uint8_t ucTemp = 0;
if(USART_GetITStatus(_DEBUG_USARTx,USART_IT_RXNE)!=RESET){
ucTemp = USART_ReceiveData(_DEBUG_USARTx);
USART_SendData(_DEBUG_USARTx ,ucTemp );
}
}
建立DMA传输的 头文件 DMA_book.h
代码如下 :
#ifndef __DMA_BOOK_H_
#define __DMA_BOOK_H_
#include "stm32f10x.h"
#define DMA_CLOCK RCC_AHBPeriph_DMA1 //DMA 时钟
/****** A ****************** ROM 到 RAM 的DMA输出 *******************************/
#define Map_DMA_CHANNEL DMA1_Channel6 // 当使用存储器到存储器模式时候,通道可以随便选,没有硬性的规定
#define Map_BUFFER_SIZE 20 // 要发送的数据大小
#define DMA_FLAG_TC DMA1_FLAG_TC6 // 传输完成标志
/* 定义 aSRC_Const_Buffer 数组作为 DMA 传输数据源
* const 关键字将 aSRC_Const_Buffer 数组变量定义为常量类型
* 表示数据存储在内部的 FLASH 中*/
extern const uint32_t aSRC_Cont_Buffer[Map_BUFFER_SIZE] ;
/* 定义 DMA 传输目标存储器存储在内部的 SRAM 中*/
extern uint32_t aDST_Buffer[Map_BUFFER_SIZE];
/*************************************************************************************/
/******** B **************** USART 到 RAM 的DMA输出 *******************************/
#define USART_DMA_CHANNEL DMA1_Channel4 //串口对应的 DMA 请求通道
#define USART_Source_ADDR (USART1_BASE+0x04) //串口数据的地址
extern uint32_t USART_BUFFER_SIZE ; // 要发送的数据大小
extern uint32_t* USART_DMA_Buffer ;
/************************************************************************************/
void _DMA_Config(DMA_Channel_TypeDef* _DMAy_Channelx , uint32_t _BUFFER_SIZE , uint32_t _DMA_OutSource_ADDR, uint32_t _DMA_InSource_ADDR , uint32_t _DMA_DIR);
void _USART_DMA_Config(DMA_Channel_TypeDef* _DMAy_Channelx , uint32_t _BUFFER_SIZE , uint32_t _DMA_OutSource_ADDR, uint32_t _DMA_InSource_ADDR , uint32_t _DMA_DIR);
uint8_t _Buffercmp(const uint32_t *pBuffer, uint32_t * pBuffer1 , uint16_t BufferLength);
void _Buffer_Show(uint32_t * pBuffer , uint16_t BufferLength);
//DMA对内存ROM数据的取出
void _DMA_ROM_TO_RAM(uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR );
//DMA对RAM到USART数据的取出
void _DMA_RAM_TO_USART(uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR );
#define _Map_DMA_Config_ _DMA_Config(Map_DMA_CHANNEL ,Map_BUFFER_SIZE ,aSRC_Cont_Buffer , aDST_Buffer , DMA_DIR_PeripheralSRC)
// ROM 到 RAM 的DMA输出 的程序初始化 DMA_DIR_PeripheralSRC:为方向外设到内存
#define _USART_DMA_Config_ _USART_DMA_Config(USART_DMA_CHANNEL ,USART_BUFFER_SIZE ,USART_Source_ADDR , USART_DMA_Buffer , DMA_DIR_PeripheralDST)
// ROM 到 RAM 的DMA输出 的程序初始化 DMA_DIR_PeripheralDST:为方向外设到内存
#define _DMA_InnerChange_ _Buffercmp(aSRC_Cont_Buffer , aDST_Buffer, Map_BUFFER_SIZE)
// ROM 到 RAM 的DMA输出 的数据验证
#define _RMA_InnerShow_ _Buffer_Show(aDST_Buffer, Map_BUFFER_SIZE)
#endif
建立DMA传输的C文件 DMA_book.c
代码如下 :
#include "DMA_book.h"
#include "USART_book.h"
#include "Systick_book.h"
const uint32_t aSRC_Cont_Buffer [Map_BUFFER_SIZE]={
'W','E','L','L',
'C','O','M','E',
' ','S','T','M',
'3','2',' ','S',
'T','U','D','Y',
};
uint32_t aDST_Buffer[Map_BUFFER_SIZE] ;
uint32_t* USART_DMA_Buffer ;
uint32_t USART_BUFFER_SIZE ;
void _DMA_Config(DMA_Channel_TypeDef* _DMAy_Channelx , uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR , uint32_t _DMA_DIR){
DMA_InitTypeDef DMA_InitStructure ;
//开启DMA时钟
RCC_AHBPeriphClockCmd(DMA_CLOCK,ENABLE);
//源数据缓存地址(外设地址)
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)_DMA_Source_ADDR ;
//转换缓存地址地址(内存地址)
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)_DMA_AIM_ADDR;
//方向:外设到存储器(这里的外设是内部的FLASH)DMA_DIR_PeripheralSRC:为方向外设到内存 DMA_DIR_PeripheralDST:为方向外设到内存
DMA_InitStructure.DMA_DIR = _DMA_DIR ;
//传输大小
DMA_InitStructure.DMA_BufferSize = _BUFFER_SIZE;
//外设(内部的FLASH)地址递增
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
//内存地址递增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//外设数据单位
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
//内存数据单位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
//DMA模式,一次或者循环模式
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
//DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
//优先级:高
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
//使能内存到内存的传输
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
//配置DMA通道
DMA_Init(_DMAy_Channelx , &DMA_InitStructure);
//使能DMA
DMA_Cmd(_DMAy_Channelx , ENABLE);
}
void _USART_DMA_Config(DMA_Channel_TypeDef* _DMAy_Channelx , uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR , uint32_t _DMA_DIR){
DMA_InitTypeDef DMA_InitStructure ;
//开启DMA时钟
RCC_AHBPeriphClockCmd(DMA_CLOCK,ENABLE);
//源数据缓存地址(外设地址)
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)_DMA_Source_ADDR ;
//转换缓存地址地址(内存地址)
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)_DMA_AIM_ADDR;
//方向:外设到存储器(这里的外设是内部的FLASH)DMA_DIR_PeripheralSRC:为方向外设到内存 DMA_DIR_PeripheralDST:为方向外设到内存
DMA_InitStructure.DMA_DIR = _DMA_DIR ;
//传输大小
DMA_InitStructure.DMA_BufferSize = _BUFFER_SIZE;
//外设(内部的FLASH)地址递增
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//内存地址递增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//外设数据单位
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//DMA_PeripheralDataSize_Byte; //注意这里需要根据数据类型经行修改
//内存数据单位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//DMA_MemoryDataSize_Byte; //注意这里需要根据数据类型经行修改
//DMA模式,一次或者循环模式
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
//DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
//优先级:高
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
//使能内存到内存的传输
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
//配置DMA通道
DMA_Init(_DMAy_Channelx , &DMA_InitStructure);
//使能DMA
DMA_Cmd(_DMAy_Channelx , ENABLE);
}
///源数据与目标地址数据对比
uint8_t _Buffercmp(const uint32_t *pBuffer, uint32_t * pBuffer1 , uint16_t BufferLength){
/*数据长度递减*/
while(BufferLength--){
// Usart_SendHalf_32_Word(_DEBUG_USARTx,*pBuffer);
// Usart_SendHalf_32_Word(_DEBUG_USARTx,*pBuffer1);
/*判断两个数据源是否相等*/
if(*pBuffer != *pBuffer1){
/* 对应数据源不相等马上退出函数,并返回 0 */
return 0;
}
/* 递增两个数据源的地址指针 */
pBuffer++;
pBuffer1++;
}
/* 完成判断并且对应数据相对 */
return 1;
}
//对RAM数据进行展示
void _Buffer_Show(uint32_t * pBuffer , uint16_t BufferLength){
/*数据长度递减*/
while(BufferLength--){
Usart_SendHalf_32_Word(_DEBUG_USARTx,*pBuffer++);
}
}
//DMA对内存ROM数据的取出
void _DMA_ROM_TO_RAM(uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR ){
//----------------------------------------------------------------
printf("开始 ROM内存到RAM内存的DMA操作 \n");
//内存到内存DMA初始化
_DMA_Config(Map_DMA_CHANNEL ,_BUFFER_SIZE ,_DMA_Source_ADDR , _DMA_AIM_ADDR , DMA_DIR_PeripheralSRC);
while(DMA_GetFlagStatus(DMA_FLAG_TC) == RESET); //判断DMA传输结果是否正确
if(_DMA_InnerChange_== 0 ){
printf("ROM内存到DMA操作异常 \n");
}else{
printf("ROM内存到DMA操作正常 \n");
}
_RMA_InnerShow_;
}
//DMA对RAM到USART数据的取出
void _DMA_RAM_TO_USART(uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR ){
// 开始 USART内存到RAM内存的DMA操作
printf("\n开始 ROM到USART的传送初始化\n");
USART_BUFFER_SIZE = _BUFFER_SIZE;
USART_DMA_Buffer = _DMA_AIM_ADDR;
//内存到USART DMA初始化
_USART_DMA_Config(USART_DMA_CHANNEL ,USART_BUFFER_SIZE ,_DMA_Source_ADDR , USART_DMA_Buffer , DMA_DIR_PeripheralDST);
USART_DMACmd(_DEBUG_USARTx , USART_DMAReq_Tx , ENABLE); //串口DMA使能
/*USART_DMACmd 函数用于控制 USART 的 DMA 请求的启动和关闭。它接收三个参
数,第一个参数用于设置串口外设,可以是 USART1/2/3 和 UART4/5 这 5 个参数可选,第
二个参数设置串口的具体 DMA 请求,有串口发送请求 USART_DMAReq_Tx 和接收请求
USART_DMAReq_Rx 可选,第三个参数用于设置启动请求 ENABLE 或者关闭请求*/
fn_Systick_Delay(250,_Systick_ms); //DMA 传输进程中进行LED输出闪烁
while(USART_GetFlagStatus(_DEBUG_USARTx,USART_FLAG_TXE)==RESET);
printf("\rROM内存到USART外设的DMA操作完毕\n");//这个函数需要Delay 一段时间才可以用
}
//----------------------------------------------------------------
建立EXIT的 头文件 Exit_book.h
代码如下 :
#ifndef __EXIT_BOOK_H_
#define __EXIT_BOOK_H_
#include "stm32f10x.h"
#define _KEY_EXTI_IN_GPIO_Port GPIOA
#define _KEY_EXTI_IN_GPIO_Pin GPIO_Pin_0
#define _EXTI_IN_GPIO_PortSource GPIO_PortSourceGPIOA
#define _EXTI_IN_GPIO_PinSource GPIO_PinSource0
#define _EXTI_IN_EXTI_Line EXTI_Line0
#define _EXTI_IN_EXTI_Trigger EXTI_Trigger_Rising
#define _EXTI_IN_GPIO_Clock RCC_APB2Periph_AFIO
#define _EXTI_IN_EXTI_Mode EXTI_Mode_Interrupt
#define _EXTI_IN_EXTI_LineCmd ENABLE
#define _NVIC_IN_EXTI_IRQChannel EXTI0_IRQn
#define _NVIC_IN_EXTI_IRQChannelCmd ENABLE
#define _KEY2_EXTI_IN_GPIO_Port GPIOC
#define _KEY2_EXTI_IN_GPIO_Pin GPIO_Pin_13
#define _EXTI_IN2_GPIO_PortSource GPIO_PortSourceGPIOC
#define _EXTI_IN2_GPIO_PinSource GPIO_PinSource13
#define _EXTI_IN2_EXTI_Line EXTI_Line13
#define _EXTI_IN2_EXTI_Trigger EXTI_Trigger_Falling
#define _EXTI_IN2_GPIO_Clock RCC_APB2Periph_AFIO
#define _EXTI_IN2_EXTI_Mode EXTI_Mode_Interrupt
#define _EXTI_IN2_EXTI_LineCmd ENABLE
#define _NVIC_IN2_EXTI_IRQChannel EXTI15_10_IRQn
#define _NVIC_IN2_EXTI_IRQChannelCmd ENABLE
void fn_EXTI_GPIO_Config(void);
void fn_NVIC_Config(void);
void EXTI0_IRQHandler(void);
#endif
建立EXIT的C文件 Exit_book.c
代码如下 :
#include "Exit_book.h"
#include "Led_book.h"
/**************************************************************
* @brief
* void fn_EXTI_GPIO_Config(void)
* @param
*
* #define _KEY_EXTI_IN_GPIO_Port GPIOA
* #define _KEY_EXTI_IN_GPIO_Pin GPIO_Pin_0
* #define _EXTI_IN_GPIO_PortSource GPIO_PortSourceGPIOA
* #define _EXTI_IN_GPIO_PinSource GPIO_PinSource0
* #define _EXTI_IN_EXTI_Line EXTI_Line0
* #define _EXTI_IN_EXTI_Trigger EXTI_Trigger_Rising
* #define _EXTI_IN_GPIO_Clock RCC_APB2Periph_AFIO
* #define _EXTI_IN_EXTI_Mode EXTI_Mode_Interrupt
* #define _EXTI_IN_EXTI_LineCmd ENABLE
*
* #define _KEY2_EXTI_IN_GPIO_Port GPIOC
* #define _KEY2_EXTI_IN_GPIO_Pin GPIO_Pin_13
* #define _EXTI_IN2_GPIO_PortSource GPIO_PortSourceGPIOC
* #define _EXTI_IN2_GPIO_PinSource GPIO_PinSource13
* #define _EXTI_IN2_EXTI_Line EXTI_Line13
* #define _EXTI_IN2_EXTI_Trigger EXTI_Trigger_Falling
* #define _EXTI_IN2_GPIO_Clock RCC_APB2Periph_AFIO
* #define _EXTI_IN2_EXTI_Mode EXTI_Mode_Interrupt
* #define _EXTI_IN2_EXTI_LineCmd ENABLE
* @retval
*************************************************************/
void fn_EXTI_GPIO_Config(void){
EXTI_InitTypeDef EXIT_InitStruck;
RCC_APB2PeriphClockCmd(_EXTI_IN_GPIO_Clock , ENABLE);
//注意:我们除了开 GPIO 的端口时钟外,我们还打开了 AFIO 的时钟
GPIO_EXTILineConfig(_EXTI_IN_GPIO_PortSource | _EXTI_IN2_GPIO_PortSource , _EXTI_IN_GPIO_PinSource | _EXTI_IN2_GPIO_PinSource);
/* 选择 EXTI 的信号源 */
// GPIO_EXTILineConfig 函数用来指定中断/事件线的输入源,它实际是设定外部中断配
// 置寄存器的 AFIO_EXTICRx 值,该函数接收两个参数,第一个参数指定 GPIO 端口源,第
// 二个参数为选择对应 GPIO 引脚源编号。
EXIT_InitStruck.EXTI_Line = _EXTI_IN_EXTI_Line ; /* 选择 EXTI 的信号源 */
EXIT_InitStruck.EXTI_Mode = _EXTI_IN_EXTI_Mode; /* EXTI 为中断模式 */
EXIT_InitStruck.EXTI_Trigger = _EXTI_IN_EXTI_Trigger ; /* 上升沿中断 */
EXIT_InitStruck.EXTI_LineCmd = _EXTI_IN_EXTI_LineCmd; /* 使能中断 */
EXTI_Init(&EXIT_InitStruck);
// EXTI初始化配置的变量
// fn_NVIC_Config();
// 调用 NVIC_Configuration函数完成对按键 1、按键 2 优先级配置并使能中断通道
EXIT_InitStruck.EXTI_Line = _EXTI_IN2_EXTI_Line; /* 选择 EXTI 的信号源 */
EXIT_InitStruck.EXTI_Mode = _EXTI_IN2_EXTI_Mode; /* EXTI 为中断模式 */
EXIT_InitStruck.EXTI_Trigger = _EXTI_IN2_EXTI_Trigger; /* 下降沿中断 */
EXIT_InitStruck.EXTI_LineCmd = _EXTI_IN_EXTI_LineCmd;/* 使能中断 */
EXTI_Init(&EXIT_InitStruck);
fn_NVIC_Config();
}
/**************************************************************
* @brief
* void fn_NVIC_Config(void)
* @param
* #define _NVIC_IN_EXTI_IRQChannel EXTI0_IRQn
* #define _NVIC_IN_EXTI_IRQChannelCmd ENABLE
* #define _NVIC_IN2_EXTI_IRQChannel EXTI15_10_IRQn
* #define _NVIC_IN2_EXTI_IRQChannelCmd ENABLE
* @retval
*************************************************************/
void fn_NVIC_Config(void){
NVIC_InitTypeDef NVIC_InitStruct;
/* 配置 NVIC 为优先级组 1 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* 配置中断源: */
NVIC_InitStruct.NVIC_IRQChannel = _NVIC_IN_EXTI_IRQChannel; //EXTI0_IRQn;
/* 配置抢占优先级:1 */
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
/* 配置子优先级:1 */
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
/* 使能中断通道 */
NVIC_InitStruct.NVIC_IRQChannelCmd = _NVIC_IN_EXTI_IRQChannelCmd; //ENABLE
NVIC_Init(&NVIC_InitStruct);
/* 配置中断源: */
NVIC_InitStruct.NVIC_IRQChannel = _NVIC_IN2_EXTI_IRQChannel; //EXTI0_IRQn;
NVIC_Init(&NVIC_InitStruct);
}
/**************************************************************
* @brief
* void fn_NVIC_Config(void)
* @param
* #define _KEY_EXTI_IN_GPIO_Port GPIOA
* #define _KEY_EXTI_IN_GPIO_Pin GPIO_Pin_0
* @retval
*************************************************************/
void EXTI0_IRQHandler(void){
// EXTI_GetITStatus 函数用来获取 EXTI 的中断标志位状态,如果 EXTI 线有中断发生函
//数返回“SET”否则返回“RESET”。实际上,EXTI_GetITStatus 函数是通过读取
//EXTI_PR寄存器值来判断 EXTI线状态的。
if(EXTI_GetITStatus(_EXTI_IN_EXTI_Line)!= RESET){
if(GPIO_ReadInputDataBit(_KEY_EXTI_IN_GPIO_Port, _KEY_EXTI_IN_GPIO_Pin)==1){
__LED_Change__;
}
}
EXTI_ClearITPendingBit(_EXTI_IN_EXTI_Line); // 重要的清除中断标志位
}
void EXTI15_10_IRQHandler(void){
if(EXTI_GetITStatus(_EXTI_IN2_EXTI_Line)!= RESET){
if(GPIO_ReadInputDataBit(_KEY2_EXTI_IN_GPIO_Port, _KEY2_EXTI_IN_GPIO_Pin)==0){
__LED_Change__;
}
}
EXTI_ClearITPendingBit(_EXTI_IN2_EXTI_Line); // 重要的清除中断标志位
}
建立Key传输的 头文件 Key_book.h
代码如下 :
#ifndef __KEY_BOOK_H_
#define __KEY_BOOK_H_
#include "stm32f10x.h"
#include "Led_book.h"
#define KEY_IN_GPIO_Port GPIOA
#define KEY_IN_GPIO_Clock RCC_APB2Periph_GPIOA
#define KEY_IN_GPIO_Pin GPIO_Pin_0
#define KEY_IN_GPIO_Pin_Bit 0
#define Key_IN_GPIO_Modle GPIO_Mode_IN_FLOATING //浮空输入
#define KEY2_IN_GPIO_Port GPIOC
#define KEY2_IN_GPIO_Clock RCC_APB2Periph_GPIOC
#define KEY2_IN_GPIO_Pin GPIO_Pin_13
#define KEY2_IN_GPIO_Pin_Bit 13
#define Key2_IN_GPIO_Modle GPIO_Mode_IN_FLOATING //浮空输入
typedef union {
struct{
unsigned char BIT0:1;unsigned char BIT1:1;unsigned char BIT2:1;unsigned char BIT3:1;
unsigned char BIT4:1;unsigned char BIT5:1;unsigned char BIT6:1;unsigned char BIT7:1;
//unsigned char BIT8:1;unsigned char BIT9:1;unsigned char BIT10:1;unsigned char BIT11:1;
//unsigned char BIT12:1;unsigned char BIT13:1;unsigned char BIT14:1;unsigned char BIT15:1;
}DATA_BIT;
uint8_t DATA_BYTE;
}Per_key_type;
extern volatile Per_key_type key_flag;
#define bkey_10ms key_flag.DATA_BIT.BIT0
#define bkey_judge key_flag.DATA_BIT.BIT1
#define bkey_judge_long key_flag.DATA_BIT.BIT2
#define bkey_Effect key_flag.DATA_BIT.BIT3
#define bkey_LongEffect key_flag.DATA_BIT.BIT4
#define bkey_Effect_Lose key_flag.DATA_BIT.BIT5
#define bkey_Effect_LLose key_flag.DATA_BIT.BIT6
void fn_Key_GPIO_Config( GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock , uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef );
void fn_Key_Init(void);
void fn_key_judge(void);
void fn_key_Effect(void);
void fn_key_Check(void);
#endif
建立Key的C文件 Key_book.c
代码如下 :
#include "Key_book.h"
volatile Per_key_type key_flag;
/**************************************************************
* @brief
* void fn_Key_GPIO_Config( GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock ,
* uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef );
* @param
* #define KEY_IN_GPIO_Port GPIOA
* #define KEY_IN_GPIO_Clock RCC_APB2Periph_GPIOA
* #define KEY_IN_GPIO_Pin GPIO_Pin_0
* #define KEY_IN_GPIO_Pin_Bit 0
* #define Key_IN_GPIO_Modle GPIO_Mode_IN_FLOATING //浮空输入
*
* #define KEY2_IN_GPIO_Port GPIOC
* #define KEY2_IN_GPIO_Clock RCC_APB2Periph_GPIOC
* #define KEY2_IN_GPIO_Pin GPIO_Pin_13
* #define KEY2_IN_GPIO_Pin_Bit 13
* #define Key2_IN_GPIO_Modle GPIO_Mode_IN_FLOATING //浮空输入
* @retval
*************************************************************/
void fn_Key_GPIO_Config( GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock , uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef ){
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = _GPIOMode_TypeDef;
GPIO_InitStruct.GPIO_Pin = _GPIO_Pin_x;
RCC_APB2PeriphClockCmd(_GPIO_Clock,ENABLE);
GPIO_Init(_GPIO_x , &GPIO_InitStruct);
}
/**************************************************************
* @brief
* void fn_Key_Init(void);
* @param
* @retval
*************************************************************/
void fn_Key_Init(void){
fn_Key_GPIO_Config(KEY_IN_GPIO_Port,KEY_IN_GPIO_Clock,KEY_IN_GPIO_Pin,Key_IN_GPIO_Modle);
fn_Key_GPIO_Config(KEY2_IN_GPIO_Port,KEY2_IN_GPIO_Clock,KEY2_IN_GPIO_Pin,Key2_IN_GPIO_Modle);
}
/************************************************************
* @brief
* void fn_key_judge(void);
* @param
* @retval
**************************************************************/
#define _LONG_key 30
static uint16_t count_key ;
void fn_key_judge(void){
if(!bkey_10ms){return;}
bkey_10ms = 0;
if(GPIO_ReadInputDataBit(KEY_IN_GPIO_Port,KEY_IN_GPIO_Pin)){
if(count_key++<3){return;}
if(!bkey_judge){
bkey_judge = 1;
bkey_Effect = 1;
}else{
if(count_key>_LONG_key){
bkey_judge_long = 1;
bkey_LongEffect = 1;
}
}
}
else{
count_key = 0;
if(bkey_judge){
bkey_judge = 0;
if(bkey_judge_long){
bkey_judge_long = 0;
bkey_Effect_LLose = 1;
}else{
bkey_judge_long = 0;
bkey_Effect_Lose = 1;
}
}else{
bkey_judge = 0;
}
}
}
/************************************************************
* @brief
* void fn_key_Effect(void);
* @param
* @retval
*************************************************************/
void fn_key_Effect(void){
if(bkey_Effect){
bkey_Effect = 0;
fn_LED_Corporate(LED_OUT_GPIO_Port,LED_OUT_GPIO_Pin,LED_Corporate_Toggle);
}
}
/**************************************************************
* @brief
* void fn_key_Check(void);
* @param