浏览代码

1、添加说明;

樊春春 2 年之前
父节点
当前提交
2efbf60ed1
共有 52 个文件被更改,包括 6386 次插入163 次删除
  1. 150 0
      Doc/03.开发环境说明.txt
  2. 206 0
      Doc/04.STM32F407IGT6引脚定义(原始定义).txt
  3. 156 0
      Doc/05.GPIO分配表(按GPIO次序排列).txt
  4. 489 0
      Doc/06.GPIO分配表(按功能排列).txt
  5. 1 1
      Project/GCC/STM32F417IG_FLASH.ld
  6. 647 0
      User/Bsp/ad7606/ad7606.c
  7. 72 0
      User/Bsp/ad7606/ad7606.h
  8. 1 1
      User/Bsp/adc/adc.h
  9. 252 0
      User/Bsp/am2303/am2303.c
  10. 13 0
      User/Bsp/am2303/am2303.h
  11. 12 1
      User/Bsp/armfly_bsp.c
  12. 4 0
      User/Bsp/armfly_bsp.h
  13. 0 1
      User/Bsp/dm9k/dm9k.c
  14. 1 1
      User/Bsp/dm9k/dm9k.h
  15. 0 1
      User/Bsp/eth/stm32f4x7_phy.c
  16. 1 1
      User/Bsp/eth/stm32f4x7_phy.h
  17. 0 1
      User/Bsp/ext_sram/ext_sram.c
  18. 1 1
      User/Bsp/ext_sram/ext_sram.h
  19. 29 4
      User/Bsp/interface/interface.c
  20. 92 6
      User/Bsp/interface/interface.h
  21. 464 0
      User/Bsp/key/key.c
  22. 161 0
      User/Bsp/key/key.h
  23. 202 0
      User/Bsp/lcd/font.h
  24. 2988 0
      User/Bsp/lcd/lcd.c
  25. 270 0
      User/Bsp/lcd/lcd.h
  26. 1 1
      User/Bsp/nor_flash/nor_flash.h
  27. 6 6
      User/Bsp/rtc/rtc.c
  28. 6 6
      User/Bsp/rtc/rtc.h
  29. 10 10
      User/Bsp/spi/spi.c
  30. 1 1
      User/Bsp/spi/spi.h
  31. 1 1
      User/Bsp/timer/timer.c
  32. 1 1
      User/Bsp/timer/timer.h
  33. 7 7
      User/Bsp/uart/uart1.c
  34. 0 1
      User/Bsp/uart/uart1.h
  35. 14 14
      User/Bsp/uart/uart3.c
  36. 1 2
      User/Bsp/uart/uart3.h
  37. 1 1
      User/app/iec104/iec101.c
  38. 1 1
      User/app/iec104/iec101.h
  39. 1 0
      User/app/iec104/iec104.c
  40. 13 2
      User/app/iec104/iec10x.c
  41. 22 28
      User/app/iec104/iec10x.h
  42. 1 4
      User/app/iec104/iec10x_conf.h
  43. 1 1
      User/app/iec104/iec10x_prio_queue.c
  44. 2 1
      User/app/iec104/iec10x_type.h
  45. 4 4
      User/app/led/led.c
  46. 4 4
      User/app/memory/memory_manager.c
  47. 1 0
      User/app/memory/memory_manager.h
  48. 4 10
      User/app/net/net.c
  49. 64 37
      User/main.c
  50. 2 0
      User/main.h
  51. 1 1
      User/system_stm32f4xx.c
  52. 4 0
      platformio.ini

+ 150 - 0
Doc/03.开发环境说明.txt

@@ -0,0 +1,150 @@
+/*
+*********************************************************************************************************
+*
+*	                          【安富莱】STM32-V5 开发板-开发环境说明
+*
+*	最后更新日期:2013-06-20
+*
+*	推荐将编辑器的缩进参数和TAB设置为4 来阅读本文件
+*
+*********************************************************************************************************
+*/
+
+【1】CPU内部资源
+	CPU型号        : STM32F407IGT6 / LQFP-176 / ARM 32-bit Cortex-M4 (带FPU 硬件浮点单元)
+	主频           : 168 MHz, 210 DMIPS/1.25 DMIPS/MHz
+	内部Flash容量  : 1MB
+	内部SRAM容量   : 192K + 4K SRAM
+	GPIO 数量      : 140个具备外部中断能力,136个快速IO(60M), 138个5V兼容(意思是GPIO可输入5V电压)
+	定时器         : 17个 - 其中12个16-bit和2个32-bit定时器可以到150 MHz
+	UART           : 6个 4个USART1,2个UART【10.5 Mbit/s】
+	SPI            : 3个 【37.5 Mbits/s】
+	I2C            : 3个
+	ADC            : 3个独立的12位ADC,最多24路复用输入
+	DAC            : 2路独立12位DAC
+	CAN            : 2个 CAN 2.0B
+	SDIO           : 1个
+	CAMERA         : 8 - 14bit 并行摄像头接口,最大速度 67.2M 字节/秒
+	Ethernet       : 10/100 Ethernet MAC, 需要外部PHY芯片。
+	USB            : USB2.0全速(主、从)无需外部PHY。USB2.0高速模式需要外部PHY芯片。
+
+【2】FSMC存储器地址分配
+   	CPU内部 FLASH  【0x0800 0000 - 0x080F FFFF】,容量1M(0x100000)字节
+	CPU内部 SRAM1  【0x2000 0000 - 0x2001 FFFF】,容量128K(0x20000)字节
+	CPU内部 SRAM2  【0x1000 0000 - 0x1000 FFFF】,容量64K(0x10000)字节
+
+	外部 NOR Flash 【0x6400 0000 - 0x64FF FFFF】,容量16M(0x1000000)字节
+
+	外部 SRAM      【0x6800 0000 - 0x681F FFFF】,容量2M(0x200000)字节
+	DM9000A芯片地址【0x6840 0000, 0x6848 0000】, 仅占用2个端口地址
+
+	TFT LCD地址    【0x6C00 0000, 0x6C08 0000】, 仅占用2个端口地址
+	外扩AD7606地址 【0x6C40 0000】, 仅占用1个端口地址,只读
+	OLED地址       【0x6C20 0000, 0x6C28 0000】, 仅占用2个端口地址
+
+	外部 NAND Flash【0x7000 0000】, 容量128M(0xC800000)字节
+
+
+【3】I2C总线外设地址分配
+  序号	器件                      地址
+	1	串行EEPROM  AT24C128 	  0xA0
+	2	音频CODEC芯片WM8978	      0x34
+	3	AM/FM收音机Si4730         0x22
+	4	摄像头OV7670              0x42
+	5	磁力计HMC5883L            0x3C
+	6	陀螺仪 MPU-6050           0xD0
+	7	光照 BH1750FVI            0x46
+	8	大气压 BMP085             0xEE
+
+【4】开发工具
+    【仿真器】
+	虽然STM32F4XX支持串口和USB口ISP下载程序,但是不支持在线调试,因此强烈推荐购买一个仿真器,提高程序开发效率。
+	- ST-LINK V2 仿真器: ST公司开发的仿真器,可以下载程序和调试跟踪程序。支持STM8和STM32。
+	- J-LINK V8 仿真器 : Segger公司开发的仿真器,可以下载程序和调试跟踪程序。支持所有ARM系列,包括STM8。
+
+    【USB转串口线】
+	- 现在大多数PC机都没有硬件串口了。但是对于单片机串口还是很有用的。安富莱的很多例程都需要通过串口打印调试信息。
+
+    【开发软件】
+	- 编译环境 IAR EWARMv6 和 KEIL 的 MDK uV4。请按需选择,如都不熟悉,推荐使用KEIL MDK (uV4)。
+	- SecureCRT : 一个优秀的功能强大的超级终端工具,主要用来显示开发板从串口打印出来的信息
+	- UltraEdit : 一个优秀的源代码编辑工具
+	- SourceInsight : 一个优秀的源代码浏览工具
+
+【5】编译和调试方法
+  说明:安富莱的例程均提供 KEIL 和 IAR两种工程,每个工程中设置了2个Target,一个是在Flash巡行的,一个是在CpuRAM运行的。请按需要选择。
+  如果需要不修改Flash中的程序调试新的例程,可以选择在CPU RAM运行。
+
+	【Keil MDK】V4.54
+		- 执行菜单 Project -> Open project                 打开 \Project\MDK-ARM(uV4)\project.uvproj (这是工程文件)
+ 		- 执行菜单 Project -> Rebuild all target files     重新编译所有的文件:
+ 		- 执行菜单 Debug->Start/Stop Debug Session (Ctrl+F5)  启动调试:
+
+ 		【备注1】选择在CPU RAM运行时,不能使用Load按钮下载程序,请直接Start Debug即可。因为Load按钮是专门用于下载到Flash的。
+ 		【备注2】对于Keil MDK,为了避免中文字符串告警,需要在C/C++编译选项中增加 --diag_suppress=870 参数。
+
+	【IAR EWARM】V6.30
+		- 执行菜单 File -> Open Workspace          (打开工程文件: Project\EWARMv6\Project.www)
+ 		- 执行菜单 Project -> Rebuild All          (重新编译整个工程)
+ 		- 执行菜单 Project -> Download and Debug(Ctrl+D)   (装载程序并启动调试)
+
+【6】例程文件夹说明
+├─Libraries :  存放第3方提供的库或其源代码,这些代码一般是成熟的并经过验证的代码。
+│  ├─CMSIS :  CMSIS是ARM公司与多家不同的芯片和软件供应商一起紧密合作定义的,提供了内核与外设、实时操作系统和中间设备之间的通用接口。
+│  ├─STM32F4xx_StdPeriph_Driver : STM32F4XX系列MCU的标准固件库源代码
+│  ├─STM32_USB_Device_Library : STM32F105/7xx, STM32F2xx and STM32F4xx USB Device Library
+│  └─STM32_USB_OTG_Driver :  STM32F105/7xx, STM32F2xx and STM32F4xx USB OTG Driver
+│
+├─User      :  这里存放用户自己编写的源代码
+│  ├─bsp_stm32f4xx :  板级支持包(Board Surport Packet),也就是硬件底层驱动程序. 该层介于固件库和应用程序之间。
+│  └─fonts  :  存放点阵字库常量数组
+│
+└─project   :  这里存放各类开发工具的工程文件,编译过程中的临时文件和最终HEX文件都放在此文件夹
+    ├─MDK-ARM(uV4) : KEIL公司MDK uVision 4工程文件夹
+    └─EWARMv6 : IAR公司的EWARM 工程文件夹
+
+【7】工程中源代码分组说明
+└─Flash               : Target名称,Flash 或 CpuRAM
+   ├─USER             : 存放 main.c 以及用户用用程序
+   ├─BSP              : 板级支持包(Board Support Packet),存放硬件底层驱动文件
+   ├─CMSIS            : 仅存放CMSISI接口文件 system_stm32f4xx.c
+   ├─StdPeriph_Drivers: 存放STM328S系列MCU的固件库源代码
+   ├─MDK-ARM          : 启动文件(汇编源程序),对于IAR是 EWARMv6
+   └─Doc              : 存放一些文档,仅限txt文件
+
+【8】公共源代码文件说明
+	- main.c          : 用户主程序,存放main()函数的文件
+	- stm32f4xx_it.c  : 集中存放中断服务程序 【除了几个异常中断外,我们建议其他的ISR放到各自的模块中】
+	- stm32f10x_assert.c : 存放断言函数   (一般无需更改)
+	- bsp.c           : 底层硬件驱动程序的主程序(包含硬件初始化入口函数)
+
+【9】C编译器中的预定义宏 (在工程设置中更改)
+	USE_STDPERIPH_DRIVER  - 增加这个符号表示使用ST公司的标准外设库
+	VECT_TAB_SRAM         - 增加这个符号表示中断向量表定位在CPU内部RAM (针对在CPU内部RAM运行的工程才需要添加)
+
+【10】BSP源码中的硬件型号宏 (直接修改 bsp.h 文件进行更改)
+	在 bsp_stm32f4xx 文件夹下,很多文件用到了开发板型号的宏:
+	STM32_X4  - 表示安富莱STM32-X4核心板(功能简单的核心板,便于外接设备)
+	STM32_V5  - 表示安富莱STM32-V5开发板(功能强大的开发板)
+
+	因为两种硬件的GPIO定义不同,为了共用一套BSP源码,因此添加这2个宏进行区别。
+	用户可以在 bsp.h 文件中define这2个宏来选择硬件类别。
+	
+【11】调整堆和栈的容量
+	对于KEIL MDK, 设置堆和栈的大小是通过修改启动文件start_stm32f4xx.s 文件实现的,比如:
+		Stack_Size      EQU     0x00004000
+		Heap_Size       EQU     0x00000400
+
+	对于IAR EWARM, 直接在工程设置中进行修改即可
+		- 菜单 project -> options -> 选择Linker -> Config页 -> 点Edit按钮 -> 切换到CSTACK/HEAP
+		比如:
+			CSTACK = 0x800
+			HEAP   = 0x400
+		
+
+【12】输出目标文件
+	在 project 下面,有编译好的 hex 文件,用户可以用仿真器直接下载 output(flash).hex 到CPU内部flash	
+	output(flash).hex - 采用KEIL MDK编译好的文件,定位在CPU 内部Flash	
+	output(ram).hex   - 采用KEIL MDK编译好的文件,定位在CPU 内部RAM(该文件需要引导程序装载到
+	                    CPU内部RAM运行,不能独立运行。
+

+ 206 - 0
Doc/04.STM32F407IGT6引脚定义(原始定义).txt

@@ -0,0 +1,206 @@
+/*
+*********************************************************************************************************
+*
+*	                    【安富莱】STM32-V5开发板CPU的原始引脚定义(供查阅复用功能用)
+*	型号: STM32F407IGT6
+*	封装: LQFP-176
+*
+*********************************************************************************************************
+*/
+
+编号    功能
+  1 PE2/TRACECLK/FSMC_A23
+  2 PE3/TRACED0/FSMC_A19
+  3 PE4/TRACED1/FSMC_A20/DCMI_D4
+  4 PE5/TRACED2/FSMC_A21/TIM9_CH1/DCMI_D6
+  5 PE6/TRACED3/FSMC_A22/TIM9_CH2/DCMI_D7
+  6 VBAT
+  7 PI8[RTC_AF2]
+  8 PC13[RTC_AF1]
+  9 PC14-OSC32_IN(PC14)[OSC32_IN]
+ 10 PC15-OSC32_OUT(PC15)[OSC32_OUT]
+ 11 PI9/CAN1_RX
+ 12 PI10/ETH_MII_RX_ER
+ 13 PI11/OTG_HS_ULPI_DIR
+ 14 VSS
+ 15 VDD
+ 16 PF0/FSMC_A0/I2C2_SDA
+ 17 PF1/FSMC_A1/I2C2_SCL
+ 18 PF2/FSMC_A2/I2C2_SMBA
+ 19 PF3/FSMC_A3[ADC3_IN9]
+ 20 PF4/FSMC_A4[ADC3_IN14]
+ 21 PF5/FSMC_A5[ADC3_IN15]
+ 22 VSS
+ 23 VDD
+ 24 PF6/TIM10_CH1/FSMC_NIORD[ADC3_IN4]
+ 25 PF7/TIM11_CH1/FSMC_NREG[ADC3_IN5]
+ 26 PF8/TIM13_CH1/FSMC_NIOWR[ADC3_IN6]
+ 27 PF9/TIM14_CH1/FSMC_CD[ADC3_IN7]
+ 28 PF10/FSMC_INTR[ADC3_IN8]
+ 29 PH0-OSC_IN(PH0)[OSC_IN]
+ 30 PH1-OSC_OUT(PH1)[OSC_OUT]
+ 31 NRST
+ 32 PC0/OTG_HS_ULPI_STP[ADC123_IN10]
+ 33 PC1/ETH_MDC[ADC123_IN11]
+ 34 PC2/SPI2_MISO/OTG_HS_ULPI_DIR/ETH_MII_TXD2/I2S2ext_SD[ADC123_IN12]
+ 35 PC3/SPI2_MOSI/I2S2_SD/OTG_HS_ULPI_NXT/ETH_MII_TX_CLK[ADC123_IN13]
+ 36 VDD
+ 37 VSSA
+ 38 VREF+
+ 39 VDDA
+ 40 PA0-WKUP(PA0)/USART2_CTS/UART4_TX/ETH_MII_CRS/TIM2_CH1_ETR/TIM5_CH1/TIM8_ETR[ADC123_IN0/WKUP]
+ 41 PA1/USART2_RTS/UART4_RX/ETH_RMII_REF_CLK/ETH_MII_RX_CLK/TIM5_CH2/TIMM2_CH2[ADC123_IN1]
+ 42 PA2/USART2_TX/TIM5_CH3/TIM9_CH1/TIM2_CH3/ETH_MDIO[ADC123_IN2]
+ 43 PH2/ETH_MII_CRS
+ 44 PH3/ETH_MII_COL
+
+ 45 PH4/I2C2_SCL/OTG_HS_ULPI_NXT
+ 46 PH5/I2C2_SDA
+ 47 PA3/USART2_RX/TIM5_CH4/TIM9_CH2/TIM2_CH4/OTG_HS_ULPI_D0/ETH_MII_COL[ADC123_IN3]
+ 48 VSS
+ 49 VDD
+ 50 PA4/SPI1_NSS/SPI3_NSS/USART2_CK/DCMI_HSYNC/OTG_HS_SOF/I2S3_WS[ADC12_IN4 /DAC1_OUT]
+ 51 PA5/SPI1_SCK/OTG_HS_ULPI_CK/TIM2_CH1_ETR/TIM8_CHIN[ADC12_IN5/DAC2_OUT]
+ 52 PA6/SPI1_MISO/TIM8_BKIN/TIM13_CH1/DCMI_PIXCLK/TIM3_CH1/TIM1_BKIN[ADC12_IN6]
+ 53 PA7/SPI1_MOSI/TIM8_CH1N/TIM14_CH1/TIM3_CH2/ETH_MII_RX_DV/TIM1_CH1N/RMII_CRS_DV[ADC12_IN7]
+ 54 PC4/ETH_RMII_RX_D0/ETH_MII_RX_D0[ADC12_IN14]
+ 55 PC5/ETH_RMII_RX_D1/ETH_MII_RX_D1[ADC12_IN15]
+ 56 PB0/TIM3_CH3/TIM8_CH2N/OTG_HS_ULPI_D1/ETH_MII_RXD2/TIM1_CH2N[ADC12_IN8]
+ 57 PB1/TIM3_CH4/TIM8_CH3N/OTG_HS_ULPI_D2/ETH_MII_RXD3/OTG_HS_INTN/TIM1_CH3N[ADC12_IN9]
+ 58 PB2-BOOT1/(PB2)
+ 59 PF11/DCMI_12
+ 60 PF12/FSMC_A6
+ 61 VSS
+ 62 VDD
+ 63 PF13/FSMC_A7
+ 64 PF14/FSMC_A8
+ 65 PF15/FSMC_A9
+ 66 PG0/FSMC_A10
+ 67 PG1/FSMC_A11
+ 68 PE7/FSMC_D4/TIM1_ETR
+ 69 PE8/FSMC_D5/TIM1_CH1N
+ 70 PE9/FSMC_D6/TIM1_CH1
+ 71 VSS
+ 72 VDD
+ 73 PE10/FSMC_D7/TIM1_CH2N
+ 74 PE11/FSMC_D8/TIM1_CH2
+ 75 PE12/FSMC_D9/TIM1_CH3N
+ 76 PE13/FSMC_D10/TIM1_CH3
+ 77 PE14/FSMC_D11/TIM1_CH4
+ 78 PE15/FSMC_D12/TIM1_BKIN
+ 79 PB10/SPI2_SCK/I2S2_CK/I2C2_SCL/USART3_TX/OTG_HS_ULPI_D3/ETH_MII_RX_ER/TIM2_CH3
+ 80 PB11/I2C2_SDA/USART3_RX/OTG_HS_ULPI_D4/ETH_RMII_TX_EN/ETH_MII_TX_EN/TIM2_CH4
+ 81 VCAP_1
+ 82 VDD
+ 83 PH6/I2C2_SMBA/TIM12_CH1/ETH_MII_RXD2
+ 84 PH7/I2C3_SCL/ETH_MII_RXD3
+ 85 PH8/I2C3_SDA/DCMI_HSYNC
+ 86 PH9/I2C3_SMBA/TIM12_CH2/DCMI_D0
+ 87 PH10/TIM5_CH1/DCMI_D1
+ 88 PH11/TIM5_CH2/DCMI_D2
+
+ 89 PH12/TIM5_CH3/DCMI_D3
+ 90 VSS
+ 91 VDD
+ 92 PB12/SPI2_NSS/I2S2_WS/I2C2_SMBA/USART3_CK/TIM1_BKIN/CAN2_RX/OTG_HS_ULPI_D5/ETH_RMII_TXD0/ETH_MII_TXD0/OTG_HS_ID
+ 93 PB13/SPI2_SCK/I2S2_CK/USART3_CTS/TIM1_CH1N/CAN2_TX/OTG_HS_ULPI_D6/ETH_RMII_TXD1/ETH_MII_TXD1[OTG_HS_VBUS]
+ 94 PB14/SPI2_MISO/TIM1_CH2N/TIM12_CH1/OTG_HS_DM/USART3_RTS/TIM8_CH2N/I2S2ext_SD
+ 95 PB15/SPI2_MOSI/I2S2_SD/TIM1_CH3N/TIM8_CH3N/TIM12_CH2/OTG_HS_DP
+ 96 PD8/FSMC_D13/USART3_TX
+ 97 PD9/FSMC_D14/USART3_RX
+ 98 PD10/FSMC_D15/USART3_CK
+ 99 PD11/FSMC_CLE/FSMC_A16/USART3_CTS
+100 PD12/FSMC_ALE/FSMC_A17/TIM4_CH1/USART3_RTS
+101 PD13/FSMC_A18/TIM4_CH2
+102 VSS
+103 VDD
+104 PD14/FSMC_D0/TIM4_CH3
+105 PD15/FSMC_D1/TIM4_CH4
+106 PG2/FSMC_A12
+107 PG3/FSMC_A13
+108 PG4/FSMC_A14
+109 PG5/FSMC_A15
+110 PG6/FSMC_INT2
+111 PG7/FSMC_INT3/USART6_CK
+112 PG8/USART6_RTS/ETH_PPS_OUT
+113 VSS
+114 VDD
+115 PC6/I2S2_MCK/TIM8_CH1/SDIO_D6/USART6_TX/DCMI_D0/TIM3_CH1
+116 PC7/I2S3_MCK/TIM8_CH2/SDIO_D7/USART6_RX/DCMI_D1/TIM3_CH2
+117 PC8/TIM8_CH3/SDIO_D0/TIM3_CH3/USART6_CK/DCMI_D2
+118 PC9/I2S_CKIN/MCO2/TIM8_CH4/SDIO_D1/I2C3_SDA/DCMI_D3/TIM3_CH4
+119 PA8/MCO1/USART1_CK/TIM1_CH1/I2C3_SCL/OTG_FS_SOF
+120 PA9/USART1_TX/TIM1_CH2/I2C3_SMBA/DCMI_D0[OTG_FS_VBUS]
+121 PA10/USART1_RX/TIM1_CH3/OTG_FS_ID/DCMI_D1
+122 PA11/USART1_CTS/CAN1_RX/TIM1_CH4/OTG_FS_DM
+123 PA12/USART1_RTS/CAN1_TX/TIM1_ETR/OTG_FS_DP
+124 PA13(JTMS-SWDIO)/JTMS-SWDIO
+125 VCAP_2
+126 VSS
+127 VDD
+128 PH13/TIM8_CH1N/CAN1_TX
+129 PH14/TIM8_CH2N/DCMI_D4
+130 PH15/TIM8_CH3N/DCMI_D11
+131 PI0/TIM5_CH4/SPI2_NSS/I2S2_WS/DCMI_D13
+132 PI1/SPI2_SCK/I2S2_CK/DCMI_D8
+
+133 PI2/TIM8_CH4/SPI2_MISO/DCMI_D9/I2S2ext_SD
+134 PI3/TIM8_ETR/SPI2_MOSI/I2S2_SD/DCMI_D10
+135 VSS
+136 VDD
+137 PA14(JTCK-SWCLK)/JTCK-SWCLK
+138 PA15(JTDI)/JTDI/SPI3_NSS/I2S3_WS/TIM2_CH1_ETR/SPI1_NSS
+139 PC10/SPI3_SCK/I2S3_CK/UART4_TX/SDIO_D2/DCMI_D8/USART3_TX
+140 PC11/UART4_RX/SPI3_MISO/SDIO_D3/DCMI_D4/USART3_RX/I2S3ext_SD
+141 PC12/UART5_TX/SDIO_CK/DCMI_D9/SPI3_MOSI/I2S3_SD/USART3_CK
+142 PD0/FSMC_D2/CAN1_RX
+143 PD1/FSMC_D3/CAN1_TX
+144 PD2/TIM3_ETR/UART5_RX/SDIO_CMD/DCMI_D11
+145 PD3/FSMC_CLK/USART2_CTS
+146 PD4/FSMC_NOE/USART2_RTS
+147 PD5/FSMC_NWE/USART2_TX
+148 VSS
+149 VDD
+150 PD6/FSMC_NWAIT/USART2_RX
+151 PD7/USART2_CK/FSMC_NE1/FSMC_NCE2
+152 PG9/USART6_RX/FSMC_NE2/FSMC_NCE3
+153 PG10/FSMC_NCE4_1/FSMC_NE3
+154 PG11/FSMC_NCE4_2/ETH_MII_TX_EN/ETH_RMII_TX_EN
+155 PG12/FSMC_NE4/USART6_RTS
+156 PG13/FSMC_A24/USART6_CTS/ETH_MII_TXD0/ETH_RMII_TXD0
+157 PG14/FSMC_A25/USART6_TX/ETH_MII_TXD1/ETH_RMII_TXD1
+158 VSS
+159 VDD
+160 PG15/USART6_CTS/DCMI_D13
+161 PB3(JTDO/TRACESWO)/JTDO/TRACESWO/SPI3_SCK/I2S3_CK/TIM2_CH2/SPI1_SCK
+162 PB4(NJTRST)/NJTRST/SPI3_MISO/TIM3_CH1/SPI1_MISO/I2S3ext_SD
+163 PB5/I2C1_SMBA/CAN2_RX/OTG_HS_ULPI_D7/ETH_PPS_OUT/TIM3_CH2/SPI1_MOSI/SPI3_MOSI/DCMI_D10/I2S3_SD
+164 PB6/I2C1_SCL/TIM4_CH1/CAN2_TX/DCMI_D5/USART1_TX
+165 PB7/I2C1_SDA/FSMC_NL/DCMI_VSYNC/USART1_RX/TIM4_CH2
+166 BOOT0
+167 PB8/TIM4_CH3/SDIO_D4/TIM10_CH1/DCMI_D6/ETH_MII_TXD3/I2C1_SCL/CAN1_RX
+168 PB9/SPI2_NSS/I2S2_WS/TIM4_CH4/TIM11_CH1/SDIO_D5/DCMI_D7/I2C1_SDA/CAN1_TX
+169 PE0/TIM4_ETR/FSMC_NBL0/DCMI_D2
+170 PE1/FSMC_NBL1/DCMI_D3
+171 PDR_ON
+172 VDD
+173 PI4/TIM8_BKIN/DCMI_D5
+174 PI5/TIM8_CH1/DCMI_VSYNC
+175 PI6/TIM8_CH2/DCMI_D6
+176 PI7/TIM8_CH3/DCMI_D7
+
+=== 结束 ====
+
+【其中OTG_HS_ULPI 高速USB2.0接口,需要占用12个GPIO】
+ 13 PI11/OTG_HS_ULPI_DIR   ----有2个----
+ 32 PC0/OTG_HS_ULPI_STP[ADC123_IN10]
+ 34 PC2/SPI2_MISO/OTG_HS_ULPI_DIR/ETH_MII_TXD2/I2S2ext_SD[ADC123_IN12] ----有2个----
+ 45 PH4/I2C2_SCL/OTG_HS_ULPI_NXT
+ 47 PA3/USART2_RX/TIM5_CH4/TIM9_CH2/TIM2_CH4/OTG_HS_ULPI_D0/ETH_MII_COL[ADC123_IN3]
+ 51 PA5/SPI1_SCK/OTG_HS_ULPI_CK/TIM2_CH1_ETR/TIM8_CHIN[ADC12_IN5/DAC2_OUT]
+ 56 PB0/TIM3_CH3/TIM8_CH2N/OTG_HS_ULPI_D1/ETH_MII_RXD2/TIM1_CH2N[ADC12_IN8]
+ 57 PB1/TIM3_CH4/TIM8_CH3N/OTG_HS_ULPI_D2/ETH_MII_RXD3/OTG_HS_INTN/TIM1_CH3N[ADC12_IN9]
+ 79 PB10/SPI2_SCK/I2S2_CK/I2C2_SCL/USART3_TX/OTG_HS_ULPI_D3/ETH_MII_RX_ER/TIM2_CH3
+ 80 PB11/I2C2_SDA/USART3_RX/OTG_HS_ULPI_D4/ETH_RMII_TX_EN/ETH_MII_TX_EN/TIM2_CH4
+ 92 PB12/SPI2_NSS/I2S2_WS/I2C2_SMBA/USART3_CK/TIM1_BKIN/CAN2_RX/OTG_HS_ULPI_D5/ETH_RMII_TXD0/ETH_MII_TXD0/OTG_HS_ID
+ 93 PB13/SPI2_SCK/I2S2_CK/USART3_CTS/TIM1_CH1N/CAN2_TX/OTG_HS_ULPI_D6/ETH_RMII_TXD1/ETH_MII_TXD1[OTG_HS_VBUS]

+ 156 - 0
Doc/05.GPIO分配表(按GPIO次序排列).txt

@@ -0,0 +1,156 @@
+/*
+*********************************************************************************************************
+*
+*	                    【安富莱】STM32-V5开发板引脚分配表(按GPIO次序排列)
+*
+*********************************************************************************************************
+*/
+【按GPIO次序排列, 一共140个GPIO】
+    PA0-WKUP/ADC123_IN0                         ADC输入
+    PA1/ETH_RMII_RX_CLK                         以太网RMII接口RX_CLK
+    PA2/USART2/ETH_MDIO                         以太网RMII接口MDIO/串口2发送
+    PA3/USART2_RX                               串口2接收,可外接GPS模块
+    PA4/NRF905_TX_EN/NRF24L01_CE/DAC1_OUT       nRF905发射使能/nRF24L01使能/DAC输出
+    PA5/NRF905_TRX_CE/VS1053_XDCS/DAC2_OUT      nRF905发送和接收模式选择/DAC输出
+    PA6/DCMI_PIXCLK                             摄像头像素时钟
+    PA7/RMII_CRS_DV                             以太网RMII接口CSR_DV
+    PA8/IR_TX                                   红外遥控发射管
+    PA9/USART1_TX                               串口1发送,和PC机串口通信
+    PA10/USART1_RX                              串口1接收,和PC机串口通信
+    PA11/OTG_FS_DM                              全速(12Mbps)USB接口数据线D-, 接PC机
+    PA12/OTG_FS_DP                              全速(12Mbps)USB接口数据线D+
+    PA13/JTMS-SWDIO                             SWD调试接口数据线
+    PA14/JTCK-SWCLK                             SWD调试接口时钟线
+    PA15/DM9000_INT                             以太网芯片DM9000AEP中断
+
+    PB0/IR_RX                                   红外遥控接收管
+    PB1/1-WIRE                                  1-Wire总线, 可外接DS18B20、DTH11等传感器
+    PB2-BOOT1/RS485_TXEN                        RS485发送使能
+    PB3/SPI3_SCK                                SPI接口时钟线
+    PB4/SPI3_MISO                               SPI接口MISO (主机输入,从机输出)
+    PB5/SPI3_MOSI                               SPI接口MOSI (主机输出,从机输入)
+    PB6/CAN2_TX/NRF905_PWR_UP                   CAN2接口发送/nRF905上电控制
+    PB7/GPRS_RESET                              GPRS模块复位
+    PB8/NRF905_DR/VS1053_DREQ                   nRF905数据就绪/VS1053数据请求
+    PB9/NRF905_AM                               nRF905地址匹配
+    PB10/USART3_TX                              串口3发送,接RS485收发芯片
+    PB11/USART3_RX                              串口3接收,接RS485收发芯片
+    PB12/I2S2_WS/CAN2_RX                        I2S数字音频接口声道选择信号/CAN2接收
+    PB13/I2S2_CK/CAN2_TX/ETH_RMII_TXD1          I2S数字音频接口时钟信号/CAN2发送/以太网RMII接口TXD1
+    PB14/OTG_HS_DM                              (全速)USB接口数据线D-, 接U盘
+    PB15/OTG_HS_DP                              (全速)USB接口数据线D+
+
+    PC0/ADC123_IN10                             ADC输入
+    PC1/ETH_MDC                                 以太网MDC
+    PC2/NRF905_CSN/VS1053_XCS                   nRF905片选/VS1053片选
+    PC3/I2S2_SD                                 I2S数字音频接口数据线(放音用)
+    PC4/ETH_RMII_RX_D0                          以太网RMII接口接收数据线D0
+    PC5/ETH_RMII_RX_D1                          以太网RMII接口接收数据线D1
+    PC6/I2S2_MCK                                I2S数字音频接口时钟源
+    PC7/USART6_RX                               串口6接收,接GPRS模块
+    PC8/SDIO_D0                                 SDIO数据线D0
+    PC9/SDIO_D1                                 SDIO数据线D1
+    PC10/SDIO_D2                                SDIO数据线D2
+    PC11/SDIO_D3                                SDIO数据线D3
+    PC12/SDIO_CK                                SDIO时钟
+    PC13/KEY2                                   独立按键KEY2
+    PC14-OSC32_IN                               32768Hz时钟输入
+    PC15-OSC32_OUT                              32768Hz时钟输出
+
+    PD0/FSMC_D2                                 FSMC数据总线D2
+    PD1/FSMC_D3                                 FSMC数据总线D3
+    PD2/SDIO_CMD                                SDIO命令
+    PD3/LCD_BUSY                                RA8875忙
+    PD4/FSMC_NOE                                FSMC控制总线读信号(N表示低有效,OE = Output Enable)
+    PD5/FSMC_NWE                                FSMC控制总线写信号(N表示低有效,WE = Write Enable)
+    PD6/FSMC_NWAIT                              FSMC总线等待信号
+    PD7/FSMC_NCE2                               FSMC片选NCE2
+    PD8/FSMC_D13                                FSMC数据总线D13
+    PD9/FSMC_D14                                FSMC数据总线D14
+    PD10/FSMC_D15                               FSMC数据总线D15
+    PD11/FSMC_CLE/FSMC_A16                      FSMC地址总线A16,和NAND Flash CLE复用
+    PD12/FSMC_ALE/FSMC_A17                      FSMC地址总线A17,和NAND Flash ALE复用
+    PD13/FSMC_A18                               FSMC地址总线A18
+    PD14/FSMC_D0                                FSMC数据总线D0
+    PD15/FSMC_D1                                FSMC数据总线D1
+
+    PE0/FSMC_NBL0                               FSMC字节选择信号,用于SRAM
+    PE1/FSMC_NBL1                               FSMC字节选择信号,用于SRAM
+    PE2/FSMC_A23/SD_DETECT                      SD卡插入检测
+    PE3/FSMC_A19                                FSMC地址总线A19
+    PE4/FSMC_A20                                FSMC地址总线A20
+    PE5/FSMC_A21                                FSMC地址总线A21
+    PE6/FSMC_A22                                FSMC地址总线A22
+    PE7/FSMC_D4                                 FSMC数据总线D4
+    PE8/FSMC_D5                                 FSMC数据总线D5
+    PE9/FSMC_D6                                 FSMC数据总线D6
+    PE10/FSMC_D7                                FSMC数据总线D7
+    PE11/FSMC_D8                                FSMC数据总线D8
+    PE12/FSMC_D9                                FSMC数据总线D9
+    PE13/FSMC_D10                               FSMC数据总线D10
+    PE14/FSMC_D11                               FSMC数据总线D11
+    PE15/FSMC_D12                               FSMC数据总线D12
+
+    PF0/FSMC_A0                                 FSMC地址总线A0
+    PF1/FSMC_A1                                 FSMC地址总线A1
+    PF2/FSMC_A2                                 FSMC地址总线A2
+    PF3/FSMC_A3                                 FSMC地址总线A3
+    PF4/FSMC_A4                                 FSMC地址总线A4
+    PF5/FSMC_A5                                 FSMC地址总线A5
+    PF6/LCD_PWM                                 LCD背光控制(对于RA8875屏无用,背光由RA8875控制)
+    PF7/NRF24L01_CSN                            nRF24L01片选
+    PF8/SF_CS                                   串行Flash片选
+    PF9/ADC3_IN7                                ADC输入
+    PF10/ADC3_IN8                               ADC输入
+    PF11/JOY_L/PS2_DATA                         摇杆左键/PS2数据线
+    PF12/FSMC_A6                                FSMC地址总线A6
+    PF13/FSMC_A7                                FSMC地址总线A7
+    PF14/FSMC_A8                                FSMC地址总线A8
+    PF15/FSMC_A9                                FSMC地址总线A9
+
+    PG0/FSMC_A10                                FSMC地址总线A10
+    PG1/FSMC_A11                                FSMC地址总线A11
+    PG2/FSMC_A12                                FSMC地址总线A12
+    PG3/FSMC_A13                                FSMC地址总线A13
+    PG4/FSMC_A14                                FSMC地址总线A14
+    PG5/FSMC_A15                                FSMC地址总线A15
+    PG6/FSMC_INT2                               FSMC中断,可用于判忙
+    PG7/JOY_R/PS2_CLK                           摇杆右键/PS2时钟
+    PG8/USART6_RTS                              串口6请求发送数据
+    PG9/FSMC_NE2                                FSMC总线片选NE2
+    PG10/FSMC_NE3                               FSMC总线片选NE3
+    PG11/ETH_RMII_TX_EN                         以太网RMII接口TX_EN
+    PG12/FSMC_NE4                               FSMC总线片选NE4
+    PG13/FSMC_A24/ETH_RMII_TXD0                 以太网RMII接口数据发送D0
+    PG14/USART6_TX/ETH_RMII_TXD1                以太网RMII接口数据发送D1
+    PG15/USART6_CTS                             串口6清除发送请求CTS
+
+    PH0-OSC_IN                                  主时钟输入(外接25M晶振)
+    PH1-OSC_OUT                                 主时钟输出(外接25M晶振)
+    PH2/JOY_U                                   摇杆上键
+    PH3/JOY_D                                   摇杆下键
+    PH4/I2C2_SCL                                I2C总线时钟线
+    PH5/I2C2_SDA                                I2C总线数据线
+    PH6/MII_INT                                 以太网MII_INT
+    PH7/NRF24L01_IRQ                            nRF24L01中断
+    PH8/DCMI_HSYNC                              摄像头水平同步信号
+    PH9/DCMI_D0/AD7606_OS0                      摄像头数据线D0
+    PH10/DCMI_D1/AD7606_OS1                     摄像头数据线D1
+    PH11/DCMI_D2/AD7606_OS2                     摄像头数据线D2
+    PH12/DCMI_D3/AD7606_CONVST                  摄像头数据线D3
+    PH13/CAN1_TX                                CAN1发送
+    PH14/DCMI_D4/AD7606_RAGE                    摄像头数据线D4
+    PH15/JOY_OK                                 摇杆OK键
+
+    PI0/GPRS_TERM_ON                            GPRS模块开机信号
+    PI1/MPU-6050_INT                            陀螺仪中断
+    PI2/I2S2ext_SD                              I2S数字音频接口数据线(录音用)
+    PI3/TP_INT                                  触摸笔中断(RA8875中断)
+    PI4/DCMI_D5/AD7606_RESET                    摄像头数据线D5
+    PI5/DCMI_VSYNC                              摄像头垂直同步
+    PI6/DCMI_D6/AD7606_BUSY                     摄像头数据线D6
+    PI7/DCMI_D7/NRF905_CD                       摄像头数据线D7
+    PI8/KEY1                                    按键KEY1
+    PI9/CAN1_RX                                 CAN1接收
+    PI10/TP_NCS                                 触摸芯片的片选(RA8875屏无需SPI接口触摸芯片)
+    PI11/KEY3                                   按键KEY3

+ 489 - 0
Doc/06.GPIO分配表(按功能排列).txt

@@ -0,0 +1,489 @@
+/*
+*********************************************************************************************************
+*
+*	                    【安富莱】STM32-V5开发板引脚分配表(按功能排列)
+*
+*********************************************************************************************************
+*/
+
+【SWD调试接口】
+	PA13/JTMS-SWDIO
+	PA14/JTCK-SWCLK
+
+【25M 主晶振】
+	PH0-OSC_IN
+	PH1-OSC_OUT
+
+【32768Hz RTC晶振】
+	PC14-OSC32_IN
+	PC15-OSC32_OUT
+
+【5向摇杆和3个独立按键】
+	PF11/JOY_L/PS2_DATA
+	PG7/JOY_R/PS2_CLK
+	PH2/JOY_U
+	PH3/JOY_D
+	PH15/JOY_OK
+	PI8/KEY1
+	PC13/KEY2
+	PI11/KEY3
+
+【RS232串口 USART1】
+	PA9/USART1_TX
+	PA10/USART1_RX
+
+【GPS 接收串口 USART2】
+	PA2/USART2_TX/ETH_MDIO	    --- 这个引脚缺省用于以太网;无需向GPS模块发送命令(只有需要对GPS模块刷新固件时才会用到)
+	PA3/USART2_RX	;接GPS模块输出
+	
+【RS485 串口USART3】
+	PB10/USART3_TX
+	PB11/USART3_RX
+	PB2-BOOT1/RS485_TXEN		--- 控制RS485发送和接收模式切换
+
+【GPRS模块 串口6 硬件流控】
+	PG14/USART6_TX/ETH_RMII_TXD1
+	PC7/USART6_RX
+	PG8/USART6_RTS
+	PG15/USART6_CTS
+	PI0/GPRS_TERM_ON		--- GPS模块开关控制
+	PB7/GPRS_RESET		    --- GPS模块硬件复位控制
+
+【CAN1 CAN2】
+	PB12/I2S2_WS/CAN2_RX      
+	PB13/I2S2_CK/CAN2_TX/ETH_RMII_TXD1	--- I2S数字音频接口时钟信号/CAN2发送/以太网RMII接口TXD1
+
+	PI9/CAN1_RX
+	PH13/CAN1_TX
+
+
+【I2C设备】 ()内是总线地址
+	--- 24C128 (0xA0)
+	--- WM8978 (0x34)
+	--- AM/FM收音机Si4730 (0x22)
+	--- 摄像头(0x42)
+	--- 磁力计HMC5883LL(0x3C)
+	--- 陀螺仪 (0xD0)
+	--- 光照 BH1750FVI (0x46)
+	--- 大气压 BMP085  (0xEE)
+
+	PH4/I2C2_SCL			--- I2C时钟线
+	PH5/I2C2_SDA			--- I2C数据线
+
+	PI1/MPU-6050_INT		--- 陀螺仪中断
+
+【SPI设备】
+	【串行Flash】
+		PB3/SPI3_SCK
+		PB4/SPI3_MISO
+		PB5/SPI3_MOSI
+
+		PF8/SF_CS			--- 串行Flash片选
+
+	【NRF24L01】
+		PB3/SPI3_SCK
+		PB4/SPI3_MISO
+		PB5/SPI3_MOSI
+
+		PF7/NRF24L01_CSN	--- nRF24L01片选
+		PH7/NRF24L01_IRQ	--- nRF24L01中断
+
+		PA4/NRF905_TX_EN/NRF24L01_CE/DAC1_OUT --- nRF24L01 CE使能
+
+	【NRF905 / VS1053B】
+		PB3/SPI3_SCK
+		PB4/SPI3_MISO
+		PB5/SPI3_MOSI
+
+		PB6/CAN2_TX/NRF905_PWR_UP
+
+		PB8/NRF905_DR/VS1053_DREQ
+		PB9/NRF905_AM
+
+		PA4/NRF905_TX_EN/NRF24L01_CE/DAC1_OUT
+		PA5/NRF905_TRX_CE/VS1053_XDCS/DAC2_OUT
+
+		PC2/NRF905_CSN/VS1053_XCS	--- NRF905片选
+		PI7/DCMI_D7/NRF905_CD
+
+	【TFT接口中的SPI】
+		PB3/SPI3_SCK
+		PB4/SPI3_MISO
+		PB5/SPI3_MOSI
+
+		PI10/TP_NCS			--- 触摸芯片的片选		(RA8875屏无需SPI接口触摸芯片)
+
+【LED指示灯,和4个SPI设备的片选复用,可以监视SPI设备的访问情况】
+	LD1 : PI10/TP_NCS
+	LD2 : PF7/NRF24L01_CSN
+	LD3 : PF8/SF_CS
+	LD4 : PC2/NRF905_CSN/VS1053_XCS
+
+【I2S音频设备:WM8978 音频编解码CODEC】
+	--- I2S总线传输音频数据留
+	PB12/I2S2_WS/CAN2_RX						I2S数字音频接口声道选择信号/CAN2接收
+	PB13/I2S2_CK/CAN2_TX/ETH_RMII_TXD1			I2S数字音频接口时钟信号/CAN2发送/以太网RMII接口TXD1
+	PI2/I2S2ext_SD								I2S数字音频接口数据线(录音用)
+	PC3/I2S2_SD									I2S数字音频接口数据线(放音用)
+	PC6/I2S2_MCK								I2S数字音频接口时钟源
+
+	--- I2C总线控制WM8978
+	PH4/I2C2_SCL
+	PH5/I2C2_SDA
+
+【DCIM设备: 摄像头  和 AD7606 模块不能同时使用】
+	PA6/DCMI_PIXCLK
+	PH8/DCMI_HSYNC
+	PH9/DCMI_D0/AD7606_OS0
+	PH10/DCMI_D1/AD7606_OS1
+	PH11/DCMI_D2/AD7606_OS2
+	PH12/DCMI_D3/AD7606_CONVST
+	PH14/DCMI_D4/AD7606_RAGE
+	PI4/DCMI_D5/AD7606_RESET
+	PI5/DCMI_VSYNC
+	PI6/DCMI_D6/AD7606_BUSY
+	PI7/DCMI_D7/NRF905_CD
+
+	--- I2C总线控制摄像头
+	PH4/I2C2_SCL
+	PH5/I2C2_SDA
+
+【SDIO设备: Micro SD卡或WIFI模块】
+	PC8/SDIO_D0
+	PC9/SDIO_D1
+	PC10/SDIO_D2
+	PC11/SDIO_D3
+	PC12/SDIO_CK
+	PD2/SDIO_CMD
+
+	PE2/FSMC_A23/SD_DETECT	--- Micro SD卡插入信号或WIFI模块电源控制
+
+【以太网 RMII】
+	PA1/ETH_RMII_RX_CLK
+	PA2/ETH_MDIO
+	PA7/RMII_CRS_DV
+	PC1/ETH_MDC
+	PC4/ETH_RMII_RX_D0
+	PC5/ETH_RMII_RX_D1
+	PG11/ETH_RMII_TX_EN
+	PG13/FSMC_A24/ETH_RMII_TXD0
+	PG14/ETH_RMII_TXD1
+	PH6/MII_INT
+
+【OTG_FS】
+	PA11/OTG_FS_DM
+	PA12/OTG_FS_DP
+	//	PA9/OTG_FS_VBUS
+	//	PA10/OTG_FS_ID
+
+【ADC】 --- ADC 和 DAC 口线均引到 CN26双排母(2*6P), 用于外扩示波器模块。
+	PA0-WKUP/ADC123_IN0
+	PC0/ADC123_IN10
+	PF9/ADC3_IN7
+	PF10/ADC3_IN8
+
+【DAC】 --- ADC 和 DAC 口线均引到 CN26双排母(2*6P), 用于外扩示波器模块。
+	PA4/NRF905_TX_EN/NRF24L01_CE/DAC1_OUT
+	PA5/NRF905_TRX_CE/VS1053_XDCS/DAC2_OUT
+
+【红外遥控发射】
+	PA8/IR_TX
+
+【红外遥控接收】
+	PB0/IR_RX
+
+【1-WIRE 单总线 DS18B20 / DHT11】
+	PB1/1-WIRE
+
+【FSMC总线汇总】
+	PD0/FSMC_D2
+	PD1/FSMC_D3
+	PD4/FSMC_NOE		--- 读控制信号,OE = Output Enable , N 表示低有效
+	PD5/FSMC_NWE		--- 写控制信号,WE = Output Enable , N 表示低有效
+
+	PD7/FSMC_NCE2		--- NAND Flash 片选
+	PD8/FSMC_D13
+	PD9/FSMC_D14
+	PD10/FSMC_D15
+	PD11/FSMC_CLE/FSMC_A16
+	PD12/FSMC_ALE/FSMC_A17
+	PD13/FSMC_A18
+	PD14/FSMC_D0
+	PD15/FSMC_D1
+
+	PE0/FSMC_NBL0		--- SRAM字节选通
+	PE1/FSMC_NBL1		--- SRAM字节选通
+	PE3/FSMC_A19
+	PE4/FSMC_A20		--- 和主片选一起译码
+	PE5/FSMC_A21		--- 和主片选一起译码
+	PE6/FSMC_A22
+	PE7/FSMC_D4
+	PE8/FSMC_D5
+	PE9/FSMC_D6
+	PE10/FSMC_D7
+	PE11/FSMC_D8
+	PE12/FSMC_D9
+	PE13/FSMC_D10
+	PE14/FSMC_D11
+	PE15/FSMC_D12
+
+	PF0/FSMC_A0
+	PF1/FSMC_A1
+	PF2/FSMC_A2
+	PF3/FSMC_A3
+	PF4/FSMC_A4
+	PF5/FSMC_A5
+	PF12/FSMC_A6
+	PF13/FSMC_A7
+	PF14/FSMC_A8
+	PF15/FSMC_A9
+
+	PG0/FSMC_A10
+	PG1/FSMC_A11
+	PG2/FSMC_A12
+	PG3/FSMC_A13
+	PG4/FSMC_A14
+	PG5/FSMC_A15
+
+	PG9/FSMC_NE2		--- NOR 片选信号
+	PG10/FSMC_NE3		--- 主片选(DM9000AEP 和 SRAM)
+	PG12/FSMC_NE4		--- 主片选(TFT, OLED 和 AD7606)
+
+	PD6/FSMC_NWAIT		--- NOR 忙信号,GPIO查询模式
+	PG6/FSMC_INT2		--- NAND 忙信号,GPIO查询模式
+
+【FSMC设备: SRAM】
+	PD0/FSMC_D2
+	PD1/FSMC_D3
+	PD4/FSMC_NOE		--- 读控制信号,OE = Output Enable , N 表示低有效
+	PD5/FSMC_NWE		--- 写控制信号,WE = Output Enable , N 表示低有效
+
+	PD8/FSMC_D13
+	PD9/FSMC_D14
+	PD10/FSMC_D15
+	PD11/FSMC_CLE/FSMC_A16
+	PD12/FSMC_ALE/FSMC_A17
+	PD13/FSMC_A18
+	PD14/FSMC_D0
+	PD15/FSMC_D1
+
+	PE0/FSMC_NBL0		--- SRAM字节选通
+	PE1/FSMC_NBL1		--- SRAM字节选通
+	PE3/FSMC_A19
+	PE4/FSMC_A20		--- 和主片选一起译码
+	PE5/FSMC_A21		--- 和主片选一起译码
+	PE7/FSMC_D4
+	PE8/FSMC_D5
+	PE9/FSMC_D6
+	PE10/FSMC_D7
+	PE11/FSMC_D8
+	PE12/FSMC_D9
+	PE13/FSMC_D10
+	PE14/FSMC_D11
+	PE15/FSMC_D12
+
+	PF0/FSMC_A0
+	PF1/FSMC_A1
+	PF2/FSMC_A2
+	PF3/FSMC_A3
+	PF4/FSMC_A4
+	PF5/FSMC_A5
+	PF12/FSMC_A6
+	PF13/FSMC_A7
+	PF14/FSMC_A8
+	PF15/FSMC_A9
+
+	PG0/FSMC_A10
+	PG1/FSMC_A11
+	PG2/FSMC_A12
+	PG3/FSMC_A13
+	PG4/FSMC_A14
+	PG5/FSMC_A15
+
+	PG10/FSMC_NE3		--- 主片选(DM9000AEP 和 SRAM)
+
+【FSMC设备:NOR Flash】
+	PD0/FSMC_D2
+	PD1/FSMC_D3
+	PD4/FSMC_NOE		--- 读控制信号,OE = Output Enable , N 表示低有效
+	PD5/FSMC_NWE		--- 写控制信号,WE = Output Enable , N 表示低有效
+
+	PD8/FSMC_D13
+	PD9/FSMC_D14
+	PD10/FSMC_D15
+	PD11/FSMC_CLE/FSMC_A16
+	PD12/FSMC_ALE/FSMC_A17
+	PD13/FSMC_A18
+	PD14/FSMC_D0
+	PD15/FSMC_D1
+
+	PE3/FSMC_A19
+	PE4/FSMC_A20
+	PE5/FSMC_A21
+	PE6/FSMC_A22
+	PE7/FSMC_D4
+	PE8/FSMC_D5
+	PE9/FSMC_D6
+	PE10/FSMC_D7
+	PE11/FSMC_D8
+	PE12/FSMC_D9
+	PE13/FSMC_D10
+	PE14/FSMC_D11
+	PE15/FSMC_D12
+
+	PF0/FSMC_A0
+	PF1/FSMC_A1
+	PF2/FSMC_A2
+	PF3/FSMC_A3
+	PF4/FSMC_A4
+	PF5/FSMC_A5
+	PF12/FSMC_A6
+	PF13/FSMC_A7
+	PF14/FSMC_A8
+	PF15/FSMC_A9
+
+	PG0/FSMC_A10
+	PG1/FSMC_A11
+	PG2/FSMC_A12
+	PG3/FSMC_A13
+	PG4/FSMC_A14
+	PG5/FSMC_A15
+
+	PG9/FSMC_NE2		--- NOR 片选信号
+
+	PD6/FSMC_NWAIT		--- NOR 忙信号,GPIO查询模式
+
+【FSMC设备:NAND Flash, 8Bit总线】
+	PD0/FSMC_D2
+	PD1/FSMC_D3
+	PD4/FSMC_NOE		--- 读控制信号,OE = Output Enable , N 表示低有效
+	PD5/FSMC_NWE		--- 写控制信号,WE = Output Enable , N 表示低有效
+
+	PD7/FSMC_NCE2		--- NAND Flash 片选
+	PD11/FSMC_CLE/FSMC_A16	--- FSMC_CLE
+	PD12/FSMC_ALE/FSMC_A17  --- FSMC_ALE
+	PD14/FSMC_D0
+	PD15/FSMC_D1
+
+	PE7/FSMC_D4
+	PE8/FSMC_D5
+	PE9/FSMC_D6
+	PE10/FSMC_D7
+
+	PG6/FSMC_INT2		--- NAND 忙信号,GPIO查询模式
+
+【FSMC总线设备:DM9000AEP以太网】
+	PD0/FSMC_D2
+	PD1/FSMC_D3
+	PD4/FSMC_NOE		--- 读控制信号,OE = Output Enable , N 表示低有效
+	PD5/FSMC_NWE		--- 写控制信号,WE = Output Enable , N 表示低有效
+
+	PD8/FSMC_D13
+	PD9/FSMC_D14
+	PD10/FSMC_D15
+	PD13/FSMC_A18		---- 地址 CMD
+	PD14/FSMC_D0
+	PD15/FSMC_D1
+
+	PE4/FSMC_A20		--- 和主片选一起译码
+	PE5/FSMC_A21		--- 和主片选一起译码
+	PE7/FSMC_D4
+	PE8/FSMC_D5
+	PE9/FSMC_D6
+	PE10/FSMC_D7
+	PE11/FSMC_D8
+	PE12/FSMC_D9
+	PE13/FSMC_D10
+	PE14/FSMC_D11
+	PE15/FSMC_D12
+
+	PG10/FSMC_NE3		--- 主片选(DM9000AEP 和 SRAM)
+
+	PA15/DM9000_INT		--- DM9000AEP 中断
+
+【FSMC设备: TFT LCD, 16Bit总线】
+	PD0/FSMC_D2
+	PD1/FSMC_D3
+	PD4/FSMC_NOE		--- 读控制信号,OE = Output Enable , N 表示低有效
+	PD5/FSMC_NWE		--- 写控制信号,WE = Output Enable , N 表示低有效
+	PD8/FSMC_D13
+	PD9/FSMC_D14
+	PD10/FSMC_D15
+	PD13/FSMC_A18		--- 地址 RS
+	PD14/FSMC_D0
+	PD15/FSMC_D1
+
+	PE4/FSMC_A20		--- 和主片选一起译码
+	PE5/FSMC_A21		--- 和主片选一起译码
+	PE7/FSMC_D4
+	PE8/FSMC_D5
+	PE9/FSMC_D6
+	PE10/FSMC_D7
+	PE11/FSMC_D8
+	PE12/FSMC_D9
+	PE13/FSMC_D10
+	PE14/FSMC_D11
+	PE15/FSMC_D12
+
+	PG12/FSMC_NE4		--- 主片选(TFT, OLED 和 AD7606)
+
+	---- 下面是 TFT LCD接口其他信号 ----
+	PD3/LCD_BUSY		--- 触摸芯片忙       (RA8875屏是RA8875芯片的忙信号)
+	PF6/LCD_PWM			--- LCD背光PWM控制  (RA8875屏无需此脚,背光由RA8875控制)
+
+	PI10/TP_NCS			--- 触摸芯片的片选		(RA8875屏无需SPI接口触摸芯片)
+	PB3/SPI3_SCK		--- 触摸芯片SPI时钟		(RA8875屏无需SPI接口触摸芯片)
+	PB4/SPI3_MISO		--- 触摸芯片SPI数据线MISO(RA8875屏无需SPI接口触摸芯片)
+	PB5/SPI3_MOSI		--- 触摸芯片SPI数据线MOSI(RA8875屏无需SPI接口触摸芯片)
+
+	PI3/TP_INT			--- 触摸芯片中断 (对于RA8875屏,是RA8875输出的中断)
+
+【FSMC设备:OLED 12864, 8Bit总线】
+	PD0/FSMC_D2
+	PD1/FSMC_D3
+	PD4/FSMC_NOE		--- 读控制信号,OE = Output Enable , N 表示低有效
+	PD5/FSMC_NWE		--- 写控制信号,WE = Output Enable , N 表示低有效
+	PD13/FSMC_A18		--- 地址 RS
+	PD14/FSMC_D0
+	PD15/FSMC_D1
+
+	PE7/FSMC_D4
+	PE8/FSMC_D5
+	PE9/FSMC_D6
+	PE10/FSMC_D7
+	PG12/FSMC_NE4		--- 主片选(TFT, OLED 和 AD7606)
+
+【FSMC设备:AD7606模块, 16Bit总线,只读】
+	PD0/FSMC_D2
+	PD1/FSMC_D3
+	PD4/FSMC_NOE		--- 读控制信号,OE = Output Enable , N 表示低有效
+
+	PD8/FSMC_D13
+	PD9/FSMC_D14
+	PD10/FSMC_D15
+	PD14/FSMC_D0
+	PD15/FSMC_D1
+
+	PE4/FSMC_A20		--- 和主片选一起译码
+	PE5/FSMC_A21		--- 和主片选一起译码
+	PE7/FSMC_D4
+	PE8/FSMC_D5
+	PE9/FSMC_D6
+	PE10/FSMC_D7
+	PE11/FSMC_D8
+	PE12/FSMC_D9
+	PE13/FSMC_D10
+	PE14/FSMC_D11
+	PE15/FSMC_D12
+
+	PG12/FSMC_NE4		--- 主片选(TFT, OLED 和 AD7606)
+
+	--- 注意: AD7606 和摄像头不同同时使用 ---
+	PH9/DCMI_D0/AD7606_OS0			---> AD7606_OS0		OS2:OS0 选择数字滤波参数
+	PH10/DCMI_D1/AD7606_OS1         ---> AD7606_OS1
+	PH11/DCMI_D2/AD7606_OS2         ---> AD7606_OS2
+	PH12/DCMI_D3/AD7606_CONVST      ---> AD7606_CONVST	启动ADC转换
+	PH14/DCMI_D4/AD7606_RAGE        ---> AD7606_RAGE	输入模拟电压量程,正负5V或正负10V
+	PI4/DCMI_D5/AD7606_RESET        ---> AD7606_RESET	复位
+	PI6/DCMI_D6/AD7606_BUSY         ---> AD7606_BUSY	忙信号
+

+ 1 - 1
Project/GCC/STM32F417IG_FLASH.ld

@@ -40,7 +40,7 @@ _Min_Stack_Size = 0x400; /* required amount of stack */
 /* Specify the memory areas */
 MEMORY
 {
-FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 1024K
+FLASH (rx)      : ORIGIN = 0x8010000, LENGTH = 1024K
 RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 128K
 CCMRAM (rw)      : ORIGIN = 0x10000000, LENGTH = 64K
 }

+ 647 - 0
User/Bsp/ad7606/ad7606.c

@@ -0,0 +1,647 @@
+/*
+*********************************************************************************************************
+*
+*	模块名称 : AD7606数据采集模块
+*	文件名称 : bsp_ad7606.c
+*	版    本 : V1.0
+*	说    明 : AD7606挂在STM32的FSMC总线上。
+*
+*			本例子使用了 TIM4 作为硬件定时器,定时启动ADC转换
+*
+*	修改记录 :
+*		版本号  日期        作者     说明
+*		V1.0    2013-02-01 armfly  正式发布
+*
+*	Copyright (C), 2013-2014, 安富莱电子 www.armfly.com
+*
+*********************************************************************************************************
+*/
+
+#include "ad7606.h"
+
+/* 设置过采样的GPIO: PH9 PH10 PH11 */
+#define OS0_1() GPIOH->BSRRL = GPIO_Pin_9
+#define OS0_0() GPIOH->BSRRH = GPIO_Pin_9
+#define OS1_1() GPIOH->BSRRL = GPIO_Pin_10
+#define OS1_0() GPIOH->BSRRH = GPIO_Pin_10
+#define OS2_1() GPIOH->BSRRL = GPIO_Pin_11
+#define OS2_0() GPIOH->BSRRH = GPIO_Pin_11
+
+/* 启动AD转换的GPIO : PH12  , PH12/TIM5_CH3/DCMI_D3 */
+#define CONVST_1() GPIOH->BSRRL = GPIO_Pin_12
+#define CONVST_0() GPIOH->BSRRH = GPIO_Pin_12
+
+/* 设置输入量程的GPIO :  */
+#define RANGE_1() GPIOH->BSRRL = GPIO_Pin_14
+#define RANGE_0() GPIOH->BSRRH = GPIO_Pin_14
+
+/* AD7606复位口线 : PI4  */
+#define RESET_1() GPIOI->BSRRL = GPIO_Pin_4
+#define RESET_0() GPIOI->BSRRH = GPIO_Pin_4
+
+/* AD7606 FSMC总线地址,只能读,无需写 */
+#define AD7606_RESULT() *(__IO uint16_t *)0x6C400000
+
+AD7606_VAR_T  g_tAD7606;  /* 定义1个全局变量,保存一些参数 */
+AD7606_FIFO_T g_tAdcFifo; /* 定义FIFO结构体变量 */
+
+static void ad7606_fsmc(void);
+
+/*
+*********************************************************************************************************
+*	函 数 名: bsp_InitAD7606
+*	功能说明: 配置连接外部SRAM的GPIO和FSMC
+*	形    参:  无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void ad7606_init(void)
+{
+    ad7606_fsmc();
+
+    AD7606_SetOS(AD_OS_NO);  /* 无过采样 */
+    AD7606_SetInputRange(0); /* 0表示输入量程为正负5V, 1表示正负10V */
+
+    AD7606_Reset();
+
+    CONVST_1(); /* 启动转换的GPIO平时设置为高 */
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: AD7606_CtrlLinesConfig
+*	功能说明: 配置LCD控制口线,FSMC管脚设置为复用功能
+*	形    参:  无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+/*
+    安富莱STM32-V5开发板接线方法:
+
+    PD0/FSMC_D2
+    PD1/FSMC_D3
+    PD4/FSMC_NOE		--- 读控制信号,OE = Output Enable , N 表示低有效
+    PD5/FSMC_NWE		--- 写控制信号,AD7606 只有读,无写信号
+    PD8/FSMC_D13
+    PD9/FSMC_D14
+    PD10/FSMC_D15
+
+    PD14/FSMC_D0
+    PD15/FSMC_D1
+
+    PE4/FSMC_A20		--- 和主片选一起译码
+    PE5/FSMC_A21		--- 和主片选一起译码
+    PE7/FSMC_D4
+    PE8/FSMC_D5
+    PE9/FSMC_D6
+    PE10/FSMC_D7
+    PE11/FSMC_D8
+    PE12/FSMC_D9
+    PE13/FSMC_D10
+    PE14/FSMC_D11
+    PE15/FSMC_D12
+
+    PG12/FSMC_NE4		--- 主片选(TFT, OLED 和 AD7606)
+
+    其他的控制IO:
+
+    PH9/DCMI_D0/AD7606_OS0			---> AD7606_OS0		OS2:OS0 选择数字滤波参数
+    PH10/DCMI_D1/AD7606_OS1         ---> AD7606_OS1
+    PH11/DCMI_D2/AD7606_OS2         ---> AD7606_OS2
+    PH12/DCMI_D3/AD7606_CONVST      ---> AD7606_CONVST	启动ADC转换 (CONVSTA 和 CONVSTB 已经并联)
+    PH14/DCMI_D4/AD7606_RAGE        ---> AD7606_RAGE	输入模拟电压量程,正负5V或正负10V
+    PI4/DCMI_D5/AD7606_RESET        ---> AD7606_RESET	复位
+    PI6/DCMI_D6/AD7606_BUSY         ---> AD7606_BUSY	忙信号	(未使用)
+
+*/
+
+/*
+*********************************************************************************************************
+*	函 数 名: ad7606_fsmc
+*	功能说明: 配置FSMC并口访问时序
+*	形    参:  无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+static void ad7606_fsmc(void)
+{
+    FSMC_NORSRAMInitTypeDef       init;
+    FSMC_NORSRAMTimingInitTypeDef timing;
+
+    /*
+        AD7606规格书要求(3.3V时):RD读信号低电平脉冲宽度最短21ns,高电平脉冲最短宽度15ns。
+
+        按照如下配置 读数均正常。为了和同BANK的LCD配置相同,选择3-0-6-1-0-0
+        3-0-5-1-0-0  : RD高持续75ns, 低电平持续50ns.  1us以内可读取8路样本数据到内存。
+        1-0-1-1-0-0  : RD高75ns,低电平执行12ns左右,下降沿差不多也12ns.  数据读取正确。
+    */
+    /* FSMC_Bank1_NORSRAM4 configuration */
+    timing.FSMC_AddressSetupTime      = 3;
+    timing.FSMC_AddressHoldTime       = 0;
+    timing.FSMC_DataSetupTime         = 6;
+    timing.FSMC_BusTurnAroundDuration = 1;
+    timing.FSMC_CLKDivision           = 0;
+    timing.FSMC_DataLatency           = 0;
+    timing.FSMC_AccessMode            = FSMC_AccessMode_A;
+
+    /*
+     LCD configured as follow:
+        - Data/Address MUX = Disable
+        - Memory Type = SRAM
+        - Data Width = 16bit
+        - Write Operation = Enable
+        - Extended Mode = Enable
+        - Asynchronous Wait = Disable
+    */
+    init.FSMC_Bank               = FSMC_Bank1_NORSRAM4;
+    init.FSMC_DataAddressMux     = FSMC_DataAddressMux_Disable;
+    init.FSMC_MemoryType         = FSMC_MemoryType_SRAM;
+    init.FSMC_MemoryDataWidth    = FSMC_MemoryDataWidth_16b;
+    init.FSMC_BurstAccessMode    = FSMC_BurstAccessMode_Disable;
+    init.FSMC_AsynchronousWait   = FSMC_AsynchronousWait_Disable;
+    init.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
+    init.FSMC_WrapMode           = FSMC_WrapMode_Disable;
+    init.FSMC_WaitSignalActive   = FSMC_WaitSignalActive_BeforeWaitState;
+    init.FSMC_WriteOperation     = FSMC_WriteOperation_Enable;
+    init.FSMC_WaitSignal         = FSMC_WaitSignal_Disable;
+    init.FSMC_ExtendedMode       = FSMC_ExtendedMode_Disable;
+    init.FSMC_WriteBurst         = FSMC_WriteBurst_Disable;
+
+    init.FSMC_ReadWriteTimingStruct = &timing;
+    init.FSMC_WriteTimingStruct     = &timing;
+
+    FSMC_NORSRAMInit(&init);
+
+    /* - BANK 1 (of NOR/SRAM Bank 1~4) is enabled */
+    FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: AD7606_SetOS
+*	功能说明: 配置AD7606数字滤波器,也就设置过采样倍率。
+*			 通过设置 AD7606_OS0、OS1、OS2口线的电平组合状态决定过采样倍率。
+*			 启动AD转换之后,AD7606内部自动实现剩余样本的采集,然后求平均值输出。
+*
+*			 过采样倍率越高,转换时间越长。
+*			 无过采样时,AD转换时间 4us;
+*				2倍过采样时 = 8.7us;
+*				4倍过采样时 = 16us
+*			 	64倍过采样时 = 286us
+*
+*	形    参: _ucOS : 过采样倍率, 0 - 6
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void AD7606_SetOS(uint8_t _ucOS)
+{
+    g_tAD7606.ucOS = _ucOS;
+    switch (_ucOS)
+    {
+    case AD_OS_X2:
+        OS2_0();
+        OS1_0();
+        OS0_1();
+        break;
+
+    case AD_OS_X4:
+        OS2_0();
+        OS1_1();
+        OS0_0();
+        break;
+
+    case AD_OS_X8:
+        OS2_0();
+        OS1_1();
+        OS0_1();
+        break;
+
+    case AD_OS_X16:
+        OS2_1();
+        OS1_0();
+        OS0_0();
+        break;
+
+    case AD_OS_X32:
+        OS2_1();
+        OS1_0();
+        OS0_1();
+        break;
+
+    case AD_OS_X64:
+        OS2_1();
+        OS1_1();
+        OS0_0();
+        break;
+
+    case AD_OS_NO:
+    default:
+        g_tAD7606.ucOS = AD_OS_NO;
+        OS2_0();
+        OS1_0();
+        OS0_0();
+        break;
+    }
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: AD7606_SetInputRange
+*	功能说明: 配置AD7606模拟信号输入量程。
+*	形    参: _ucRange : 0 表示正负5V   1表示正负10V
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void AD7606_SetInputRange(uint8_t _ucRange)
+{
+    if (_ucRange == 0)
+    {
+        g_tAD7606.ucRange = 0;
+        RANGE_0(); /* 设置为正负5V */
+    }
+    else
+    {
+        g_tAD7606.ucRange = 1;
+        RANGE_1(); /* 设置为正负10V */
+    }
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: AD7606_Reset
+*	功能说明: 硬件复位AD7606。复位之后恢复到正常工作状态。
+*	形    参: 无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void AD7606_Reset(void)
+{
+    RESET_0(); /* 退出复位状态 */
+
+    RESET_1(); /* 进入复位状态 */
+    RESET_1(); /* 仅用于延迟。 RESET复位高电平脉冲宽度最小50ns。 */
+    RESET_1();
+    RESET_1();
+
+    RESET_0(); /* 退出复位状态 */
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: AD7606_StartConvst
+*	功能说明: 启动1次ADC转换
+*	形    参: 无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void AD7606_StartConvst(void)
+{
+    /* page 7:  CONVST 高电平脉冲宽度和低电平脉冲宽度最短 25ns */
+    /* CONVST平时为高 */
+    CONVST_0();
+    CONVST_0();
+    CONVST_0();
+
+    CONVST_1();
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: AD7606_ReadNowAdc
+*	功能说明: 读取8路采样结果。结果存储在全局变量 g_tAD7606
+*	形    参: 无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void AD7606_ReadNowAdc(void)
+{
+    g_tAD7606.sNowAdc[0] = AD7606_RESULT(); /* 读第1路样本 */
+    g_tAD7606.sNowAdc[1] = AD7606_RESULT(); /* 读第2路样本 */
+    g_tAD7606.sNowAdc[2] = AD7606_RESULT(); /* 读第3路样本 */
+    g_tAD7606.sNowAdc[3] = AD7606_RESULT(); /* 读第4路样本 */
+    g_tAD7606.sNowAdc[4] = AD7606_RESULT(); /* 读第5路样本 */
+    g_tAD7606.sNowAdc[5] = AD7606_RESULT(); /* 读第6路样本 */
+    g_tAD7606.sNowAdc[6] = AD7606_RESULT(); /* 读第7路样本 */
+    g_tAD7606.sNowAdc[7] = AD7606_RESULT(); /* 读第8路样本 */
+}
+
+/*
+*********************************************************************************************************
+*		下面的函数用于定时采集模式。 TIM5硬件定时中断中读取ADC结果,存在全局FIFO
+*
+*
+*********************************************************************************************************
+*/
+
+/*
+        CONVST 引脚,PH12使用TIM5_CH3输出PWM脉冲,触发AD7606启动ADC转换。
+        设置BUSY口线为下降沿中断。在中断服务程序保存ADC结果。
+*/
+
+/*
+*********************************************************************************************************
+*	函 数 名: AD7606_EnterAutoMode
+*	功能说明: 配置硬件工作在自动采集模式,结果存储在FIFO缓冲区。
+*	形    参:  _ulFreq : 采样频率,单位Hz,	1k,2k,5k,10k,20K,50k,100k,200k
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void AD7606_EnterAutoMode(uint32_t _ulFreq)
+{
+    /* 配置PH2为复用功能,TIM5_CH3 . 执行后bsp_InitAD7606()对PH2口线的配置将失效 */
+    {
+        GPIO_InitTypeDef GPIO_InitStructure;
+
+        /* TIM5 clock enable */
+        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
+
+        /* GPIOH clock enable */
+        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);
+
+        /* GPIOH Configuration: PH12  -> TIM5 CH3 */
+        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_12;
+        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
+        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
+        GPIO_Init(GPIOH, &GPIO_InitStructure);
+
+        /* Connect TIM5 pins to AF2 */
+        GPIO_PinAFConfig(GPIOH, GPIO_PinSource12, GPIO_AF_TIM5);
+    }
+
+    {
+        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
+        TIM_OCInitTypeDef       TIM_OCInitStructure;
+        uint32_t                uiTIMxCLK;
+        uint16_t                usPrescaler;
+        uint16_t                usPeriod;
+
+        // TIM_DeInit(TIM5);	/* 复位TIM定时器 */
+
+        /*-----------------------------------------------------------------------
+            system_stm32f4xx.c 文件中 void SetSysClock(void) 函数对时钟的配置如下:
+
+            HCLK = SYSCLK / 1     (AHB1Periph)
+            PCLK2 = HCLK / 2      (APB2Periph)
+            PCLK1 = HCLK / 4      (APB1Periph)
+
+            因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2;
+            因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock;
+
+            APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM6, TIM12, TIM13,TIM14
+            APB2 定时器有 TIM1, TIM8 ,TIM9, TIM10, TIM11
+        */
+
+        uiTIMxCLK = SystemCoreClock / 2;
+
+        if (_ulFreq < 3000)
+        {
+            usPrescaler = 100 - 1;                         /* 分频比 = 10 */
+            usPeriod    = (uiTIMxCLK / 100) / _ulFreq - 1; /* 自动重装的值 */
+        }
+        else /* 大于4K的频率,无需分频 */
+        {
+            usPrescaler = 0;                       /* 分频比 = 1 */
+            usPeriod    = uiTIMxCLK / _ulFreq - 1; /* 自动重装的值 */
+        }
+
+        /* Time base configuration */
+        TIM_TimeBaseStructure.TIM_Period        = usPeriod;
+        TIM_TimeBaseStructure.TIM_Prescaler     = usPrescaler;
+        TIM_TimeBaseStructure.TIM_ClockDivision = 0;
+        TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;
+
+        TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
+
+        /* PWM1 Mode configuration: Channel1 */
+        TIM_OCInitStructure.TIM_OCMode      = TIM_OCMode_PWM1;
+        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
+        TIM_OCInitStructure.TIM_Pulse       = 4;
+        TIM_OCInitStructure.TIM_OCPolarity  = TIM_OCPolarity_Low;
+
+        TIM_OC3Init(TIM5, &TIM_OCInitStructure);
+
+        TIM_OC3PreloadConfig(TIM5, TIM_OCPreload_Enable);
+
+        TIM_ARRPreloadConfig(TIM5, ENABLE);
+
+        TIM_Cmd(TIM5, ENABLE);
+    }
+
+    /* 配置PI6, BUSY 作为中断输入口,下降沿触发 */
+    {
+        EXTI_InitTypeDef EXTI_InitStructure;
+        GPIO_InitTypeDef GPIO_InitStructure;
+        NVIC_InitTypeDef NVIC_InitStructure;
+
+        /* Enable GPIOA clock */
+        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOI, ENABLE);
+        /* Enable SYSCFG clock */
+        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
+
+        /* Configure PI6 pin as input floating */
+        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
+        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6;
+        GPIO_Init(GPIOI, &GPIO_InitStructure);
+
+        /* Connect EXTI Line6 to PI6 pin */
+        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOI, EXTI_PinSource6);
+
+        /* Configure EXTI Line6 */
+        EXTI_InitStructure.EXTI_Line    = EXTI_Line6;
+        EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;
+        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
+
+        // EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
+        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+        EXTI_Init(&EXTI_InitStructure);
+
+        /* Enable and set EXTI Line6 Interrupt to the lowest priority */
+        NVIC_InitStructure.NVIC_IRQChannel                   = EXTI9_5_IRQn;
+        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
+        NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0x00;
+        NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
+        NVIC_Init(&NVIC_InitStructure);
+    }
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: AD7606_HasNewData
+*	功能说明: 判断FIFO中是否有新数据
+*	形    参:  _usReadAdc : 存放ADC结果的变量指针
+*	返 回 值: 1 表示有,0表示暂无数据
+*********************************************************************************************************
+*/
+uint8_t AD7606_HasNewData(void)
+{
+    if (g_tAdcFifo.usCount > 0)
+    {
+        return 1;
+    }
+    return 0;
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: AD7606_FifoFull
+*	功能说明: 判断FIFO是否满
+*	形    参:  _usReadAdc : 存放ADC结果的变量指针
+*	返 回 值: 1 表示满,0表示未满
+*********************************************************************************************************
+*/
+uint8_t AD7606_FifoFull(void)
+{
+    return g_tAdcFifo.ucFull;
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: AD7606_ReadFifo
+*	功能说明: 从FIFO中读取一个ADC值
+*	形    参:  _usReadAdc : 存放ADC结果的变量指针
+*	返 回 值: 1 表示OK,0表示暂无数据
+*********************************************************************************************************
+*/
+uint8_t AD7606_ReadFifo(uint16_t *_usReadAdc)
+{
+    if (AD7606_HasNewData())
+    {
+        *_usReadAdc = g_tAdcFifo.sBuf[g_tAdcFifo.usRead];
+        if (++g_tAdcFifo.usRead >= ADC_FIFO_SIZE)
+        {
+            g_tAdcFifo.usRead = 0;
+        }
+
+        DISABLE_INT();
+        if (g_tAdcFifo.usCount > 0)
+        {
+            g_tAdcFifo.usCount--;
+        }
+        ENABLE_INT();
+        return 1;
+    }
+    return 0;
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: AD7606_StartRecord
+*	功能说明: 开始采集
+*	形    参:  无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void AD7606_StartRecord(uint32_t _ulFreq)
+{
+    AD7606_StopRecord();
+
+    AD7606_Reset();       /* 复位硬件 */
+    AD7606_StartConvst(); /* 启动采样,避免第1组数据全0的问题 */
+
+    g_tAdcFifo.usRead  = 0; /* 必须在开启TIM2之前清0 */
+    g_tAdcFifo.usWrite = 0;
+    g_tAdcFifo.usCount = 0;
+    g_tAdcFifo.ucFull  = 0;
+
+    AD7606_EnterAutoMode(_ulFreq);
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: AD7606_StopRecord
+*	功能说明: 停止采集定时器
+*	形    参:  无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void AD7606_StopRecord(void)
+{
+    TIM_Cmd(TIM5, DISABLE);
+
+    /* 将PH12 重新配置为普通输出口 */
+    {
+        GPIO_InitTypeDef GPIO_InitStructure;
+
+        /* 使能 GPIO时钟 */
+        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);
+
+        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
+        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
+
+        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
+        GPIO_Init(GPIOH, &GPIO_InitStructure);
+    }
+
+    /* 配置PI6, 禁止 BUSY 作为中断输入口 */
+    {
+        EXTI_InitTypeDef EXTI_InitStructure;
+
+        /* Configure EXTI Line6 */
+        EXTI_InitStructure.EXTI_Line    = EXTI_Line6;
+        EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;
+        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
+        EXTI_InitStructure.EXTI_LineCmd = DISABLE;
+        EXTI_Init(&EXTI_InitStructure);
+    }
+    CONVST_1(); /* 启动转换的GPIO平时设置为高 */
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: AD7606_ISR
+*	功能说明: 定时采集中断服务程序
+*	形    参:  无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void AD7606_ISR(void)
+{
+    uint8_t i;
+
+    AD7606_ReadNowAdc();
+
+    for (i = 0; i < 8; i++)
+    {
+        g_tAdcFifo.sBuf[g_tAdcFifo.usWrite] = g_tAD7606.sNowAdc[i];
+        if (++g_tAdcFifo.usWrite >= ADC_FIFO_SIZE)
+        {
+            g_tAdcFifo.usWrite = 0;
+        }
+        if (g_tAdcFifo.usCount < ADC_FIFO_SIZE)
+        {
+            g_tAdcFifo.usCount++;
+        }
+        else
+        {
+            g_tAdcFifo.ucFull = 1; /* FIFO 满,主程序来不及处理数据 */
+        }
+    }
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: EXTI9_5_IRQHandler
+*	功能说明: 外部中断服务程序入口。PI6 / AD7606_BUSY 下降沿中断触发
+*	形    参: 无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+#ifndef EXTI9_5_ISR_MOVE_OUT /* bsp.h 中定义此行,表示本函数移到 stam32f4xx_it.c。 避免重复定义 */
+void EXTI9_5_IRQHandler(void)
+{
+    if (EXTI_GetITStatus(EXTI_Line6) != RESET)
+    {
+        AD7606_ISR();
+
+        /* Clear the EXTI line 6 pending bit */
+        EXTI_ClearITPendingBit(EXTI_Line6);
+    }
+}
+#endif
+
+/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/

+ 72 - 0
User/Bsp/ad7606/ad7606.h

@@ -0,0 +1,72 @@
+/*
+*********************************************************************************************************
+*
+*	模块名称 : AD7606数据采集模块
+*	文件名称 : bsp_ad7606.h
+*	版    本 : V1.0
+*
+*	Copyright (C), 2013-2014, 安富莱电子 www.armfly.com
+*
+*********************************************************************************************************
+*/
+
+#ifndef __AD7606_H
+#define __AD7606_H
+#include "interface.h"
+
+/* 过采样倍率 */
+typedef enum
+{
+    AD_OS_NO  = 0,
+    AD_OS_X2  = 1,
+    AD_OS_X4  = 2,
+    AD_OS_X8  = 3,
+    AD_OS_X16 = 4,
+    AD_OS_X32 = 5,
+    AD_OS_X64 = 6
+} AD7606_OS_E;
+
+/* AD数据采集缓冲区 FIFO */
+#define ADC_FIFO_SIZE (2 * 1024) /* 总体样本数 */
+
+typedef struct
+{
+    uint8_t ucOS;       /* 过采样倍率,0 - 6. 0表示无过采样 */
+    uint8_t ucRange;    /* 输入量程,0表示正负5V, 1表示正负10V */
+    int16_t sNowAdc[8]; /* 当前ADC值, 有符号数 */
+} AD7606_VAR_T;
+
+typedef struct
+{
+    /* FIFO 结构 */
+    uint16_t usRead;  /* 读指针 */
+    uint16_t usWrite; /* 写指针 */
+
+    uint16_t usCount; /* 新数据个数 */
+    uint8_t  ucFull;  /* FIFO满标志 */
+
+    int16_t sBuf[ADC_FIFO_SIZE];
+} AD7606_FIFO_T;
+
+void ad7606_init(void);
+void AD7606_SetOS(uint8_t _ucOS);
+void AD7606_SetInputRange(uint8_t _ucRange);
+void AD7606_Reset(void);
+void AD7606_StartConvst(void);
+void AD7606_ReadNowAdc(void);
+
+/* 下面的函数用于FIFO操作模式 */
+void    AD7606_EnterAutoMode(uint32_t _ulFreq);
+void    AD7606_StartRecord(uint32_t _ulFreq);
+void    AD7606_StopRecord(void);
+uint8_t AD7606_FifoNewData(void);
+uint8_t AD7606_ReadFifo(uint16_t *_usReadAdc);
+uint8_t AD7606_FifoFull(void);
+
+/* 全局变量 */
+extern AD7606_VAR_T  g_tAD7606;
+extern AD7606_FIFO_T g_tAdcFifo;
+
+#endif
+
+/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/

+ 1 - 1
User/Bsp/adc/adc.h

@@ -1,7 +1,7 @@
 #ifndef __ADC_H
 #define __ADC_H
 
-#include "includes.h"
+#include "interface.h"
 
 void adc3_init(void);
 

+ 252 - 0
User/Bsp/am2303/am2303.c

@@ -0,0 +1,252 @@
+#include "am2303.h"
+#include "dwt.h"
+
+//复位AM2303
+void am2303_rst(void)
+{
+    AM2303_IO_OUT;  // SET OUTPUT
+    AM2303_DO_LOW;  //拉低DQ
+    ms_delay(20);   //拉低至少18ms
+    AM2303_DO_HIGH; // DQ=1
+    us_delay(30);   //主机拉高20~40us
+}
+//等待AM2303的回应
+//返回1:未检测到AM2303的存在
+//返回0:存在
+INT8U am2303_check(void)
+{
+    INT8U retry = 0;
+    AM2303_IO_IN;                                                                // SET INPUT
+    while ((GPIO_ReadInputDataBit(AM2303_PORT, AM2303_PIN) == 1) && retry < 100) // AM2303会拉低40~80us
+    {
+        retry++;
+        us_delay(1);
+    };
+    if (retry >= 100)
+        return 1;
+    else
+        retry = 0;
+    while ((GPIO_ReadInputDataBit(AM2303_PORT, AM2303_PIN) == 0) && retry < 100) // AM2303拉低后会再次拉高40~80us
+    {
+        retry++;
+        us_delay(1);
+    };
+    if (retry >= 100)
+        return 1;
+    return 0;
+}
+//从AM2303读取一个位
+//返回值:1/0
+INT8U am2303_read_bit(void)
+{
+    INT8U retry = 0;
+    while ((GPIO_ReadInputDataBit(AM2303_PORT, AM2303_PIN) == 1) && retry < 100) //等待变为低电平
+    {
+        retry++;
+        us_delay(1);
+    }
+    retry = 0;
+    while ((GPIO_ReadInputDataBit(AM2303_PORT, AM2303_PIN) == 0) && retry < 100) //等待变高电平
+    {
+        retry++;
+        us_delay(1);
+    }
+    us_delay(40); //等待40us
+    if (GPIO_ReadInputDataBit(AM2303_PORT, AM2303_PIN) == 1)
+        return 1;
+    else
+        return 0;
+}
+//从AM2303读取一个字节
+//返回值:读到的数据
+INT8U am2303_read_byte(void)
+{
+    INT8U i, dat;
+    dat = 0;
+    for (i = 0; i < 8; i++)
+    {
+        dat <<= 1;
+        dat |= am2303_read_bit();
+    }
+    return dat;
+}
+//从AM2303读取一次数据
+// temp:温度值(范围:0~50°)
+// humi:湿度值(范围:20%~90%)
+//返回值:0,正常;1,读取失败
+// INT8U am2303_read_data(INT8U *temp, INT8U *humi)
+// {
+//     INT8U buf[5];
+//     INT8U i;
+//     am2303_rst();
+//     if (am2303_check() == 0)
+//     {
+//         for (i = 0; i < 5; i++) //读取40位数据
+//         {
+//             buf[i] = am2303_read_byte();
+//         }
+//         if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
+//         {
+//             *humi = buf[0];
+//             *temp = buf[2];
+//         }
+//     }
+//     else
+//         return 1;
+//     return 0;
+// }
+
+/*
+*********************************************************************************************************
+*	函 数 名: DHT11_ReadData
+*	功能说明: 复位DHT11。 拉低DQ为低,持续最少480us,然后等待
+*	形    参: 无
+*	返 回 值: 0 失败; 1 表示成功
+*********************************************************************************************************
+*/
+INT8U am2303_read_data(INT8U *temp, INT8U *humi)
+{
+    INT8U buf[5];
+    INT8U i;
+    INT8U k;
+    /*
+        时序:
+        1. MCU拉低QD持续时间大于 18ms, 然后释放QD = 1
+    */
+
+    /* 1. 主机发送起始信号, DQ拉低时间 > 18ms */
+    AM2303_DO_LOW; /* DQ = 0 */
+    ms_delay(20);
+    AM2303_DO_HIGH; /* DQ = 1 */
+
+    us_delay(15); /* 等待15us */
+
+    /* 2. 等待DQ电平变低 ( 超时100us) */
+    for (k = 0; k < 10; k++)
+    {
+        if (DQ_IS_LOW())
+        {
+            break;
+        }
+        us_delay(10);
+    }
+    if (k >= 10)
+    {
+        goto quit; /* 超时无应答,失败 */
+    }
+
+    /* 3.等待DQ电平变高 (超时100us) */
+    for (k = 0; k < 10; k++)
+    {
+        if (!DQ_IS_LOW())
+        {
+            break;
+        }
+        us_delay(10);
+    }
+    if (k >= 10)
+    {
+        goto quit; /* 超时无应答,失败 */
+    }
+
+    /* 4.等待DQ电平变低 (超时100us) */
+    for (k = 0; k < 10; k++)
+    {
+        if (DQ_IS_LOW())
+        {
+            break;
+        }
+        us_delay(10);
+    }
+    if (k >= 10)
+    {
+        goto quit; /* 超时无应答,失败 */
+    }
+
+    /* 读40bit 数据 */
+    for (i = 0; i < 5; i++)
+    {
+        buf[i] = DHT11_ReadByte();
+    }
+    us_delay(100);
+
+    if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
+    {
+        *humi = buf[0];
+        *temp = buf[2];
+        return 1;
+    }
+
+quit:
+    return 0;
+}
+//初始化AM2303的IO口 DQ 同时检测AM2303的存在
+//返回1:不存在
+//返回0:存在
+#if 0
+INT8U am2303_init(void)
+{
+    am2303_rst();          //复位AM2303
+    return am2303_check(); //等待AM2303的回应
+}
+#else
+INT8U am2303_init(void)
+{
+    AM2303_DO_LOW;
+}
+#endif
+
+/*
+*********************************************************************************************************
+*	函 数 名: DHT11_ReadByte
+*	功能说明: 向DHT11读取1字节数据
+*	形    参: 无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+uint8_t DHT11_ReadByte(void)
+{
+    /*
+        写数据时序, 见DHT11 page 16
+    */
+    uint8_t i, k;
+    uint8_t read = 0;
+
+    for (i = 0; i < 8; i++)
+    {
+        read <<= 1;
+        /* 等待DQ电平变高 (超时100us) */
+        for (k = 0; k < 10; k++)
+        {
+            if (!DQ_IS_LOW())
+            {
+                break;
+            }
+            us_delay(10);
+        }
+        if (k >= 10)
+        {
+            goto quit; /* 超时无应答,失败 */
+        }
+
+        /* 等待DQ电平变低,统计DQ高电平时长 (超时100us) */
+        for (k = 0; k < 10; k++)
+        {
+            if (DQ_IS_LOW())
+            {
+                break;
+            }
+            us_delay(10);
+        }
+
+        if (k > 3) /* 高脉冲持续时间大于40us ,认为是1,否则是0 */
+        {
+            read++;
+        }
+    }
+
+    return read;
+
+quit:
+    return 0xFF;
+}

+ 13 - 0
User/Bsp/am2303/am2303.h

@@ -0,0 +1,13 @@
+#ifndef __AM2303_H
+#define __AM2303_H
+
+#include "interface.h"
+
+INT8U   am2303_init(void);                          //初始化AM2303
+INT8U   am2303_read_data(INT8U *temp, INT8U *humi); //读取温湿度
+INT8U   am2303_read_byte(void);                     //读出一个字节
+INT8U   am2303_read_bit(void);                      //读出一个位
+INT8U   am2303_check(void);                         //检测是否存在AM2303
+void    am2303_rst(void);                           //复位AM2303
+uint8_t DHT11_ReadByte(void);
+#endif

+ 12 - 1
User/Bsp/armfly_bsp.c

@@ -1,3 +1,11 @@
+/*
+ * @Author: 樊春春 [email protected]
+ * @Date: 2022-07-06 19:12:52
+ * @LastEditors: 樊春春 [email protected]
+ * @LastEditTime: 2022-08-08 19:56:29
+ * @FilePath: /ArmFly/User/bsp/armfly_bsp.c
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
 #include "armfly_bsp.h"
 
 void bsp_init(void)
@@ -13,13 +21,16 @@ void bsp_init(void)
     // GPIO初始化
     gpio_clock_init();
     interface_init();
-
+    ad7606_init();
+    am2303_init();
     dwt_init();
     spi1_init();
     uart1_init();
     uart3_init();
     nor_flash_init();
     lwip_setup();
+    LCD_Init();
+    key_init();
     // can初始化
     can_network_init();
 }

+ 4 - 0
User/Bsp/armfly_bsp.h

@@ -1,10 +1,14 @@
 #ifndef _ARMFLY_H__
 #define _ARMFLY_H__
 
+#include "ad7606.h"
+#include "am2303.h"
 #include "can.h"
 #include "dwt.h"
 #include "fly_param.h"
 #include "interface.h"
+#include "key.h"
+#include "lcd.h"
 #include "lwip_init.h"
 #include "nor_flash.h"
 #include "queue.h"

+ 0 - 1
User/Bsp/dm9k/dm9k.c

@@ -17,7 +17,6 @@
 */
 
 #include "dm9k.h"
-#include "interface.h"
 #include "lwip_dm9k.h"
 
 /****************************************************************************

+ 1 - 1
User/Bsp/dm9k/dm9k.h

@@ -14,7 +14,7 @@
 #define _DM9K_H_
 
 #include "dwt.h"
-#include "includes.h"
+#include "interface.h"
 #include "lwip_init.h"
 #include <inttypes.h>
 

+ 0 - 1
User/Bsp/eth/stm32f4x7_phy.c

@@ -1,6 +1,5 @@
 #include "stm32f4x7_phy.h"
 #include "dwt.h"
-#include "interface.h"
 #include "lwip/api.h"
 #include "lwip/sockets.h"
 #include "stm32f4x7_eth.h"

+ 1 - 1
User/Bsp/eth/stm32f4x7_phy.h

@@ -2,7 +2,7 @@
 #ifndef __STM32F4x7_PHY_H
 #define __STM32F4x7_PHY_H
 
-#include "includes.h"
+#include "interface.h"
 #include "lwip/netif.h"
 #include "lwip_eth.h"
 

+ 0 - 1
User/Bsp/ext_sram/ext_sram.c

@@ -16,7 +16,6 @@
 */
 
 #include "ext_sram.h"
-#include "interface.h"
 #include <inttypes.h>
 
 /*

+ 1 - 1
User/Bsp/ext_sram/ext_sram.h

@@ -1,7 +1,7 @@
 #ifndef _FSMC_SRAM_H
 #define _FSMC_SRAM_H
 
-#include "includes.h"
+#include "interface.h"
 
 #define EXT_SRAM_ADDR ((uint32_t)0x68000000)
 #define EXT_SRAM_SIZE (2 * 1024 * 1024)

+ 29 - 4
User/Bsp/interface/interface.c

@@ -136,16 +136,41 @@ Interface_struct interface_info[] = {
     {.type = kFSMC, .GPIOx = GPIOG, .GPIO_Pin = GPIO_Pin_5, .GPIO_Mode = GPIO_Mode_AF, .AF_Info = {.GPIOx = GPIOG, .GPIO_PinSource = GPIO_PinSource5, .GPIO_AF = GPIO_AF_FSMC}, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_UP},
     {.type = kFSMC, .GPIOx = GPIOG, .GPIO_Pin = GPIO_Pin_9, .GPIO_Mode = GPIO_Mode_AF, .AF_Info = {.GPIOx = GPIOG, .GPIO_PinSource = GPIO_PinSource9, .GPIO_AF = GPIO_AF_FSMC}, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_UP},
     {.type = kFSMC, .GPIOx = GPIOG, .GPIO_Pin = GPIO_Pin_10, .GPIO_Mode = GPIO_Mode_AF, .AF_Info = {.GPIOx = GPIOG, .GPIO_PinSource = GPIO_PinSource10, .GPIO_AF = GPIO_AF_FSMC}, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_UP},
+    {.type = kFSMC, .GPIOx = GPIOG, .GPIO_Pin = GPIO_Pin_12, .GPIO_Mode = GPIO_Mode_AF, .AF_Info = {.GPIOx = GPIOG, .GPIO_PinSource = GPIO_PinSource12, .GPIO_AF = GPIO_AF_FSMC}, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_UP},
+
+    // am2303
+    {.type = kOutput, .Out_Type = kAM2303, .GPIOx = AM2303_PORT, .GPIO_Pin = AM2303_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_OD, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
 
     // input
     {.type = kInput, .In_Type = DM9K_INIT, .GPIOx = DM9K_RESET_PORT, .GPIO_Pin = DM9K_RESET_PIN, .GPIO_Mode = GPIO_Mode_IN, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
     {.type = kInput, .In_Type = NOR_FLASH_STATE, .GPIOx = NOR_FLASH_STATE_PORT, .GPIO_Pin = NOR_FLASH_STATE_PIN, .GPIO_Mode = GPIO_Mode_IN, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
 
+    {.type = kInput, .In_Type = kKey, .GPIOx = GPIO_PORT_K1, .GPIO_Pin = GPIO_PIN_K1, .GPIO_Mode = GPIO_Mode_IN, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kInput, .In_Type = kKey, .GPIOx = GPIO_PORT_K2, .GPIO_Pin = GPIO_PIN_K2, .GPIO_Mode = GPIO_Mode_IN, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kInput, .In_Type = kKey, .GPIOx = GPIO_PORT_K3, .GPIO_Pin = GPIO_PIN_K3, .GPIO_Mode = GPIO_Mode_IN, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kInput, .In_Type = kKey, .GPIOx = GPIO_PORT_K4, .GPIO_Pin = GPIO_PIN_K4, .GPIO_Mode = GPIO_Mode_IN, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kInput, .In_Type = kKey, .GPIOx = GPIO_PORT_K5, .GPIO_Pin = GPIO_PIN_K5, .GPIO_Mode = GPIO_Mode_IN, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kInput, .In_Type = kKey, .GPIOx = GPIO_PORT_K6, .GPIO_Pin = GPIO_PIN_K6, .GPIO_Mode = GPIO_Mode_IN, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kInput, .In_Type = kKey, .GPIOx = GPIO_PORT_K7, .GPIO_Pin = GPIO_PIN_K7, .GPIO_Mode = GPIO_Mode_IN, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kInput, .In_Type = kKey, .GPIOx = GPIO_PORT_K8, .GPIO_Pin = GPIO_PIN_K8, .GPIO_Mode = GPIO_Mode_IN, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+
     // output
-    {.type = kOutput, .Out_Type = kRunLed, .GPIOx = LED0_RUN_PORT, .GPIO_Pin = LED0_RUN_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_High_Speed, .GPIO_PuPd = GPIO_PuPd_DOWN},
-    {.type = kOutput, .Out_Type = kRunLed, .GPIOx = LED1_RUN_PORT, .GPIO_Pin = LED1_RUN_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_High_Speed, .GPIO_PuPd = GPIO_PuPd_DOWN},
-    {.type = kOutput, .Out_Type = kRunLed, .GPIOx = LED2_RUN_PORT, .GPIO_Pin = LED2_RUN_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_High_Speed, .GPIO_PuPd = GPIO_PuPd_DOWN},
-    {.type = kOutput, .Out_Type = kRunLed, .GPIOx = LED3_RUN_PORT, .GPIO_Pin = LED3_RUN_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_High_Speed, .GPIO_PuPd = GPIO_PuPd_DOWN},
+    {.type = kOutput, .Out_Type = kRunLed, .GPIOx = LED0_RUN_PORT, .GPIO_Pin = LED0_RUN_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kOutput, .Out_Type = kRunLed, .GPIOx = LED1_RUN_PORT, .GPIO_Pin = LED1_RUN_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kOutput, .Out_Type = kRunLed, .GPIOx = LED2_RUN_PORT, .GPIO_Pin = LED2_RUN_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kOutput, .Out_Type = kTFTLCD, .GPIOx = LCD_PWM_PORT, .GPIO_Pin = LCD_PWM_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kOutput, .Out_Type = kTFTLCD, .GPIOx = LCD_BUSY_PORT, .GPIO_Pin = LCD_BUSY_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    // {.type = kOutput, .Out_Type = kTFTLCD, .GPIOx = LED2_RUN_PORT, .GPIO_Pin = LED2_RUN_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+
+    // {.type = kOutput, .Out_Type = kRunLed, .GPIOx = LED3_RUN_PORT, .GPIO_Pin = LED3_RUN_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kOutput, .Out_Type = kAd7606, .GPIOx = AD7606_OS0_PORT, .GPIO_Pin = AD7606_OS0_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kOutput, .Out_Type = kAd7606, .GPIOx = AD7606_OS1_PORT, .GPIO_Pin = AD7606_OS1_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kOutput, .Out_Type = kAd7606, .GPIOx = AD7606_OS2_PORT, .GPIO_Pin = AD7606_OS2_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kOutput, .Out_Type = kAd7606, .GPIOx = AD7606_CONVST_PORT, .GPIO_Pin = AD7606_CONVST_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kOutput, .Out_Type = kAd7606, .GPIOx = AD7606_RAGE_PORT, .GPIO_Pin = AD7606_RAGE_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kOutput, .Out_Type = kAd7606, .GPIOx = AD7606_RESET_PORT, .GPIO_Pin = AD7606_RESET_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+    {.type = kOutput, .Out_Type = kAd7606, .GPIOx = AD7606_BUSY_PORT, .GPIO_Pin = AD7606_BUSY_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_Speed_100MHz, .GPIO_PuPd = GPIO_PuPd_NOPULL},
+
     //         {.type = kOutput, .Out_Type = kPRelayCtr, .GPIOx = PRelayCtr_PORT, .GPIO_Pin = PRelayCtr_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_High_Speed, .GPIO_PuPd = GPIO_PuPd_DOWN},
     //         {.type = kOutput, .Out_Type = kNRelayCtr, .GPIOx = NRelayCtr_PORT, .GPIO_Pin = NRelayCtr_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_High_Speed, .GPIO_PuPd = GPIO_PuPd_DOWN},
     //         {.type = kOutput, .Out_Type = kPreRelayCtr, .GPIOx = PreRelayCtr_PORT, .GPIO_Pin = PreRelayCtr_PIN, .GPIO_Mode = GPIO_Mode_OUT, .GPIO_OType = GPIO_OType_PP, .GPIO_Speed = GPIO_High_Speed, .GPIO_PuPd = GPIO_PuPd_DOWN},

+ 92 - 6
User/Bsp/interface/interface.h

@@ -23,6 +23,7 @@ typedef enum
     kOutput,
     kPMU,
     kDMA1,
+    kAM2303,
     //    kTIMER1,
     kInterfaceEnd,
 } interface_type;
@@ -45,7 +46,9 @@ typedef struct
 
 typedef enum
 {
+    kTFTLCD,
     kRunLed,
+    kAd7606,
     kPRelayCtr,
     kNRelayCtr,
     kPreRelayCtr,
@@ -69,6 +72,7 @@ typedef enum
     DM9K_INIT,
     NOR_FLASH_STATE,
     kInputEnd,
+    kKey,
 } Input_type;
 
 typedef struct
@@ -124,7 +128,7 @@ typedef struct
 #define UART3_TX_ENABLE   GPIO_SetBits(UART3_ENABLE_PORT, UART3_ENABLE_PIN)
 #define UART3_RX_ENABLE   GPIO_ResetBits(UART3_ENABLE_PORT, UART3_ENABLE_PIN)
 
-// // SPI
+// SPI
 #define SPI1_CS_PORT GPIOF
 #define SPI1_CS_PIN  GPIO_Pin_8
 #define SPI1_CS_HIGH GPIO_SetBits(SPI2_CS_PORT, SPI2_CS_PIN)
@@ -146,8 +150,32 @@ typedef struct
 
 #define NOR_FLASH_STATE_PORT GPIOD
 #define NOR_FLASH_STATE_PIN  GPIO_Pin_6
-#define DM9K_RESET_ON        GPIO_ResetBits(NOR_FLASH_STATE_PORT, NOR_FLASH_STATE_PIN)
-#define DM9K_RESET_OFF       GPIO_SetBits(NOR_FLASH_STATE_PORT, NOR_FLASH_STATE_PIN)
+#define NOR_FLASH_STATE_ON   GPIO_ResetBits(NOR_FLASH_STATE_PORT, NOR_FLASH_STATE_PIN)
+#define NOR_FLASH_STATE_OFF  GPIO_SetBits(NOR_FLASH_STATE_PORT, NOR_FLASH_STATE_PIN)
+
+#define GPIO_PORT_K1 GPIOI
+#define GPIO_PIN_K1  GPIO_Pin_8
+
+#define GPIO_PORT_K2 GPIOC
+#define GPIO_PIN_K2  GPIO_Pin_13
+
+#define GPIO_PORT_K3 GPIOI
+#define GPIO_PIN_K3  GPIO_Pin_11
+
+#define GPIO_PORT_K4 GPIOH
+#define GPIO_PIN_K4  GPIO_Pin_2
+
+#define GPIO_PORT_K5 GPIOH
+#define GPIO_PIN_K5  GPIO_Pin_3
+
+#define GPIO_PORT_K6 GPIOF
+#define GPIO_PIN_K6  GPIO_Pin_11
+
+#define GPIO_PORT_K7 GPIOG
+#define GPIO_PIN_K7  GPIO_Pin_7
+
+#define GPIO_PORT_K8 GPIOH
+#define GPIO_PIN_K8  GPIO_Pin_15
 
 // output
 #define LED0_RUN_PORT GPIOC
@@ -158,6 +186,43 @@ typedef struct
 #define LED2_RUN_PIN  GPIO_Pin_8
 #define LED3_RUN_PORT GPIOI
 #define LED3_RUN_PIN  GPIO_Pin_10
+
+#define LCD_PWM_PORT  GPIOF
+#define LCD_PWM_PIN   GPIO_Pin_6
+#define LCD_BUSY_PORT GPIOD
+#define LCD_BUSY_PIN  GPIO_Pin_3
+// #define LED2_RUN_PORT GPIOF
+// #define LED2_RUN_PIN  GPIO_Pin_8
+// #define LED3_RUN_PORT GPIOI
+// #define LED3_RUN_PIN  GPIO_Pin_10
+/*	配置几个控制用的GPIO
+    PH9/DCMI_D0/AD7606_OS0			---> AD7606_OS0		OS2:OS0 选择数字滤波参数
+    PH10/DCMI_D1/AD7606_OS1         ---> AD7606_OS1
+    PH11/DCMI_D2/AD7606_OS2         ---> AD7606_OS2
+    PH12/DCMI_D3/AD7606_CONVST      ---> AD7606_CONVST	启动ADC转换
+    PH14/DCMI_D4/AD7606_RAGE        ---> AD7606_RAGE	输入模拟电压量程,正负5V或正负10V
+    PI4/DCMI_D5/AD7606_RESET        ---> AD7606_RESET	复位
+
+    PI6/DCMI_D6/AD7606_BUSY			---> AD7606_BUSY    转换结束的信号
+*/
+#define AD7606_OS0_PORT    GPIOH
+#define AD7606_OS0_PIN     GPIO_Pin_9
+#define AD7606_OS1_PORT    GPIOH
+#define AD7606_OS1_PIN     GPIO_Pin_10
+#define AD7606_OS2_PORT    GPIOH
+#define AD7606_OS2_PIN     GPIO_Pin_11
+#define AD7606_CONVST_PORT GPIOH
+#define AD7606_CONVST_PIN  GPIO_Pin_12
+#define AD7606_RAGE_PORT   GPIOH
+#define AD7606_RAGE_PIN    GPIO_Pin_14
+#define AD7606_RESET_PORT  GPIOI
+#define AD7606_RESET_PIN   GPIO_Pin_4
+#define AD7606_BUSY_PORT   GPIOI
+#define AD7606_BUSY_PIN    GPIO_Pin_6
+
+#define AM2303_PORT GPIOB
+#define AM2303_PIN  GPIO_Pin_1
+
 // #define PRelayCtr_PORT GPIOD
 // #define PRelayCtr_PIN GPIO_PIN_6
 // #define NRelayCtr_PORT GPIOD
@@ -195,9 +260,30 @@ typedef struct
 #define LED2_RUN_ON     GPIO_SetBits(LED2_RUN_PORT, LED2_RUN_PIN)
 #define LED2_RUN_OFF    GPIO_ResetBits(LED2_RUN_PORT, LED2_RUN_PIN)
 #define LED2_RUN_TOGGLE GPIO_ToggleBits(LED2_RUN_PORT, LED2_RUN_PIN)
-#define LED3_RUN_ON     GPIO_SetBits(LED3_RUN_PORT, LED3_RUN_PIN)
-#define LED3_RUN_OFF    GPIO_ResetBits(LED3_RUN_PORT, LED3_RUN_PIN)
-#define LED3_RUN_TOGGLE GPIO_ToggleBits(LED3_RUN_PORT, LED3_RUN_PIN)
+
+// TFTLCD
+#define LCD_PWM_HIGH GPIO_SetBits(LCD_PWM_PORT, LCD_PWM_PIN)
+#define LCD_PWM_LOW  GPIO_ResetBits(LCD_PWM_PORT, LCD_PWM_PIN)
+
+#define AM2303_DO_HIGH GPIO_SetBits(AM2303_PORT, AM2303_PIN)
+#define AM2303_DO_LOW  GPIO_ResetBits(AM2303_PORT, AM2303_PIN)
+#define AM2303_TOGGLE  GPIO_ToggleBits(AM2303_PORT, AM2303_PIN)
+
+// IO方向设置
+#define AM2303_IO_IN                     \
+    {                                    \
+        GPIOB->MODER &= ~(3 << (1 * 2)); \
+        GPIOB->MODER |= 0 << (1 * 2);    \
+    }
+#define AM2303_IO_OUT                    \
+    {                                    \
+        GPIOB->MODER &= ~(3 << (1 * 2)); \
+        GPIOB->MODER |= 1 << (1 * 2);    \
+    }
+#define DQ_IS_LOW() ((AM2303_PORT->IDR & AM2303_PIN) == 0)
+// #define LED3_RUN_ON     GPIO_SetBits(LED3_RUN_PORT, LED3_RUN_PIN)
+// #define LED3_RUN_OFF    GPIO_ResetBits(LED3_RUN_PORT, LED3_RUN_PIN)
+// #define LED3_RUN_TOGGLE GPIO_ToggleBits(LED3_RUN_PORT, LED3_RUN_PIN)
 // #define PRelayCtr_ON GPIO_SetBits(PRelayCtr_PORT, PRelayCtr_PIN)
 // #define PRelayCtr_OFF GPIO_ResetBits(PRelayCtr_PORT, PRelayCtr_PIN)
 // #define NRelayCtr_ON GPIO_SetBits(NRelayCtr_PORT, NRelayCtr_PIN)

+ 464 - 0
User/Bsp/key/key.c

@@ -0,0 +1,464 @@
+/*
+*********************************************************************************************************
+*
+*	模块名称 : 独立按键驱动模块
+*	文件名称 : bsp_key.c
+*	版    本 : V1.0
+*	说    明 : 扫描独立按键,具有软件滤波机制,具有按键FIFO。可以检测如下事件:
+*				(1) 按键按下
+*				(2) 按键弹起
+*				(3) 长按键
+*				(4) 长按时自动连发
+*
+*	修改记录 :
+*		版本号  日期        作者     说明
+*		V1.0    2013-02-01 armfly  正式发布
+*		V1.1    2013-06-29 armfly  增加1个读指针,用于bsp_Idle() 函数读取系统控制组合键(截屏)
+*								   增加 K1 K2 组合键 和 K2 K3 组合键,用于系统控制
+*
+*	Copyright (C), 2013-2014, 安富莱电子 www.armfly.com
+*
+*********************************************************************************************************
+*/
+
+/*
+    该程序适用于安富莱STM32-X3、STM32-V5开发板
+
+    如果用于其它硬件,请修改GPIO定义和 IsKeyDown1 - IsKeyDown8 函数
+
+    如果用户的按键个数小于8个,你可以将多余的按键全部定义为和第1个按键一样,并不影响程序功能
+    #define KEY_COUNT    8	  这个在 bsp_key.h 文件中定义
+*/
+#include "key.h"
+
+static KEY_T      s_tBtn[KEY_COUNT];
+static KEY_FIFO_T s_tKey; /* 按键FIFO变量,结构体 */
+
+static void bsp_DetectKey(uint8_t i);
+
+/*
+*********************************************************************************************************
+*	函 数 名: IsKeyDownX
+*	功能说明: 判断按键是否按下
+*	形    参: 无
+*	返 回 值: 返回值1 表示按下,0表示未按下
+*********************************************************************************************************
+*/
+#ifdef STM32_X3 /* 安富莱 STM32-X3 开发板 */
+static uint8_t IsKeyDown1(void)
+{
+    if ((GPIO_PORT_K1->IDR & GPIO_PIN_K1) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown2(void)
+{
+    if ((GPIO_PORT_K2->IDR & GPIO_PIN_K2) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown3(void)
+{
+    if ((GPIO_PORT_K3->IDR & GPIO_PIN_K3) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown4(void)
+{
+    if ((GPIO_PORT_K4->IDR & GPIO_PIN_K4) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown5(void)
+{
+    if ((GPIO_PORT_K5->IDR & GPIO_PIN_K5) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown6(void)
+{
+    if ((GPIO_PORT_K6->IDR & GPIO_PIN_K6) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown7(void)
+{
+    if ((GPIO_PORT_K7->IDR & GPIO_PIN_K7) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown8(void)
+{
+    if ((GPIO_PORT_K8->IDR & GPIO_PIN_K8) == 0)
+        return 1;
+    else
+        return 0;
+}
+#else /* 安富莱 STM32-V5 开发板 */
+static uint8_t IsKeyDown1(void)
+{
+    if ((GPIO_PORT_K1->IDR & GPIO_PIN_K1) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown2(void)
+{
+    if ((GPIO_PORT_K2->IDR & GPIO_PIN_K2) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown3(void)
+{
+    if ((GPIO_PORT_K3->IDR & GPIO_PIN_K3) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown4(void)
+{
+    if ((GPIO_PORT_K4->IDR & GPIO_PIN_K4) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown5(void)
+{
+    if ((GPIO_PORT_K5->IDR & GPIO_PIN_K5) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown6(void)
+{
+    if ((GPIO_PORT_K6->IDR & GPIO_PIN_K6) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown7(void)
+{
+    if ((GPIO_PORT_K7->IDR & GPIO_PIN_K7) == 0)
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown8(void)
+{
+    if ((GPIO_PORT_K8->IDR & GPIO_PIN_K8) == 0)
+        return 1;
+    else
+        return 0;
+}
+#endif
+static uint8_t IsKeyDown9(void)
+{
+    if (IsKeyDown1() && IsKeyDown2())
+        return 1;
+    else
+        return 0;
+}
+static uint8_t IsKeyDown10(void)
+{
+    if (IsKeyDown1() && IsKeyDown2())
+        return 1;
+    else
+        return 0;
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: bsp_PutKey
+*	功能说明: 将1个键值压入按键FIFO缓冲区。可用于模拟一个按键。
+*	形    参:  _KeyCode : 按键代码
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void bsp_PutKey(uint8_t _KeyCode)
+{
+    s_tKey.Buf[s_tKey.Write] = _KeyCode;
+
+    if (++s_tKey.Write >= KEY_FIFO_SIZE)
+    {
+        s_tKey.Write = 0;
+    }
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: bsp_GetKey
+*	功能说明: 从按键FIFO缓冲区读取一个键值。
+*	形    参:  无
+*	返 回 值: 按键代码
+*********************************************************************************************************
+*/
+uint8_t bsp_GetKey(void)
+{
+    uint8_t ret;
+
+    if (s_tKey.Read == s_tKey.Write)
+    {
+        return KEY_NONE;
+    }
+    else
+    {
+        ret = s_tKey.Buf[s_tKey.Read];
+
+        if (++s_tKey.Read >= KEY_FIFO_SIZE)
+        {
+            s_tKey.Read = 0;
+        }
+        return ret;
+    }
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: bsp_GetKey2
+*	功能说明: 从按键FIFO缓冲区读取一个键值。独立的读指针。
+*	形    参:  无
+*	返 回 值: 按键代码
+*********************************************************************************************************
+*/
+uint8_t bsp_GetKey2(void)
+{
+    uint8_t ret;
+
+    if (s_tKey.Read2 == s_tKey.Write)
+    {
+        return KEY_NONE;
+    }
+    else
+    {
+        ret = s_tKey.Buf[s_tKey.Read2];
+
+        if (++s_tKey.Read2 >= KEY_FIFO_SIZE)
+        {
+            s_tKey.Read2 = 0;
+        }
+        return ret;
+    }
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: bsp_GetKeyState
+*	功能说明: 读取按键的状态
+*	形    参:  _ucKeyID : 按键ID,从0开始
+*	返 回 值: 1 表示按下, 0 表示未按下
+*********************************************************************************************************
+*/
+uint8_t bsp_GetKeyState(KEY_ID_E _ucKeyID)
+{
+    return s_tBtn[_ucKeyID].State;
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: bsp_SetKeyParam
+*	功能说明: 设置按键参数
+*	形    参:_ucKeyID : 按键ID,从0开始
+*			_LongTime : 长按事件时间
+*			 _RepeatSpeed : 连发速度
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void bsp_SetKeyParam(uint8_t _ucKeyID, uint16_t _LongTime, uint8_t _RepeatSpeed)
+{
+    s_tBtn[_ucKeyID].LongTime    = _LongTime;    /* 长按时间 0 表示不检测长按键事件 */
+    s_tBtn[_ucKeyID].RepeatSpeed = _RepeatSpeed; /* 按键连发的速度,0表示不支持连发 */
+    s_tBtn[_ucKeyID].RepeatCount = 0;            /* 连发计数器 */
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: bsp_ClearKey
+*	功能说明: 清空按键FIFO缓冲区
+*	形    参:无
+*	返 回 值: 按键代码
+*********************************************************************************************************
+*/
+void bsp_ClearKey(void)
+{
+    s_tKey.Read = s_tKey.Write;
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: key_init
+*	功能说明: 初始化按键变量
+*	形    参:  无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void key_init(void)
+{
+    uint8_t i;
+
+    /* 对按键FIFO读写指针清零 */
+    s_tKey.Read  = 0;
+    s_tKey.Write = 0;
+    s_tKey.Read2 = 0;
+
+    /* 给每个按键结构体成员变量赋一组缺省值 */
+    for (i = 0; i < KEY_COUNT; i++)
+    {
+        s_tBtn[i].LongTime = KEY_LONG_TIME;       /* 长按时间 0 表示不检测长按键事件 */
+        s_tBtn[i].Count    = KEY_FILTER_TIME / 2; /* 计数器设置为滤波时间的一半 */
+        s_tBtn[i].State    = 0;                   /* 按键缺省状态,0为未按下 */
+        // s_tBtn[i].KeyCodeDown = 3 * i + 1;				/* 按键按下的键值代码 */
+        // s_tBtn[i].KeyCodeUp   = 3 * i + 2;				/* 按键弹起的键值代码 */
+        // s_tBtn[i].KeyCodeLong = 3 * i + 3;				/* 按键被持续按下的键值代码 */
+        s_tBtn[i].RepeatSpeed = 0; /* 按键连发的速度,0表示不支持连发 */
+        s_tBtn[i].RepeatCount = 0; /* 连发计数器 */
+    }
+
+    /* 如果需要单独更改某个按键的参数,可以在此单独重新赋值 */
+    /* 比如,我们希望按键1按下超过1秒后,自动重发相同键值 */
+    s_tBtn[KID_JOY_U].LongTime    = 100;
+    s_tBtn[KID_JOY_U].RepeatSpeed = 5; /* 每隔50ms自动发送键值 */
+
+    s_tBtn[KID_JOY_D].LongTime    = 100;
+    s_tBtn[KID_JOY_D].RepeatSpeed = 5; /* 每隔50ms自动发送键值 */
+
+    s_tBtn[KID_JOY_L].LongTime    = 100;
+    s_tBtn[KID_JOY_L].RepeatSpeed = 5; /* 每隔50ms自动发送键值 */
+
+    s_tBtn[KID_JOY_R].LongTime    = 100;
+    s_tBtn[KID_JOY_R].RepeatSpeed = 5; /* 每隔50ms自动发送键值 */
+
+    /* 判断按键按下的函数 */
+    s_tBtn[0].IsKeyDownFunc = IsKeyDown1;
+    s_tBtn[1].IsKeyDownFunc = IsKeyDown2;
+    s_tBtn[2].IsKeyDownFunc = IsKeyDown3;
+    s_tBtn[3].IsKeyDownFunc = IsKeyDown4;
+    s_tBtn[4].IsKeyDownFunc = IsKeyDown5;
+    s_tBtn[5].IsKeyDownFunc = IsKeyDown6;
+    s_tBtn[6].IsKeyDownFunc = IsKeyDown7;
+    s_tBtn[7].IsKeyDownFunc = IsKeyDown8;
+
+    /* 组合键 */
+    s_tBtn[8].IsKeyDownFunc = IsKeyDown9;
+    s_tBtn[9].IsKeyDownFunc = IsKeyDown10;
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: bsp_DetectKey
+*	功能说明: 检测一个按键。非阻塞状态,必须被周期性的调用。
+*	形    参:  按键结构变量指针
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+static void bsp_DetectKey(uint8_t i)
+{
+    KEY_T *pBtn;
+
+    /*
+        如果没有初始化按键函数,则报错
+        if (s_tBtn[i].IsKeyDownFunc == 0)
+        {
+            printf("Fault : DetectButton(), s_tBtn[i].IsKeyDownFunc undefine");
+        }
+    */
+
+    pBtn = &s_tBtn[i];
+    if (pBtn->IsKeyDownFunc())
+    {
+        if (pBtn->Count < KEY_FILTER_TIME)
+        {
+            pBtn->Count = KEY_FILTER_TIME;
+        }
+        else if (pBtn->Count < 2 * KEY_FILTER_TIME)
+        {
+            pBtn->Count++;
+        }
+        else
+        {
+            if (pBtn->State == 0)
+            {
+                pBtn->State = 1;
+
+                /* 发送按钮按下的消息 */
+                bsp_PutKey((uint8_t)(3 * i + 1));
+            }
+
+            if (pBtn->LongTime > 0)
+            {
+                if (pBtn->LongCount < pBtn->LongTime)
+                {
+                    /* 发送按钮持续按下的消息 */
+                    if (++pBtn->LongCount == pBtn->LongTime)
+                    {
+                        /* 键值放入按键FIFO */
+                        bsp_PutKey((uint8_t)(3 * i + 3));
+                    }
+                }
+                else
+                {
+                    if (pBtn->RepeatSpeed > 0)
+                    {
+                        if (++pBtn->RepeatCount >= pBtn->RepeatSpeed)
+                        {
+                            pBtn->RepeatCount = 0;
+                            /* 常按键后,每隔10ms发送1个按键 */
+                            bsp_PutKey((uint8_t)(3 * i + 1));
+                        }
+                    }
+                }
+            }
+        }
+    }
+    else
+    {
+        if (pBtn->Count > KEY_FILTER_TIME)
+        {
+            pBtn->Count = KEY_FILTER_TIME;
+        }
+        else if (pBtn->Count != 0)
+        {
+            pBtn->Count--;
+        }
+        else
+        {
+            if (pBtn->State == 1)
+            {
+                pBtn->State = 0;
+
+                /* 发送按钮弹起的消息 */
+                bsp_PutKey((uint8_t)(3 * i + 2));
+            }
+        }
+
+        pBtn->LongCount   = 0;
+        pBtn->RepeatCount = 0;
+    }
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: bsp_KeyScan
+*	功能说明: 扫描所有按键。非阻塞,被systick中断周期性的调用
+*	形    参:  无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void bsp_KeyScan(void)
+{
+    uint8_t i;
+
+    for (i = 0; i < KEY_COUNT; i++)
+    {
+        bsp_DetectKey(i);
+    }
+}
+
+/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/

+ 161 - 0
User/Bsp/key/key.h

@@ -0,0 +1,161 @@
+#ifndef __KEY_H
+#define __KEY_H
+
+#include "interface.h"
+
+#define KEY_COUNT 10 /* 按键个数, 8个独立建 + 2个组合键 */
+
+/* 根据应用程序的功能重命名按键宏 */
+#define KEY_DOWN_K1 KEY_1_DOWN
+#define KEY_UP_K1   KEY_1_UP
+#define KEY_LONG_K1 KEY_1_LONG
+
+#define KEY_DOWN_K2 KEY_2_DOWN
+#define KEY_UP_K2   KEY_2_UP
+#define KEY_LONG_K2 KEY_2_LONG
+
+#define KEY_DOWN_K3 KEY_3_DOWN
+#define KEY_UP_K3   KEY_3_UP
+#define KEY_LONG_K3 KEY_3_LONG
+
+#define JOY_DOWN_U KEY_4_DOWN /* 上 */
+#define JOY_UP_U   KEY_4_UP
+#define JOY_LONG_U KEY_4_LONG
+
+#define JOY_DOWN_D KEY_5_DOWN /* 下 */
+#define JOY_UP_D   KEY_5_UP
+#define JOY_LONG_D KEY_5_LONG
+
+#define JOY_DOWN_L KEY_6_DOWN /* 左 */
+#define JOY_UP_L   KEY_6_UP
+#define JOY_LONG_L KEY_6_LONG
+
+#define JOY_DOWN_R KEY_7_DOWN /* 右 */
+#define JOY_UP_R   KEY_7_UP
+#define JOY_LONG_R KEY_7_LONG
+
+#define JOY_DOWN_OK KEY_8_DOWN /* ok */
+#define JOY_UP_OK   KEY_8_UP
+#define JOY_LONG_OK KEY_8_LONG
+
+#define SYS_DOWN_K1K2 KEY_9_DOWN /* K1 K2 组合键 */
+#define SYS_UP_K1K2   KEY_9_UP
+#define SYS_LONG_K1K2 KEY_9_LONG
+
+#define SYS_DOWN_K2K3 KEY_10_DOWN /* K2 K3 组合键 */
+#define SYS_UP_K2K3   KEY_10_UP
+#define SYS_LONG_K2K3 KEY_10_LONG
+
+/* 按键ID, 主要用于bsp_KeyState()函数的入口参数 */
+typedef enum
+{
+    KID_K1 = 0,
+    KID_K2,
+    KID_K3,
+    KID_JOY_U,
+    KID_JOY_D,
+    KID_JOY_L,
+    KID_JOY_R,
+    KID_JOY_OK
+} KEY_ID_E;
+
+/*
+    按键滤波时间50ms, 单位10ms。
+    只有连续检测到50ms状态不变才认为有效,包括弹起和按下两种事件
+    即使按键电路不做硬件滤波,该滤波机制也可以保证可靠地检测到按键事件
+*/
+#define KEY_FILTER_TIME 5
+#define KEY_LONG_TIME   100 /* 单位10ms, 持续1秒,认为长按事件 */
+
+/*
+    每个按键对应1个全局的结构体变量。
+*/
+typedef struct
+{
+    /* 下面是一个函数指针,指向判断按键手否按下的函数 */
+    uint8_t (*IsKeyDownFunc)(void); /* 按键按下的判断函数,1表示按下 */
+
+    uint8_t  Count;       /* 滤波器计数器 */
+    uint16_t LongCount;   /* 长按计数器 */
+    uint16_t LongTime;    /* 按键按下持续时间, 0表示不检测长按 */
+    uint8_t  State;       /* 按键当前状态(按下还是弹起) */
+    uint8_t  RepeatSpeed; /* 连续按键周期 */
+    uint8_t  RepeatCount; /* 连续按键计数器 */
+} KEY_T;
+
+/*
+    定义键值代码, 必须按如下次序定时每个键的按下、弹起和长按事件
+
+    推荐使用enum, 不用#define,原因:
+    (1) 便于新增键值,方便调整顺序,使代码看起来舒服点
+    (2) 编译器可帮我们避免键值重复。
+*/
+typedef enum
+{
+    KEY_NONE = 0, /* 0 表示按键事件 */
+
+    KEY_1_DOWN, /* 1键按下 */
+    KEY_1_UP,   /* 1键弹起 */
+    KEY_1_LONG, /* 1键长按 */
+
+    KEY_2_DOWN, /* 2键按下 */
+    KEY_2_UP,   /* 2键弹起 */
+    KEY_2_LONG, /* 2键长按 */
+
+    KEY_3_DOWN, /* 3键按下 */
+    KEY_3_UP,   /* 3键弹起 */
+    KEY_3_LONG, /* 3键长按 */
+
+    KEY_4_DOWN, /* 4键按下 */
+    KEY_4_UP,   /* 4键弹起 */
+    KEY_4_LONG, /* 4键长按 */
+
+    KEY_5_DOWN, /* 5键按下 */
+    KEY_5_UP,   /* 5键弹起 */
+    KEY_5_LONG, /* 5键长按 */
+
+    KEY_6_DOWN, /* 6键按下 */
+    KEY_6_UP,   /* 6键弹起 */
+    KEY_6_LONG, /* 6键长按 */
+
+    KEY_7_DOWN, /* 7键按下 */
+    KEY_7_UP,   /* 7键弹起 */
+    KEY_7_LONG, /* 7键长按 */
+
+    KEY_8_DOWN, /* 8键按下 */
+    KEY_8_UP,   /* 8键弹起 */
+    KEY_8_LONG, /* 8键长按 */
+
+    /* 组合键 */
+    KEY_9_DOWN, /* 9键按下 */
+    KEY_9_UP,   /* 9键弹起 */
+    KEY_9_LONG, /* 9键长按 */
+
+    KEY_10_DOWN, /* 10键按下 */
+    KEY_10_UP,   /* 10键弹起 */
+    KEY_10_LONG, /* 10键长按 */
+} KEY_ENUM;
+
+/* 按键FIFO用到变量 */
+#define KEY_FIFO_SIZE 10
+typedef struct
+{
+    uint8_t Buf[KEY_FIFO_SIZE]; /* 键值缓冲区 */
+    uint8_t Read;               /* 缓冲区读指针1 */
+    uint8_t Write;              /* 缓冲区写指针 */
+    uint8_t Read2;              /* 缓冲区读指针2 */
+} KEY_FIFO_T;
+
+/* 供外部调用的函数声明 */
+void    key_init(void);
+void    bsp_KeyScan(void);
+void    bsp_PutKey(uint8_t _KeyCode);
+uint8_t bsp_GetKey(void);
+uint8_t bsp_GetKey2(void);
+uint8_t bsp_GetKeyState(KEY_ID_E _ucKeyID);
+void    bsp_SetKeyParam(uint8_t _ucKeyID, uint16_t _LongTime, uint8_t _RepeatSpeed);
+void    bsp_ClearKey(void);
+
+#endif
+
+/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/

+ 202 - 0
User/Bsp/lcd/font.h

@@ -0,0 +1,202 @@
+#ifndef __FONT_H
+#define __FONT_H
+//常用ASCII表
+//偏移量32
+// ASCII字符集
+//偏移量32
+//大小:12*6
+const unsigned char asc2_1206[95][12] = {
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*" ",0*/
+    {0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"!",1*/
+    {0x00, 0x00, 0x30, 0x00, 0x40, 0x00, 0x30, 0x00, 0x40, 0x00, 0x00, 0x00}, /*""",2*/
+    {0x09, 0x00, 0x0B, 0xC0, 0x3D, 0x00, 0x0B, 0xC0, 0x3D, 0x00, 0x09, 0x00}, /*"#",3*/
+    {0x18, 0xC0, 0x24, 0x40, 0x7F, 0xE0, 0x22, 0x40, 0x31, 0x80, 0x00, 0x00}, /*"$",4*/
+    {0x18, 0x00, 0x24, 0xC0, 0x1B, 0x00, 0x0D, 0x80, 0x32, 0x40, 0x01, 0x80}, /*"%",5*/
+    {0x03, 0x80, 0x1C, 0x40, 0x27, 0x40, 0x1C, 0x80, 0x07, 0x40, 0x00, 0x40}, /*"&",6*/
+    {0x10, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"'",7*/
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x80, 0x20, 0x40, 0x40, 0x20}, /*"(",8*/
+    {0x00, 0x00, 0x40, 0x20, 0x20, 0x40, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00}, /*")",9*/
+    {0x09, 0x00, 0x06, 0x00, 0x1F, 0x80, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00}, /*"*",10*/
+    {0x04, 0x00, 0x04, 0x00, 0x3F, 0x80, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00}, /*"+",11*/
+    {0x00, 0x10, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*",",12*/
+    {0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00}, /*"-",13*/
+    {0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*".",14*/
+    {0x00, 0x20, 0x01, 0xC0, 0x06, 0x00, 0x38, 0x00, 0x40, 0x00, 0x00, 0x00}, /*"/",15*/
+    {0x1F, 0x80, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x1F, 0x80, 0x00, 0x00}, /*"0",16*/
+    {0x00, 0x00, 0x10, 0x40, 0x3F, 0xC0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00}, /*"1",17*/
+    {0x18, 0xC0, 0x21, 0x40, 0x22, 0x40, 0x24, 0x40, 0x18, 0x40, 0x00, 0x00}, /*"2",18*/
+    {0x10, 0x80, 0x20, 0x40, 0x24, 0x40, 0x24, 0x40, 0x1B, 0x80, 0x00, 0x00}, /*"3",19*/
+    {0x02, 0x00, 0x0D, 0x00, 0x11, 0x00, 0x3F, 0xC0, 0x01, 0x40, 0x00, 0x00}, /*"4",20*/
+    {0x3C, 0x80, 0x24, 0x40, 0x24, 0x40, 0x24, 0x40, 0x23, 0x80, 0x00, 0x00}, /*"5",21*/
+    {0x1F, 0x80, 0x24, 0x40, 0x24, 0x40, 0x34, 0x40, 0x03, 0x80, 0x00, 0x00}, /*"6",22*/
+    {0x30, 0x00, 0x20, 0x00, 0x27, 0xC0, 0x38, 0x00, 0x20, 0x00, 0x00, 0x00}, /*"7",23*/
+    {0x1B, 0x80, 0x24, 0x40, 0x24, 0x40, 0x24, 0x40, 0x1B, 0x80, 0x00, 0x00}, /*"8",24*/
+    {0x1C, 0x00, 0x22, 0xC0, 0x22, 0x40, 0x22, 0x40, 0x1F, 0x80, 0x00, 0x00}, /*"9",25*/
+    {0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*":",26*/
+    {0x00, 0x00, 0x00, 0x00, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*";",27*/
+    {0x00, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x20, 0x80, 0x40, 0x40}, /*"<",28*/
+    {0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00}, /*"=",29*/
+    {0x00, 0x00, 0x40, 0x40, 0x20, 0x80, 0x11, 0x00, 0x0A, 0x00, 0x04, 0x00}, /*">",30*/
+    {0x18, 0x00, 0x20, 0x00, 0x23, 0x40, 0x24, 0x00, 0x18, 0x00, 0x00, 0x00}, /*"?",31*/
+    {0x1F, 0x80, 0x20, 0x40, 0x27, 0x40, 0x29, 0x40, 0x1F, 0x40, 0x00, 0x00}, /*"@",32*/
+    {0x00, 0x40, 0x07, 0xC0, 0x39, 0x00, 0x0F, 0x00, 0x01, 0xC0, 0x00, 0x40}, /*"A",33*/
+    {0x20, 0x40, 0x3F, 0xC0, 0x24, 0x40, 0x24, 0x40, 0x1B, 0x80, 0x00, 0x00}, /*"B",34*/
+    {0x1F, 0x80, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x30, 0x80, 0x00, 0x00}, /*"C",35*/
+    {0x20, 0x40, 0x3F, 0xC0, 0x20, 0x40, 0x20, 0x40, 0x1F, 0x80, 0x00, 0x00}, /*"D",36*/
+    {0x20, 0x40, 0x3F, 0xC0, 0x24, 0x40, 0x2E, 0x40, 0x30, 0xC0, 0x00, 0x00}, /*"E",37*/
+    {0x20, 0x40, 0x3F, 0xC0, 0x24, 0x40, 0x2E, 0x00, 0x30, 0x00, 0x00, 0x00}, /*"F",38*/
+    {0x0F, 0x00, 0x10, 0x80, 0x20, 0x40, 0x22, 0x40, 0x33, 0x80, 0x02, 0x00}, /*"G",39*/
+    {0x20, 0x40, 0x3F, 0xC0, 0x04, 0x00, 0x04, 0x00, 0x3F, 0xC0, 0x20, 0x40}, /*"H",40*/
+    {0x20, 0x40, 0x20, 0x40, 0x3F, 0xC0, 0x20, 0x40, 0x20, 0x40, 0x00, 0x00}, /*"I",41*/
+    {0x00, 0x60, 0x20, 0x20, 0x20, 0x20, 0x3F, 0xC0, 0x20, 0x00, 0x20, 0x00}, /*"J",42*/
+    {0x20, 0x40, 0x3F, 0xC0, 0x24, 0x40, 0x0B, 0x00, 0x30, 0xC0, 0x20, 0x40}, /*"K",43*/
+    {0x20, 0x40, 0x3F, 0xC0, 0x20, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xC0}, /*"L",44*/
+    {0x3F, 0xC0, 0x3C, 0x00, 0x03, 0xC0, 0x3C, 0x00, 0x3F, 0xC0, 0x00, 0x00}, /*"M",45*/
+    {0x20, 0x40, 0x3F, 0xC0, 0x0C, 0x40, 0x23, 0x00, 0x3F, 0xC0, 0x20, 0x00}, /*"N",46*/
+    {0x1F, 0x80, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x1F, 0x80, 0x00, 0x00}, /*"O",47*/
+    {0x20, 0x40, 0x3F, 0xC0, 0x24, 0x40, 0x24, 0x00, 0x18, 0x00, 0x00, 0x00}, /*"P",48*/
+    {0x1F, 0x80, 0x21, 0x40, 0x21, 0x40, 0x20, 0xE0, 0x1F, 0xA0, 0x00, 0x00}, /*"Q",49*/
+    {0x20, 0x40, 0x3F, 0xC0, 0x24, 0x40, 0x26, 0x00, 0x19, 0xC0, 0x00, 0x40}, /*"R",50*/
+    {0x18, 0xC0, 0x24, 0x40, 0x24, 0x40, 0x22, 0x40, 0x31, 0x80, 0x00, 0x00}, /*"S",51*/
+    {0x30, 0x00, 0x20, 0x40, 0x3F, 0xC0, 0x20, 0x40, 0x30, 0x00, 0x00, 0x00}, /*"T",52*/
+    {0x20, 0x00, 0x3F, 0x80, 0x00, 0x40, 0x00, 0x40, 0x3F, 0x80, 0x20, 0x00}, /*"U",53*/
+    {0x20, 0x00, 0x3E, 0x00, 0x01, 0xC0, 0x07, 0x00, 0x38, 0x00, 0x20, 0x00}, /*"V",54*/
+    {0x38, 0x00, 0x07, 0xC0, 0x3C, 0x00, 0x07, 0xC0, 0x38, 0x00, 0x00, 0x00}, /*"W",55*/
+    {0x20, 0x40, 0x39, 0xC0, 0x06, 0x00, 0x39, 0xC0, 0x20, 0x40, 0x00, 0x00}, /*"X",56*/
+    {0x20, 0x00, 0x38, 0x40, 0x07, 0xC0, 0x38, 0x40, 0x20, 0x00, 0x00, 0x00}, /*"Y",57*/
+    {0x30, 0x40, 0x21, 0xC0, 0x26, 0x40, 0x38, 0x40, 0x20, 0xC0, 0x00, 0x00}, /*"Z",58*/
+    {0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x40, 0x20, 0x40, 0x20, 0x00, 0x00}, /*"[",59*/
+    {0x00, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x03, 0x80, 0x00, 0x40, 0x00, 0x00}, /*"\",60*/
+    {0x00, 0x00, 0x40, 0x20, 0x40, 0x20, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00}, /*"]",61*/
+    {0x00, 0x00, 0x20, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"^",62*/
+    {0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10}, /*"_",63*/
+    {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"`",64*/
+    {0x00, 0x00, 0x02, 0x80, 0x05, 0x40, 0x05, 0x40, 0x03, 0xC0, 0x00, 0x40}, /*"a",65*/
+    {0x20, 0x00, 0x3F, 0xC0, 0x04, 0x40, 0x04, 0x40, 0x03, 0x80, 0x00, 0x00}, /*"b",66*/
+    {0x00, 0x00, 0x03, 0x80, 0x04, 0x40, 0x04, 0x40, 0x06, 0x40, 0x00, 0x00}, /*"c",67*/
+    {0x00, 0x00, 0x03, 0x80, 0x04, 0x40, 0x24, 0x40, 0x3F, 0xC0, 0x00, 0x40}, /*"d",68*/
+    {0x00, 0x00, 0x03, 0x80, 0x05, 0x40, 0x05, 0x40, 0x03, 0x40, 0x00, 0x00}, /*"e",69*/
+    {0x00, 0x00, 0x04, 0x40, 0x1F, 0xC0, 0x24, 0x40, 0x24, 0x40, 0x20, 0x00}, /*"f",70*/
+    {0x00, 0x00, 0x02, 0xE0, 0x05, 0x50, 0x05, 0x50, 0x06, 0x50, 0x04, 0x20}, /*"g",71*/
+    {0x20, 0x40, 0x3F, 0xC0, 0x04, 0x40, 0x04, 0x00, 0x03, 0xC0, 0x00, 0x40}, /*"h",72*/
+    {0x00, 0x00, 0x04, 0x40, 0x27, 0xC0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00}, /*"i",73*/
+    {0x00, 0x10, 0x00, 0x10, 0x04, 0x10, 0x27, 0xE0, 0x00, 0x00, 0x00, 0x00}, /*"j",74*/
+    {0x20, 0x40, 0x3F, 0xC0, 0x01, 0x40, 0x07, 0x00, 0x04, 0xC0, 0x04, 0x40}, /*"k",75*/
+    {0x20, 0x40, 0x20, 0x40, 0x3F, 0xC0, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00}, /*"l",76*/
+    {0x07, 0xC0, 0x04, 0x00, 0x07, 0xC0, 0x04, 0x00, 0x03, 0xC0, 0x00, 0x00}, /*"m",77*/
+    {0x04, 0x40, 0x07, 0xC0, 0x04, 0x40, 0x04, 0x00, 0x03, 0xC0, 0x00, 0x40}, /*"n",78*/
+    {0x00, 0x00, 0x03, 0x80, 0x04, 0x40, 0x04, 0x40, 0x03, 0x80, 0x00, 0x00}, /*"o",79*/
+    {0x04, 0x10, 0x07, 0xF0, 0x04, 0x50, 0x04, 0x40, 0x03, 0x80, 0x00, 0x00}, /*"p",80*/
+    {0x00, 0x00, 0x03, 0x80, 0x04, 0x40, 0x04, 0x50, 0x07, 0xF0, 0x00, 0x10}, /*"q",81*/
+    {0x04, 0x40, 0x07, 0xC0, 0x02, 0x40, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00}, /*"r",82*/
+    {0x00, 0x00, 0x06, 0x40, 0x05, 0x40, 0x05, 0x40, 0x04, 0xC0, 0x00, 0x00}, /*"s",83*/
+    {0x00, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x04, 0x40, 0x00, 0x40, 0x00, 0x00}, /*"t",84*/
+    {0x04, 0x00, 0x07, 0x80, 0x00, 0x40, 0x04, 0x40, 0x07, 0xC0, 0x00, 0x40}, /*"u",85*/
+    {0x04, 0x00, 0x07, 0x00, 0x04, 0xC0, 0x01, 0x80, 0x06, 0x00, 0x04, 0x00}, /*"v",86*/
+    {0x06, 0x00, 0x01, 0xC0, 0x07, 0x00, 0x01, 0xC0, 0x06, 0x00, 0x00, 0x00}, /*"w",87*/
+    {0x04, 0x40, 0x06, 0xC0, 0x01, 0x00, 0x06, 0xC0, 0x04, 0x40, 0x00, 0x00}, /*"x",88*/
+    {0x04, 0x10, 0x07, 0x10, 0x04, 0xE0, 0x01, 0x80, 0x06, 0x00, 0x04, 0x00}, /*"y",89*/
+    {0x00, 0x00, 0x04, 0x40, 0x05, 0xC0, 0x06, 0x40, 0x04, 0x40, 0x00, 0x00}, /*"z",90*/
+    {0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x7B, 0xE0, 0x40, 0x20, 0x00, 0x00}, /*"{",91*/
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00}, /*"|",92*/
+    {0x00, 0x00, 0x40, 0x20, 0x7B, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"}",93*/
+    {0x40, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x40, 0x00}, /*"~",94*/
+};
+const unsigned char asc2_1608[95][16] = {
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*" ",0*/
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xCC, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"!",1*/
+    {0x00, 0x00, 0x08, 0x00, 0x30, 0x00, 0x60, 0x00, 0x08, 0x00, 0x30, 0x00, 0x60, 0x00, 0x00, 0x00}, /*""",2*/
+    {0x02, 0x20, 0x03, 0xFC, 0x1E, 0x20, 0x02, 0x20, 0x03, 0xFC, 0x1E, 0x20, 0x02, 0x20, 0x00, 0x00}, /*"#",3*/
+    {0x00, 0x00, 0x0E, 0x18, 0x11, 0x04, 0x3F, 0xFF, 0x10, 0x84, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00}, /*"$",4*/
+    {0x0F, 0x00, 0x10, 0x84, 0x0F, 0x38, 0x00, 0xC0, 0x07, 0x78, 0x18, 0x84, 0x00, 0x78, 0x00, 0x00}, /*"%",5*/
+    {0x00, 0x78, 0x0F, 0x84, 0x10, 0xC4, 0x11, 0x24, 0x0E, 0x98, 0x00, 0xE4, 0x00, 0x84, 0x00, 0x08}, /*"&",6*/
+    {0x08, 0x00, 0x68, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"'",7*/
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x18, 0x18, 0x20, 0x04, 0x40, 0x02, 0x00, 0x00}, /*"(",8*/
+    {0x00, 0x00, 0x40, 0x02, 0x20, 0x04, 0x18, 0x18, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*")",9*/
+    {0x02, 0x40, 0x02, 0x40, 0x01, 0x80, 0x0F, 0xF0, 0x01, 0x80, 0x02, 0x40, 0x02, 0x40, 0x00, 0x00}, /*"*",10*/
+    {0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x0F, 0xF8, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00}, /*"+",11*/
+    {0x00, 0x01, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*",",12*/
+    {0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80}, /*"-",13*/
+    {0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*".",14*/
+    {0x00, 0x00, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x01, 0x80, 0x06, 0x00, 0x18, 0x00, 0x20, 0x00}, /*"/",15*/
+    {0x00, 0x00, 0x07, 0xF0, 0x08, 0x08, 0x10, 0x04, 0x10, 0x04, 0x08, 0x08, 0x07, 0xF0, 0x00, 0x00}, /*"0",16*/
+    {0x00, 0x00, 0x08, 0x04, 0x08, 0x04, 0x1F, 0xFC, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, /*"1",17*/
+    {0x00, 0x00, 0x0E, 0x0C, 0x10, 0x14, 0x10, 0x24, 0x10, 0x44, 0x11, 0x84, 0x0E, 0x0C, 0x00, 0x00}, /*"2",18*/
+    {0x00, 0x00, 0x0C, 0x18, 0x10, 0x04, 0x11, 0x04, 0x11, 0x04, 0x12, 0x88, 0x0C, 0x70, 0x00, 0x00}, /*"3",19*/
+    {0x00, 0x00, 0x00, 0xE0, 0x03, 0x20, 0x04, 0x24, 0x08, 0x24, 0x1F, 0xFC, 0x00, 0x24, 0x00, 0x00}, /*"4",20*/
+    {0x00, 0x00, 0x1F, 0x98, 0x10, 0x84, 0x11, 0x04, 0x11, 0x04, 0x10, 0x88, 0x10, 0x70, 0x00, 0x00}, /*"5",21*/
+    {0x00, 0x00, 0x07, 0xF0, 0x08, 0x88, 0x11, 0x04, 0x11, 0x04, 0x18, 0x88, 0x00, 0x70, 0x00, 0x00}, /*"6",22*/
+    {0x00, 0x00, 0x1C, 0x00, 0x10, 0x00, 0x10, 0xFC, 0x13, 0x00, 0x1C, 0x00, 0x10, 0x00, 0x00, 0x00}, /*"7",23*/
+    {0x00, 0x00, 0x0E, 0x38, 0x11, 0x44, 0x10, 0x84, 0x10, 0x84, 0x11, 0x44, 0x0E, 0x38, 0x00, 0x00}, /*"8",24*/
+    {0x00, 0x00, 0x07, 0x00, 0x08, 0x8C, 0x10, 0x44, 0x10, 0x44, 0x08, 0x88, 0x07, 0xF0, 0x00, 0x00}, /*"9",25*/
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x03, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*":",26*/
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*";",27*/
+    {0x00, 0x00, 0x00, 0x80, 0x01, 0x40, 0x02, 0x20, 0x04, 0x10, 0x08, 0x08, 0x10, 0x04, 0x00, 0x00}, /*"<",28*/
+    {0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x00, 0x00}, /*"=",29*/
+    {0x00, 0x00, 0x10, 0x04, 0x08, 0x08, 0x04, 0x10, 0x02, 0x20, 0x01, 0x40, 0x00, 0x80, 0x00, 0x00}, /*">",30*/
+    {0x00, 0x00, 0x0E, 0x00, 0x12, 0x00, 0x10, 0x0C, 0x10, 0x6C, 0x10, 0x80, 0x0F, 0x00, 0x00, 0x00}, /*"?",31*/
+    {0x03, 0xE0, 0x0C, 0x18, 0x13, 0xE4, 0x14, 0x24, 0x17, 0xC4, 0x08, 0x28, 0x07, 0xD0, 0x00, 0x00}, /*"@",32*/
+    {0x00, 0x04, 0x00, 0x3C, 0x03, 0xC4, 0x1C, 0x40, 0x07, 0x40, 0x00, 0xE4, 0x00, 0x1C, 0x00, 0x04}, /*"A",33*/
+    {0x10, 0x04, 0x1F, 0xFC, 0x11, 0x04, 0x11, 0x04, 0x11, 0x04, 0x0E, 0x88, 0x00, 0x70, 0x00, 0x00}, /*"B",34*/
+    {0x03, 0xE0, 0x0C, 0x18, 0x10, 0x04, 0x10, 0x04, 0x10, 0x04, 0x10, 0x08, 0x1C, 0x10, 0x00, 0x00}, /*"C",35*/
+    {0x10, 0x04, 0x1F, 0xFC, 0x10, 0x04, 0x10, 0x04, 0x10, 0x04, 0x08, 0x08, 0x07, 0xF0, 0x00, 0x00}, /*"D",36*/
+    {0x10, 0x04, 0x1F, 0xFC, 0x11, 0x04, 0x11, 0x04, 0x17, 0xC4, 0x10, 0x04, 0x08, 0x18, 0x00, 0x00}, /*"E",37*/
+    {0x10, 0x04, 0x1F, 0xFC, 0x11, 0x04, 0x11, 0x00, 0x17, 0xC0, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00}, /*"F",38*/
+    {0x03, 0xE0, 0x0C, 0x18, 0x10, 0x04, 0x10, 0x04, 0x10, 0x44, 0x1C, 0x78, 0x00, 0x40, 0x00, 0x00}, /*"G",39*/
+    {0x10, 0x04, 0x1F, 0xFC, 0x10, 0x84, 0x00, 0x80, 0x00, 0x80, 0x10, 0x84, 0x1F, 0xFC, 0x10, 0x04}, /*"H",40*/
+    {0x00, 0x00, 0x10, 0x04, 0x10, 0x04, 0x1F, 0xFC, 0x10, 0x04, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00}, /*"I",41*/
+    {0x00, 0x03, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x1F, 0xFE, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00}, /*"J",42*/
+    {0x10, 0x04, 0x1F, 0xFC, 0x11, 0x04, 0x03, 0x80, 0x14, 0x64, 0x18, 0x1C, 0x10, 0x04, 0x00, 0x00}, /*"K",43*/
+    {0x10, 0x04, 0x1F, 0xFC, 0x10, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00}, /*"L",44*/
+    {0x10, 0x04, 0x1F, 0xFC, 0x1F, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x1F, 0xFC, 0x10, 0x04, 0x00, 0x00}, /*"M",45*/
+    {0x10, 0x04, 0x1F, 0xFC, 0x0C, 0x04, 0x03, 0x00, 0x00, 0xE0, 0x10, 0x18, 0x1F, 0xFC, 0x10, 0x00}, /*"N",46*/
+    {0x07, 0xF0, 0x08, 0x08, 0x10, 0x04, 0x10, 0x04, 0x10, 0x04, 0x08, 0x08, 0x07, 0xF0, 0x00, 0x00}, /*"O",47*/
+    {0x10, 0x04, 0x1F, 0xFC, 0x10, 0x84, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x0F, 0x00, 0x00, 0x00}, /*"P",48*/
+    {0x07, 0xF0, 0x08, 0x18, 0x10, 0x24, 0x10, 0x24, 0x10, 0x1C, 0x08, 0x0A, 0x07, 0xF2, 0x00, 0x00}, /*"Q",49*/
+    {0x10, 0x04, 0x1F, 0xFC, 0x11, 0x04, 0x11, 0x00, 0x11, 0xC0, 0x11, 0x30, 0x0E, 0x0C, 0x00, 0x04}, /*"R",50*/
+    {0x00, 0x00, 0x0E, 0x1C, 0x11, 0x04, 0x10, 0x84, 0x10, 0x84, 0x10, 0x44, 0x1C, 0x38, 0x00, 0x00}, /*"S",51*/
+    {0x18, 0x00, 0x10, 0x00, 0x10, 0x04, 0x1F, 0xFC, 0x10, 0x04, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00}, /*"T",52*/
+    {0x10, 0x00, 0x1F, 0xF8, 0x10, 0x04, 0x00, 0x04, 0x00, 0x04, 0x10, 0x04, 0x1F, 0xF8, 0x10, 0x00}, /*"U",53*/
+    {0x10, 0x00, 0x1E, 0x00, 0x11, 0xE0, 0x00, 0x1C, 0x00, 0x70, 0x13, 0x80, 0x1C, 0x00, 0x10, 0x00}, /*"V",54*/
+    {0x1F, 0xC0, 0x10, 0x3C, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0xE0, 0x10, 0x3C, 0x1F, 0xC0, 0x00, 0x00}, /*"W",55*/
+    {0x10, 0x04, 0x18, 0x0C, 0x16, 0x34, 0x01, 0xC0, 0x01, 0xC0, 0x16, 0x34, 0x18, 0x0C, 0x10, 0x04}, /*"X",56*/
+    {0x10, 0x00, 0x1C, 0x00, 0x13, 0x04, 0x00, 0xFC, 0x13, 0x04, 0x1C, 0x00, 0x10, 0x00, 0x00, 0x00}, /*"Y",57*/
+    {0x08, 0x04, 0x10, 0x1C, 0x10, 0x64, 0x10, 0x84, 0x13, 0x04, 0x1C, 0x04, 0x10, 0x18, 0x00, 0x00}, /*"Z",58*/
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x00, 0x00}, /*"[",59*/
+    {0x00, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x03, 0x80, 0x00, 0x60, 0x00, 0x1C, 0x00, 0x03, 0x00, 0x00}, /*"\",60*/
+    {0x00, 0x00, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"]",61*/
+    {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00}, /*"^",62*/
+    {0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01}, /*"_",63*/
+    {0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"`",64*/
+    {0x00, 0x00, 0x00, 0x98, 0x01, 0x24, 0x01, 0x44, 0x01, 0x44, 0x01, 0x44, 0x00, 0xFC, 0x00, 0x04}, /*"a",65*/
+    {0x10, 0x00, 0x1F, 0xFC, 0x00, 0x88, 0x01, 0x04, 0x01, 0x04, 0x00, 0x88, 0x00, 0x70, 0x00, 0x00}, /*"b",66*/
+    {0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x01, 0x04, 0x01, 0x04, 0x01, 0x04, 0x00, 0x88, 0x00, 0x00}, /*"c",67*/
+    {0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x01, 0x04, 0x01, 0x04, 0x11, 0x08, 0x1F, 0xFC, 0x00, 0x04}, /*"d",68*/
+    {0x00, 0x00, 0x00, 0xF8, 0x01, 0x44, 0x01, 0x44, 0x01, 0x44, 0x01, 0x44, 0x00, 0xC8, 0x00, 0x00}, /*"e",69*/
+    {0x00, 0x00, 0x01, 0x04, 0x01, 0x04, 0x0F, 0xFC, 0x11, 0x04, 0x11, 0x04, 0x11, 0x00, 0x18, 0x00}, /*"f",70*/
+    {0x00, 0x00, 0x00, 0xD6, 0x01, 0x29, 0x01, 0x29, 0x01, 0x29, 0x01, 0xC9, 0x01, 0x06, 0x00, 0x00}, /*"g",71*/
+    {0x10, 0x04, 0x1F, 0xFC, 0x00, 0x84, 0x01, 0x00, 0x01, 0x00, 0x01, 0x04, 0x00, 0xFC, 0x00, 0x04}, /*"h",72*/
+    {0x00, 0x00, 0x01, 0x04, 0x19, 0x04, 0x19, 0xFC, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, /*"i",73*/
+    {0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x01, 0x01, 0x19, 0x01, 0x19, 0xFE, 0x00, 0x00, 0x00, 0x00}, /*"j",74*/
+    {0x10, 0x04, 0x1F, 0xFC, 0x00, 0x24, 0x00, 0x40, 0x01, 0xB4, 0x01, 0x0C, 0x01, 0x04, 0x00, 0x00}, /*"k",75*/
+    {0x00, 0x00, 0x10, 0x04, 0x10, 0x04, 0x1F, 0xFC, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, /*"l",76*/
+    {0x01, 0x04, 0x01, 0xFC, 0x01, 0x04, 0x01, 0x00, 0x01, 0xFC, 0x01, 0x04, 0x01, 0x00, 0x00, 0xFC}, /*"m",77*/
+    {0x01, 0x04, 0x01, 0xFC, 0x00, 0x84, 0x01, 0x00, 0x01, 0x00, 0x01, 0x04, 0x00, 0xFC, 0x00, 0x04}, /*"n",78*/
+    {0x00, 0x00, 0x00, 0xF8, 0x01, 0x04, 0x01, 0x04, 0x01, 0x04, 0x01, 0x04, 0x00, 0xF8, 0x00, 0x00}, /*"o",79*/
+    {0x01, 0x01, 0x01, 0xFF, 0x00, 0x85, 0x01, 0x04, 0x01, 0x04, 0x00, 0x88, 0x00, 0x70, 0x00, 0x00}, /*"p",80*/
+    {0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x01, 0x04, 0x01, 0x04, 0x01, 0x05, 0x01, 0xFF, 0x00, 0x01}, /*"q",81*/
+    {0x01, 0x04, 0x01, 0x04, 0x01, 0xFC, 0x00, 0x84, 0x01, 0x04, 0x01, 0x00, 0x01, 0x80, 0x00, 0x00}, /*"r",82*/
+    {0x00, 0x00, 0x00, 0xCC, 0x01, 0x24, 0x01, 0x24, 0x01, 0x24, 0x01, 0x24, 0x01, 0x98, 0x00, 0x00}, /*"s",83*/
+    {0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x07, 0xF8, 0x01, 0x04, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00}, /*"t",84*/
+    {0x01, 0x00, 0x01, 0xF8, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x01, 0x08, 0x01, 0xFC, 0x00, 0x04}, /*"u",85*/
+    {0x01, 0x00, 0x01, 0x80, 0x01, 0x70, 0x00, 0x0C, 0x00, 0x10, 0x01, 0x60, 0x01, 0x80, 0x01, 0x00}, /*"v",86*/
+    {0x01, 0xF0, 0x01, 0x0C, 0x00, 0x30, 0x01, 0xC0, 0x00, 0x30, 0x01, 0x0C, 0x01, 0xF0, 0x01, 0x00}, /*"w",87*/
+    {0x00, 0x00, 0x01, 0x04, 0x01, 0x8C, 0x00, 0x74, 0x01, 0x70, 0x01, 0x8C, 0x01, 0x04, 0x00, 0x00}, /*"x",88*/
+    {0x01, 0x01, 0x01, 0x81, 0x01, 0x71, 0x00, 0x0E, 0x00, 0x18, 0x01, 0x60, 0x01, 0x80, 0x01, 0x00}, /*"y",89*/
+    {0x00, 0x00, 0x01, 0x84, 0x01, 0x0C, 0x01, 0x34, 0x01, 0x44, 0x01, 0x84, 0x01, 0x0C, 0x00, 0x00}, /*"z",90*/
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3E, 0xFC, 0x40, 0x02, 0x40, 0x02}, /*"{",91*/
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"|",92*/
+    {0x00, 0x00, 0x40, 0x02, 0x40, 0x02, 0x3E, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*"}",93*/
+    {0x00, 0x00, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00}, /*"~",94*/
+};
+#endif

+ 2988 - 0
User/Bsp/lcd/lcd.c

@@ -0,0 +1,2988 @@
+#include "lcd.h"
+#include "dwt.h"
+#include "font.h"
+#include "stdlib.h"
+//////////////////////////////////////////////////////////////////////////////////
+//本程序只供学习使用,未经作者许可,不得用于其它任何用途
+// ALIENTEK战舰STM32开发板
+// 2.4寸/2.8寸/3.5寸/4.3寸 TFT液晶驱动
+//支持驱动IC型号包括:ILI9341/ILI9325/RM68042/RM68021/ILI9320/ILI9328/LGDP4531/LGDP4535/
+//                  SPFD5408/SSD1289/1505/B505/C505/NT35310/NT35510等
+//正点原子@ALIENTEK
+//技术论坛:www.openedv.com
+//修改日期:2014/2/11
+//版本:V2.5
+//版权所有,盗版必究。
+// Copyright(C) 广州市星翼电子科技有限公司 2009-2019
+// All rights reserved
+//********************************************************************************
+// V1.2修改说明
+//支持了SPFD5408的驱动,另外把液晶ID直接打印成HEX格式.方便查看LCD驱动IC.
+// V1.3
+//加入了快速IO的支持
+//修改了背光控制的极性(适用于V1.8及以后的开发板版本)
+//对于1.8版本之前(不包括1.8)的液晶模块,请修改LCD_Init函数的LCD_LED=1;为LCD_LED=1;
+// V1.4
+//修改了LCD_ShowChar函数,使用画点功能画字符。
+//加入了横竖屏显示的支持
+// V1.5 20110730
+// 1,修改了B505液晶读颜色有误的bug.
+// 2,修改了快速IO及横竖屏的设置方式.
+// V1.6 20111116
+// 1,加入对LGDP4535液晶的驱动支持
+// V1.7 20120713
+// 1,增加LCD_RD_DATA函数
+// 2,增加对ILI9341的支持
+// 3,增加ILI9325的独立驱动代码
+// 4,增加LCD_Scan_Dir函数(慎重使用)
+// 6,另外修改了部分原来的函数,以适应9341的操作
+// V1.8 20120905
+// 1,加入LCD重要参数设置结构体lcddev
+// 2,加入LCD_Display_Dir函数,支持在线横竖屏切换
+// V1.9 20120911
+// 1,新增RM68042驱动(ID:6804),但是6804不支持横屏显示!!原因:改变扫描方式,
+//导致6804坐标设置失效,试过很多方法都不行,暂时无解。
+// V2.0 20120924
+//在不硬件复位的情况下,ILI9341的ID读取会被误读成9300,修改LCD_Init,将无法识别
+//的情况(读到ID为9300/非法ID),强制指定驱动IC为ILI9341,执行9341的初始化。
+// V2.1 20120930
+//修正ILI9325读颜色的bug。
+// V2.2 20121007
+//修正LCD_Scan_Dir的bug。
+// V2.3 20130120
+//新增6804支持横屏显示
+// V2.4 20131120
+// 1,新增NT35310(ID:5310)驱动器的支持
+// 2,新增LCD_Set_Window函数,用于设置窗口,对快速填充,比较有用,但是该函数在横屏时,不支持6804.
+// V2.5 20140211
+// 1,新增NT35510(ID:5510)驱动器的支持
+//////////////////////////////////////////////////////////////////////////////////
+
+// LCD的画笔颜色和背景色
+u16 POINT_COLOR = 0x0000; //画笔颜色
+u16 BACK_COLOR  = 0xFFFF; //背景色
+
+//管理LCD重要参数
+//默认为竖屏
+_lcd_dev lcddev;
+
+//写寄存器函数
+// regval:寄存器值
+void LCD_WR_REG(volatile u16 regval)
+{
+    regval       = regval; //使用-O2优化的时候,必须插入的延时
+    LCD->LCD_REG = regval; //写入要写的寄存器序号
+}
+//写LCD数据
+// data:要写入的值
+void LCD_WR_DATA(volatile u16 data)
+{
+    data         = data; //使用-O2优化的时候,必须插入的延时
+    LCD->LCD_RAM = data;
+}
+//读LCD数据
+//返回值:读到的值
+u16 LCD_RD_DATA(void)
+{
+    volatile u16 ram; //防止被优化
+    ram = LCD->LCD_RAM;
+    return ram;
+}
+//写寄存器
+// LCD_Reg:寄存器地址
+// LCD_RegValue:要写入的数据
+void LCD_WriteReg(u16 LCD_Reg, u16 LCD_RegValue)
+{
+    LCD->LCD_REG = LCD_Reg;      //写入要写的寄存器序号
+    LCD->LCD_RAM = LCD_RegValue; //写入数据
+}
+//读寄存器
+// LCD_Reg:寄存器地址
+//返回值:读到的数据
+u16 LCD_ReadReg(u16 LCD_Reg)
+{
+    LCD_WR_REG(LCD_Reg); //写入要读的寄存器序号
+    us_delay(5);
+    return LCD_RD_DATA(); //返回读到的值
+}
+//开始写GRAM
+void LCD_WriteRAM_Prepare(void)
+{
+    LCD->LCD_REG = lcddev.wramcmd;
+}
+// LCD写GRAM
+// RGB_Code:颜色值
+void LCD_WriteRAM(u16 RGB_Code)
+{
+    LCD->LCD_RAM = RGB_Code; //写十六位GRAM
+}
+//从ILI93xx读出的数据为GBR格式,而我们写入的时候为RGB格式。
+//通过该函数转换
+// c:GBR格式的颜色值
+//返回值:RGB格式的颜色值
+u16 LCD_BGR2RGB(u16 c)
+{
+    u16 r, g, b, rgb;
+    b   = (c >> 0) & 0x1f;
+    g   = (c >> 5) & 0x3f;
+    r   = (c >> 11) & 0x1f;
+    rgb = (b << 11) + (g << 5) + (r << 0);
+    return (rgb);
+}
+//当mdk -O1时间优化时需要设置
+//延时i
+void opt_delay(u8 i)
+{
+    while (i--)
+        ;
+}
+//读取个某点的颜色值
+// x,y:坐标
+//返回值:此点的颜色
+u16 LCD_ReadPoint(u16 x, u16 y)
+{
+    u16 r = 0, g = 0, b = 0;
+    if (x >= lcddev.width || y >= lcddev.height)
+        return 0; //超过了范围,直接返回
+    LCD_SetCursor(x, y);
+    if (lcddev.id == 0X9341 || lcddev.id == 0X6804 || lcddev.id == 0X5310)
+        LCD_WR_REG(0X2E); // 9341/6804/3510 发送读GRAM指令
+    else if (lcddev.id == 0X5510)
+        LCD_WR_REG(0X2E00); // 5510 发送读GRAM指令
+    else
+        LCD_WR_REG(R34); //其他IC发送读GRAM指令
+    if (lcddev.id == 0X9320)
+        opt_delay(2); // FOR 9320,延时2us
+    if (LCD->LCD_RAM)
+        r = 0; // dummy Read
+    opt_delay(2);
+    r = LCD->LCD_RAM;                                                      //实际坐标颜色
+    if (lcddev.id == 0X9341 || lcddev.id == 0X5310 || lcddev.id == 0X5510) // 9341/NT35310/NT35510要分2次读出
+    {
+        opt_delay(2);
+        b = LCD->LCD_RAM;
+        g = r & 0XFF; //对于9341/5310/5510,第一次读取的是RG的值,R在前,G在后,各占8位
+        g <<= 8;
+    }
+    else if (lcddev.id == 0X6804)
+        r = LCD->LCD_RAM; // 6804第二次读取的才是真实值
+    if (lcddev.id == 0X9325 || lcddev.id == 0X4535 || lcddev.id == 0X4531 || lcddev.id == 0X8989 || lcddev.id == 0XB505)
+        return r; //这几种IC直接返回颜色值
+    else if (lcddev.id == 0X9341 || lcddev.id == 0X5310 || lcddev.id == 0X5510)
+        return (((r >> 11) << 11) | ((g >> 10) << 5) | (b >> 11)); // ILI9341/NT35310/NT35510需要公式转换一下
+    else
+        return LCD_BGR2RGB(r); //其他IC
+}
+// LCD开启显示
+void LCD_DisplayOn(void)
+{
+    if (lcddev.id == 0X9341 || lcddev.id == 0X6804 || lcddev.id == 0X5310)
+        LCD_WR_REG(0X29); //开启显示
+    else if (lcddev.id == 0X5510)
+        LCD_WR_REG(0X2900); //开启显示
+    else
+        LCD_WriteReg(R7, 0x0173); //开启显示
+}
+// LCD关闭显示
+void LCD_DisplayOff(void)
+{
+    if (lcddev.id == 0X9341 || lcddev.id == 0X6804 || lcddev.id == 0X5310)
+        LCD_WR_REG(0X28); //关闭显示
+    else if (lcddev.id == 0X5510)
+        LCD_WR_REG(0X2800); //关闭显示
+    else
+        LCD_WriteReg(R7, 0x0); //关闭显示
+}
+//设置光标位置
+// Xpos:横坐标
+// Ypos:纵坐标
+void LCD_SetCursor(u16 Xpos, u16 Ypos)
+{
+    if (lcddev.id == 0X9341 || lcddev.id == 0X5310)
+    {
+        LCD_WR_REG(lcddev.setxcmd);
+        LCD_WR_DATA(Xpos >> 8);
+        LCD_WR_DATA(Xpos & 0XFF);
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(Ypos >> 8);
+        LCD_WR_DATA(Ypos & 0XFF);
+    }
+    else if (lcddev.id == 0X6804)
+    {
+        if (lcddev.dir == 1)
+            Xpos = lcddev.width - 1 - Xpos; //横屏时处理
+        LCD_WR_REG(lcddev.setxcmd);
+        LCD_WR_DATA(Xpos >> 8);
+        LCD_WR_DATA(Xpos & 0XFF);
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(Ypos >> 8);
+        LCD_WR_DATA(Ypos & 0XFF);
+    }
+    else if (lcddev.id == 0X5510)
+    {
+        LCD_WR_REG(lcddev.setxcmd);
+        LCD_WR_DATA(Xpos >> 8);
+        LCD_WR_REG(lcddev.setxcmd + 1);
+        LCD_WR_DATA(Xpos & 0XFF);
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(Ypos >> 8);
+        LCD_WR_REG(lcddev.setycmd + 1);
+        LCD_WR_DATA(Ypos & 0XFF);
+    }
+    else
+    {
+        if (lcddev.dir == 1)
+            Xpos = lcddev.width - 1 - Xpos; //横屏其实就是调转x,y坐标
+        LCD_WriteReg(lcddev.setxcmd, Xpos);
+        LCD_WriteReg(lcddev.setycmd, Ypos);
+    }
+}
+//设置LCD的自动扫描方向
+//注意:其他函数可能会受到此函数设置的影响(尤其是9341/6804这两个奇葩),
+//所以,一般设置为L2R_U2D即可,如果设置为其他扫描方式,可能导致显示不正常.
+// dir:0~7,代表8个方向(具体定义见lcd.h)
+// 9320/9325/9328/4531/4535/1505/b505/8989/5408/9341/5310/5510等IC已经实际测试
+void LCD_Scan_Dir(uint8_t dir)
+{
+    uint16_t regval = 0;
+    uint16_t dirreg = 0;
+    uint16_t temp;
+    if ((lcddev.dir == 1 && lcddev.id != 0X6804 && lcddev.id != 0X1963) || (lcddev.dir == 0 && lcddev.id == 0X1963)) //横屏时,对6804和1963不改变扫描方向!竖屏时1963改变方向
+    {
+        switch (dir) //方向转换
+        {
+        case 0:
+            dir = 6;
+            break;
+        case 1:
+            dir = 7;
+            break;
+        case 2:
+            dir = 4;
+            break;
+        case 3:
+            dir = 5;
+            break;
+        case 4:
+            dir = 1;
+            break;
+        case 5:
+            dir = 0;
+            break;
+        case 6:
+            dir = 3;
+            break;
+        case 7:
+            dir = 2;
+            break;
+        }
+    }
+    if (lcddev.id == 0x9341 || lcddev.id == 0X6804 || lcddev.id == 0X5310 || lcddev.id == 0X5510 || lcddev.id == 0X1963) // 9341/6804/5310/5510/1963,特殊处理
+    {
+        switch (dir)
+        {
+        case L2R_U2D: //从左到右,从上到下
+            regval |= (0 << 7) | (0 << 6) | (0 << 5);
+            break;
+        case L2R_D2U: //从左到右,从下到上
+            regval |= (1 << 7) | (0 << 6) | (0 << 5);
+            break;
+        case R2L_U2D: //从右到左,从上到下
+            regval |= (0 << 7) | (1 << 6) | (0 << 5);
+            break;
+        case R2L_D2U: //从右到左,从下到上
+            regval |= (1 << 7) | (1 << 6) | (0 << 5);
+            break;
+        case U2D_L2R: //从上到下,从左到右
+            regval |= (0 << 7) | (0 << 6) | (1 << 5);
+            break;
+        case U2D_R2L: //从上到下,从右到左
+            regval |= (0 << 7) | (1 << 6) | (1 << 5);
+            break;
+        case D2U_L2R: //从下到上,从左到右
+            regval |= (1 << 7) | (0 << 6) | (1 << 5);
+            break;
+        case D2U_R2L: //从下到上,从右到左
+            regval |= (1 << 7) | (1 << 6) | (1 << 5);
+            break;
+        }
+        if (lcddev.id == 0X5510)
+            dirreg = 0X3600;
+        else
+            dirreg = 0X36;
+        if ((lcddev.id != 0X5310) && (lcddev.id != 0X5510) && (lcddev.id != 0X1963))
+            regval |= 0X08; // 5310/5510/1963不需要BGR
+        if (lcddev.id == 0X6804)
+            regval |= 0x02; // 6804的BIT6和9341的反了
+        LCD_WriteReg(dirreg, regval);
+        if (lcddev.id != 0X1963) // 1963不做坐标处理
+        {
+            if (regval & 0X20)
+            {
+                if (lcddev.width < lcddev.height) //交换X,Y
+                {
+                    temp          = lcddev.width;
+                    lcddev.width  = lcddev.height;
+                    lcddev.height = temp;
+                }
+            }
+            else
+            {
+                if (lcddev.width > lcddev.height) //交换X,Y
+                {
+                    temp          = lcddev.width;
+                    lcddev.width  = lcddev.height;
+                    lcddev.height = temp;
+                }
+            }
+        }
+        if (lcddev.id == 0X5510)
+        {
+            LCD_WR_REG(lcddev.setxcmd);
+            LCD_WR_DATA(0);
+            LCD_WR_REG(lcddev.setxcmd + 1);
+            LCD_WR_DATA(0);
+            LCD_WR_REG(lcddev.setxcmd + 2);
+            LCD_WR_DATA((lcddev.width - 1) >> 8);
+            LCD_WR_REG(lcddev.setxcmd + 3);
+            LCD_WR_DATA((lcddev.width - 1) & 0XFF);
+            LCD_WR_REG(lcddev.setycmd);
+            LCD_WR_DATA(0);
+            LCD_WR_REG(lcddev.setycmd + 1);
+            LCD_WR_DATA(0);
+            LCD_WR_REG(lcddev.setycmd + 2);
+            LCD_WR_DATA((lcddev.height - 1) >> 8);
+            LCD_WR_REG(lcddev.setycmd + 3);
+            LCD_WR_DATA((lcddev.height - 1) & 0XFF);
+        }
+        else
+        {
+            LCD_WR_REG(lcddev.setxcmd);
+            LCD_WR_DATA(0);
+            LCD_WR_DATA(0);
+            LCD_WR_DATA((lcddev.width - 1) >> 8);
+            LCD_WR_DATA((lcddev.width - 1) & 0XFF);
+            LCD_WR_REG(lcddev.setycmd);
+            LCD_WR_DATA(0);
+            LCD_WR_DATA(0);
+            LCD_WR_DATA((lcddev.height - 1) >> 8);
+            LCD_WR_DATA((lcddev.height - 1) & 0XFF);
+        }
+    }
+    else
+    {
+        switch (dir)
+        {
+        case L2R_U2D: //从左到右,从上到下
+            regval |= (1 << 5) | (1 << 4) | (0 << 3);
+            break;
+        case L2R_D2U: //从左到右,从下到上
+            regval |= (0 << 5) | (1 << 4) | (0 << 3);
+            break;
+        case R2L_U2D: //从右到左,从上到下
+            regval |= (1 << 5) | (0 << 4) | (0 << 3);
+            break;
+        case R2L_D2U: //从右到左,从下到上
+            regval |= (0 << 5) | (0 << 4) | (0 << 3);
+            break;
+        case U2D_L2R: //从上到下,从左到右
+            regval |= (1 << 5) | (1 << 4) | (1 << 3);
+            break;
+        case U2D_R2L: //从上到下,从右到左
+            regval |= (1 << 5) | (0 << 4) | (1 << 3);
+            break;
+        case D2U_L2R: //从下到上,从左到右
+            regval |= (0 << 5) | (1 << 4) | (1 << 3);
+            break;
+        case D2U_R2L: //从下到上,从右到左
+            regval |= (0 << 5) | (0 << 4) | (1 << 3);
+            break;
+        }
+        dirreg = 0X03;
+        regval |= 1 << 12;
+        LCD_WriteReg(dirreg, regval);
+    }
+}
+//画点
+// x,y:坐标
+// POINT_COLOR:此点的颜色
+void LCD_DrawPoint(u16 x, u16 y)
+{
+    LCD_SetCursor(x, y);    //设置光标位置
+    LCD_WriteRAM_Prepare(); //开始写入GRAM
+    LCD->LCD_RAM = POINT_COLOR;
+}
+//快速画点
+// x,y:坐标
+// color:颜色
+void LCD_Fast_DrawPoint(u16 x, u16 y, u16 color)
+{
+    if (lcddev.id == 0X9341 || lcddev.id == 0X5310)
+    {
+        LCD_WR_REG(lcddev.setxcmd);
+        LCD_WR_DATA(x >> 8);
+        LCD_WR_DATA(x & 0XFF);
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(y >> 8);
+        LCD_WR_DATA(y & 0XFF);
+    }
+    else if (lcddev.id == 0X5510)
+    {
+        LCD_WR_REG(lcddev.setxcmd);
+        LCD_WR_DATA(x >> 8);
+        LCD_WR_REG(lcddev.setxcmd + 1);
+        LCD_WR_DATA(x & 0XFF);
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(y >> 8);
+        LCD_WR_REG(lcddev.setycmd + 1);
+        LCD_WR_DATA(y & 0XFF);
+    }
+    else if (lcddev.id == 0X6804)
+    {
+        if (lcddev.dir == 1)
+            x = lcddev.width - 1 - x; //横屏时处理
+        LCD_WR_REG(lcddev.setxcmd);
+        LCD_WR_DATA(x >> 8);
+        LCD_WR_DATA(x & 0XFF);
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(y >> 8);
+        LCD_WR_DATA(y & 0XFF);
+    }
+    else
+    {
+        if (lcddev.dir == 1)
+            x = lcddev.width - 1 - x; //横屏其实就是调转x,y坐标
+        LCD_WriteReg(lcddev.setxcmd, x);
+        LCD_WriteReg(lcddev.setycmd, y);
+    }
+    LCD->LCD_REG = lcddev.wramcmd;
+    LCD->LCD_RAM = color;
+}
+
+//设置LCD显示方向
+// dir:0,竖屏;1,横屏
+void LCD_Display_Dir(u8 dir)
+{
+    if (dir == 0) //竖屏
+    {
+        lcddev.dir    = 0; //竖屏
+        lcddev.width  = 240;
+        lcddev.height = 320;
+        if (lcddev.id == 0X9341 || lcddev.id == 0X6804 || lcddev.id == 0X5310)
+        {
+            lcddev.wramcmd = 0X2C;
+            lcddev.setxcmd = 0X2A;
+            lcddev.setycmd = 0X2B;
+            if (lcddev.id == 0X6804 || lcddev.id == 0X5310)
+            {
+                lcddev.width  = 320;
+                lcddev.height = 480;
+            }
+        }
+        else if (lcddev.id == 0X8989)
+        {
+            lcddev.wramcmd = R34;
+            lcddev.setxcmd = 0X4E;
+            lcddev.setycmd = 0X4F;
+        }
+        else if (lcddev.id == 0x5510)
+        {
+            lcddev.wramcmd = 0X2C00;
+            lcddev.setxcmd = 0X2A00;
+            lcddev.setycmd = 0X2B00;
+            lcddev.width   = 480;
+            lcddev.height  = 800;
+        }
+        else
+        {
+            lcddev.wramcmd = R34;
+            lcddev.setxcmd = R32;
+            lcddev.setycmd = R33;
+        }
+    }
+    else //横屏
+    {
+        lcddev.dir    = 1; //横屏
+        lcddev.width  = 320;
+        lcddev.height = 240;
+        if (lcddev.id == 0X9341 || lcddev.id == 0X5310)
+        {
+            lcddev.wramcmd = 0X2C;
+            lcddev.setxcmd = 0X2A;
+            lcddev.setycmd = 0X2B;
+        }
+        else if (lcddev.id == 0X6804)
+        {
+            lcddev.wramcmd = 0X2C;
+            lcddev.setxcmd = 0X2B;
+            lcddev.setycmd = 0X2A;
+        }
+        else if (lcddev.id == 0X8989)
+        {
+            lcddev.wramcmd = R34;
+            lcddev.setxcmd = 0X4F;
+            lcddev.setycmd = 0X4E;
+        }
+        else if (lcddev.id == 0x5510)
+        {
+            lcddev.wramcmd = 0X2C00;
+            lcddev.setxcmd = 0X2A00;
+            lcddev.setycmd = 0X2B00;
+            lcddev.width   = 800;
+            lcddev.height  = 480;
+        }
+        else
+        {
+            lcddev.wramcmd = R34;
+            lcddev.setxcmd = R33;
+            lcddev.setycmd = R32;
+        }
+        if (lcddev.id == 0X6804 || lcddev.id == 0X5310)
+        {
+            lcddev.width  = 480;
+            lcddev.height = 320;
+        }
+    }
+    LCD_Scan_Dir(DFT_SCAN_DIR); //默认扫描方向
+}
+//设置窗口,并自动设置画点坐标到窗口左上角(sx,sy).
+// sx,sy:窗口起始坐标(左上角)
+// width,height:窗口宽度和高度,必须大于0!!
+//窗体大小:width*height.
+// 68042,横屏时不支持窗口设置!!
+void LCD_Set_Window(u16 sx, u16 sy, u16 width, u16 height)
+{
+    u8  hsareg, heareg, vsareg, veareg;
+    u16 hsaval, heaval, vsaval, veaval;
+    width  = sx + width - 1;
+    height = sy + height - 1;
+    if (lcddev.id == 0X9341 || lcddev.id == 0X5310 || lcddev.id == 0X6804) // 6804横屏不支持
+    {
+        LCD_WR_REG(lcddev.setxcmd);
+        LCD_WR_DATA(sx >> 8);
+        LCD_WR_DATA(sx & 0XFF);
+        LCD_WR_DATA(width >> 8);
+        LCD_WR_DATA(width & 0XFF);
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(sy >> 8);
+        LCD_WR_DATA(sy & 0XFF);
+        LCD_WR_DATA(height >> 8);
+        LCD_WR_DATA(height & 0XFF);
+    }
+    else if (lcddev.id == 0X5510)
+    {
+        LCD_WR_REG(lcddev.setxcmd);
+        LCD_WR_DATA(sx >> 8);
+        LCD_WR_REG(lcddev.setxcmd + 1);
+        LCD_WR_DATA(sx & 0XFF);
+        LCD_WR_REG(lcddev.setxcmd + 2);
+        LCD_WR_DATA(width >> 8);
+        LCD_WR_REG(lcddev.setxcmd + 3);
+        LCD_WR_DATA(width & 0XFF);
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(sy >> 8);
+        LCD_WR_REG(lcddev.setycmd + 1);
+        LCD_WR_DATA(sy & 0XFF);
+        LCD_WR_REG(lcddev.setycmd + 2);
+        LCD_WR_DATA(height >> 8);
+        LCD_WR_REG(lcddev.setycmd + 3);
+        LCD_WR_DATA(height & 0XFF);
+    }
+    else //其他驱动IC
+    {
+        if (lcddev.dir == 1) //横屏
+        {
+            //窗口值
+            hsaval = sy;
+            heaval = height;
+            vsaval = lcddev.width - width - 1;
+            veaval = lcddev.width - sx - 1;
+        }
+        else
+        {
+            hsaval = sx;
+            heaval = width;
+            vsaval = sy;
+            veaval = height;
+        }
+        if (lcddev.id == 0X8989) // 8989 IC
+        {
+            hsareg = 0X44;
+            heareg = 0X44;           //水平方向窗口寄存器 (1289的由一个寄存器控制)
+            hsaval |= (heaval << 8); //得到寄存器值.
+            heaval = hsaval;
+            vsareg = 0X45;
+            veareg = 0X46; //垂直方向窗口寄存器
+        }
+        else //其他驱动IC
+        {
+            hsareg = 0X50;
+            heareg = 0X51; //水平方向窗口寄存器
+            vsareg = 0X52;
+            veareg = 0X53; //垂直方向窗口寄存器
+        }
+        //设置寄存器值
+        LCD_WriteReg(hsareg, hsaval);
+        LCD_WriteReg(heareg, heaval);
+        LCD_WriteReg(vsareg, vsaval);
+        LCD_WriteReg(veareg, veaval);
+        LCD_SetCursor(sx, sy); //设置光标位置
+    }
+}
+//初始化lcd
+//该初始化函数可以初始化各种ILI93XX液晶,但是其他函数是基于ILI9320的!!!
+//在其他型号的驱动芯片上没有测试!
+void LCD_Init(void)
+{
+    FSMC_NORSRAMInitTypeDef       init;
+    FSMC_NORSRAMTimingInitTypeDef timingWrite;
+    FSMC_NORSRAMTimingInitTypeDef timingRead;
+
+    // GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0;       // PB0 推挽输出 背光
+    // GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP; //推挽输出
+    // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+    // GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+    // // PORTD复用推挽输出
+    // GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15; //	//PORTD复用推挽输出
+    // GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;                                                                                                       //复用推挽输出
+    // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+    // GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+    // // PORTE复用推挽输出
+    // GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; //	//PORTD复用推挽输出
+    // GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;                                                                                                          //复用推挽输出
+    // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+    // GPIO_Init(GPIOE, &GPIO_InitStructure);
+
+    // //	//PORTG12复用推挽输出 A0
+    // GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_12; //	//PORTD复用推挽输出
+    // GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;          //复用推挽输出
+    // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+    // GPIO_Init(GPIOG, &GPIO_InitStructure);
+
+    timingWrite.FSMC_AddressSetupTime      = 4;
+    timingWrite.FSMC_AddressHoldTime       = 0;
+    timingWrite.FSMC_DataSetupTime         = 6;
+    timingWrite.FSMC_BusTurnAroundDuration = 1;
+    timingWrite.FSMC_CLKDivision           = 0;
+    timingWrite.FSMC_DataLatency           = 0;
+    timingWrite.FSMC_AccessMode            = FSMC_AccessMode_A;
+
+    timingRead.FSMC_AddressSetupTime      = 4;
+    timingRead.FSMC_AddressHoldTime       = 0;
+    timingRead.FSMC_DataSetupTime         = 8;
+    timingRead.FSMC_BusTurnAroundDuration = 1;
+    timingRead.FSMC_CLKDivision           = 0;
+    timingRead.FSMC_DataLatency           = 0;
+    timingRead.FSMC_AccessMode            = FSMC_AccessMode_A;
+
+    init.FSMC_Bank               = FSMC_Bank1_NORSRAM4;
+    init.FSMC_DataAddressMux     = FSMC_DataAddressMux_Disable;
+    init.FSMC_MemoryType         = FSMC_MemoryType_SRAM;
+    init.FSMC_MemoryDataWidth    = FSMC_MemoryDataWidth_16b;
+    init.FSMC_BurstAccessMode    = FSMC_BurstAccessMode_Disable;
+    init.FSMC_AsynchronousWait   = FSMC_AsynchronousWait_Disable;
+    init.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
+    init.FSMC_WrapMode           = FSMC_WrapMode_Disable;
+    init.FSMC_WaitSignalActive   = FSMC_WaitSignalActive_BeforeWaitState;
+    init.FSMC_WriteOperation     = FSMC_WriteOperation_Enable;
+    init.FSMC_WaitSignal         = FSMC_WaitSignal_Disable;
+    init.FSMC_ExtendedMode       = FSMC_ExtendedMode_Disable;
+    init.FSMC_WriteBurst         = FSMC_WriteBurst_Disable;
+
+    init.FSMC_ReadWriteTimingStruct = &timingRead;
+    init.FSMC_WriteTimingStruct     = &timingWrite;
+
+    FSMC_NORSRAMInit(&init);
+
+    /* - BANK 1 (of NOR/SRAM Bank 1~4) is enabled */
+    FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);
+
+    ms_delay(50); // delay 50 ms
+    LCD_WriteReg(0x0000, 0x0001);
+    ms_delay(50); // delay 50 ms
+    lcddev.id = LCD_ReadReg(0x0000);
+    if (lcddev.id < 0XFF || lcddev.id == 0XFFFF || lcddev.id == 0X9300) //读到ID不正确,新增lcddev.id==0X9300判断,因为9341在未被复位的情况下会被读成9300
+    {
+        //尝试9341 ID的读取
+        LCD_WR_REG(0XD3);
+        LCD_RD_DATA();             // dummy read
+        LCD_RD_DATA();             //读到0X00
+        lcddev.id = LCD_RD_DATA(); //读取93
+        lcddev.id <<= 8;
+        lcddev.id |= LCD_RD_DATA(); //读取41
+        if (lcddev.id != 0X9341)    //非9341,尝试是不是6804
+        {
+            LCD_WR_REG(0XBF);
+            LCD_RD_DATA();             // dummy read
+            LCD_RD_DATA();             //读回0X01
+            LCD_RD_DATA();             //读回0XD0
+            lcddev.id = LCD_RD_DATA(); //这里读回0X68
+            lcddev.id <<= 8;
+            lcddev.id |= LCD_RD_DATA(); //这里读回0X04
+            if (lcddev.id != 0X6804)    //也不是6804,尝试看看是不是NT35310
+            {
+                LCD_WR_REG(0XD4);
+                LCD_RD_DATA();             // dummy read
+                LCD_RD_DATA();             //读回0X01
+                lcddev.id = LCD_RD_DATA(); //读回0X53
+                lcddev.id <<= 8;
+                lcddev.id |= LCD_RD_DATA(); //这里读回0X10
+                if (lcddev.id != 0X5310)    //也不是NT35310,尝试看看是不是NT35510
+                {
+                    LCD_WR_REG(0XDA00);
+                    LCD_RD_DATA(); //读回0X00
+                    LCD_WR_REG(0XDB00);
+                    lcddev.id = LCD_RD_DATA(); //读回0X80
+                    lcddev.id <<= 8;
+                    LCD_WR_REG(0XDC00);
+                    lcddev.id |= LCD_RD_DATA(); //读回0X00
+                    if (lcddev.id == 0x8000)
+                        lcddev.id = 0x5510; // NT35510读回的ID是8000H,为方便区分,我们强制设置为5510
+                }
+            }
+        }
+    }
+    printf(" LCD ID:%x\r\n", lcddev.id); //打印LCD ID
+    if (lcddev.id == 0X9341)             // 9341初始化
+    {
+        LCD_WR_REG(0xCF);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC1);
+        LCD_WR_DATA(0X30);
+        LCD_WR_REG(0xED);
+        LCD_WR_DATA(0x64);
+        LCD_WR_DATA(0x03);
+        LCD_WR_DATA(0X12);
+        LCD_WR_DATA(0X81);
+        LCD_WR_REG(0xE8);
+        LCD_WR_DATA(0x85);
+        LCD_WR_DATA(0x10);
+        LCD_WR_DATA(0x7A);
+        LCD_WR_REG(0xCB);
+        LCD_WR_DATA(0x39);
+        LCD_WR_DATA(0x2C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x34);
+        LCD_WR_DATA(0x02);
+        LCD_WR_REG(0xF7);
+        LCD_WR_DATA(0x20);
+        LCD_WR_REG(0xEA);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_REG(0xC0);  // Power control
+        LCD_WR_DATA(0x1B); // VRH[5:0]
+        LCD_WR_REG(0xC1);  // Power control
+        LCD_WR_DATA(0x01); // SAP[2:0];BT[3:0]
+        LCD_WR_REG(0xC5);  // VCM control
+        LCD_WR_DATA(0x30); // 3F
+        LCD_WR_DATA(0x30); // 3C
+        LCD_WR_REG(0xC7);  // VCM control2
+        LCD_WR_DATA(0XB7);
+        LCD_WR_REG(0x36); // Memory Access Control
+        LCD_WR_DATA(0x48);
+        LCD_WR_REG(0x3A);
+        LCD_WR_DATA(0x55);
+        LCD_WR_REG(0xB1);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x1A);
+        LCD_WR_REG(0xB6); // Display Function Control
+        LCD_WR_DATA(0x0A);
+        LCD_WR_DATA(0xA2);
+        LCD_WR_REG(0xF2); // 3Gamma Function Disable
+        LCD_WR_DATA(0x00);
+        LCD_WR_REG(0x26); // Gamma curve selected
+        LCD_WR_DATA(0x01);
+        LCD_WR_REG(0xE0); // Set Gamma
+        LCD_WR_DATA(0x0F);
+        LCD_WR_DATA(0x2A);
+        LCD_WR_DATA(0x28);
+        LCD_WR_DATA(0x08);
+        LCD_WR_DATA(0x0E);
+        LCD_WR_DATA(0x08);
+        LCD_WR_DATA(0x54);
+        LCD_WR_DATA(0XA9);
+        LCD_WR_DATA(0x43);
+        LCD_WR_DATA(0x0A);
+        LCD_WR_DATA(0x0F);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_REG(0XE1); // Set Gamma
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x15);
+        LCD_WR_DATA(0x17);
+        LCD_WR_DATA(0x07);
+        LCD_WR_DATA(0x11);
+        LCD_WR_DATA(0x06);
+        LCD_WR_DATA(0x2B);
+        LCD_WR_DATA(0x56);
+        LCD_WR_DATA(0x3C);
+        LCD_WR_DATA(0x05);
+        LCD_WR_DATA(0x10);
+        LCD_WR_DATA(0x0F);
+        LCD_WR_DATA(0x3F);
+        LCD_WR_DATA(0x3F);
+        LCD_WR_DATA(0x0F);
+        LCD_WR_REG(0x2B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x01);
+        LCD_WR_DATA(0x3f);
+        LCD_WR_REG(0x2A);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xef);
+        LCD_WR_REG(0x11); // Exit Sleep
+        ms_delay(120);
+        LCD_WR_REG(0x29); // display on
+    }
+    else if (lcddev.id == 0x6804) // 6804初始化
+    {
+        LCD_WR_REG(0X11);
+        ms_delay(20);
+        LCD_WR_REG(0XD0); // VCI1  VCL  VGH  VGL DDVDH VREG1OUT power amplitude setting
+        LCD_WR_DATA(0X07);
+        LCD_WR_DATA(0X42);
+        LCD_WR_DATA(0X1D);
+        LCD_WR_REG(0XD1); // VCOMH VCOM_AC amplitude setting
+        LCD_WR_DATA(0X00);
+        LCD_WR_DATA(0X1a);
+        LCD_WR_DATA(0X09);
+        LCD_WR_REG(0XD2); // Operational Amplifier Circuit Constant Current Adjust , charge pump frequency setting
+        LCD_WR_DATA(0X01);
+        LCD_WR_DATA(0X22);
+        LCD_WR_REG(0XC0); // REV SM GS
+        LCD_WR_DATA(0X10);
+        LCD_WR_DATA(0X3B);
+        LCD_WR_DATA(0X00);
+        LCD_WR_DATA(0X02);
+        LCD_WR_DATA(0X11);
+
+        LCD_WR_REG(0XC5); // Frame rate setting = 72HZ  when setting 0x03
+        LCD_WR_DATA(0X03);
+
+        LCD_WR_REG(0XC8); // Gamma setting
+        LCD_WR_DATA(0X00);
+        LCD_WR_DATA(0X25);
+        LCD_WR_DATA(0X21);
+        LCD_WR_DATA(0X05);
+        LCD_WR_DATA(0X00);
+        LCD_WR_DATA(0X0a);
+        LCD_WR_DATA(0X65);
+        LCD_WR_DATA(0X25);
+        LCD_WR_DATA(0X77);
+        LCD_WR_DATA(0X50);
+        LCD_WR_DATA(0X0f);
+        LCD_WR_DATA(0X00);
+
+        LCD_WR_REG(0XF8);
+        LCD_WR_DATA(0X01);
+
+        LCD_WR_REG(0XFE);
+        LCD_WR_DATA(0X00);
+        LCD_WR_DATA(0X02);
+
+        LCD_WR_REG(0X20); // Exit invert mode
+
+        LCD_WR_REG(0X36);
+        LCD_WR_DATA(0X08); //原来是a
+
+        LCD_WR_REG(0X3A);
+        LCD_WR_DATA(0X55); // 16位模式
+        LCD_WR_REG(0X2B);
+        LCD_WR_DATA(0X00);
+        LCD_WR_DATA(0X00);
+        LCD_WR_DATA(0X01);
+        LCD_WR_DATA(0X3F);
+
+        LCD_WR_REG(0X2A);
+        LCD_WR_DATA(0X00);
+        LCD_WR_DATA(0X00);
+        LCD_WR_DATA(0X01);
+        LCD_WR_DATA(0XDF);
+        ms_delay(120);
+        LCD_WR_REG(0X29);
+    }
+    else if (lcddev.id == 0x5310)
+    {
+        LCD_WR_REG(0xED);
+        LCD_WR_DATA(0x01);
+        LCD_WR_DATA(0xFE);
+
+        LCD_WR_REG(0xEE);
+        LCD_WR_DATA(0xDE);
+        LCD_WR_DATA(0x21);
+
+        LCD_WR_REG(0xF1);
+        LCD_WR_DATA(0x01);
+        LCD_WR_REG(0xDF);
+        LCD_WR_DATA(0x10);
+
+        // VCOMvoltage//
+        LCD_WR_REG(0xC4);
+        LCD_WR_DATA(0x8F); // 5f
+
+        LCD_WR_REG(0xC6);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xE2);
+        LCD_WR_DATA(0xE2);
+        LCD_WR_DATA(0xE2);
+        LCD_WR_REG(0xBF);
+        LCD_WR_DATA(0xAA);
+
+        LCD_WR_REG(0xB0);
+        LCD_WR_DATA(0x0D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x0D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x11);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x19);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x21);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x2D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x5D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x5D);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB1);
+        LCD_WR_DATA(0x80);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x8B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x96);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x02);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x03);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB4);
+        LCD_WR_DATA(0x8B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x96);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA1);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB5);
+        LCD_WR_DATA(0x02);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x03);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x04);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB6);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB7);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3F);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x5E);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x64);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x8C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xAC);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xDC);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x70);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x90);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xEB);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xDC);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB8);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xBA);
+        LCD_WR_DATA(0x24);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC1);
+        LCD_WR_DATA(0x20);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x54);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xFF);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC2);
+        LCD_WR_DATA(0x0A);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x04);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC3);
+        LCD_WR_DATA(0x3C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3A);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x39);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x37);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x36);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x32);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x2F);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x2C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x29);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x26);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x24);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x24);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x23);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x36);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x32);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x2F);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x2C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x29);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x26);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x24);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x24);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x23);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC4);
+        LCD_WR_DATA(0x62);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x05);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x84);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF0);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x18);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA4);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x18);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x50);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x0C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x17);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x95);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xE6);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC5);
+        LCD_WR_DATA(0x32);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x65);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x76);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x88);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC6);
+        LCD_WR_DATA(0x20);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x17);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x01);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC7);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC8);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC9);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE0);
+        LCD_WR_DATA(0x16);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x1C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x21);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x36);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x46);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x52);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x64);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x7A);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x8B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA8);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xB9);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC4);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xCA);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD9);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xE0);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE1);
+        LCD_WR_DATA(0x16);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x1C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x22);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x36);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x45);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x52);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x64);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x7A);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x8B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA8);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xB9);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC4);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xCA);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD8);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xE0);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE2);
+        LCD_WR_DATA(0x05);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x0B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x1B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x34);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x4F);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x61);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x79);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x88);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x97);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA6);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xB7);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC7);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD1);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD6);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xDD);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_REG(0xE3);
+        LCD_WR_DATA(0x05);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x1C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x33);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x50);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x62);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x78);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x88);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x97);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA6);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xB7);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC7);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD1);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD5);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xDD);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE4);
+        LCD_WR_DATA(0x01);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x01);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x02);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x2A);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x4B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x5D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x74);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x84);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x93);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xB3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xBE);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC4);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xCD);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xDD);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_REG(0xE5);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x02);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x29);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x4B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x5D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x74);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x84);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x93);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xB3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xBE);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC4);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xCD);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xDC);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE6);
+        LCD_WR_DATA(0x11);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x34);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x56);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x76);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x77);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x66);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x88);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xBB);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x66);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x55);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x55);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x45);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x43);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE7);
+        LCD_WR_DATA(0x32);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x55);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x76);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x66);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x67);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x67);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x87);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xBB);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x77);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x56);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x23);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x33);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x45);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE8);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x87);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x88);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x77);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x66);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x88);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xAA);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xBB);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x66);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x55);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x55);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x55);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE9);
+        LCD_WR_DATA(0xAA);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0x00);
+        LCD_WR_DATA(0xAA);
+
+        LCD_WR_REG(0xCF);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xF0);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x50);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xF3);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xF9);
+        LCD_WR_DATA(0x06);
+        LCD_WR_DATA(0x10);
+        LCD_WR_DATA(0x29);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0x3A);
+        LCD_WR_DATA(0x55); // 66
+
+        LCD_WR_REG(0x11);
+        ms_delay(100);
+        LCD_WR_REG(0x29);
+        LCD_WR_REG(0x35);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0x51);
+        LCD_WR_DATA(0xFF);
+        LCD_WR_REG(0x53);
+        LCD_WR_DATA(0x2C);
+        LCD_WR_REG(0x55);
+        LCD_WR_DATA(0x82);
+        LCD_WR_REG(0x2c);
+    }
+    else if (lcddev.id == 0x5510)
+    {
+        LCD_WriteReg(0xF000, 0x55);
+        LCD_WriteReg(0xF001, 0xAA);
+        LCD_WriteReg(0xF002, 0x52);
+        LCD_WriteReg(0xF003, 0x08);
+        LCD_WriteReg(0xF004, 0x01);
+        // AVDD Set AVDD 5.2V
+        LCD_WriteReg(0xB000, 0x0D);
+        LCD_WriteReg(0xB001, 0x0D);
+        LCD_WriteReg(0xB002, 0x0D);
+        // AVDD ratio
+        LCD_WriteReg(0xB600, 0x34);
+        LCD_WriteReg(0xB601, 0x34);
+        LCD_WriteReg(0xB602, 0x34);
+        // AVEE -5.2V
+        LCD_WriteReg(0xB100, 0x0D);
+        LCD_WriteReg(0xB101, 0x0D);
+        LCD_WriteReg(0xB102, 0x0D);
+        // AVEE ratio
+        LCD_WriteReg(0xB700, 0x34);
+        LCD_WriteReg(0xB701, 0x34);
+        LCD_WriteReg(0xB702, 0x34);
+        // VCL -2.5V
+        LCD_WriteReg(0xB200, 0x00);
+        LCD_WriteReg(0xB201, 0x00);
+        LCD_WriteReg(0xB202, 0x00);
+        // VCL ratio
+        LCD_WriteReg(0xB800, 0x24);
+        LCD_WriteReg(0xB801, 0x24);
+        LCD_WriteReg(0xB802, 0x24);
+        // VGH 15V (Free pump)
+        LCD_WriteReg(0xBF00, 0x01);
+        LCD_WriteReg(0xB300, 0x0F);
+        LCD_WriteReg(0xB301, 0x0F);
+        LCD_WriteReg(0xB302, 0x0F);
+        // VGH ratio
+        LCD_WriteReg(0xB900, 0x34);
+        LCD_WriteReg(0xB901, 0x34);
+        LCD_WriteReg(0xB902, 0x34);
+        // VGL_REG -10V
+        LCD_WriteReg(0xB500, 0x08);
+        LCD_WriteReg(0xB501, 0x08);
+        LCD_WriteReg(0xB502, 0x08);
+        LCD_WriteReg(0xC200, 0x03);
+        // VGLX ratio
+        LCD_WriteReg(0xBA00, 0x24);
+        LCD_WriteReg(0xBA01, 0x24);
+        LCD_WriteReg(0xBA02, 0x24);
+        // VGMP/VGSP 4.5V/0V
+        LCD_WriteReg(0xBC00, 0x00);
+        LCD_WriteReg(0xBC01, 0x78);
+        LCD_WriteReg(0xBC02, 0x00);
+        // VGMN/VGSN -4.5V/0V
+        LCD_WriteReg(0xBD00, 0x00);
+        LCD_WriteReg(0xBD01, 0x78);
+        LCD_WriteReg(0xBD02, 0x00);
+        // VCOM
+        LCD_WriteReg(0xBE00, 0x00);
+        LCD_WriteReg(0xBE01, 0x64);
+        // Gamma Setting
+        LCD_WriteReg(0xD100, 0x00);
+        LCD_WriteReg(0xD101, 0x33);
+        LCD_WriteReg(0xD102, 0x00);
+        LCD_WriteReg(0xD103, 0x34);
+        LCD_WriteReg(0xD104, 0x00);
+        LCD_WriteReg(0xD105, 0x3A);
+        LCD_WriteReg(0xD106, 0x00);
+        LCD_WriteReg(0xD107, 0x4A);
+        LCD_WriteReg(0xD108, 0x00);
+        LCD_WriteReg(0xD109, 0x5C);
+        LCD_WriteReg(0xD10A, 0x00);
+        LCD_WriteReg(0xD10B, 0x81);
+        LCD_WriteReg(0xD10C, 0x00);
+        LCD_WriteReg(0xD10D, 0xA6);
+        LCD_WriteReg(0xD10E, 0x00);
+        LCD_WriteReg(0xD10F, 0xE5);
+        LCD_WriteReg(0xD110, 0x01);
+        LCD_WriteReg(0xD111, 0x13);
+        LCD_WriteReg(0xD112, 0x01);
+        LCD_WriteReg(0xD113, 0x54);
+        LCD_WriteReg(0xD114, 0x01);
+        LCD_WriteReg(0xD115, 0x82);
+        LCD_WriteReg(0xD116, 0x01);
+        LCD_WriteReg(0xD117, 0xCA);
+        LCD_WriteReg(0xD118, 0x02);
+        LCD_WriteReg(0xD119, 0x00);
+        LCD_WriteReg(0xD11A, 0x02);
+        LCD_WriteReg(0xD11B, 0x01);
+        LCD_WriteReg(0xD11C, 0x02);
+        LCD_WriteReg(0xD11D, 0x34);
+        LCD_WriteReg(0xD11E, 0x02);
+        LCD_WriteReg(0xD11F, 0x67);
+        LCD_WriteReg(0xD120, 0x02);
+        LCD_WriteReg(0xD121, 0x84);
+        LCD_WriteReg(0xD122, 0x02);
+        LCD_WriteReg(0xD123, 0xA4);
+        LCD_WriteReg(0xD124, 0x02);
+        LCD_WriteReg(0xD125, 0xB7);
+        LCD_WriteReg(0xD126, 0x02);
+        LCD_WriteReg(0xD127, 0xCF);
+        LCD_WriteReg(0xD128, 0x02);
+        LCD_WriteReg(0xD129, 0xDE);
+        LCD_WriteReg(0xD12A, 0x02);
+        LCD_WriteReg(0xD12B, 0xF2);
+        LCD_WriteReg(0xD12C, 0x02);
+        LCD_WriteReg(0xD12D, 0xFE);
+        LCD_WriteReg(0xD12E, 0x03);
+        LCD_WriteReg(0xD12F, 0x10);
+        LCD_WriteReg(0xD130, 0x03);
+        LCD_WriteReg(0xD131, 0x33);
+        LCD_WriteReg(0xD132, 0x03);
+        LCD_WriteReg(0xD133, 0x6D);
+        LCD_WriteReg(0xD200, 0x00);
+        LCD_WriteReg(0xD201, 0x33);
+        LCD_WriteReg(0xD202, 0x00);
+        LCD_WriteReg(0xD203, 0x34);
+        LCD_WriteReg(0xD204, 0x00);
+        LCD_WriteReg(0xD205, 0x3A);
+        LCD_WriteReg(0xD206, 0x00);
+        LCD_WriteReg(0xD207, 0x4A);
+        LCD_WriteReg(0xD208, 0x00);
+        LCD_WriteReg(0xD209, 0x5C);
+        LCD_WriteReg(0xD20A, 0x00);
+
+        LCD_WriteReg(0xD20B, 0x81);
+        LCD_WriteReg(0xD20C, 0x00);
+        LCD_WriteReg(0xD20D, 0xA6);
+        LCD_WriteReg(0xD20E, 0x00);
+        LCD_WriteReg(0xD20F, 0xE5);
+        LCD_WriteReg(0xD210, 0x01);
+        LCD_WriteReg(0xD211, 0x13);
+        LCD_WriteReg(0xD212, 0x01);
+        LCD_WriteReg(0xD213, 0x54);
+        LCD_WriteReg(0xD214, 0x01);
+        LCD_WriteReg(0xD215, 0x82);
+        LCD_WriteReg(0xD216, 0x01);
+        LCD_WriteReg(0xD217, 0xCA);
+        LCD_WriteReg(0xD218, 0x02);
+        LCD_WriteReg(0xD219, 0x00);
+        LCD_WriteReg(0xD21A, 0x02);
+        LCD_WriteReg(0xD21B, 0x01);
+        LCD_WriteReg(0xD21C, 0x02);
+        LCD_WriteReg(0xD21D, 0x34);
+        LCD_WriteReg(0xD21E, 0x02);
+        LCD_WriteReg(0xD21F, 0x67);
+        LCD_WriteReg(0xD220, 0x02);
+        LCD_WriteReg(0xD221, 0x84);
+        LCD_WriteReg(0xD222, 0x02);
+        LCD_WriteReg(0xD223, 0xA4);
+        LCD_WriteReg(0xD224, 0x02);
+        LCD_WriteReg(0xD225, 0xB7);
+        LCD_WriteReg(0xD226, 0x02);
+        LCD_WriteReg(0xD227, 0xCF);
+        LCD_WriteReg(0xD228, 0x02);
+        LCD_WriteReg(0xD229, 0xDE);
+        LCD_WriteReg(0xD22A, 0x02);
+        LCD_WriteReg(0xD22B, 0xF2);
+        LCD_WriteReg(0xD22C, 0x02);
+        LCD_WriteReg(0xD22D, 0xFE);
+        LCD_WriteReg(0xD22E, 0x03);
+        LCD_WriteReg(0xD22F, 0x10);
+        LCD_WriteReg(0xD230, 0x03);
+        LCD_WriteReg(0xD231, 0x33);
+        LCD_WriteReg(0xD232, 0x03);
+        LCD_WriteReg(0xD233, 0x6D);
+        LCD_WriteReg(0xD300, 0x00);
+        LCD_WriteReg(0xD301, 0x33);
+        LCD_WriteReg(0xD302, 0x00);
+        LCD_WriteReg(0xD303, 0x34);
+        LCD_WriteReg(0xD304, 0x00);
+        LCD_WriteReg(0xD305, 0x3A);
+        LCD_WriteReg(0xD306, 0x00);
+        LCD_WriteReg(0xD307, 0x4A);
+        LCD_WriteReg(0xD308, 0x00);
+        LCD_WriteReg(0xD309, 0x5C);
+        LCD_WriteReg(0xD30A, 0x00);
+
+        LCD_WriteReg(0xD30B, 0x81);
+        LCD_WriteReg(0xD30C, 0x00);
+        LCD_WriteReg(0xD30D, 0xA6);
+        LCD_WriteReg(0xD30E, 0x00);
+        LCD_WriteReg(0xD30F, 0xE5);
+        LCD_WriteReg(0xD310, 0x01);
+        LCD_WriteReg(0xD311, 0x13);
+        LCD_WriteReg(0xD312, 0x01);
+        LCD_WriteReg(0xD313, 0x54);
+        LCD_WriteReg(0xD314, 0x01);
+        LCD_WriteReg(0xD315, 0x82);
+        LCD_WriteReg(0xD316, 0x01);
+        LCD_WriteReg(0xD317, 0xCA);
+        LCD_WriteReg(0xD318, 0x02);
+        LCD_WriteReg(0xD319, 0x00);
+        LCD_WriteReg(0xD31A, 0x02);
+        LCD_WriteReg(0xD31B, 0x01);
+        LCD_WriteReg(0xD31C, 0x02);
+        LCD_WriteReg(0xD31D, 0x34);
+        LCD_WriteReg(0xD31E, 0x02);
+        LCD_WriteReg(0xD31F, 0x67);
+        LCD_WriteReg(0xD320, 0x02);
+        LCD_WriteReg(0xD321, 0x84);
+        LCD_WriteReg(0xD322, 0x02);
+        LCD_WriteReg(0xD323, 0xA4);
+        LCD_WriteReg(0xD324, 0x02);
+        LCD_WriteReg(0xD325, 0xB7);
+        LCD_WriteReg(0xD326, 0x02);
+        LCD_WriteReg(0xD327, 0xCF);
+        LCD_WriteReg(0xD328, 0x02);
+        LCD_WriteReg(0xD329, 0xDE);
+        LCD_WriteReg(0xD32A, 0x02);
+        LCD_WriteReg(0xD32B, 0xF2);
+        LCD_WriteReg(0xD32C, 0x02);
+        LCD_WriteReg(0xD32D, 0xFE);
+        LCD_WriteReg(0xD32E, 0x03);
+        LCD_WriteReg(0xD32F, 0x10);
+        LCD_WriteReg(0xD330, 0x03);
+        LCD_WriteReg(0xD331, 0x33);
+        LCD_WriteReg(0xD332, 0x03);
+        LCD_WriteReg(0xD333, 0x6D);
+        LCD_WriteReg(0xD400, 0x00);
+        LCD_WriteReg(0xD401, 0x33);
+        LCD_WriteReg(0xD402, 0x00);
+        LCD_WriteReg(0xD403, 0x34);
+        LCD_WriteReg(0xD404, 0x00);
+        LCD_WriteReg(0xD405, 0x3A);
+        LCD_WriteReg(0xD406, 0x00);
+        LCD_WriteReg(0xD407, 0x4A);
+        LCD_WriteReg(0xD408, 0x00);
+        LCD_WriteReg(0xD409, 0x5C);
+        LCD_WriteReg(0xD40A, 0x00);
+        LCD_WriteReg(0xD40B, 0x81);
+
+        LCD_WriteReg(0xD40C, 0x00);
+        LCD_WriteReg(0xD40D, 0xA6);
+        LCD_WriteReg(0xD40E, 0x00);
+        LCD_WriteReg(0xD40F, 0xE5);
+        LCD_WriteReg(0xD410, 0x01);
+        LCD_WriteReg(0xD411, 0x13);
+        LCD_WriteReg(0xD412, 0x01);
+        LCD_WriteReg(0xD413, 0x54);
+        LCD_WriteReg(0xD414, 0x01);
+        LCD_WriteReg(0xD415, 0x82);
+        LCD_WriteReg(0xD416, 0x01);
+        LCD_WriteReg(0xD417, 0xCA);
+        LCD_WriteReg(0xD418, 0x02);
+        LCD_WriteReg(0xD419, 0x00);
+        LCD_WriteReg(0xD41A, 0x02);
+        LCD_WriteReg(0xD41B, 0x01);
+        LCD_WriteReg(0xD41C, 0x02);
+        LCD_WriteReg(0xD41D, 0x34);
+        LCD_WriteReg(0xD41E, 0x02);
+        LCD_WriteReg(0xD41F, 0x67);
+        LCD_WriteReg(0xD420, 0x02);
+        LCD_WriteReg(0xD421, 0x84);
+        LCD_WriteReg(0xD422, 0x02);
+        LCD_WriteReg(0xD423, 0xA4);
+        LCD_WriteReg(0xD424, 0x02);
+        LCD_WriteReg(0xD425, 0xB7);
+        LCD_WriteReg(0xD426, 0x02);
+        LCD_WriteReg(0xD427, 0xCF);
+        LCD_WriteReg(0xD428, 0x02);
+        LCD_WriteReg(0xD429, 0xDE);
+        LCD_WriteReg(0xD42A, 0x02);
+        LCD_WriteReg(0xD42B, 0xF2);
+        LCD_WriteReg(0xD42C, 0x02);
+        LCD_WriteReg(0xD42D, 0xFE);
+        LCD_WriteReg(0xD42E, 0x03);
+        LCD_WriteReg(0xD42F, 0x10);
+        LCD_WriteReg(0xD430, 0x03);
+        LCD_WriteReg(0xD431, 0x33);
+        LCD_WriteReg(0xD432, 0x03);
+        LCD_WriteReg(0xD433, 0x6D);
+        LCD_WriteReg(0xD500, 0x00);
+        LCD_WriteReg(0xD501, 0x33);
+        LCD_WriteReg(0xD502, 0x00);
+        LCD_WriteReg(0xD503, 0x34);
+        LCD_WriteReg(0xD504, 0x00);
+        LCD_WriteReg(0xD505, 0x3A);
+        LCD_WriteReg(0xD506, 0x00);
+        LCD_WriteReg(0xD507, 0x4A);
+        LCD_WriteReg(0xD508, 0x00);
+        LCD_WriteReg(0xD509, 0x5C);
+        LCD_WriteReg(0xD50A, 0x00);
+        LCD_WriteReg(0xD50B, 0x81);
+
+        LCD_WriteReg(0xD50C, 0x00);
+        LCD_WriteReg(0xD50D, 0xA6);
+        LCD_WriteReg(0xD50E, 0x00);
+        LCD_WriteReg(0xD50F, 0xE5);
+        LCD_WriteReg(0xD510, 0x01);
+        LCD_WriteReg(0xD511, 0x13);
+        LCD_WriteReg(0xD512, 0x01);
+        LCD_WriteReg(0xD513, 0x54);
+        LCD_WriteReg(0xD514, 0x01);
+        LCD_WriteReg(0xD515, 0x82);
+        LCD_WriteReg(0xD516, 0x01);
+        LCD_WriteReg(0xD517, 0xCA);
+        LCD_WriteReg(0xD518, 0x02);
+        LCD_WriteReg(0xD519, 0x00);
+        LCD_WriteReg(0xD51A, 0x02);
+        LCD_WriteReg(0xD51B, 0x01);
+        LCD_WriteReg(0xD51C, 0x02);
+        LCD_WriteReg(0xD51D, 0x34);
+        LCD_WriteReg(0xD51E, 0x02);
+        LCD_WriteReg(0xD51F, 0x67);
+        LCD_WriteReg(0xD520, 0x02);
+        LCD_WriteReg(0xD521, 0x84);
+        LCD_WriteReg(0xD522, 0x02);
+        LCD_WriteReg(0xD523, 0xA4);
+        LCD_WriteReg(0xD524, 0x02);
+        LCD_WriteReg(0xD525, 0xB7);
+        LCD_WriteReg(0xD526, 0x02);
+        LCD_WriteReg(0xD527, 0xCF);
+        LCD_WriteReg(0xD528, 0x02);
+        LCD_WriteReg(0xD529, 0xDE);
+        LCD_WriteReg(0xD52A, 0x02);
+        LCD_WriteReg(0xD52B, 0xF2);
+        LCD_WriteReg(0xD52C, 0x02);
+        LCD_WriteReg(0xD52D, 0xFE);
+        LCD_WriteReg(0xD52E, 0x03);
+        LCD_WriteReg(0xD52F, 0x10);
+        LCD_WriteReg(0xD530, 0x03);
+        LCD_WriteReg(0xD531, 0x33);
+        LCD_WriteReg(0xD532, 0x03);
+        LCD_WriteReg(0xD533, 0x6D);
+        LCD_WriteReg(0xD600, 0x00);
+        LCD_WriteReg(0xD601, 0x33);
+        LCD_WriteReg(0xD602, 0x00);
+        LCD_WriteReg(0xD603, 0x34);
+        LCD_WriteReg(0xD604, 0x00);
+        LCD_WriteReg(0xD605, 0x3A);
+        LCD_WriteReg(0xD606, 0x00);
+        LCD_WriteReg(0xD607, 0x4A);
+        LCD_WriteReg(0xD608, 0x00);
+        LCD_WriteReg(0xD609, 0x5C);
+        LCD_WriteReg(0xD60A, 0x00);
+        LCD_WriteReg(0xD60B, 0x81);
+
+        LCD_WriteReg(0xD60C, 0x00);
+        LCD_WriteReg(0xD60D, 0xA6);
+        LCD_WriteReg(0xD60E, 0x00);
+        LCD_WriteReg(0xD60F, 0xE5);
+        LCD_WriteReg(0xD610, 0x01);
+        LCD_WriteReg(0xD611, 0x13);
+        LCD_WriteReg(0xD612, 0x01);
+        LCD_WriteReg(0xD613, 0x54);
+        LCD_WriteReg(0xD614, 0x01);
+        LCD_WriteReg(0xD615, 0x82);
+        LCD_WriteReg(0xD616, 0x01);
+        LCD_WriteReg(0xD617, 0xCA);
+        LCD_WriteReg(0xD618, 0x02);
+        LCD_WriteReg(0xD619, 0x00);
+        LCD_WriteReg(0xD61A, 0x02);
+        LCD_WriteReg(0xD61B, 0x01);
+        LCD_WriteReg(0xD61C, 0x02);
+        LCD_WriteReg(0xD61D, 0x34);
+        LCD_WriteReg(0xD61E, 0x02);
+        LCD_WriteReg(0xD61F, 0x67);
+        LCD_WriteReg(0xD620, 0x02);
+        LCD_WriteReg(0xD621, 0x84);
+        LCD_WriteReg(0xD622, 0x02);
+        LCD_WriteReg(0xD623, 0xA4);
+        LCD_WriteReg(0xD624, 0x02);
+        LCD_WriteReg(0xD625, 0xB7);
+        LCD_WriteReg(0xD626, 0x02);
+        LCD_WriteReg(0xD627, 0xCF);
+        LCD_WriteReg(0xD628, 0x02);
+        LCD_WriteReg(0xD629, 0xDE);
+        LCD_WriteReg(0xD62A, 0x02);
+        LCD_WriteReg(0xD62B, 0xF2);
+        LCD_WriteReg(0xD62C, 0x02);
+        LCD_WriteReg(0xD62D, 0xFE);
+        LCD_WriteReg(0xD62E, 0x03);
+        LCD_WriteReg(0xD62F, 0x10);
+        LCD_WriteReg(0xD630, 0x03);
+        LCD_WriteReg(0xD631, 0x33);
+        LCD_WriteReg(0xD632, 0x03);
+        LCD_WriteReg(0xD633, 0x6D);
+        // LV2 Page 0 enable
+        LCD_WriteReg(0xF000, 0x55);
+        LCD_WriteReg(0xF001, 0xAA);
+        LCD_WriteReg(0xF002, 0x52);
+        LCD_WriteReg(0xF003, 0x08);
+        LCD_WriteReg(0xF004, 0x00);
+        // Display control
+        LCD_WriteReg(0xB100, 0xCC);
+        LCD_WriteReg(0xB101, 0x00);
+        // Source hold time
+        LCD_WriteReg(0xB600, 0x05);
+        // Gate EQ control
+        LCD_WriteReg(0xB700, 0x70);
+        LCD_WriteReg(0xB701, 0x70);
+        // Source EQ control (Mode 2)
+        LCD_WriteReg(0xB800, 0x01);
+        LCD_WriteReg(0xB801, 0x03);
+        LCD_WriteReg(0xB802, 0x03);
+        LCD_WriteReg(0xB803, 0x03);
+        // Inversion mode (2-dot)
+        LCD_WriteReg(0xBC00, 0x02);
+        LCD_WriteReg(0xBC01, 0x00);
+        LCD_WriteReg(0xBC02, 0x00);
+        // Timing control 4H w/ 4-delay
+        LCD_WriteReg(0xC900, 0xD0);
+        LCD_WriteReg(0xC901, 0x02);
+        LCD_WriteReg(0xC902, 0x50);
+        LCD_WriteReg(0xC903, 0x50);
+        LCD_WriteReg(0xC904, 0x50);
+        LCD_WriteReg(0x3500, 0x00);
+        LCD_WriteReg(0x3A00, 0x55); // 16-bit/pixel
+        LCD_WR_REG(0x1100);
+        us_delay(120);
+        LCD_WR_REG(0x2900);
+    }
+    else if (lcddev.id == 0x9325) // 9325
+    {
+        LCD_WriteReg(0x00E5, 0x78F0);
+        LCD_WriteReg(0x0001, 0x0100);
+        LCD_WriteReg(0x0002, 0x0700);
+        LCD_WriteReg(0x0003, 0x1030);
+        LCD_WriteReg(0x0004, 0x0000);
+        LCD_WriteReg(0x0008, 0x0202);
+        LCD_WriteReg(0x0009, 0x0000);
+        LCD_WriteReg(0x000A, 0x0000);
+        LCD_WriteReg(0x000C, 0x0000);
+        LCD_WriteReg(0x000D, 0x0000);
+        LCD_WriteReg(0x000F, 0x0000);
+        // power on sequence VGHVGL
+        LCD_WriteReg(0x0010, 0x0000);
+        LCD_WriteReg(0x0011, 0x0007);
+        LCD_WriteReg(0x0012, 0x0000);
+        LCD_WriteReg(0x0013, 0x0000);
+        LCD_WriteReg(0x0007, 0x0000);
+        // vgh
+        LCD_WriteReg(0x0010, 0x1690);
+        LCD_WriteReg(0x0011, 0x0227);
+        // delayms(100);
+        // vregiout
+        LCD_WriteReg(0x0012, 0x009D); // 0x001b
+        // delayms(100);
+        // vom amplitude
+        LCD_WriteReg(0x0013, 0x1900);
+        // delayms(100);
+        // vom H
+        LCD_WriteReg(0x0029, 0x0025);
+        LCD_WriteReg(0x002B, 0x000D);
+        // gamma
+        LCD_WriteReg(0x0030, 0x0007);
+        LCD_WriteReg(0x0031, 0x0303);
+        LCD_WriteReg(0x0032, 0x0003); // 0006
+        LCD_WriteReg(0x0035, 0x0206);
+        LCD_WriteReg(0x0036, 0x0008);
+        LCD_WriteReg(0x0037, 0x0406);
+        LCD_WriteReg(0x0038, 0x0304); // 0200
+        LCD_WriteReg(0x0039, 0x0007);
+        LCD_WriteReg(0x003C, 0x0602); // 0504
+        LCD_WriteReg(0x003D, 0x0008);
+        // ram
+        LCD_WriteReg(0x0050, 0x0000);
+        LCD_WriteReg(0x0051, 0x00EF);
+        LCD_WriteReg(0x0052, 0x0000);
+        LCD_WriteReg(0x0053, 0x013F);
+        LCD_WriteReg(0x0060, 0xA700);
+        LCD_WriteReg(0x0061, 0x0001);
+        LCD_WriteReg(0x006A, 0x0000);
+        //
+        LCD_WriteReg(0x0080, 0x0000);
+        LCD_WriteReg(0x0081, 0x0000);
+        LCD_WriteReg(0x0082, 0x0000);
+        LCD_WriteReg(0x0083, 0x0000);
+        LCD_WriteReg(0x0084, 0x0000);
+        LCD_WriteReg(0x0085, 0x0000);
+        //
+        LCD_WriteReg(0x0090, 0x0010);
+        LCD_WriteReg(0x0092, 0x0600);
+
+        LCD_WriteReg(0x0007, 0x0133);
+        LCD_WriteReg(0x00, 0x0022); //
+    }
+    else if (lcddev.id == 0x9328) // ILI9328   OK
+    {
+        LCD_WriteReg(0x00EC, 0x108F); // internal timeing
+        LCD_WriteReg(0x00EF, 0x1234); // ADD
+                                      // LCD_WriteReg(0x00e7,0x0010);
+        // LCD_WriteReg(0x0000,0x0001);//开启内部时钟
+        LCD_WriteReg(0x0001, 0x0100);
+        LCD_WriteReg(0x0002, 0x0700);                          //电源开启
+                                                               // LCD_WriteReg(0x0003,(1<<3)|(1<<4) ); 	//65K  RGB
+                                                               // DRIVE TABLE(寄存器 03H)
+                                                               // BIT3=AM BIT4:5=ID0:1
+                                                               // AM ID0 ID1   FUNCATION
+                                                               // 0  0   0	   R->L D->U
+                                                               // 1  0   0	   D->U	R->L
+                                                               // 0  1   0	   L->R D->U
+                                                               // 1  1   0    D->U	L->R
+                                                               // 0  0   1	   R->L U->D
+                                                               // 1  0   1    U->D	R->L
+                                                               // 0  1   1    L->R U->D 正常就用这个.
+                                                               // 1  1   1	   U->D	L->R
+        LCD_WriteReg(0x0003, (1 << 12) | (3 << 4) | (0 << 3)); // 65K
+        LCD_WriteReg(0x0004, 0x0000);
+        LCD_WriteReg(0x0008, 0x0202);
+        LCD_WriteReg(0x0009, 0x0000);
+        LCD_WriteReg(0x000a, 0x0000); // display setting
+        LCD_WriteReg(0x000c, 0x0001); // display setting
+        LCD_WriteReg(0x000d, 0x0000); // 0f3c
+        LCD_WriteReg(0x000f, 0x0000);
+        //电源配置
+        LCD_WriteReg(0x0010, 0x0000);
+        LCD_WriteReg(0x0011, 0x0007);
+        LCD_WriteReg(0x0012, 0x0000);
+        LCD_WriteReg(0x0013, 0x0000);
+        LCD_WriteReg(0x0007, 0x0001);
+        ms_delay(50);
+        LCD_WriteReg(0x0010, 0x1490);
+        LCD_WriteReg(0x0011, 0x0227);
+        ms_delay(50);
+        LCD_WriteReg(0x0012, 0x008A);
+        ms_delay(50);
+        LCD_WriteReg(0x0013, 0x1a00);
+        LCD_WriteReg(0x0029, 0x0006);
+        LCD_WriteReg(0x002b, 0x000d);
+        ms_delay(50);
+        LCD_WriteReg(0x0020, 0x0000);
+        LCD_WriteReg(0x0021, 0x0000);
+        ms_delay(50);
+        //伽马校正
+        LCD_WriteReg(0x0030, 0x0000);
+        LCD_WriteReg(0x0031, 0x0604);
+        LCD_WriteReg(0x0032, 0x0305);
+        LCD_WriteReg(0x0035, 0x0000);
+        LCD_WriteReg(0x0036, 0x0C09);
+        LCD_WriteReg(0x0037, 0x0204);
+        LCD_WriteReg(0x0038, 0x0301);
+        LCD_WriteReg(0x0039, 0x0707);
+        LCD_WriteReg(0x003c, 0x0000);
+        LCD_WriteReg(0x003d, 0x0a0a);
+        ms_delay(50);
+        LCD_WriteReg(0x0050, 0x0000); //水平GRAM起始位置
+        LCD_WriteReg(0x0051, 0x00ef); //水平GRAM终止位置
+        LCD_WriteReg(0x0052, 0x0000); //垂直GRAM起始位置
+        LCD_WriteReg(0x0053, 0x013f); //垂直GRAM终止位置
+
+        LCD_WriteReg(0x0060, 0xa700);
+        LCD_WriteReg(0x0061, 0x0001);
+        LCD_WriteReg(0x006a, 0x0000);
+        LCD_WriteReg(0x0080, 0x0000);
+        LCD_WriteReg(0x0081, 0x0000);
+        LCD_WriteReg(0x0082, 0x0000);
+        LCD_WriteReg(0x0083, 0x0000);
+        LCD_WriteReg(0x0084, 0x0000);
+        LCD_WriteReg(0x0085, 0x0000);
+
+        LCD_WriteReg(0x0090, 0x0010);
+        LCD_WriteReg(0x0092, 0x0600);
+        //开启显示设置
+        LCD_WriteReg(0x0007, 0x0133);
+    }
+    else if (lcddev.id == 0x9320) //测试OK.
+    {
+        LCD_WriteReg(0x00, 0x0000);
+        LCD_WriteReg(0x01, 0x0100); // Driver Output Contral.
+        LCD_WriteReg(0x02, 0x0700); // LCD Driver Waveform Contral.
+        LCD_WriteReg(0x03, 0x1030); // Entry Mode Set.
+        // LCD_WriteReg(0x03,0x1018);	//Entry Mode Set.
+
+        LCD_WriteReg(0x04, 0x0000);   // Scalling Contral.
+        LCD_WriteReg(0x08, 0x0202);   // Display Contral 2.(0x0207)
+        LCD_WriteReg(0x09, 0x0000);   // Display Contral 3.(0x0000)
+        LCD_WriteReg(0x0a, 0x0000);   // Frame Cycle Contal.(0x0000)
+        LCD_WriteReg(0x0c, (1 << 0)); // Extern Display Interface Contral 1.(0x0000)
+        LCD_WriteReg(0x0d, 0x0000);   // Frame Maker Position.
+        LCD_WriteReg(0x0f, 0x0000);   // Extern Display Interface Contral 2.
+        ms_delay(50);
+        LCD_WriteReg(0x07, 0x0101); // Display Contral.
+        ms_delay(50);
+        LCD_WriteReg(0x10, (1 << 12) | (0 << 8) | (1 << 7) | (1 << 6) | (0 << 4)); // Power Control 1.(0x16b0)
+        LCD_WriteReg(0x11, 0x0007);                                                // Power Control 2.(0x0001)
+        LCD_WriteReg(0x12, (1 << 8) | (1 << 4) | (0 << 0));                        // Power Control 3.(0x0138)
+        LCD_WriteReg(0x13, 0x0b00);                                                // Power Control 4.
+        LCD_WriteReg(0x29, 0x0000);                                                // Power Control 7.
+
+        LCD_WriteReg(0x2b, (1 << 14) | (1 << 4));
+        LCD_WriteReg(0x50, 0); // Set X Star
+        //水平GRAM终止位置Set X End.
+        LCD_WriteReg(0x51, 239); // Set Y Star
+        LCD_WriteReg(0x52, 0);   // Set Y End.t.
+        LCD_WriteReg(0x53, 319); //
+
+        LCD_WriteReg(0x60, 0x2700); // Driver Output Control.
+        LCD_WriteReg(0x61, 0x0001); // Driver Output Control.
+        LCD_WriteReg(0x6a, 0x0000); // Vertical Srcoll Control.
+
+        LCD_WriteReg(0x80, 0x0000); // Display Position? Partial Display 1.
+        LCD_WriteReg(0x81, 0x0000); // RAM Address Start? Partial Display 1.
+        LCD_WriteReg(0x82, 0x0000); // RAM Address End-Partial Display 1.
+        LCD_WriteReg(0x83, 0x0000); // Displsy Position? Partial Display 2.
+        LCD_WriteReg(0x84, 0x0000); // RAM Address Start? Partial Display 2.
+        LCD_WriteReg(0x85, 0x0000); // RAM Address End? Partial Display 2.
+
+        LCD_WriteReg(0x90, (0 << 7) | (16 << 0)); // Frame Cycle Contral.(0x0013)
+        LCD_WriteReg(0x92, 0x0000);               // Panel Interface Contral 2.(0x0000)
+        LCD_WriteReg(0x93, 0x0001);               // Panel Interface Contral 3.
+        LCD_WriteReg(0x95, 0x0110);               // Frame Cycle Contral.(0x0110)
+        LCD_WriteReg(0x97, (0 << 8));             //
+        LCD_WriteReg(0x98, 0x0000);               // Frame Cycle Contral.
+        LCD_WriteReg(0x07, 0x0173);               //(0x0173)
+    }
+    else if (lcddev.id == 0X9331) // OK |/|/|
+    {
+        LCD_WriteReg(0x00E7, 0x1014);
+        LCD_WriteReg(0x0001, 0x0100);                          // set SS and SM bit
+        LCD_WriteReg(0x0002, 0x0200);                          // set 1 line inversion
+        LCD_WriteReg(0x0003, (1 << 12) | (3 << 4) | (1 << 3)); // 65K
+        // LCD_WriteReg(0x0003, 0x1030); // set GRAM write direction and BGR=1.
+        LCD_WriteReg(0x0008, 0x0202); // set the back porch and front porch
+        LCD_WriteReg(0x0009, 0x0000); // set non-display area refresh cycle ISC[3:0]
+        LCD_WriteReg(0x000A, 0x0000); // FMARK function
+        LCD_WriteReg(0x000C, 0x0000); // RGB interface setting
+        LCD_WriteReg(0x000D, 0x0000); // Frame marker Position
+        LCD_WriteReg(0x000F, 0x0000); // RGB interface polarity
+        //*************Power On sequence ****************//
+        LCD_WriteReg(0x0010, 0x0000); // SAP, BT[3:0], AP, DSTB, SLP, STB
+        LCD_WriteReg(0x0011, 0x0007); // DC1[2:0], DC0[2:0], VC[2:0]
+        LCD_WriteReg(0x0012, 0x0000); // VREG1OUT voltage
+        LCD_WriteReg(0x0013, 0x0000); // VDV[4:0] for VCOM amplitude
+        ms_delay(200);                // Dis-charge capacitor power voltage
+        LCD_WriteReg(0x0010, 0x1690); // SAP, BT[3:0], AP, DSTB, SLP, STB
+        LCD_WriteReg(0x0011, 0x0227); // DC1[2:0], DC0[2:0], VC[2:0]
+        ms_delay(50);                 // Delay 50ms
+        LCD_WriteReg(0x0012, 0x000C); // Internal reference voltage= Vci;
+        ms_delay(50);                 // Delay 50ms
+        LCD_WriteReg(0x0013, 0x0800); // Set VDV[4:0] for VCOM amplitude
+        LCD_WriteReg(0x0029, 0x0011); // Set VCM[5:0] for VCOMH
+        LCD_WriteReg(0x002B, 0x000B); // Set Frame Rate
+        ms_delay(50);                 // Delay 50ms
+        LCD_WriteReg(0x0020, 0x0000); // GRAM horizontal Address
+        LCD_WriteReg(0x0021, 0x013f); // GRAM Vertical Address
+        // ----------- Adjust the Gamma Curve ----------//
+        LCD_WriteReg(0x0030, 0x0000);
+        LCD_WriteReg(0x0031, 0x0106);
+        LCD_WriteReg(0x0032, 0x0000);
+        LCD_WriteReg(0x0035, 0x0204);
+        LCD_WriteReg(0x0036, 0x160A);
+        LCD_WriteReg(0x0037, 0x0707);
+        LCD_WriteReg(0x0038, 0x0106);
+        LCD_WriteReg(0x0039, 0x0707);
+        LCD_WriteReg(0x003C, 0x0402);
+        LCD_WriteReg(0x003D, 0x0C0F);
+        //------------------ Set GRAM area ---------------//
+        LCD_WriteReg(0x0050, 0x0000); // Horizontal GRAM Start Address
+        LCD_WriteReg(0x0051, 0x00EF); // Horizontal GRAM End Address
+        LCD_WriteReg(0x0052, 0x0000); // Vertical GRAM Start Address
+        LCD_WriteReg(0x0053, 0x013F); // Vertical GRAM Start Address
+        LCD_WriteReg(0x0060, 0x2700); // Gate Scan Line
+        LCD_WriteReg(0x0061, 0x0001); // NDL,VLE, REV
+        LCD_WriteReg(0x006A, 0x0000); // set scrolling line
+        //-------------- Partial Display Control ---------//
+        LCD_WriteReg(0x0080, 0x0000);
+        LCD_WriteReg(0x0081, 0x0000);
+        LCD_WriteReg(0x0082, 0x0000);
+        LCD_WriteReg(0x0083, 0x0000);
+        LCD_WriteReg(0x0084, 0x0000);
+        LCD_WriteReg(0x0085, 0x0000);
+        //-------------- Panel Control -------------------//
+        LCD_WriteReg(0x0090, 0x0010);
+        LCD_WriteReg(0x0092, 0x0600);
+        LCD_WriteReg(0x0007, 0x0133); // 262K color and display ON
+    }
+    else if (lcddev.id == 0x5408)
+    {
+        LCD_WriteReg(0x01, 0x0100);
+        LCD_WriteReg(0x02, 0x0700); // LCD Driving Waveform Contral
+        LCD_WriteReg(0x03, 0x1030); // Entry Mode设置
+        //指针从左至右自上而下的自动增模式
+        // Normal Mode(Window Mode disable)
+        // RGB格式
+        // 16位数据2次传输的8总线设置
+        LCD_WriteReg(0x04, 0x0000); // Scalling Control register
+        LCD_WriteReg(0x08, 0x0207); // Display Control 2
+        LCD_WriteReg(0x09, 0x0000); // Display Control 3
+        LCD_WriteReg(0x0A, 0x0000); // Frame Cycle Control
+        LCD_WriteReg(0x0C, 0x0000); // External Display Interface Control 1
+        LCD_WriteReg(0x0D, 0x0000); // Frame Maker Position
+        LCD_WriteReg(0x0F, 0x0000); // External Display Interface Control 2
+        ms_delay(20);
+        // TFT 液晶彩色图像显示方法14
+        LCD_WriteReg(0x10, 0x16B0); // 0x14B0 //Power Control 1
+        LCD_WriteReg(0x11, 0x0001); // 0x0007 //Power Control 2
+        LCD_WriteReg(0x17, 0x0001); // 0x0000 //Power Control 3
+        LCD_WriteReg(0x12, 0x0138); // 0x013B //Power Control 4
+        LCD_WriteReg(0x13, 0x0800); // 0x0800 //Power Control 5
+        LCD_WriteReg(0x29, 0x0009); // NVM read data 2
+        LCD_WriteReg(0x2a, 0x0009); // NVM read data 3
+        LCD_WriteReg(0xa4, 0x0000);
+        LCD_WriteReg(0x50, 0x0000); //设置操作窗口的X轴开始列
+        LCD_WriteReg(0x51, 0x00EF); //设置操作窗口的X轴结束列
+        LCD_WriteReg(0x52, 0x0000); //设置操作窗口的Y轴开始行
+        LCD_WriteReg(0x53, 0x013F); //设置操作窗口的Y轴结束行
+        LCD_WriteReg(0x60, 0x2700); // Driver Output Control
+        //设置屏幕的点数以及扫描的起始行
+        LCD_WriteReg(0x61, 0x0001); // Driver Output Control
+        LCD_WriteReg(0x6A, 0x0000); // Vertical Scroll Control
+        LCD_WriteReg(0x80, 0x0000); // Display Position – Partial Display 1
+        LCD_WriteReg(0x81, 0x0000); // RAM Address Start – Partial Display 1
+        LCD_WriteReg(0x82, 0x0000); // RAM address End - Partial Display 1
+        LCD_WriteReg(0x83, 0x0000); // Display Position – Partial Display 2
+        LCD_WriteReg(0x84, 0x0000); // RAM Address Start – Partial Display 2
+        LCD_WriteReg(0x85, 0x0000); // RAM address End – Partail Display2
+        LCD_WriteReg(0x90, 0x0013); // Frame Cycle Control
+        LCD_WriteReg(0x92, 0x0000); // Panel Interface Control 2
+        LCD_WriteReg(0x93, 0x0003); // Panel Interface control 3
+        LCD_WriteReg(0x95, 0x0110); // Frame Cycle Control
+        LCD_WriteReg(0x07, 0x0173);
+        ms_delay(50);
+    }
+    else if (lcddev.id == 0x1505) // OK
+    {
+        // second release on 3/5  ,luminance is acceptable,water wave appear during camera preview
+        LCD_WriteReg(0x0007, 0x0000);
+        ms_delay(50);
+        LCD_WriteReg(0x0012, 0x011C); // 0x011A   why need to set several times?
+        LCD_WriteReg(0x00A4, 0x0001); // NVM
+        LCD_WriteReg(0x0008, 0x000F);
+        LCD_WriteReg(0x000A, 0x0008);
+        LCD_WriteReg(0x000D, 0x0008);
+        //伽马校正
+        LCD_WriteReg(0x0030, 0x0707);
+        LCD_WriteReg(0x0031, 0x0007); // 0x0707
+        LCD_WriteReg(0x0032, 0x0603);
+        LCD_WriteReg(0x0033, 0x0700);
+        LCD_WriteReg(0x0034, 0x0202);
+        LCD_WriteReg(0x0035, 0x0002); //?0x0606
+        LCD_WriteReg(0x0036, 0x1F0F);
+        LCD_WriteReg(0x0037, 0x0707); // 0x0f0f  0x0105
+        LCD_WriteReg(0x0038, 0x0000);
+        LCD_WriteReg(0x0039, 0x0000);
+        LCD_WriteReg(0x003A, 0x0707);
+        LCD_WriteReg(0x003B, 0x0000); // 0x0303
+        LCD_WriteReg(0x003C, 0x0007); //?0x0707
+        LCD_WriteReg(0x003D, 0x0000); // 0x1313//0x1f08
+        ms_delay(50);
+        LCD_WriteReg(0x0007, 0x0001);
+        LCD_WriteReg(0x0017, 0x0001); //开启电源
+        ms_delay(50);
+        //电源配置
+        LCD_WriteReg(0x0010, 0x17A0);
+        LCD_WriteReg(0x0011, 0x0217); // reference voltage VC[2:0]   Vciout = 1.00*Vcivl
+        LCD_WriteReg(0x0012, 0x011E); // 0x011c  //Vreg1out = Vcilvl*1.80   is it the same as Vgama1out ?
+        LCD_WriteReg(0x0013, 0x0F00); // VDV[4:0]-->VCOM Amplitude VcomL = VcomH - Vcom Ampl
+        LCD_WriteReg(0x002A, 0x0000);
+        LCD_WriteReg(0x0029, 0x000A); // 0x0001F  Vcomh = VCM1[4:0]*Vreg1out    gate source voltage??
+        LCD_WriteReg(0x0012, 0x013E); // 0x013C  power supply on
+        // Coordinates Control//
+        LCD_WriteReg(0x0050, 0x0000); // 0x0e00
+        LCD_WriteReg(0x0051, 0x00EF);
+        LCD_WriteReg(0x0052, 0x0000);
+        LCD_WriteReg(0x0053, 0x013F);
+        // Pannel Image Control//
+        LCD_WriteReg(0x0060, 0x2700);
+        LCD_WriteReg(0x0061, 0x0001);
+        LCD_WriteReg(0x006A, 0x0000);
+        LCD_WriteReg(0x0080, 0x0000);
+        // Partial Image Control//
+        LCD_WriteReg(0x0081, 0x0000);
+        LCD_WriteReg(0x0082, 0x0000);
+        LCD_WriteReg(0x0083, 0x0000);
+        LCD_WriteReg(0x0084, 0x0000);
+        LCD_WriteReg(0x0085, 0x0000);
+        // Panel Interface Control//
+        LCD_WriteReg(0x0090, 0x0013); // 0x0010 frenqucy
+        LCD_WriteReg(0x0092, 0x0300);
+        LCD_WriteReg(0x0093, 0x0005);
+        LCD_WriteReg(0x0095, 0x0000);
+        LCD_WriteReg(0x0097, 0x0000);
+        LCD_WriteReg(0x0098, 0x0000);
+
+        LCD_WriteReg(0x0001, 0x0100);
+        LCD_WriteReg(0x0002, 0x0700);
+        LCD_WriteReg(0x0003, 0x1038); //扫描方向 上->下  左->右
+        LCD_WriteReg(0x0004, 0x0000);
+        LCD_WriteReg(0x000C, 0x0000);
+        LCD_WriteReg(0x000F, 0x0000);
+        LCD_WriteReg(0x0020, 0x0000);
+        LCD_WriteReg(0x0021, 0x0000);
+        LCD_WriteReg(0x0007, 0x0021);
+        ms_delay(20);
+        LCD_WriteReg(0x0007, 0x0061);
+        ms_delay(20);
+        LCD_WriteReg(0x0007, 0x0173);
+        ms_delay(20);
+    }
+    else if (lcddev.id == 0xB505)
+    {
+        LCD_WriteReg(0x0000, 0x0000);
+        LCD_WriteReg(0x0000, 0x0000);
+        LCD_WriteReg(0x0000, 0x0000);
+        LCD_WriteReg(0x0000, 0x0000);
+
+        LCD_WriteReg(0x00a4, 0x0001);
+        ms_delay(20);
+        LCD_WriteReg(0x0060, 0x2700);
+        LCD_WriteReg(0x0008, 0x0202);
+
+        LCD_WriteReg(0x0030, 0x0214);
+        LCD_WriteReg(0x0031, 0x3715);
+        LCD_WriteReg(0x0032, 0x0604);
+        LCD_WriteReg(0x0033, 0x0e16);
+        LCD_WriteReg(0x0034, 0x2211);
+        LCD_WriteReg(0x0035, 0x1500);
+        LCD_WriteReg(0x0036, 0x8507);
+        LCD_WriteReg(0x0037, 0x1407);
+        LCD_WriteReg(0x0038, 0x1403);
+        LCD_WriteReg(0x0039, 0x0020);
+
+        LCD_WriteReg(0x0090, 0x001a);
+        LCD_WriteReg(0x0010, 0x0000);
+        LCD_WriteReg(0x0011, 0x0007);
+        LCD_WriteReg(0x0012, 0x0000);
+        LCD_WriteReg(0x0013, 0x0000);
+        ms_delay(20);
+
+        LCD_WriteReg(0x0010, 0x0730);
+        LCD_WriteReg(0x0011, 0x0137);
+        ms_delay(20);
+
+        LCD_WriteReg(0x0012, 0x01b8);
+        ms_delay(20);
+
+        LCD_WriteReg(0x0013, 0x0f00);
+        LCD_WriteReg(0x002a, 0x0080);
+        LCD_WriteReg(0x0029, 0x0048);
+        ms_delay(20);
+
+        LCD_WriteReg(0x0001, 0x0100);
+        LCD_WriteReg(0x0002, 0x0700);
+        LCD_WriteReg(0x0003, 0x1038); //扫描方向 上->下  左->右
+        LCD_WriteReg(0x0008, 0x0202);
+        LCD_WriteReg(0x000a, 0x0000);
+        LCD_WriteReg(0x000c, 0x0000);
+        LCD_WriteReg(0x000d, 0x0000);
+        LCD_WriteReg(0x000e, 0x0030);
+        LCD_WriteReg(0x0050, 0x0000);
+        LCD_WriteReg(0x0051, 0x00ef);
+        LCD_WriteReg(0x0052, 0x0000);
+        LCD_WriteReg(0x0053, 0x013f);
+        LCD_WriteReg(0x0060, 0x2700);
+        LCD_WriteReg(0x0061, 0x0001);
+        LCD_WriteReg(0x006a, 0x0000);
+        // LCD_WriteReg(0x0080,0x0000);
+        // LCD_WriteReg(0x0081,0x0000);
+        LCD_WriteReg(0x0090, 0X0011);
+        LCD_WriteReg(0x0092, 0x0600);
+        LCD_WriteReg(0x0093, 0x0402);
+        LCD_WriteReg(0x0094, 0x0002);
+        ms_delay(20);
+
+        LCD_WriteReg(0x0007, 0x0001);
+        ms_delay(20);
+        LCD_WriteReg(0x0007, 0x0061);
+        LCD_WriteReg(0x0007, 0x0173);
+
+        LCD_WriteReg(0x0020, 0x0000);
+        LCD_WriteReg(0x0021, 0x0000);
+        LCD_WriteReg(0x00, 0x22);
+    }
+    else if (lcddev.id == 0xC505)
+    {
+        LCD_WriteReg(0x0000, 0x0000);
+        LCD_WriteReg(0x0000, 0x0000);
+        ms_delay(20);
+        LCD_WriteReg(0x0000, 0x0000);
+        LCD_WriteReg(0x0000, 0x0000);
+        LCD_WriteReg(0x0000, 0x0000);
+        LCD_WriteReg(0x0000, 0x0000);
+        LCD_WriteReg(0x00a4, 0x0001);
+        ms_delay(20);
+        LCD_WriteReg(0x0060, 0x2700);
+        LCD_WriteReg(0x0008, 0x0806);
+
+        LCD_WriteReg(0x0030, 0x0703); // gamma setting
+        LCD_WriteReg(0x0031, 0x0001);
+        LCD_WriteReg(0x0032, 0x0004);
+        LCD_WriteReg(0x0033, 0x0102);
+        LCD_WriteReg(0x0034, 0x0300);
+        LCD_WriteReg(0x0035, 0x0103);
+        LCD_WriteReg(0x0036, 0x001F);
+        LCD_WriteReg(0x0037, 0x0703);
+        LCD_WriteReg(0x0038, 0x0001);
+        LCD_WriteReg(0x0039, 0x0004);
+
+        LCD_WriteReg(0x0090, 0x0015); // 80Hz
+        LCD_WriteReg(0x0010, 0X0410); // BT,AP
+        LCD_WriteReg(0x0011, 0x0247); // DC1,DC0,VC
+        LCD_WriteReg(0x0012, 0x01BC);
+        LCD_WriteReg(0x0013, 0x0e00);
+        ms_delay(120);
+        LCD_WriteReg(0x0001, 0x0100);
+        LCD_WriteReg(0x0002, 0x0200);
+        LCD_WriteReg(0x0003, 0x1030);
+
+        LCD_WriteReg(0x000A, 0x0008);
+        LCD_WriteReg(0x000C, 0x0000);
+
+        LCD_WriteReg(0x000E, 0x0020);
+        LCD_WriteReg(0x000F, 0x0000);
+        LCD_WriteReg(0x0020, 0x0000); // H Start
+        LCD_WriteReg(0x0021, 0x0000); // V Start
+        LCD_WriteReg(0x002A, 0x003D); // vcom2
+        ms_delay(20);
+        LCD_WriteReg(0x0029, 0x002d);
+        LCD_WriteReg(0x0050, 0x0000);
+        LCD_WriteReg(0x0051, 0xD0EF);
+        LCD_WriteReg(0x0052, 0x0000);
+        LCD_WriteReg(0x0053, 0x013F);
+        LCD_WriteReg(0x0061, 0x0000);
+        LCD_WriteReg(0x006A, 0x0000);
+        LCD_WriteReg(0x0092, 0x0300);
+
+        LCD_WriteReg(0x0093, 0x0005);
+        LCD_WriteReg(0x0007, 0x0100);
+    }
+    else if (lcddev.id == 0x8989) // OK |/|/|
+    {
+        LCD_WriteReg(0x0000, 0x0001); //打开晶振
+        LCD_WriteReg(0x0003, 0xA8A4); // 0xA8A4
+        LCD_WriteReg(0x000C, 0x0000);
+        LCD_WriteReg(0x000D, 0x080C);
+        LCD_WriteReg(0x000E, 0x2B00);
+        LCD_WriteReg(0x001E, 0x00B0);
+        LCD_WriteReg(0x0001, 0x2B3F); //驱动输出控制320*240  0x6B3F
+        LCD_WriteReg(0x0002, 0x0600);
+        LCD_WriteReg(0x0010, 0x0000);
+        LCD_WriteReg(0x0011, 0x6078); //定义数据格式  16位色 		横屏 0x6058
+        LCD_WriteReg(0x0005, 0x0000);
+        LCD_WriteReg(0x0006, 0x0000);
+        LCD_WriteReg(0x0016, 0xEF1C);
+        LCD_WriteReg(0x0017, 0x0003);
+        LCD_WriteReg(0x0007, 0x0233); // 0x0233
+        LCD_WriteReg(0x000B, 0x0000);
+        LCD_WriteReg(0x000F, 0x0000); //扫描开始地址
+        LCD_WriteReg(0x0041, 0x0000);
+        LCD_WriteReg(0x0042, 0x0000);
+        LCD_WriteReg(0x0048, 0x0000);
+        LCD_WriteReg(0x0049, 0x013F);
+        LCD_WriteReg(0x004A, 0x0000);
+        LCD_WriteReg(0x004B, 0x0000);
+        LCD_WriteReg(0x0044, 0xEF00);
+        LCD_WriteReg(0x0045, 0x0000);
+        LCD_WriteReg(0x0046, 0x013F);
+        LCD_WriteReg(0x0030, 0x0707);
+        LCD_WriteReg(0x0031, 0x0204);
+        LCD_WriteReg(0x0032, 0x0204);
+        LCD_WriteReg(0x0033, 0x0502);
+        LCD_WriteReg(0x0034, 0x0507);
+        LCD_WriteReg(0x0035, 0x0204);
+        LCD_WriteReg(0x0036, 0x0204);
+        LCD_WriteReg(0x0037, 0x0502);
+        LCD_WriteReg(0x003A, 0x0302);
+        LCD_WriteReg(0x003B, 0x0302);
+        LCD_WriteReg(0x0023, 0x0000);
+        LCD_WriteReg(0x0024, 0x0000);
+        LCD_WriteReg(0x0025, 0x8000);
+        LCD_WriteReg(0x004f, 0); //行首址0
+        LCD_WriteReg(0x004e, 0); //列首址0
+    }
+    else if (lcddev.id == 0x4531) // OK |/|/|
+    {
+        LCD_WriteReg(0X00, 0X0001);
+        ms_delay(10);
+        LCD_WriteReg(0X10, 0X1628);
+        LCD_WriteReg(0X12, 0X000e); // 0x0006
+        LCD_WriteReg(0X13, 0X0A39);
+        ms_delay(10);
+        LCD_WriteReg(0X11, 0X0040);
+        LCD_WriteReg(0X15, 0X0050);
+        ms_delay(10);
+        LCD_WriteReg(0X12, 0X001e); // 16
+        ms_delay(10);
+        LCD_WriteReg(0X10, 0X1620);
+        LCD_WriteReg(0X13, 0X2A39);
+        ms_delay(10);
+        LCD_WriteReg(0X01, 0X0100);
+        LCD_WriteReg(0X02, 0X0300);
+        LCD_WriteReg(0X03, 0X1038); //改变方向的
+        LCD_WriteReg(0X08, 0X0202);
+        LCD_WriteReg(0X0A, 0X0008);
+        LCD_WriteReg(0X30, 0X0000);
+        LCD_WriteReg(0X31, 0X0402);
+        LCD_WriteReg(0X32, 0X0106);
+        LCD_WriteReg(0X33, 0X0503);
+        LCD_WriteReg(0X34, 0X0104);
+        LCD_WriteReg(0X35, 0X0301);
+        LCD_WriteReg(0X36, 0X0707);
+        LCD_WriteReg(0X37, 0X0305);
+        LCD_WriteReg(0X38, 0X0208);
+        LCD_WriteReg(0X39, 0X0F0B);
+        LCD_WriteReg(0X41, 0X0002);
+        LCD_WriteReg(0X60, 0X2700);
+        LCD_WriteReg(0X61, 0X0001);
+        LCD_WriteReg(0X90, 0X0210);
+        LCD_WriteReg(0X92, 0X010A);
+        LCD_WriteReg(0X93, 0X0004);
+        LCD_WriteReg(0XA0, 0X0100);
+        LCD_WriteReg(0X07, 0X0001);
+        LCD_WriteReg(0X07, 0X0021);
+        LCD_WriteReg(0X07, 0X0023);
+        LCD_WriteReg(0X07, 0X0033);
+        LCD_WriteReg(0X07, 0X0133);
+        LCD_WriteReg(0XA0, 0X0000);
+    }
+    else if (lcddev.id == 0x4535)
+    {
+        LCD_WriteReg(0X15, 0X0030);
+        LCD_WriteReg(0X9A, 0X0010);
+        LCD_WriteReg(0X11, 0X0020);
+        LCD_WriteReg(0X10, 0X3428);
+        LCD_WriteReg(0X12, 0X0002); // 16
+        LCD_WriteReg(0X13, 0X1038);
+        ms_delay(40);
+        LCD_WriteReg(0X12, 0X0012); // 16
+        ms_delay(40);
+        LCD_WriteReg(0X10, 0X3420);
+        LCD_WriteReg(0X13, 0X3038);
+        ms_delay(70);
+        LCD_WriteReg(0X30, 0X0000);
+        LCD_WriteReg(0X31, 0X0402);
+        LCD_WriteReg(0X32, 0X0307);
+        LCD_WriteReg(0X33, 0X0304);
+        LCD_WriteReg(0X34, 0X0004);
+        LCD_WriteReg(0X35, 0X0401);
+        LCD_WriteReg(0X36, 0X0707);
+        LCD_WriteReg(0X37, 0X0305);
+        LCD_WriteReg(0X38, 0X0610);
+        LCD_WriteReg(0X39, 0X0610);
+
+        LCD_WriteReg(0X01, 0X0100);
+        LCD_WriteReg(0X02, 0X0300);
+        LCD_WriteReg(0X03, 0X1030); //改变方向的
+        LCD_WriteReg(0X08, 0X0808);
+        LCD_WriteReg(0X0A, 0X0008);
+        LCD_WriteReg(0X60, 0X2700);
+        LCD_WriteReg(0X61, 0X0001);
+        LCD_WriteReg(0X90, 0X013E);
+        LCD_WriteReg(0X92, 0X0100);
+        LCD_WriteReg(0X93, 0X0100);
+        LCD_WriteReg(0XA0, 0X3000);
+        LCD_WriteReg(0XA3, 0X0010);
+        LCD_WriteReg(0X07, 0X0001);
+        LCD_WriteReg(0X07, 0X0021);
+        LCD_WriteReg(0X07, 0X0023);
+        LCD_WriteReg(0X07, 0X0033);
+        LCD_WriteReg(0X07, 0X0133);
+    }
+    LCD_Display_Dir(0); //默认为竖屏
+    LCD_PWM_HIGH;       //点亮背光
+    LCD_Clear(WHITE);
+}
+//清屏函数
+// color:要清屏的填充色
+void LCD_Clear(u16 color)
+{
+    u32 index      = 0;
+    u32 totalpoint = lcddev.width;
+    totalpoint *= lcddev.height;                    //得到总点数
+    if ((lcddev.id == 0X6804) && (lcddev.dir == 1)) // 6804横屏的时候特殊处理
+    {
+        lcddev.dir     = 0;
+        lcddev.setxcmd = 0X2A;
+        lcddev.setycmd = 0X2B;
+        LCD_SetCursor(0x00, 0x0000); //设置光标位置
+        lcddev.dir     = 1;
+        lcddev.setxcmd = 0X2B;
+        lcddev.setycmd = 0X2A;
+    }
+    else
+        LCD_SetCursor(0x00, 0x0000); //设置光标位置
+    LCD_WriteRAM_Prepare();          //开始写入GRAM
+    for (index = 0; index < totalpoint; index++)
+    {
+        LCD->LCD_RAM = color;
+    }
+}
+//在指定区域内填充单个颜色
+//(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex-sx+1)*(ey-sy+1)
+// color:要填充的颜色
+void LCD_Fill(u16 sx, u16 sy, u16 ex, u16 ey, u16 color)
+{
+    u16 i, j;
+    u16 xlen = 0;
+    u16 temp;
+    if ((lcddev.id == 0X6804) && (lcddev.dir == 1)) // 6804横屏的时候特殊处理
+    {
+        temp           = sx;
+        sx             = sy;
+        sy             = lcddev.width - ex - 1;
+        ex             = ey;
+        ey             = lcddev.width - temp - 1;
+        lcddev.dir     = 0;
+        lcddev.setxcmd = 0X2A;
+        lcddev.setycmd = 0X2B;
+        LCD_Fill(sx, sy, ex, ey, color);
+        lcddev.dir     = 1;
+        lcddev.setxcmd = 0X2B;
+        lcddev.setycmd = 0X2A;
+    }
+    else
+    {
+        xlen = ex - sx + 1;
+        for (i = sy; i <= ey; i++)
+        {
+            LCD_SetCursor(sx, i);   //设置光标位置
+            LCD_WriteRAM_Prepare(); //开始写入GRAM
+            for (j = 0; j < xlen; j++)
+                LCD_WR_DATA(color); //设置光标位置
+        }
+    }
+}
+//在指定区域内填充指定颜色块
+//(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex-sx+1)*(ey-sy+1)
+// color:要填充的颜色
+void LCD_Color_Fill(u16 sx, u16 sy, u16 ex, u16 ey, u16 *color)
+{
+    u16 height, width;
+    u16 i, j;
+    width  = ex - sx + 1; //得到填充的宽度
+    height = ey - sy + 1; //高度
+    for (i = 0; i < height; i++)
+    {
+        LCD_SetCursor(sx, sy + i); //设置光标位置
+        LCD_WriteRAM_Prepare();    //开始写入GRAM
+        for (j = 0; j < width; j++)
+            LCD->LCD_RAM = color[i * height + j]; //写入数据
+    }
+}
+//画线
+// x1,y1:起点坐标
+// x2,y2:终点坐标
+void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2)
+{
+    u16 t;
+    int xerr = 0, yerr = 0, delta_x, delta_y, distance;
+    int incx, incy, uRow, uCol;
+    delta_x = x2 - x1; //计算坐标增量
+    delta_y = y2 - y1;
+    uRow    = x1;
+    uCol    = y1;
+    if (delta_x > 0)
+        incx = 1; //设置单步方向
+    else if (delta_x == 0)
+        incx = 0; //垂直线
+    else
+    {
+        incx    = -1;
+        delta_x = -delta_x;
+    }
+    if (delta_y > 0)
+        incy = 1;
+    else if (delta_y == 0)
+        incy = 0; //水平线
+    else
+    {
+        incy    = -1;
+        delta_y = -delta_y;
+    }
+    if (delta_x > delta_y)
+        distance = delta_x; //选取基本增量坐标轴
+    else
+        distance = delta_y;
+    for (t = 0; t <= distance + 1; t++) //画线输出
+    {
+        LCD_DrawPoint(uRow, uCol); //画点
+        xerr += delta_x;
+        yerr += delta_y;
+        if (xerr > distance)
+        {
+            xerr -= distance;
+            uRow += incx;
+        }
+        if (yerr > distance)
+        {
+            yerr -= distance;
+            uCol += incy;
+        }
+    }
+}
+//画矩形
+//(x1,y1),(x2,y2):矩形的对角坐标
+void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2)
+{
+    LCD_DrawLine(x1, y1, x2, y1);
+    LCD_DrawLine(x1, y1, x1, y2);
+    LCD_DrawLine(x1, y2, x2, y2);
+    LCD_DrawLine(x2, y1, x2, y2);
+}
+//在指定位置画一个指定大小的圆
+//(x,y):中心点
+// r    :半径
+void Draw_Circle(u16 x0, u16 y0, u8 r)
+{
+    int a, b;
+    int di;
+    a  = 0;
+    b  = r;
+    di = 3 - (r << 1); //判断下个点位置的标志
+    while (a <= b)
+    {
+        LCD_DrawPoint(x0 + a, y0 - b); // 5
+        LCD_DrawPoint(x0 + b, y0 - a); // 0
+        LCD_DrawPoint(x0 + b, y0 + a); // 4
+        LCD_DrawPoint(x0 + a, y0 + b); // 6
+        LCD_DrawPoint(x0 - a, y0 + b); // 1
+        LCD_DrawPoint(x0 - b, y0 + a);
+        LCD_DrawPoint(x0 - a, y0 - b); // 2
+        LCD_DrawPoint(x0 - b, y0 - a); // 7
+        a++;
+        //使用Bresenham算法画圆
+        if (di < 0)
+            di += 4 * a + 6;
+        else
+        {
+            di += 10 + 4 * (a - b);
+            b--;
+        }
+    }
+}
+//在指定位置显示一个字符
+// x,y:起始坐标
+// num:要显示的字符:" "--->"~"
+// size:字体大小 12/16
+// mode:叠加方式(1)还是非叠加方式(0)
+void LCD_ShowChar(u16 x, u16 y, u8 num, u8 size, u8 mode)
+{
+    u8  temp, t1, t;
+    u16 y0        = y;
+    u16 colortemp = POINT_COLOR;
+    //设置窗口
+    num = num - ' '; //得到偏移后的值
+    if (!mode)       //非叠加方式
+    {
+        for (t = 0; t < size; t++)
+        {
+            if (size == 12)
+                temp = asc2_1206[num][t]; //调用1206字体
+            else
+                temp = asc2_1608[num][t]; //调用1608字体
+            for (t1 = 0; t1 < 8; t1++)
+            {
+                if (temp & 0x80)
+                    POINT_COLOR = colortemp;
+                else
+                    POINT_COLOR = BACK_COLOR;
+                LCD_DrawPoint(x, y);
+                temp <<= 1;
+                y++;
+                if (x >= lcddev.width)
+                {
+                    POINT_COLOR = colortemp;
+                    return;
+                } //超区域了
+                if ((y - y0) == size)
+                {
+                    y = y0;
+                    x++;
+                    if (x >= lcddev.width)
+                    {
+                        POINT_COLOR = colortemp;
+                        return;
+                    } //超区域了
+                    break;
+                }
+            }
+        }
+    }
+    else //叠加方式
+    {
+        for (t = 0; t < size; t++)
+        {
+            if (size == 12)
+                temp = asc2_1206[num][t]; //调用1206字体
+            else
+                temp = asc2_1608[num][t]; //调用1608字体
+            for (t1 = 0; t1 < 8; t1++)
+            {
+                if (temp & 0x80)
+                    LCD_DrawPoint(x, y);
+                temp <<= 1;
+                y++;
+                if (x >= lcddev.height)
+                {
+                    POINT_COLOR = colortemp;
+                    return;
+                } //超区域了
+                if ((y - y0) == size)
+                {
+                    y = y0;
+                    x++;
+                    if (x >= lcddev.width)
+                    {
+                        POINT_COLOR = colortemp;
+                        return;
+                    } //超区域了
+                    break;
+                }
+            }
+        }
+    }
+    POINT_COLOR = colortemp;
+}
+// m^n函数
+//返回值:m^n次方.
+u32 LCD_Pow(u8 m, u8 n)
+{
+    u32 result = 1;
+    while (n--)
+        result *= m;
+    return result;
+}
+//显示数字,高位为0,则不显示
+// x,y :起点坐标
+// len :数字的位数
+// size:字体大小
+// color:颜色
+// num:数值(0~4294967295);
+void LCD_ShowNum(u16 x, u16 y, u32 num, u8 len, u8 size)
+{
+    u8 t, temp;
+    u8 enshow = 0;
+    for (t = 0; t < len; t++)
+    {
+        temp = (num / LCD_Pow(10, len - t - 1)) % 10;
+        if (enshow == 0 && t < (len - 1))
+        {
+            if (temp == 0)
+            {
+                LCD_ShowChar(x + (size / 2) * t, y, ' ', size, 0);
+                continue;
+            }
+            else
+                enshow = 1;
+        }
+        LCD_ShowChar(x + (size / 2) * t, y, temp + '0', size, 0);
+    }
+}
+//显示数字,高位为0,还是显示
+// x,y:起点坐标
+// num:数值(0~999999999);
+// len:长度(即要显示的位数)
+// size:字体大小
+// mode:
+//[7]:0,不填充;1,填充0.
+//[6:1]:保留
+//[0]:0,非叠加显示;1,叠加显示.
+void LCD_ShowxNum(u16 x, u16 y, u32 num, u8 len, u8 size, u8 mode)
+{
+    u8 t, temp;
+    u8 enshow = 0;
+    for (t = 0; t < len; t++)
+    {
+        temp = (num / LCD_Pow(10, len - t - 1)) % 10;
+        if (enshow == 0 && t < (len - 1))
+        {
+            if (temp == 0)
+            {
+                if (mode & 0X80)
+                    LCD_ShowChar(x + (size / 2) * t, y, '0', size, mode & 0X01);
+                else
+                    LCD_ShowChar(x + (size / 2) * t, y, ' ', size, mode & 0X01);
+                continue;
+            }
+            else
+                enshow = 1;
+        }
+        LCD_ShowChar(x + (size / 2) * t, y, temp + '0', size, mode & 0X01);
+    }
+}
+//显示字符串
+// x,y:起点坐标
+// width,height:区域大小
+// size:字体大小
+//*p:字符串起始地址
+void LCD_ShowString(u16 x, u16 y, u16 width, u16 height, u8 size, u8 *p)
+{
+    u8 x0 = x;
+    width += x;
+    height += y;
+    while ((*p <= '~') && (*p >= ' ')) //判断是不是非法字符!
+    {
+        if (x >= width)
+        {
+            x = x0;
+            y += size;
+        }
+        if (y >= height)
+            break; //退出
+        LCD_ShowChar(x, y, *p, size, 0);
+        x += size / 2;
+        p++;
+    }
+}

+ 270 - 0
User/Bsp/lcd/lcd.h

@@ -0,0 +1,270 @@
+#ifndef __LCD_H
+#define __LCD_H
+#include "interface.h"
+#include "stdlib.h"
+
+//////////////////////////////////////////////////////////////////////////////////
+//本程序只供学习使用,未经作者许可,不得用于其它任何用途
+// ALIENTEK战舰STM32开发板
+// 2.4寸/2.8寸/3.5寸/4.3寸 TFT液晶驱动
+//支持驱动IC型号包括:ILI9341/ILI9325/RM68042/RM68021/ILI9320/ILI9328/LGDP4531/LGDP4535/
+//                  SPFD5408/SSD1289/1505/B505/C505/NT35310/NT35510等
+//正点原子@ALIENTEK
+//技术论坛:www.openedv.com
+//修改日期:2014/2/11
+//版本:V2.5
+//版权所有,盗版必究。
+// Copyright(C) 广州市星翼电子科技有限公司 2009-2019
+// All rights reserved
+//********************************************************************************
+// V1.2修改说明
+//支持了SPFD5408的驱动,另外把液晶ID直接打印成HEX格式.方便查看LCD驱动IC.
+// V1.3
+//加入了快速IO的支持
+//修改了背光控制的极性(适用于V1.8及以后的开发板版本)
+//对于1.8版本之前(不包括1.8)的液晶模块,请修改LCD_Init函数的LCD_LED=1;为LCD_LED=1;
+// V1.4
+//修改了LCD_ShowChar函数,使用画点功能画字符。
+//加入了横竖屏显示的支持
+// V1.5 20110730
+// 1,修改了B505液晶读颜色有误的bug.
+// 2,修改了快速IO及横竖屏的设置方式.
+// V1.6 20111116
+// 1,加入对LGDP4535液晶的驱动支持
+// V1.7 20120713
+// 1,增加LCD_RD_DATA函数
+// 2,增加对ILI9341的支持
+// 3,增加ILI9325的独立驱动代码
+// 4,增加LCD_Scan_Dir函数(慎重使用)
+// 6,另外修改了部分原来的函数,以适应9341的操作
+// V1.8 20120905
+// 1,加入LCD重要参数设置结构体lcddev
+// 2,加入LCD_Display_Dir函数,支持在线横竖屏切换
+// V1.9 20120911
+// 1,新增RM68042驱动(ID:6804),但是6804不支持横屏显示!!原因:改变扫描方式,
+//导致6804坐标设置失效,试过很多方法都不行,暂时无解。
+// V2.0 20120924
+//在不硬件复位的情况下,ILI9341的ID读取会被误读成9300,修改LCD_Init,将无法识别
+//的情况(读到ID为9300/非法ID),强制指定驱动IC为ILI9341,执行9341的初始化。
+// V2.1 20120930
+//修正ILI9325读颜色的bug。
+// V2.2 20121007
+//修正LCD_Scan_Dir的bug。
+// V2.3 20130120
+//新增6804支持横屏显示
+// V2.4 20131120
+// 1,新增NT35310(ID:5310)驱动器的支持
+// 2,新增LCD_Set_Window函数,用于设置窗口,对快速填充,比较有用,但是该函数在横屏时,不支持6804.
+// V2.5 20140211
+// 1,新增NT35510(ID:5510)驱动器的支持
+//////////////////////////////////////////////////////////////////////////////////
+
+// LCD重要参数集
+typedef struct
+{
+    u16 width;   // LCD 宽度
+    u16 height;  // LCD 高度
+    u16 id;      // LCD ID
+    u8  dir;     //横屏还是竖屏控制:0,竖屏;1,横屏。
+    u16 wramcmd; //开始写gram指令
+    u16 setxcmd; //设置x坐标指令
+    u16 setycmd; //设置y坐标指令
+} _lcd_dev;
+
+// LCD参数
+extern _lcd_dev lcddev; //管理LCD重要参数
+// LCD的画笔颜色和背景色
+extern u16 POINT_COLOR; //默认红色
+extern u16 BACK_COLOR;  //背景颜色.默认为白色
+
+//////////////////////////////////////////////////////////////////////////////////
+//-----------------LCD端口定义----------------
+#define LCD_LED PBout(0) // LCD背光    		 PB0
+// LCD地址结构体
+typedef struct
+{
+    u16 LCD_REG;
+    u16 LCD_RAM;
+} LCD_TypeDef;
+//使用NOR/SRAM的 Bank1.sector4,地址位HADDR[27,26]=11 A10作为数据命令区分线
+//注意设置时STM32内部会右移一位对其! 111110=0X3E
+#define LCD_BASE ((u32)(0x6C000000 | 0x000007FE))
+#define LCD      ((LCD_TypeDef *)LCD_BASE)
+//////////////////////////////////////////////////////////////////////////////////
+
+//扫描方向定义
+#define L2R_U2D 0 //从左到右,从上到下
+#define L2R_D2U 1 //从左到右,从下到上
+#define R2L_U2D 2 //从右到左,从上到下
+#define R2L_D2U 3 //从右到左,从下到上
+
+#define U2D_L2R 4 //从上到下,从左到右
+#define U2D_R2L 5 //从上到下,从右到左
+#define D2U_L2R 6 //从下到上,从左到右
+#define D2U_R2L 7 //从下到上,从右到左
+
+#define DFT_SCAN_DIR L2R_U2D //默认的扫描方向
+//画笔颜色
+#define WHITE   0xFFFF
+#define BLACK   0x0000
+#define BLUE    0x001F
+#define BRED    0XF81F
+#define GRED    0XFFE0
+#define GBLUE   0X07FF
+#define RED     0xF800
+#define MAGENTA 0xF81F
+#define GREEN   0x07E0
+#define CYAN    0x7FFF
+#define YELLOW  0xFFE0
+#define BROWN   0XBC40 //棕色
+#define BRRED   0XFC07 //棕红色
+#define GRAY    0X8430 //灰色
+// GUI颜色
+
+#define DARKBLUE  0X01CF //深蓝色
+#define LIGHTBLUE 0X7D7C //浅蓝色
+#define GRAYBLUE  0X5458 //灰蓝色
+//以上三色为PANEL的颜色
+
+#define LIGHTGREEN 0X841F //浅绿色
+//#define LIGHTGRAY        0XEF5B //浅灰色(PANNEL)
+#define LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色
+
+#define LGRAYBLUE 0XA651 //浅灰蓝色(中间层颜色)
+#define LBBLUE    0X2B12 //浅棕蓝色(选择条目的反色)
+
+void LCD_Init(void);                                                      //初始化
+void LCD_DisplayOn(void);                                                 //开显示
+void LCD_DisplayOff(void);                                                //关显示
+void LCD_Clear(u16 Color);                                                //清屏
+void LCD_SetCursor(u16 Xpos, u16 Ypos);                                   //设置光标
+void LCD_DrawPoint(u16 x, u16 y);                                         //画点
+void LCD_Fast_DrawPoint(u16 x, u16 y, u16 color);                         //快速画点
+u16  LCD_ReadPoint(u16 x, u16 y);                                         //读点
+void Draw_Circle(u16 x0, u16 y0, u8 r);                                   //画圆
+void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2);                        //画线
+void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2);                   //画矩形
+void LCD_Fill(u16 sx, u16 sy, u16 ex, u16 ey, u16 color);                 //填充单色
+void LCD_Color_Fill(u16 sx, u16 sy, u16 ex, u16 ey, u16 *color);          //填充指定颜色
+void LCD_ShowChar(u16 x, u16 y, u8 num, u8 size, u8 mode);                //显示一个字符
+void LCD_ShowNum(u16 x, u16 y, u32 num, u8 len, u8 size);                 //显示一个数字
+void LCD_ShowxNum(u16 x, u16 y, u32 num, u8 len, u8 size, u8 mode);       //显示 数字
+void LCD_ShowString(u16 x, u16 y, u16 width, u16 height, u8 size, u8 *p); //显示一个字符串,12/16字体
+
+void LCD_WriteReg(u16 LCD_Reg, u16 LCD_RegValue);
+u16  LCD_ReadReg(u16 LCD_Reg);
+void LCD_WriteRAM_Prepare(void);
+void LCD_WriteRAM(u16 RGB_Code);
+void LCD_Scan_Dir(u8 dir);                                  //设置屏扫描方向
+void LCD_Display_Dir(u8 dir);                               //设置屏幕显示方向
+void LCD_Set_Window(u16 sx, u16 sy, u16 width, u16 height); //设置窗口
+// 9320/9325 LCD寄存器
+#define R0   0x00
+#define R1   0x01
+#define R2   0x02
+#define R3   0x03
+#define R4   0x04
+#define R5   0x05
+#define R6   0x06
+#define R7   0x07
+#define R8   0x08
+#define R9   0x09
+#define R10  0x0A
+#define R12  0x0C
+#define R13  0x0D
+#define R14  0x0E
+#define R15  0x0F
+#define R16  0x10
+#define R17  0x11
+#define R18  0x12
+#define R19  0x13
+#define R20  0x14
+#define R21  0x15
+#define R22  0x16
+#define R23  0x17
+#define R24  0x18
+#define R25  0x19
+#define R26  0x1A
+#define R27  0x1B
+#define R28  0x1C
+#define R29  0x1D
+#define R30  0x1E
+#define R31  0x1F
+#define R32  0x20
+#define R33  0x21
+#define R34  0x22
+#define R36  0x24
+#define R37  0x25
+#define R40  0x28
+#define R41  0x29
+#define R43  0x2B
+#define R45  0x2D
+#define R48  0x30
+#define R49  0x31
+#define R50  0x32
+#define R51  0x33
+#define R52  0x34
+#define R53  0x35
+#define R54  0x36
+#define R55  0x37
+#define R56  0x38
+#define R57  0x39
+#define R59  0x3B
+#define R60  0x3C
+#define R61  0x3D
+#define R62  0x3E
+#define R63  0x3F
+#define R64  0x40
+#define R65  0x41
+#define R66  0x42
+#define R67  0x43
+#define R68  0x44
+#define R69  0x45
+#define R70  0x46
+#define R71  0x47
+#define R72  0x48
+#define R73  0x49
+#define R74  0x4A
+#define R75  0x4B
+#define R76  0x4C
+#define R77  0x4D
+#define R78  0x4E
+#define R79  0x4F
+#define R80  0x50
+#define R81  0x51
+#define R82  0x52
+#define R83  0x53
+#define R96  0x60
+#define R97  0x61
+#define R106 0x6A
+#define R118 0x76
+#define R128 0x80
+#define R129 0x81
+#define R130 0x82
+#define R131 0x83
+#define R132 0x84
+#define R133 0x85
+#define R134 0x86
+#define R135 0x87
+#define R136 0x88
+#define R137 0x89
+#define R139 0x8B
+#define R140 0x8C
+#define R141 0x8D
+#define R143 0x8F
+#define R144 0x90
+#define R145 0x91
+#define R146 0x92
+#define R147 0x93
+#define R148 0x94
+#define R149 0x95
+#define R150 0x96
+#define R151 0x97
+#define R152 0x98
+#define R153 0x99
+#define R154 0x9A
+#define R157 0x9D
+#define R192 0xC0
+#define R193 0xC1
+#define R229 0xE5
+#endif

+ 1 - 1
User/Bsp/nor_flash/nor_flash.h

@@ -18,7 +18,7 @@
 #ifndef _NOR_FLASH_H
 #define _NOR_FLASH_H
 
-#include "includes.h"
+#include "interface.h"
 
 /*
     安富莱STM32-V5开发板 NOR Flash 型号 S29GL128P10TFI01

+ 6 - 6
User/Bsp/rtc/rtc.c

@@ -28,7 +28,7 @@ NVIC_InitTypeDef NVIC_InitStructure;
 // ampm:@RTC_AM_PM_Definitions  :RTC_H12_AM/RTC_H12_PM
 //返回值:SUCEE(1),成功
 //        ERROR(0),进入初始化模式失败
-ErrorStatus RTC_Set_Time(u8 hour, u8 min, u8 sec, u8 ampm)
+ErrorStatus RTC_Set_Time(uint8_t hour, uint8_t min, uint8_t sec, uint8_t ampm)
 {
     RTC_TimeTypeDef RTC_TimeTypeInitStructure;
 
@@ -44,7 +44,7 @@ ErrorStatus RTC_Set_Time(u8 hour, u8 min, u8 sec, u8 ampm)
 // week:星期(1~7,0,非法!)
 //返回值:SUCEE(1),成功
 //        ERROR(0),进入初始化模式失败
-ErrorStatus RTC_Set_Date(u8 year, u8 month, u8 date, u8 week)
+ErrorStatus RTC_Set_Date(uint8_t year, uint8_t month, uint8_t date, uint8_t week)
 {
 
     RTC_DateTypeDef RTC_DateTypeInitStructure;
@@ -59,10 +59,10 @@ ErrorStatus RTC_Set_Date(u8 year, u8 month, u8 date, u8 week)
 //返回值:0,初始化成功;
 //        1,LSE开启失败;
 //        2,进入初始化模式失败;
-u8 MyRTC_Init(void)
+uint8_t MyRTC_Init(void)
 {
     RTC_InitTypeDef RTC_InitStructure;
-    u16             retry = 0X1FFF;
+    uint16_t        retry = 0X1FFF;
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能PWR时钟
     PWR_BackupAccessCmd(ENABLE);                        //使能后备寄存器访问
 
@@ -100,10 +100,10 @@ u8 MyRTC_Init(void)
  * Return:
  * Others:
  */
-u32 GetCur_TimeStamp(void)
+uint32_t GetCur_TimeStamp(void)
 {
     struct tm TmStruct;
-    u32       UnixNum;
+    uint32_t  UnixNum;
 
     RTC_DateTypeDef RTC_DateStruct;
     RTC_TimeTypeDef RTC_TimeStruct;

+ 6 - 6
User/Bsp/rtc/rtc.h

@@ -18,12 +18,12 @@
 //新增:RTC_Get_Week函数,用于根据年月日信息,得到星期信息.
 //////////////////////////////////////////////////////////////////////////////////
 
-u8          MyRTC_Init(void);                                  // RTC初始化
-ErrorStatus RTC_Set_Time(u8 hour, u8 min, u8 sec, u8 ampm);    // RTC时间设置
-ErrorStatus RTC_Set_Date(u8 year, u8 month, u8 date, u8 week); // RTC日期设置
-// void RTC_Set_AlarmA(u8 week,u8 hour,u8 min,u8 sec);		//设置闹钟时间(按星期闹铃,24小时制)
-// void RTC_Set_WakeUp(u32 wksel,u16 cnt);					//周期性唤醒定时器设置
+uint8_t     MyRTC_Init(void);                                                      // RTC初始化
+ErrorStatus RTC_Set_Time(uint8_t hour, uint8_t min, uint8_t sec, uint8_t ampm);    // RTC时间设置
+ErrorStatus RTC_Set_Date(uint8_t year, uint8_t month, uint8_t date, uint8_t week); // RTC日期设置
+// void RTC_Set_AlarmA(uint8_t week,uint8_t hour,uint8_t min,uint8_t sec);		//设置闹钟时间(按星期闹铃,24小时制)
+// void RTC_Set_WakeUp(uint32_t wksel,uint16_t cnt);					//周期性唤醒定时器设置
 
-u32 GetCur_TimeStamp(void);
+uint32_t GetCur_TimeStamp(void);
 
 #endif

+ 10 - 10
User/Bsp/spi/spi.c

@@ -1,11 +1,11 @@
 #include "spi.h"
 
-u8 spi1_rec_buf[SPI1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
-u8 spi1_tx_buf[SPI1_TX_LEN];   // 发送缓冲区
-u8 spi1_rec_cnt;
-u8 spi1_rec_flag = 0; // spi1接收标志位
+uint8_t spi1_rec_buf[SPI1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
+uint8_t spi1_tx_buf[SPI1_TX_LEN];   // 发送缓冲区
+uint8_t spi1_rec_cnt;
+uint8_t spi1_rec_flag = 0; // spi1接收标志位
 
-void SPI1DMA_Enable(DMA_Stream_TypeDef *DMA_Streamx, u16 count)
+void SPI1DMA_Enable(DMA_Stream_TypeDef *DMA_Streamx, uint16_t count)
 {
     DMA_Cmd(DMA_Streamx, DISABLE); //关闭DMA传输
     while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE)
@@ -50,8 +50,8 @@ void spi1_dma_config(void)
 
     /* 配置 DMA Stream */
     DMA_InitStructure.DMA_Channel            = SPI1_DMA;                   //通道选择
-    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;             // DMA外设地址
-    DMA_InitStructure.DMA_Memory0BaseAddr    = (u32)spi1_tx_buf;           // DMA 存储器0地址
+    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;        // DMA外设地址
+    DMA_InitStructure.DMA_Memory0BaseAddr    = (uint32_t)spi1_tx_buf;      // DMA 存储器0地址
     DMA_InitStructure.DMA_DIR                = DMA_DIR_MemoryToPeripheral; //存储器到外设模式
 
     DMA_InitStructure.DMA_BufferSize         = SPI1_TX_LEN;                 //数据传输量
@@ -74,8 +74,8 @@ void spi1_dma_config(void)
         ; //等待DMA可配置
     /* 配置 DMA Stream */
     DMA_InitStructure.DMA_Channel            = SPI1_DMA;                   //通道选择
-    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;             // DMA外设地址
-    DMA_InitStructure.DMA_Memory0BaseAddr    = (u32)spi1_rec_buf;          // DMA 存储器0地址
+    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;        // DMA外设地址
+    DMA_InitStructure.DMA_Memory0BaseAddr    = (uint32_t)spi1_rec_buf;     // DMA 存储器0地址
     DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralToMemory; //外设到存储器模式
 
     DMA_InitStructure.DMA_BufferSize         = SPI1_REC_LEN;                //数据传输量
@@ -105,7 +105,7 @@ void spi1_init(void)
     SPI_I2S_ClearITPendingBit(SPI1, SPI_I2S_IT_RXNE);
 }
 
-void SPI1DMA_Trans(const u8 *data, u16 count)
+void SPI1DMA_Trans(const uint8_t *data, uint16_t count)
 {
     DMA_Cmd(SPI1_DMA_RXCH, DISABLE);
     DMA_Cmd(SPI1_DMA_TXCH, DISABLE);

+ 1 - 1
User/Bsp/spi/spi.h

@@ -11,6 +11,6 @@
 #define SPI1_DMA_TXCH DMA2_Stream3
 
 void spi1_init(void);
-void SPI1DMA_Trans(const u8 *data, u16 count);
+void SPI1DMA_Trans(const uint8_t *data, uint16_t count);
 
 #endif

+ 1 - 1
User/Bsp/timer/timer.c

@@ -37,7 +37,7 @@ void user_timer_init(void)
 
 void TIM2_IRQHandler(void)
 {
-    static INT16U cnt = 0;
+    static uint16_t cnt = 0;
     if (cnt >= 100)
     {
         IWDG_ReloadCounter();

+ 1 - 1
User/Bsp/timer/timer.h

@@ -1,6 +1,6 @@
 #ifndef __TIMER_H
 #define __TIMER_H
-#include "includes.h"
+#include "interface.h"
 #include "stm32f4xx_iwdg.h"
 #include "stm32f4xx_tim.h"
 

+ 7 - 7
User/Bsp/uart/uart1.c

@@ -11,14 +11,14 @@
 #include "uart1.h"
 #include "queue.h"
 
-static INT8U uart1_tx_buf[UART1_TX_LEN]  = {0};
-static INT8U uart1_rx_buf[UART1_REC_LEN] = {0};
+static uint8_t uart1_tx_buf[UART1_TX_LEN]  = {0};
+static uint8_t uart1_rx_buf[UART1_REC_LEN] = {0};
 
-__IO INT8U rx_index = 0x00;
+__IO uint8_t rx_index = 0x00;
 
-__IO INT8U tx_index = 0x00;
+__IO uint8_t tx_index = 0x00;
 
-__IO INT8U TimeOut = 0x00;
+__IO uint8_t TimeOut = 0x00;
 
 //  重定义fputc函数
 #ifdef __GNUC__
@@ -50,7 +50,7 @@ int _read(int fd, char *buffer, int size)
 }
 // int _write(int fd, char *buffer, int size)
 // {
-//     uart1_dma_send((INT8U *)buffer, size);
+//     uart1_dma_send((uint8_t *)buffer, size);
 //     while (USART_GetITStatus(USART1, USART_IT_TC) != RESET)
 //         ;
 //     return size;
@@ -62,7 +62,7 @@ int _read(int fd, char *buffer, int size)
 //     /* 等待串口1输入数据 */
 //     while (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
 //         ;
-//     // INT8U err = 0;
+//     // uint8_t err = 0;
 //     // UartFrame_TypeDef *msg;
 
 //     // msg = (UartFrame_TypeDef *)OSMboxPend(uart1_mbox, 50, &err);

+ 0 - 1
User/Bsp/uart/uart1.h

@@ -1,7 +1,6 @@
 #ifndef __UART1_H
 #define __UART1_H
 
-#include "includes.h"
 #include "interface.h"
 #include "stm32f4xx_usart.h"
 #include "string.h"

+ 14 - 14
User/Bsp/uart/uart3.c

@@ -11,8 +11,8 @@
 
 #include "uart3.h"
 
-static INT8U uart3_tx_buf[UART3_TX_LEN]  = {0};
-static INT8U uart3_rx_buf[UART3_REC_LEN] = {0};
+static uint8_t uart3_tx_buf[UART3_TX_LEN]  = {0};
+static uint8_t uart3_rx_buf[UART3_REC_LEN] = {0};
 
 UartFrame_TypeDef Uart3FrameStruct[UART3_MAX_MSG_NUM];
 
@@ -32,7 +32,7 @@ void uart3_nvic_config(void)
 void uart3_dma_init(void)
 {
     DMA_InitTypeDef DMA_InitStructure;
-    if ((u32)UART3_DMA_TXCH > (u32)DMA2)
+    if ((uint32_t)UART3_DMA_TXCH > (uint32_t)DMA2)
     {
         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // DMA2时钟使能
     }
@@ -46,8 +46,8 @@ void uart3_dma_init(void)
     } //等待DMA可配置
     /* 配置 DMA Stream */
     DMA_InitStructure.DMA_Channel            = UART3_DMA;                   //通道选择
-    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART3->DR;            // DMA外设地址
-    DMA_InitStructure.DMA_Memory0BaseAddr    = (u32)uart3_tx_buf;           // DMA 存储器0地址
+    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3->DR;       // DMA外设地址
+    DMA_InitStructure.DMA_Memory0BaseAddr    = (uint32_t)uart3_tx_buf;      // DMA 存储器0地址
     DMA_InitStructure.DMA_DIR                = DMA_DIR_MemoryToPeripheral;  //存储器到外设模式
     DMA_InitStructure.DMA_BufferSize         = UART3_TX_LEN;                //数据传输量
     DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;   //外设非增量模式
@@ -62,7 +62,7 @@ void uart3_dma_init(void)
     DMA_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single; //外设突发单次传输
     DMA_Init(UART3_DMA_TXCH, &DMA_InitStructure);                          //初始化DMA Stream
 
-    if ((u32)UART3_DMA_RXCH > (u32)DMA2) //得到当前stream是属于DMA2还是DMA1
+    if ((uint32_t)UART3_DMA_RXCH > (uint32_t)DMA2) //得到当前stream是属于DMA2还是DMA1
     {
         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // DMA2时钟使能
     }
@@ -77,8 +77,8 @@ void uart3_dma_init(void)
     } //等待DMA可配置
     /* 配置 DMA Stream */
     DMA_InitStructure.DMA_Channel            = UART3_DMA;                   //通道选择
-    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART3->DR;            // DMA外设地址
-    DMA_InitStructure.DMA_Memory0BaseAddr    = (u32)uart3_rx_buf;           // DMA 存储器0地址
+    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3->DR;       // DMA外设地址
+    DMA_InitStructure.DMA_Memory0BaseAddr    = (uint32_t)uart3_rx_buf;      // DMA 存储器0地址
     DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralToMemory;  //外设到存储器模式
     DMA_InitStructure.DMA_BufferSize         = UART3_REC_LEN;               //数据传输量
     DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;   //外设非增量模式
@@ -141,9 +141,9 @@ void uart3_init(void)
  *  入口参数:buf 待发送数据  len 数据长度
  *  说    明:
  *****************************************************/
-void Uart3_Send_Data(const INT8U *buf, INT16U len)
+void Uart3_Send_Data(const uint8_t *buf, uint16_t len)
 {
-    INT8U i;
+    uint8_t i;
 
     UART3_TX_ENABLE;          // 485 发送使能
     for (i = 0; i < len; i++) //循环发送数据
@@ -158,7 +158,7 @@ void Uart3_Send_Data(const INT8U *buf, INT16U len)
     UART3_RX_ENABLE; // 接收使能
 }
 
-void uart3_dma_send(const INT8U *buf, INT16U len)
+void uart3_dma_send(const uint8_t *buf, uint16_t len)
 {
     if (DMA_GetFlagStatus(UART3_DMA_TXCH, DMA_FLAG_TCIF3) != RESET)
     {
@@ -177,9 +177,9 @@ void uart3_dma_send(const INT8U *buf, INT16U len)
 
 void USART3_IRQHandler(void)
 {
-    static INT8U   u3_index = 0;
-    volatile INT8U clear    = 0;
-    INT8U          rec_cnt  = 0;
+    static uint8_t   u3_index = 0;
+    volatile uint8_t clear    = 0;
+    uint8_t          rec_cnt  = 0;
     if (RESET != USART_GetITStatus(USART3, USART_IT_IDLE))
     {
         clear = USART3->SR;

+ 1 - 2
User/Bsp/uart/uart3.h

@@ -1,7 +1,6 @@
 #ifndef __UART3_H
 #define __UART3_H
 
-#include "includes.h"
 #include "interface.h"
 #include "queue.h"
 #include "stm32f4xx_usart.h"
@@ -16,6 +15,6 @@
 #define UART3_DMA_TXCH DMA1_Stream3
 
 void uart3_init(void);
-void uart3_dma_send(const INT8U *buf, INT16U len);
+void uart3_dma_send(const uint8_t *buf, uint16_t len);
 
 #endif // __UART3_H

+ 1 - 1
User/app/iec104/iec101.c

@@ -4,7 +4,7 @@
 #include "iec10x_conf.h"
 #include "iec10x_type.h"
 
-#ifdef IEC101_STM32
+#ifdef IEC101_SET
 /*
  * GLOABLE VARIALBLE
  */

+ 1 - 1
User/app/iec104/iec101.h

@@ -23,7 +23,7 @@ History      :
 #include <stdio.h>
 #include <string.h>
 
-#ifdef IEC101_STM32
+#ifdef IEC101_SET
 #define ARM_PACK __packed
 #ifdef __cplusplus
 extern "C"

+ 1 - 0
User/app/iec104/iec104.c

@@ -7,6 +7,7 @@
  */
 
 iec_8u Iec104_Sendbuf[IEC104_MAX_BUF_LEN];
+
 /*
  * STATE
  * */

+ 13 - 2
User/app/iec104/iec10x.c

@@ -1,3 +1,14 @@
+/**
+************************************************************************************************
+* @文件    : Iec10x.c
+* @作者    : 樊春春
+* @版本    : V1.0
+* @时间    : 2022/07/09 16:18:42
+* @邮箱    : [email protected]
+* @说明    :
+************************************************************************************************
+**/
+
 #include "iec10x.h"
 #include "iec10x_conf.h"
 #include "iec10x_type.h"
@@ -190,9 +201,9 @@ iec_32s RegisterIEC10XMoudle(void *_IEC10X)
             ret = IEC10X->Init();
             if (0 == ret)
             {
-#ifdef IEC101_STM32
+#ifdef IEC101_SET
                 LOG("\r\nRegister \"%s\" IEC101 Success, < HuiXing 2014-2015 > ...\r\n", IEC10X->name);
-#elif defined(IEC104_STM32)
+#elif defined(IEC104_SET)
                 LOG("\r\nRegister \"%s\" IEC104 Success, < HuiXing 2014-2015 > ...\r\n", IEC10X->name);
 #endif
             }

+ 22 - 28
User/app/iec104/iec10x.h

@@ -1,19 +1,13 @@
-/*******************************************************************
-Copyright (C):
-File name    :    Iec10x.h
-DESCRIPTION  :
-AUTHOR       :
-Version      :    1.0
-Date         :    2014/07/23
-Others       :
-History      :
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-1) Date: 2014/07/23         Author: ChenDajie
-   content:
-           add iec104
-
-*******************************************************************/
-
+/**
+************************************************************************************************
+* @文件    : Iec10x.h
+* @作者    : 樊春春
+* @版本    : V1.0
+* @时间    : 2022/07/09 16:18:16
+* @邮箱    : [email protected]
+* @说明    :
+************************************************************************************************
+**/
 #ifndef _IEC10X_H
 #define _IEC10X_H
 
@@ -29,9 +23,9 @@ History      :
 #define IEC10XLOCK
 #define PRIO_QUEUE
 
-#ifdef IEC101_STM32
+#ifdef IEC101_SET
 #define IEC10X_PRIO_MAX 7
-#elif defined(IEC104_STM32)
+#elif defined(IEC104_SET)
 #define IEC10X_PRIO_MAX 7
 #endif
 #define IEC10X_HEADER_LENGTH 1
@@ -255,11 +249,11 @@ typedef struct
  * */
 typedef struct
 {
-#ifdef IEC101_STM32
+#ifdef IEC101_SET
     iec_8u _reason : 6;
     iec_8u _pn     : 1;
     iec_8u _test   : 1;
-#elif defined(IEC104_STM32)
+#elif defined(IEC104_SET)
     iec_16u _reason : 14;
     iec_16u _pn     : 1;
     iec_16u _test   : 1;
@@ -284,9 +278,9 @@ typedef struct
 typedef struct
 {
 
-#ifdef IEC101_STM32
+#ifdef IEC101_SET
     iec_16u _addr;
-#elif defined(IEC104_STM32)
+#elif defined(IEC104_SET)
     iec_8u  _addr[3];
 #endif
     iec_8u _element[1];
@@ -326,9 +320,9 @@ typedef struct
 typedef struct
 {
 
-#ifdef IEC101_STM32
+#ifdef IEC101_SET
     iec_16u _addr;
-#elif defined(IEC104_STM32)
+#elif defined(IEC104_SET)
     iec_8u  _addr[3];
 #endif
     iec_16s _detect;
@@ -339,9 +333,9 @@ typedef struct
 typedef struct
 {
 
-#ifdef IEC101_STM32
+#ifdef IEC101_SET
     iec_16u _addr;
-#elif defined(IEC104_STM32)
+#elif defined(IEC104_SET)
     iec_8u  _addr[3];
 #endif
     float  _detect;
@@ -425,7 +419,7 @@ typedef struct _iec10x
     iec_8u (*enqueue)(Iec10x_PrioQueue_T *QueueHdr, Iec10x_PrioNode_T *newnode);
     Iec10x_PrioNode_T *(*dequeue)(Iec10x_PrioQueue_T *QueueHdr);
     Iec10x_PrioNode_T *(*FindQHead)(Iec10x_PrioQueue_T *QueueHdr);
-    char (*GetPrio)(void);
+    iec_8u (*GetPrio)(void);
     void (*InitQueue)(Iec10x_PrioQueue_T *PrioQueue);
     void (*ClearQueue)(Iec10x_PrioQueue_T *QueueHdr);
     iec_8u (*Send)(int socketfd, char *data, int len);
@@ -492,7 +486,7 @@ extern iec_8u       Iec10x_FirmwareUpdateFlag;
  * */
 iec_8u             IEC10X_PrioEnQueue(Iec10x_PrioQueue_T *QueueHdr, Iec10x_PrioNode_T *new_p);
 Iec10x_PrioNode_T *IEC10X_PrioDeQueue(Iec10x_PrioQueue_T *QueueHdr);
-char               IEC10X_HighestPrio(void);
+iec_8u             IEC10X_HighestPrio(void);
 void               IEC10X_PrioInitQueue(Iec10x_PrioQueue_T *PrioQueue);
 void               IEC10X_Prio_ClearQueue(Iec10x_PrioQueue_T *QueueHdr);
 Iec10x_PrioNode_T *IEC10X_PrioFindQueueHead(Iec10x_PrioQueue_T *QueueHdr);

+ 1 - 4
User/app/iec104/iec10x_conf.h

@@ -9,11 +9,8 @@
 #define RET_SUCESS 0
 #define RET_ERROR  1
 
-//#define IEC101_STM32
-#define IEC104_STM32
-//#define IEC104_STM32_FUJIAN_HX
+#define IEC104_SET
 
-//#define SIM900_MODE_SERVER
 #define SIM900_MODE_CLIENT
 
 #define SERIAL_DEBUG

+ 1 - 1
User/app/iec104/iec10x_prio_queue.c

@@ -18,7 +18,7 @@ extern Iec10x_PrioQueue_T Iec10x_PrioQueueArray[IEC10X_PRIO_MAX];
 * Return         : RET_ERROR failure
                    len sucess
 *******************************************************************************/
-char IEC10X_HighestPrio(void)
+iec_8u IEC10X_HighestPrio(void)
 {
 
     int    i, prio;

+ 2 - 1
User/app/iec104/iec10x_type.h

@@ -1,5 +1,5 @@
 // #ifndef __int8_t_defined
-#define __int8_t_defined
+// #define __int8_t_defined
 typedef signed char iec_8s;
 typedef short int   iec_16s;
 typedef int         iec_32s;
@@ -16,6 +16,7 @@ typedef unsigned short int iec_16u;
 #ifndef ___uint32_t_defined
 typedef unsigned int iec_32u;
 #define ___uint32_t_defined
+typedef unsigned int iec_32u;
 #endif
 #if __WORDSIZE == 64
 typedef unsigned long int iec_64u;

+ 4 - 4
User/app/led/led.c

@@ -13,9 +13,9 @@ void led_task(void)
         OSTimeDly(100);
         LED1_RUN_OFF;
         OSTimeDly(100);
-        LED2_RUN_ON;
-        OSTimeDly(100);
-        LED2_RUN_OFF;
-        OSTimeDly(100);
+        // LED2_RUN_ON;
+        // OSTimeDly(100);
+        // LED2_RUN_OFF;
+        // OSTimeDly(100);
     }
 }

+ 4 - 4
User/app/memory/memory_manager.c

@@ -68,7 +68,7 @@ void *pMemoryMalloc(MemoryStruct *mem, size_t xWantedSize)
     BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
     void        *pvReturn = NULL;
 
-    // __set_FAULTMASK(1); //  关闭所有中断();
+    __set_PRIMASK(1); //  关闭所有中断();
 
     /* 申请内存大小不能大于 pBlockAllocatedBit */
     if ((xWantedSize & pBlockAllocatedBit) == 0)
@@ -139,7 +139,7 @@ void *pMemoryMalloc(MemoryStruct *mem, size_t xWantedSize)
         }
     }
 
-    // __set_FAULTMASK(0);
+    // __set_PRIMASK(0);
 
     return pvReturn;
 }
@@ -189,13 +189,13 @@ void pMemoryFree(MemoryStruct *mem, void *pv)
             /* 去掉使用标志 */
             pxLink->xBlockSize &= ~pBlockAllocatedBit;
 
-            // __set_FAULTMASK(1); //  关闭所有中断();
+            __set_PRIMASK(1); //  关闭所有中断();
 
             /* 把这个BLOCK 添加到剩余内存中 */
             mem->Free += pxLink->xBlockSize;
             pInsertBlockIntoFreeList(mem, ((BlockLink_t *)pxLink));
 
-            // __set_FAULTMASK(0);
+            __set_PRIMASK(0);
         }
     }
 }

+ 1 - 0
User/app/memory/memory_manager.h

@@ -1,6 +1,7 @@
 #ifndef _MEMORY_H
 #define _MEMORY_H
 
+#include "includes.h"
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>

+ 4 - 10
User/app/net/net.c

@@ -22,7 +22,7 @@ static err_t bms_net_process(int fd)
 
 void net_task(void)
 {
-    INT8U              buf[50];
+    INT8U              buf[500];
     INT32S             ret    = 0;
     INT32S             sockfd = -1, newfd = -1;
     INT32U             len = 0;
@@ -66,21 +66,15 @@ void net_task(void)
             ret = recv(newfd, buf, sizeof(buf) - 1, 0);
             if (ret <= 0)
             {
+                printf("the other side has been closed (%d).\n", sizeof(buf) - 1);
                 lwip_close(newfd);
                 newfd = -1;
                 break;
             }
             bms_net_process(newfd);
-            Iec104_RecvLen = read(newfd, buf, 1500);
-            if (Iec104_RecvLen <= 0 || Iec104_RecvLen > 1500)
-            {
-                printf("the other side has been closed (%d).\n", Iec104_RecvLen);
-                continue;
-            }
             LOG("#####################received \n");
-
-            DumpHEX(buf, Iec104_RecvLen);
-            Iex104_Receive(buf, Iec104_RecvLen);
+            DumpHEX(buf, read(newfd, buf, 1500));
+            Iex104_Receive(buf, read(newfd, buf, 1500));
         }
 
         lwip_close(sockfd);

+ 64 - 37
User/main.c

@@ -159,45 +159,72 @@ void misc_task(void)
 {
     INT8U  cnt      = 0;
     INT16U save_cnt = 0;
+    INT8U  temperature;
+    INT8U  humidity;
+    INT8U  ret;
+    AD7606_SetOS(AD_OS_NO);  /* 无过采样 */
+    AD7606_SetInputRange(0); /* 0表示输入量程为正负5V, 1表示正负10V */
+
+    // bsp_StartAutoTimer(0, 500); /* 启动1个200ms的自动重装的定时器 */
+    AD7606_ReadNowAdc();  /* 读取采样结果 */
+    AD7606_StartConvst(); /* 启动1次转换 */
     while (1)
     {
         iwdg_feed(MISC_DOG);
-        OSTimeDly(500);
-        LED3_RUN_TOGGLE;
-        //     if ((cnt % 10 == 0) && (cnt != 0))
-        //     {
-        //         continue;
-        //     }
-        //     if ((cnt % 25 == 0) && (cnt != 0))
-        //     {
-        //         LED3_RUN_TOGGLE;
-        //     }
-
-        //     if ((cnt % 15 == 0) && (cnt != 0))
-        //     {
-        //         continue;
-        //     }
-        //     if (cnt == 10)
-        //     {
-        //         continue;
-        //     }
-        //     if (cnt >= 50)
-        //     {
-        //         cnt = 0;
-        //     }
-        //     else
-        //     {
-        //         cnt++;
-        //     }
-
-        //     if (save_cnt >= 1500)
-        //     {
-        //         printf(1111);
-        //         save_cnt = 0;
-        //     }
-        //     else
-        //     {
-        //         save_cnt++;
-        //     }
+        // if ((cnt % 10 == 0) && (cnt != 0))
+        // {
+        //     return;
+        // }
+        if ((cnt % 25 == 0) && (cnt != 0))
+        {
+            LED2_RUN_TOGGLE;
+        }
+
+        // if ((cnt % 15 == 0) && (cnt != 0))
+        // {
+        //     return;
+        // }
+        if (cnt == 10)
+        {
+            // if (am2303_init())
+            // {
+            //     printf("error\r\n");
+            // }
+            // else
+            // {
+            ret = am2303_read_data(&temperature, &humidity); //读取温湿度值
+            if (ret == 1)
+            {
+                printf("Temp: (%d).\n", temperature);
+                printf("Humi: (%d).\n", humidity);
+            }
+            else
+            {
+                printf("\r\n未发现DHT11温湿度传感器\r\n");
+            }
+            // }
+        }
+        if (cnt >= 25)
+        {
+            /* 每隔500ms 进来一次. 由软件启动转换 */
+            AD7606_ReadNowAdc();  /* 读取采样结果 */
+            AD7606_StartConvst(); /* 启动下次转换 */
+
+            cnt = 0; /* 刷新显示 */
+        }
+        else
+        {
+            cnt++;
+        }
+
+        if (save_cnt >= 25)
+        {
+            save_cnt = 0;
+        }
+        else
+        {
+            save_cnt++;
+        }
+        OSTimeDly(20);
     };
 }

+ 2 - 0
User/main.h

@@ -1,6 +1,8 @@
 #ifndef __MAIN_H
 #define __MAIN_H
 
+#include "ad7606.h"
+#include "am2303.h"
 #include "fly_param.h"
 #include "iec10x_type.h"
 #include "includes.h"

+ 1 - 1
User/system_stm32f4xx.c

@@ -361,7 +361,7 @@
 /*!< Uncomment the following line if you need to relocate your vector Table in
      Internal SRAM. */
 /* #define VECT_TAB_SRAM */
-#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. \
+#define VECT_TAB_OFFSET 0x10000 /*!< Vector Table base offset field. \
                                   This value must be a multiple of 0x200. */
 /******************************************************************************/
 

+ 4 - 0
platformio.ini

@@ -15,6 +15,8 @@ monitor_speed = 9600
 build_flags = 
   -IUser
   ; -IUser/bsp
+  -IUser/bsp/ad7606
+  -IUser/bsp/am2303
   -IUser/bsp/can
   -IUser/bsp/dm9k
   -IUser/bsp/eth
@@ -22,6 +24,8 @@ build_flags =
   -IUser/bsp/dwt
   -IUser/bsp/interface
   -IUser/bsp/iwdg
+  -IUser/bsp/key
+  -IUser/bsp/lcd
   -IUser/bsp/nor_flash
   -IUser/bsp/sdio
   -IUser/bsp/spi