打印

[创新制造展示] 21ic第三届设计大赛 + 波形发生器

[复制链接]
1708|30
跳转到指定楼层
楼主
本帖最后由 一路向北lm 于 2019-6-17 13:55 编辑

为了调动大家的积极性,先开个贴,万一你们都不参加呢!哈哈侥幸心理...............
先发个波让你们看看 ,吓吓你们,快点来参赛!!!







1)项目方案的构想


01.产生五种波形,分别是正弦波,方波,三角波,锯齿波,杂波,离散点暂定一个周期内为36个点,频率范围为1-100K,幅值为STM32的电压范围(0-3.3V)。

后续经过广大网友提出要求,采样点数太少,故增加了10倍,现在已使用360点作为一个周期的数据。
2)设计、搭建

02.波形发生器设计流程如下图,采用STM32作为主控芯片,通过DA输出离散点的电压,通过LCD进行数据交互,控制MCU产生各种波形,以及几种波形的切换。增加串口,通过串口工具与开发的上位机进行数据通讯,完成各种波形的产生。

03.本次用到的硬件和调试器如下图,硬件选择野火电子的霸道开发板+LCD屏幕,调试器使用Jlink


04.示波器暂时借用学校实验室的示波器。(偷偷告诉大家,千万不能让导师知道,要不我又得挨骂!)



使用特权

评论回复

评论

21ic小喇叭 2019-6-10 10:50 回复TA
666 
来自 2楼
 楼主 | 2019-6-14 11:36 | 只看该作者
本帖最后由 一路向北lm 于 2019-6-14 14:43 编辑

3)调试流程

1.正弦波的产生
01.使用matlab工具,生成一个周期内36点正弦波数据,由于正弦波的幅值位于-1~1之间,我们需要将幅值范围转为0~3.3 具体matlab代码如下,以及matlab绘制的正弦曲线图像如下所示,为了方便移植到我们的单片机中,我们将36点的数据输出到.c文件中。
m文件代码如下:

  1. %用于产生正弦数据表,输出到文件sinWave.c 文件中,复制到c语言数组即可

  2. n = 2*pi/36 : 2*pi/36 : 2*pi      %分成36等份

  3. a = sin(n)+1;                     %求取sin函数值并向上平移一个单位,消除负数值
  4. a = a * 3.3/2;                    %调整幅值,使范围限制为0~3.3   
  5. r = a* (2.^12) /3.3               %求取dac数值,12位dac LSB = 6.3/2.^12
  6. r = uint16(r);                    %把double型数据转化成16位整型数据

  7. for i = 1:36                        
  8. if r(i) > 4095                      %限制数据最大不超过4095
  9.     r(i) = 4095
  10. end
  11. end

  12. dlmwrite('C:\Users\JY-LM\Desktop\波形发生器\教程提到的正弦波表制作脚本\matlab脚本\sinWave.c',r);      %把数据写入到文件,方便添加到stm32工程中
  13. plot(n,r,'.')                     %把这些点画出来

复制代码
matlab图像如下:
02.36点的正弦波数据填入数组中,DMA周期性搬运数据到从该数组到DA外设。
  1. /* 36点正弦波数据---------------------------------------------------------*/
  2. const uint16_t Sine12bit[POINT_NUM] =
  3. {
  4.          2404, 2748,3072,3364,3617,3822,3972,4065,
  5.          4095, 4065,3972,3822,3617,3364,3072,2748,
  6.    2404, 2048,1692,1348,1024,732, 479, 274,
  7.    124,  31,  0,   31,  124, 274, 479, 732,   
  8.          1024, 1348,1692,2048
  9. };
复制代码
  1. /* 填充波形数据,单通道输出对应引脚PA5*/
  2. for (Idx = 0; Idx < POINT_NUM; Idx++)
  3. {
  4.     DualSine12bit[Idx] = (Sine12bit[Idx] << 16) + (Sine12bit[Idx]);
  5. }
复制代码
03.示波器探头连接stm32单片机PA5端口,可以看到已经输出了100kHZ的正弦波,当然还可以增加每个周期的采样点数,更加逼近正弦波。
2.方波的产生
01.对于方波就比较简单了,直接填充36个点的数据,前18点为低电平(DA数据位0),后18点为高电平(DA数据为4095 对应3.3V)。
  1. /* 方波数据 ---------------------------------------------------------*/
  2. const uint16_t Square12bit[POINT_NUM] =
  3. {
  4.          0,0,0,0,0,0,0,0,0,
  5.          0,0,0,0,0,0,0,0,0,
  6.          4095,4095,4095,4095,4095,4095,
  7.          4095,4095,4095,4095,4095,4095,
  8.          4095,4095,4095,4095,4095,4095,
  9. };
复制代码
02.想象是美好的,在低频段区域(1-10K)出现的方波还是比较好的,后面我将频率增大到100K时,示波器上出现的波形还是有一定的缺陷,这里的边缘处,高低电平的切换存在着过渡期,这个是我们所不想看到的。由于STM32 DA自身的响应速度,这个我也无能为力,如果我们采用PWM的方式这样出来的方波将会更加完美,本次比赛题目限定使用DA,所以这里就先这样了。

10 K时的方波图:
100K时的方波图:
3.三角波的产生
01.对于对于三角波也是采用matlab输出36个点,前18点从0V3.3V线性递增(DA数据从0线性增长到4095),后18点从3.3V0V线性递减(DA数据从4095线性递减到0)。
  1. /* 三角波数据 ---------------------------------------------------------*/
  2. const uint16_t Triangular12bit[POINT_NUM] =
  3. {
  4.          0,   227, 455, 682, 910, 1137,1365,1592,1820,
  5.          2047,2275,2502,2730,2957,3185,3412,3640,3867,
  6.          4095,3867,3640,3412,3185,2957,2730,2502,2275,
  7.          2047,1820,1592,1365,1137,910, 682, 455, 227,         
  8. };
复制代码
10kHZ100KHZ的波形如下,从波形上来看,随着频率的升高,三角波的波尖越来越平滑。这些是我们不希望看到的,由于DA本身的局限性,这里也在所难免。

10k三角波图:
100k三角波图:
4.锯齿波的产生
01.对于对于三角波也是采用matlab输出36个点,36点从3.3V0V线性递减(DA数据从4095线性递减到0)。
  1. /* 锯齿波数据---------------------------------------------------------*/
  2. const uint16_t Sawtooth12bit[POINT_NUM] =
  3. {
  4.          4095,3978,3861,3744,3627,3510,
  5.          3393,3276,3159,3042,2925,2808,
  6.          2691,2574,2457,2340,2223,2106,
  7.          1989,1872,1755,1638,1521,1404,
  8.          1287,1170,1053,936, 819, 702,
  9.          585, 468, 351, 234, 117, 0
  10. };
复制代码
02.10kHZ100KHZ的波形如下,从波形上来看,随着频率的升高,锯齿波的波尖越来越平滑。这些是我们不希望看到的,由于DA本身的局限性,这里也在所难免。

10k锯齿波图:
100k锯齿波图:
5.杂波的产生



使用特权

评论回复

评论

一路向北lm 2019-6-15 12:10 回复TA
@zhanzr21 :增加点,使劲增加 
一路向北lm 2019-6-15 12:09 回复TA
@zhanzr21 : 
zhanzr21 2019-6-14 22:03 回复TA
因为最后还有幅度变换, 建议尽量还是本机运算. 
zhanzr21 2019-6-14 22:01 回复TA
36个点的正弦波太寒酸了, 多做些点, 反正这个点可以存在flash区, 方波,三角波这样的就没有必要查表了, 小Cortex M算得过来. 个人意见,仅供参考! 
来自 3楼
 楼主 | 2019-6-17 11:14 | 只看该作者
本帖最后由 一路向北lm 于 2019-6-17 13:53 编辑

第二次调试
      为了响应广大网友的号召,将采样点数增加10倍,一个周期内的点数为360个点。好多网友说正弦波可以采用查表的方式,对于方波、三角波、锯齿波就没有必要采用查表的方式了。这里我主要是采用DMA搬运列表数据到DA外设的方式,这样就不会占用CPU的资源了。为了后面的LCD和串口接受部分程序顺利执行,使用DMA搬运是比较好的方法。当然使用操作系统也可以,根据自己的方式,找到最适合自己的方法。
        增加到360点的正弦波,matlab生成的波形和数据点如下,这样一看,哇!波形不错啊,不知道stm32可以增加到多少个点!360个点不少了!再多了,我怕DMA被累死了!
  1. %用于产生正弦数据表,输出到文件sinWave.c 文件中,复制到c语言数组即可
  2. n = 2*pi/360 : 2*pi/360 : 2*pi      %分成36等份
  3. a = sin(n)+1;                     %求取sin函数值并向上平移一个单位,消除负数值
  4. a = a * 3.3/2;                    %调整幅值,使范围限制为0~3.3   
  5. r = a* (2.^12) /3.3               %求取dac数值,12位dac LSB = 6.3/2.^12
  6. r = uint16(r);                    %把double型数据转化成16位整型数据
  7. for i = 1:360                        
  8. if r(i) > 4095                      %限制数据最大不超过4095
  9.     r(i) = 4095
  10. end
  11. end
  12. dlmwrite('C:\Users\JY-LM\Desktop\21ic第三届大赛\波形发生器\教程提到的正弦波表制作脚本\matlab脚本\sinWave.c',r);      %把数据写入到文件,方便添加到stm32工程中
  13. plot(n,r,'.')                     %把这些点画出来
复制代码
庞大的数据集………..DMA来也……….
  1. const uint16_t Sine12bit[POINT_NUM] =
  2. {
  3.          2084,2119,2155,2191,2226,2262,2298,2333,2368,2404,
  4.          2439,2474,2509,2543,2578,2613,2647,2681,2715,2748,
  5.          2782,2815,2848,2881,2914,2946,2978,3009,3041,3072,
  6.          3103,3133,3163,3193,3223,3252,3281,3309,3337,3364,
  7.          3392,3418,3445,3471,3496,3521,3546,3570,3594,3617,
  8.          3640,3662,3684,3705,3726,3746,3766,3785,3803,3822,
  9.          3839,3856,3873,3889,3904,3919,3933,3947,3960,3972,
  10.          3984,3996,4007,4017,4026,4035,4044,4051,4058,4065,
  11.          4071,4076,4081,4085,4088,4091,4093,4095,4095,4095,
  12.          4095,4095,4093,4091,4088,4085,4081,4076,4071,4065,
  13.          4058,4051,4044,4035,4026,4017,4007,3996,3984,3972,
  14.          3960,3947,3933,3919,3904,3889,3873,3856,3839,3822,
  15.          3803,3785,3766,3746,3726,3705,3684,3662,3640,3617,
  16.          3594,3570,3546,3521,3496,3471,3445,3418,3392,3364,
  17.          3337,3309,3281,3252,3223,3193,3163,3133,3103,3072,
  18.          3041,3009,2978,2946,2914,2881,2848,2815,2782,2748,
  19.          2715,2681,2647,2613,2578,2543,2509,2474,2439,2404,
  20.          2368,2333,2298,2262,2226,2191,2155,2119,2084,2048,
  21.          2012,1977,1941,1905,1870,1834,1798,1763,1728,1692,
  22.          1657,1622,1587,1553,1518,1483,1449,1415,1381,1348,
  23.          1314,1281,1248,1215,1182,1150,1118,1087,1055,1024,
  24.          993, 963, 933, 903, 873, 844, 815, 787, 759, 732,
  25.          704, 678, 651, 625, 600, 575, 550, 526, 502, 479,
  26.          456, 434, 412, 391, 370, 350, 330, 311, 293, 274,
  27.          257, 240, 223, 207, 192, 177, 163, 149, 136, 124,
  28.          112, 100, 89,  79,  70,  61,  52,  45,  38,  31,
  29.          25,  20,  15,  11,  8,   5,   3,   1,   0,   0,
  30.          0,   1,   3,   5,   8,   11,  15,  20,  25,  31,
  31.          38,  45,  52,  61,  70,  79,  89,  100, 112, 124,
  32.          136, 149, 163, 177, 192, 207, 223, 240, 257, 274,
  33.          293, 311, 330, 350, 370, 391, 412, 434, 456, 479,
  34.          502, 526, 550, 575, 600, 625, 651, 678, 704, 732,
  35.          759, 787, 815, 844, 873, 903, 933, 963, 993, 1024,
  36.          1055,1087,1118,1150,1182,1215,1248,1281,1314,1348,
  37.          1381,1415,1449,1483,1518,1553,1587,1622,1657,1692,
  38.          1728,1763,1798,1834,1870,1905,1941,1977,2012,2048
  39. };
复制代码
从matlab 绘制的正弦波来看,还是有模有样的!
示波器输出波形如下,没看出来与36点的区别,方正现在可以称得上是正弦波了吧!

360点的正弦波

360点的方波

360点的三角波

360点的锯齿波


你怕,你怕,生活欺骗了你,所以你不敢想象,你不敢去尝试。如今,我尝试了,为什么波还是那个波,没有什么起色呢?也许是生活又欺骗了你吧!


使用特权

评论回复
来自 4楼
 楼主 | 2019-6-17 13:58 | 只看该作者
本帖最后由 一路向北lm 于 2019-6-18 17:45 编辑

LCD驱动显示界面
LCD显示界面如下,使用按键1来切换波形,使用按键2来切换频率。
1.产生方波 10k Hz  3.3V
2.产生正弦波 10HZ  3.3V

LCD驱动代码


  1. #include "./lcd/bsp_ili9341_lcd.h"
  2. #include "./font/fonts.h"       

  3. //根据液晶扫描方向而变化的XY像素宽度
  4. //调用ILI9341_GramScan函数设置方向时会自动更改
  5. uint16_t LCD_X_LENGTH = ILI9341_LESS_PIXEL;
  6. uint16_t LCD_Y_LENGTH = ILI9341_MORE_PIXEL;

  7. //液晶屏扫描模式,本变量主要用于方便选择触摸屏的计算参数
  8. //参数可选值为0-7
  9. //调用ILI9341_GramScan函数设置方向时会自动更改
  10. //LCD刚初始化完成时会使用本默认值
  11. uint8_t LCD_SCAN_MODE = 6;


  12. static sFONT *LCD_Currentfonts = &Font8x16;  //英文字体
  13. static uint16_t CurrentTextColor   = BLACK;//前景色
  14. static uint16_t CurrentBackColor   = WHITE;//背景色

  15. __inline void                 ILI9341_Write_Cmd           ( uint16_t usCmd );
  16. __inline void                 ILI9341_Write_Data          ( uint16_t usData );
  17. __inline uint16_t             ILI9341_Read_Data           ( void );
  18. static void                   ILI9341_Delay               ( __IO uint32_t nCount );
  19. static void                   ILI9341_GPIO_Config         ( void );
  20. static void                   ILI9341_FSMC_Config         ( void );
  21. static void                   ILI9341_REG_Config          ( void );
  22. static void                   ILI9341_SetCursor           ( uint16_t usX, uint16_t usY );
  23. static __inline void          ILI9341_FillColor           ( uint32_t ulAmout_Point, uint16_t usColor );
  24. static uint16_t               ILI9341_Read_PixelData      ( void );




  25. /**
  26.   * [url=home.php?mod=space&uid=247401]@brief[/url]  向ILI9341写入命令
  27.   * @param  usCmd :要写入的命令(表寄存器地址)
  28.   * @retval 无
  29.   */       
  30. __inline void ILI9341_Write_Cmd ( uint16_t usCmd )
  31. {
  32.         * ( __IO uint16_t * ) ( FSMC_Addr_ILI9341_CMD ) = usCmd;
  33.        
  34. }


  35. /**
  36.   * @brief  向ILI9341写入数据
  37.   * @param  usData :要写入的数据
  38.   * @retval 无
  39.   */       
  40. __inline void ILI9341_Write_Data ( uint16_t usData )
  41. {
  42.         * ( __IO uint16_t * ) ( FSMC_Addr_ILI9341_DATA ) = usData;
  43.        
  44. }


  45. /**
  46.   * @brief  从ILI9341读取数据
  47.   * @param  无
  48.   * @retval 读取到的数据
  49.   */       
  50. __inline uint16_t ILI9341_Read_Data ( void )
  51. {
  52.         return ( * ( __IO uint16_t * ) ( FSMC_Addr_ILI9341_DATA ) );
  53.        
  54. }


  55. /**
  56.   * @brief  用于 ILI9341 简单延时函数
  57.   * @param  nCount :延时计数值
  58.   * @retval 无
  59.   */       
  60. static void ILI9341_Delay ( __IO uint32_t nCount )
  61. {
  62.   for ( ; nCount != 0; nCount -- );
  63.        
  64. }


  65. /**
  66.   * @brief  初始化ILI9341的IO引脚
  67.   * @param  无
  68.   * @retval 无
  69.   */
  70. static void ILI9341_GPIO_Config ( void )
  71. {
  72.         GPIO_InitTypeDef GPIO_InitStructure;

  73.         /* 使能FSMC对应相应管脚时钟*/
  74.         RCC_APB2PeriphClockCmd (        
  75.                                                                                                         /*控制信号*/
  76.                                                                                                         ILI9341_CS_CLK|ILI9341_DC_CLK|ILI9341_WR_CLK|
  77.                                                                                                         ILI9341_RD_CLK        |ILI9341_BK_CLK|ILI9341_RST_CLK|
  78.                                                                                                         /*数据信号*/
  79.                                                                                                         ILI9341_D0_CLK|ILI9341_D1_CLK|        ILI9341_D2_CLK |
  80.                                                                                                         ILI9341_D3_CLK | ILI9341_D4_CLK|ILI9341_D5_CLK|
  81.                                                                                                         ILI9341_D6_CLK | ILI9341_D7_CLK|ILI9341_D8_CLK|
  82.                                                                                                         ILI9341_D9_CLK | ILI9341_D10_CLK|ILI9341_D11_CLK|
  83.                                                                                                         ILI9341_D12_CLK | ILI9341_D13_CLK|ILI9341_D14_CLK|
  84.                                                                                                         ILI9341_D15_CLK        , ENABLE );
  85.                
  86.        
  87.         /* 配置FSMC相对应的数据线,FSMC-D0~D15 */       
  88.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  89.         GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_AF_PP;
  90.        
  91.         GPIO_InitStructure.GPIO_Pin = ILI9341_D0_PIN;
  92.         GPIO_Init ( ILI9341_D0_PORT, & GPIO_InitStructure );

  93.         GPIO_InitStructure.GPIO_Pin = ILI9341_D1_PIN;
  94.         GPIO_Init ( ILI9341_D1_PORT, & GPIO_InitStructure );
  95.        
  96.         GPIO_InitStructure.GPIO_Pin = ILI9341_D2_PIN;
  97.         GPIO_Init ( ILI9341_D2_PORT, & GPIO_InitStructure );
  98.        
  99.         GPIO_InitStructure.GPIO_Pin = ILI9341_D3_PIN;
  100.         GPIO_Init ( ILI9341_D3_PORT, & GPIO_InitStructure );
  101.        
  102.         GPIO_InitStructure.GPIO_Pin = ILI9341_D4_PIN;
  103.         GPIO_Init ( ILI9341_D4_PORT, & GPIO_InitStructure );
  104.        
  105.         GPIO_InitStructure.GPIO_Pin = ILI9341_D5_PIN;
  106.         GPIO_Init ( ILI9341_D5_PORT, & GPIO_InitStructure );
  107.        
  108.         GPIO_InitStructure.GPIO_Pin = ILI9341_D6_PIN;
  109.         GPIO_Init ( ILI9341_D6_PORT, & GPIO_InitStructure );
  110.        
  111.         GPIO_InitStructure.GPIO_Pin = ILI9341_D7_PIN;
  112.         GPIO_Init ( ILI9341_D7_PORT, & GPIO_InitStructure );
  113.        
  114.         GPIO_InitStructure.GPIO_Pin = ILI9341_D8_PIN;
  115.         GPIO_Init ( ILI9341_D8_PORT, & GPIO_InitStructure );
  116.        
  117.         GPIO_InitStructure.GPIO_Pin = ILI9341_D9_PIN;
  118.         GPIO_Init ( ILI9341_D9_PORT, & GPIO_InitStructure );
  119.        
  120.         GPIO_InitStructure.GPIO_Pin = ILI9341_D10_PIN;
  121.         GPIO_Init ( ILI9341_D10_PORT, & GPIO_InitStructure );
  122.        
  123.         GPIO_InitStructure.GPIO_Pin = ILI9341_D11_PIN;
  124.         GPIO_Init ( ILI9341_D11_PORT, & GPIO_InitStructure );

  125.         GPIO_InitStructure.GPIO_Pin = ILI9341_D12_PIN;
  126.         GPIO_Init ( ILI9341_D12_PORT, & GPIO_InitStructure );       
  127.        
  128.         GPIO_InitStructure.GPIO_Pin = ILI9341_D13_PIN;
  129.         GPIO_Init ( ILI9341_D13_PORT, & GPIO_InitStructure );
  130.        
  131.         GPIO_InitStructure.GPIO_Pin = ILI9341_D14_PIN;
  132.         GPIO_Init ( ILI9341_D14_PORT, & GPIO_InitStructure );
  133.        
  134.         GPIO_InitStructure.GPIO_Pin = ILI9341_D15_PIN;
  135.         GPIO_Init ( ILI9341_D15_PORT, & GPIO_InitStructure );
  136.        

  137.        
  138.         /* 配置FSMC相对应的控制线
  139.          * FSMC_NOE   :LCD-RD
  140.          * FSMC_NWE   :LCD-WR
  141.          * FSMC_NE1   :LCD-CS
  142.          * FSMC_A16          :LCD-DC
  143.          */
  144.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  145.         GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_AF_PP;
  146.        
  147.         GPIO_InitStructure.GPIO_Pin = ILI9341_RD_PIN;
  148.         GPIO_Init (ILI9341_RD_PORT, & GPIO_InitStructure );
  149.        
  150.         GPIO_InitStructure.GPIO_Pin = ILI9341_WR_PIN;
  151.         GPIO_Init (ILI9341_WR_PORT, & GPIO_InitStructure );
  152.        
  153.         GPIO_InitStructure.GPIO_Pin = ILI9341_CS_PIN;
  154.         GPIO_Init ( ILI9341_CS_PORT, & GPIO_InitStructure );  
  155.        
  156.         GPIO_InitStructure.GPIO_Pin = ILI9341_DC_PIN;
  157.         GPIO_Init ( ILI9341_DC_PORT, & GPIO_InitStructure );
  158.        

  159.   /* 配置LCD复位RST控制管脚*/
  160.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  161.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  162.        
  163.         GPIO_InitStructure.GPIO_Pin = ILI9341_RST_PIN;
  164.         GPIO_Init ( ILI9341_RST_PORT, & GPIO_InitStructure );
  165.        
  166.        
  167.         /* 配置LCD背光控制管脚BK*/
  168.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  169.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  170.        
  171.         GPIO_InitStructure.GPIO_Pin = ILI9341_BK_PIN;
  172.         GPIO_Init ( ILI9341_BK_PORT, & GPIO_InitStructure );
  173. }


  174. /**
  175.   * @brief  LCD  FSMC 模式配置
  176.   * @param  无
  177.   * @retval 无
  178.   */
  179. static void ILI9341_FSMC_Config ( void )
  180. {
  181.         FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
  182.         FSMC_NORSRAMTimingInitTypeDef  readWriteTiming;        
  183.        
  184.         /* 使能FSMC时钟*/
  185.         RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_FSMC, ENABLE );

  186.         //地址建立时间(ADDSET)为1个HCLK 2/72M=28ns
  187.         readWriteTiming.FSMC_AddressSetupTime      = 0x01;         //地址建立时间
  188.         //数据保持时间(DATAST)+ 1个HCLK = 5/72M=70ns       
  189.         readWriteTiming.FSMC_DataSetupTime         = 0x04;         //数据建立时间
  190.         //选择控制的模式
  191.         //模式B,异步NOR FLASH模式,与ILI9341的8080时序匹配
  192.         readWriteTiming.FSMC_AccessMode            = FSMC_AccessMode_B;       
  193.        
  194.         /*以下配置与模式B无关*/
  195.         //地址保持时间(ADDHLD)模式A未用到
  196.         readWriteTiming.FSMC_AddressHoldTime       = 0x00;         //地址保持时间
  197.         //设置总线转换周期,仅用于复用模式的NOR操作
  198.         readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
  199.         //设置时钟分频,仅用于同步类型的存储器
  200.         readWriteTiming.FSMC_CLKDivision           = 0x00;
  201.         //数据保持时间,仅用于同步型的NOR       
  202.         readWriteTiming.FSMC_DataLatency           = 0x00;       

  203.        
  204.         FSMC_NORSRAMInitStructure.FSMC_Bank                  = FSMC_Bank1_NORSRAMx;
  205.         FSMC_NORSRAMInitStructure.FSMC_DataAddressMux        = FSMC_DataAddressMux_Disable;
  206.         FSMC_NORSRAMInitStructure.FSMC_MemoryType            = FSMC_MemoryType_NOR;
  207.         FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth       = FSMC_MemoryDataWidth_16b;
  208.         FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode       = FSMC_BurstAccessMode_Disable;
  209.         FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity    = FSMC_WaitSignalPolarity_Low;
  210.         FSMC_NORSRAMInitStructure.FSMC_WrapMode              = FSMC_WrapMode_Disable;
  211.         FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive      = FSMC_WaitSignalActive_BeforeWaitState;
  212.         FSMC_NORSRAMInitStructure.FSMC_WriteOperation        = FSMC_WriteOperation_Enable;
  213.         FSMC_NORSRAMInitStructure.FSMC_WaitSignal            = FSMC_WaitSignal_Disable;
  214.         FSMC_NORSRAMInitStructure.FSMC_ExtendedMode          = FSMC_ExtendedMode_Disable;
  215.         FSMC_NORSRAMInitStructure.FSMC_WriteBurst            = FSMC_WriteBurst_Disable;
  216.         FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming;
  217.         FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct     = &readWriteTiming;  
  218.        
  219.         FSMC_NORSRAMInit ( & FSMC_NORSRAMInitStructure );
  220.        
  221.        
  222.         /* 使能 FSMC_Bank1_NORSRAM4 */
  223.         FSMC_NORSRAMCmd ( FSMC_Bank1_NORSRAMx, ENABLE );  
  224.                
  225.                
  226. }


  227. /**
  228. * @brief  初始化ILI9341寄存器
  229. * @param  无
  230. * @retval 无
  231. */
  232. static void ILI9341_REG_Config ( void )
  233. {
  234.         /*  Power control B (CFh)  */
  235.         DEBUG_DELAY  ();
  236.         ILI9341_Write_Cmd ( 0xCF  );
  237.         ILI9341_Write_Data ( 0x00  );
  238.         ILI9341_Write_Data ( 0x81  );
  239.         ILI9341_Write_Data ( 0x30  );
  240.        
  241.         /*  Power on sequence control (EDh) */
  242.         DEBUG_DELAY ();
  243.         ILI9341_Write_Cmd ( 0xED );
  244.         ILI9341_Write_Data ( 0x64 );
  245.         ILI9341_Write_Data ( 0x03 );
  246.         ILI9341_Write_Data ( 0x12 );
  247.         ILI9341_Write_Data ( 0x81 );
  248.        
  249.         /*  Driver timing control A (E8h) */
  250.         DEBUG_DELAY ();
  251.         ILI9341_Write_Cmd ( 0xE8 );
  252.         ILI9341_Write_Data ( 0x85 );
  253.         ILI9341_Write_Data ( 0x10 );
  254.         ILI9341_Write_Data ( 0x78 );
  255.        
  256.         /*  Power control A (CBh) */
  257.         DEBUG_DELAY ();
  258.         ILI9341_Write_Cmd ( 0xCB );
  259.         ILI9341_Write_Data ( 0x39 );
  260.         ILI9341_Write_Data ( 0x2C );
  261.         ILI9341_Write_Data ( 0x00 );
  262.         ILI9341_Write_Data ( 0x34 );
  263.         ILI9341_Write_Data ( 0x02 );
  264.        
  265.         /* Pump ratio control (F7h) */
  266.         DEBUG_DELAY ();
  267.         ILI9341_Write_Cmd ( 0xF7 );
  268.         ILI9341_Write_Data ( 0x20 );
  269.        
  270.         /* Driver timing control B */
  271.         DEBUG_DELAY ();
  272.         ILI9341_Write_Cmd ( 0xEA );
  273.         ILI9341_Write_Data ( 0x00 );
  274.         ILI9341_Write_Data ( 0x00 );
  275.        
  276.         /* Frame Rate Control (In Normal Mode/Full Colors) (B1h) */
  277.         DEBUG_DELAY ();
  278.         ILI9341_Write_Cmd ( 0xB1 );
  279.         ILI9341_Write_Data ( 0x00 );
  280.         ILI9341_Write_Data ( 0x1B );
  281.        
  282.         /*  Display Function Control (B6h) */
  283.         DEBUG_DELAY ();
  284.         ILI9341_Write_Cmd ( 0xB6 );
  285.         ILI9341_Write_Data ( 0x0A );
  286.         ILI9341_Write_Data ( 0xA2 );
  287.        
  288.         /* Power Control 1 (C0h) */
  289.         DEBUG_DELAY ();
  290.         ILI9341_Write_Cmd ( 0xC0 );
  291.         ILI9341_Write_Data ( 0x35 );
  292.        
  293.         /* Power Control 2 (C1h) */
  294.         DEBUG_DELAY ();
  295.         ILI9341_Write_Cmd ( 0xC1 );
  296.         ILI9341_Write_Data ( 0x11 );
  297.        
  298.         /* VCOM Control 1 (C5h) */
  299.         ILI9341_Write_Cmd ( 0xC5 );
  300.         ILI9341_Write_Data ( 0x45 );
  301.         ILI9341_Write_Data ( 0x45 );
  302.        
  303.         /*  VCOM Control 2 (C7h)  */
  304.         ILI9341_Write_Cmd ( 0xC7 );
  305.         ILI9341_Write_Data ( 0xA2 );
  306.        
  307.         /* Enable 3G (F2h) */
  308.         ILI9341_Write_Cmd ( 0xF2 );
  309.         ILI9341_Write_Data ( 0x00 );
  310.        
  311.         /* Gamma Set (26h) */
  312.         ILI9341_Write_Cmd ( 0x26 );
  313.         ILI9341_Write_Data ( 0x01 );
  314.         DEBUG_DELAY ();
  315.        
  316.         /* Positive Gamma Correction */
  317.         ILI9341_Write_Cmd ( 0xE0 ); //Set Gamma
  318.         ILI9341_Write_Data ( 0x0F );
  319.         ILI9341_Write_Data ( 0x26 );
  320.         ILI9341_Write_Data ( 0x24 );
  321.         ILI9341_Write_Data ( 0x0B );
  322.         ILI9341_Write_Data ( 0x0E );
  323.         ILI9341_Write_Data ( 0x09 );
  324.         ILI9341_Write_Data ( 0x54 );
  325.         ILI9341_Write_Data ( 0xA8 );
  326.         ILI9341_Write_Data ( 0x46 );
  327.         ILI9341_Write_Data ( 0x0C );
  328.         ILI9341_Write_Data ( 0x17 );
  329.         ILI9341_Write_Data ( 0x09 );
  330.         ILI9341_Write_Data ( 0x0F );
  331.         ILI9341_Write_Data ( 0x07 );
  332.         ILI9341_Write_Data ( 0x00 );
  333.        
  334.         /* Negative Gamma Correction (E1h) */
  335.         ILI9341_Write_Cmd ( 0XE1 ); //Set Gamma
  336.         ILI9341_Write_Data ( 0x00 );
  337.         ILI9341_Write_Data ( 0x19 );
  338.         ILI9341_Write_Data ( 0x1B );
  339.         ILI9341_Write_Data ( 0x04 );
  340.         ILI9341_Write_Data ( 0x10 );
  341.         ILI9341_Write_Data ( 0x07 );
  342.         ILI9341_Write_Data ( 0x2A );
  343.         ILI9341_Write_Data ( 0x47 );
  344.         ILI9341_Write_Data ( 0x39 );
  345.         ILI9341_Write_Data ( 0x03 );
  346.         ILI9341_Write_Data ( 0x06 );
  347.         ILI9341_Write_Data ( 0x06 );
  348.         ILI9341_Write_Data ( 0x30 );
  349.         ILI9341_Write_Data ( 0x38 );
  350.         ILI9341_Write_Data ( 0x0F );
  351.        
  352.         /* memory access control set */
  353.         DEBUG_DELAY ();
  354.         ILI9341_Write_Cmd ( 0x36 );        
  355.         ILI9341_Write_Data ( 0xC8 );    /*竖屏  左上角到 (起点)到右下角 (终点)扫描方式*/
  356.         DEBUG_DELAY ();
  357.        
  358.         /* column address control set */
  359.         ILI9341_Write_Cmd ( CMD_SetCoordinateX );
  360.         ILI9341_Write_Data ( 0x00 );
  361.         ILI9341_Write_Data ( 0x00 );
  362.         ILI9341_Write_Data ( 0x00 );
  363.         ILI9341_Write_Data ( 0xEF );
  364.        
  365.         /* page address control set */
  366.         DEBUG_DELAY ();
  367.         ILI9341_Write_Cmd ( CMD_SetCoordinateY );
  368.         ILI9341_Write_Data ( 0x00 );
  369.         ILI9341_Write_Data ( 0x00 );
  370.         ILI9341_Write_Data ( 0x01 );
  371.         ILI9341_Write_Data ( 0x3F );
  372.        
  373.         /*  Pixel Format Set (3Ah)  */
  374.         DEBUG_DELAY ();
  375.         ILI9341_Write_Cmd ( 0x3a );
  376.         ILI9341_Write_Data ( 0x55 );
  377.        
  378.         /* Sleep Out (11h)  */
  379.         ILI9341_Write_Cmd ( 0x11 );       
  380.         ILI9341_Delay ( 0xAFFf<<2 );
  381.         DEBUG_DELAY ();
  382.        
  383.         /* Display ON (29h) */
  384.         ILI9341_Write_Cmd ( 0x29 );
  385.        
  386.        
  387. }


  388. /**
  389. * @brief  ILI9341初始化函数,如果要用到lcd,一定要调用这个函数
  390. * @param  无
  391. * @retval 无
  392. */
  393. void ILI9341_Init ( void )
  394. {
  395.         ILI9341_GPIO_Config ();
  396.         ILI9341_FSMC_Config ();
  397.        
  398.         ILI9341_BackLed_Control ( ENABLE );      //点亮LCD背光灯
  399.         ILI9341_Rst ();
  400.         ILI9341_REG_Config ();
  401.        
  402.         //设置默认扫描方向,其中 6 模式为大部分液晶例程的默认显示方向  
  403.         ILI9341_GramScan(LCD_SCAN_MODE);
  404. }


  405. /**
  406. * @brief  ILI9341背光LED控制
  407. * @param  enumState :决定是否使能背光LED
  408.   *   该参数为以下值之一:
  409.   *     [url=home.php?mod=space&uid=2817080]@ARG[/url] ENABLE :使能背光LED
  410.   *     @arg DISABLE :禁用背光LED
  411. * @retval 无
  412. */
  413. void ILI9341_BackLed_Control ( FunctionalState enumState )
  414. {
  415.         if ( enumState )
  416.                 GPIO_ResetBits ( ILI9341_BK_PORT, ILI9341_BK_PIN );       
  417.         else
  418.                 GPIO_SetBits ( ILI9341_BK_PORT, ILI9341_BK_PIN );
  419.                
  420. }



  421. /**
  422. * @brief  ILI9341 软件复位
  423. * @param  无
  424. * @retval 无
  425. */
  426. void ILI9341_Rst ( void )
  427. {                       
  428.         GPIO_ResetBits ( ILI9341_RST_PORT, ILI9341_RST_PIN );         //低电平复位

  429.         ILI9341_Delay ( 0xAFF );                                           

  430.         GPIO_SetBits ( ILI9341_RST_PORT, ILI9341_RST_PIN );                          

  431.         ILI9341_Delay ( 0xAFF );        
  432.        
  433. }




  434. /**
  435. * @brief  设置ILI9341的GRAM的扫描方向
  436. * @param  ucOption :选择GRAM的扫描方向
  437. *     @arg 0-7 :参数可选值为0-7这八个方向
  438. *
  439. *        !!!其中0、3、5、6 模式适合从左至右显示文字,
  440. *                                不推荐使用其它模式显示文字        其它模式显示文字会有镜像效果                       
  441. *               
  442. *        其中0、2、4、6 模式的X方向像素为240,Y方向像素为320
  443. *        其中1、3、5、7 模式下X方向像素为320,Y方向像素为240
  444. *
  445. *        其中 6 模式为大部分液晶例程的默认显示方向
  446. *        其中 3 模式为摄像头例程使用的方向
  447. *        其中 0 模式为BMP图片显示例程使用的方向
  448. *
  449. * @retval 无
  450. * [url=home.php?mod=space&uid=536309]@NOTE[/url]  坐标图例:A表示向上,V表示向下,<表示向左,>表示向右
  451.                                         X表示X轴,Y表示Y轴

  452. ------------------------------------------------------------
  453. 模式0:                                .                模式1:                .        模式2:                        .        模式3:                                       
  454.                                         A                .                                        A                .                A                                        .                A                                                                       
  455.                                         |                .                                        |                .                |                                        .                |                                                       
  456.                                         Y                .                                        X                .                Y                                        .                X                                       
  457.                                         0                .                                        1                .                2                                        .                3                                       
  458.         <--- X0 o                .        <----Y1        o                .                o 2X--->  .                o 3Y--->       
  459. ------------------------------------------------------------       
  460. 模式4:                                .        模式5:                        .        模式6:                        .        模式7:                                       
  461.         <--- X4 o                .        <--- Y5 o                .                o 6X--->  .                o 7Y--->       
  462.                                         4                .                                        5                .                6                                        .                7       
  463.                                         Y                .                                        X                .                Y                                        .                X                                               
  464.                                         |                .                                        |                .                |                                        .                |                                                       
  465.                                         V                .                                        V                .                V                                        .                V               
  466. ---------------------------------------------------------                               
  467.                                                                                          LCD屏示例
  468.                                                                 |-----------------|
  469.                                                                 |                        野火Logo                |
  470.                                                                 |                                                                        |
  471.                                                                 |                                                                        |
  472.                                                                 |                                                                        |
  473.                                                                 |                                                                        |
  474.                                                                 |                                                                        |
  475.                                                                 |                                                                        |
  476.                                                                 |                                                                        |
  477.                                                                 |                                                                        |
  478.                                                                 |-----------------|
  479.                                                                 屏幕正面(宽240,高320)

  480. *******************************************************/
  481. void ILI9341_GramScan ( uint8_t ucOption )
  482. {       
  483.         //参数检查,只可输入0-7
  484.         if(ucOption >7 )
  485.                 return;
  486.        
  487.         //根据模式更新LCD_SCAN_MODE的值,主要用于触摸屏选择计算参数
  488.         LCD_SCAN_MODE = ucOption;
  489.        
  490.         //根据模式更新XY方向的像素宽度
  491.         if(ucOption%2 == 0)       
  492.         {
  493.                 //0 2 4 6模式下X方向像素宽度为240,Y方向为320
  494.                 LCD_X_LENGTH = ILI9341_LESS_PIXEL;
  495.                 LCD_Y_LENGTH =        ILI9341_MORE_PIXEL;
  496.         }
  497.         else                               
  498.         {
  499.                 //1 3 5 7模式下X方向像素宽度为320,Y方向为240
  500.                 LCD_X_LENGTH = ILI9341_MORE_PIXEL;
  501.                 LCD_Y_LENGTH =        ILI9341_LESS_PIXEL;
  502.         }

  503.         //0x36命令参数的高3位可用于设置GRAM扫描方向       
  504.         ILI9341_Write_Cmd ( 0x36 );
  505.         ILI9341_Write_Data ( 0x08 |(ucOption<<5));//根据ucOption的值设置LCD参数,共0-7种模式
  506.         ILI9341_Write_Cmd ( CMD_SetCoordinateX );
  507.         ILI9341_Write_Data ( 0x00 );                /* x 起始坐标高8位 */
  508.         ILI9341_Write_Data ( 0x00 );                /* x 起始坐标低8位 */
  509.         ILI9341_Write_Data ( ((LCD_X_LENGTH-1)>>8)&0xFF ); /* x 结束坐标高8位 */       
  510.         ILI9341_Write_Data ( (LCD_X_LENGTH-1)&0xFF );                                /* x 结束坐标低8位 */

  511.         ILI9341_Write_Cmd ( CMD_SetCoordinateY );
  512.         ILI9341_Write_Data ( 0x00 );                /* y 起始坐标高8位 */
  513.         ILI9341_Write_Data ( 0x00 );                /* y 起始坐标低8位 */
  514.         ILI9341_Write_Data ( ((LCD_Y_LENGTH-1)>>8)&0xFF );        /* y 结束坐标高8位 */         
  515.         ILI9341_Write_Data ( (LCD_Y_LENGTH-1)&0xFF );                                /* y 结束坐标低8位 */

  516.         /* write gram start */
  517.         ILI9341_Write_Cmd ( CMD_SetPixel );       
  518. }



  519. /**
  520. * @brief  在ILI9341显示器上开辟一个窗口
  521. * @param  usX :在特定扫描方向下窗口的起点X坐标
  522. * @param  usY :在特定扫描方向下窗口的起点Y坐标
  523. * @param  usWidth :窗口的宽度
  524. * @param  usHeight :窗口的高度
  525. * @retval 无
  526. */
  527. void ILI9341_OpenWindow ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight )
  528. {       
  529.         ILI9341_Write_Cmd ( CMD_SetCoordinateX );                                  /* 设置X坐标 */
  530.         ILI9341_Write_Data ( usX >> 8  );         /* 先高8位,然后低8位 */
  531.         ILI9341_Write_Data ( usX & 0xff  );         /* 设置起始点和结束点*/
  532.         ILI9341_Write_Data ( ( usX + usWidth - 1 ) >> 8  );
  533.         ILI9341_Write_Data ( ( usX + usWidth - 1 ) & 0xff  );

  534.         ILI9341_Write_Cmd ( CMD_SetCoordinateY );                              /* 设置Y坐标*/
  535.         ILI9341_Write_Data ( usY >> 8  );
  536.         ILI9341_Write_Data ( usY & 0xff  );
  537.         ILI9341_Write_Data ( ( usY + usHeight - 1 ) >> 8 );
  538.         ILI9341_Write_Data ( ( usY + usHeight - 1) & 0xff );
  539.        
  540. }


  541. /**
  542. * @brief  设定ILI9341的光标坐标
  543. * @param  usX :在特定扫描方向下光标的X坐标
  544. * @param  usY :在特定扫描方向下光标的Y坐标
  545. * @retval 无
  546. */
  547. static void ILI9341_SetCursor ( uint16_t usX, uint16_t usY )       
  548. {
  549.         ILI9341_OpenWindow ( usX, usY, 1, 1 );
  550. }


  551. /**
  552. * @brief  在ILI9341显示器上以某一颜色填充像素点
  553. * @param  ulAmout_Point :要填充颜色的像素点的总数目
  554. * @param  usColor :颜色
  555. * @retval 无
  556. */
  557. static __inline void ILI9341_FillColor ( uint32_t ulAmout_Point, uint16_t usColor )
  558. {
  559.         uint32_t i = 0;
  560.        
  561.        
  562.         /* memory write */
  563.         ILI9341_Write_Cmd ( CMD_SetPixel );       
  564.                
  565.         for ( i = 0; i < ulAmout_Point; i ++ )
  566.                 ILI9341_Write_Data ( usColor );
  567.                
  568.        
  569. }


  570. /**
  571. * @brief  对ILI9341显示器的某一窗口以某种颜色进行清屏
  572. * @param  usX :在特定扫描方向下窗口的起点X坐标
  573. * @param  usY :在特定扫描方向下窗口的起点Y坐标
  574. * @param  usWidth :窗口的宽度
  575. * @param  usHeight :窗口的高度
  576. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  577. * @retval 无
  578. */
  579. void ILI9341_Clear ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight )
  580. {
  581.         ILI9341_OpenWindow ( usX, usY, usWidth, usHeight );

  582.         ILI9341_FillColor ( usWidth * usHeight, CurrentBackColor );               
  583.        
  584. }


  585. /**
  586. * @brief  对ILI9341显示器的某一点以某种颜色进行填充
  587. * @param  usX :在特定扫描方向下该点的X坐标
  588. * @param  usY :在特定扫描方向下该点的Y坐标
  589. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  590. * @retval 无
  591. */
  592. void ILI9341_SetPointPixel ( uint16_t usX, uint16_t usY )       
  593. {       
  594.         if ( ( usX < LCD_X_LENGTH ) && ( usY < LCD_Y_LENGTH ) )
  595.   {
  596.                 ILI9341_SetCursor ( usX, usY );
  597.                
  598.                 ILI9341_FillColor ( 1, CurrentTextColor );
  599.         }
  600.        
  601. }


  602. /**
  603. * @brief  读取ILI9341 GRAN 的一个像素数据
  604. * @param  无
  605. * @retval 像素数据
  606. */
  607. static uint16_t ILI9341_Read_PixelData ( void )       
  608. {       
  609.         uint16_t usR=0, usG=0, usB=0 ;

  610.        
  611.         ILI9341_Write_Cmd ( 0x2E );   /* 读数据 */
  612.        
  613.         usR = ILI9341_Read_Data ();         /*FIRST READ OUT DUMMY DATA*/
  614.        
  615.         usR = ILI9341_Read_Data ();          /*READ OUT RED DATA  */
  616.         usB = ILI9341_Read_Data ();          /*READ OUT BLUE DATA*/
  617.         usG = ILI9341_Read_Data ();          /*READ OUT GREEN DATA*/       
  618.        
  619.   return ( ( ( usR >> 11 ) << 11 ) | ( ( usG >> 10 ) << 5 ) | ( usB >> 11 ) );
  620.        
  621. }


  622. /**
  623. * @brief  获取 ILI9341 显示器上某一个坐标点的像素数据
  624. * @param  usX :在特定扫描方向下该点的X坐标
  625. * @param  usY :在特定扫描方向下该点的Y坐标
  626. * @retval 像素数据
  627. */
  628. uint16_t ILI9341_GetPointPixel ( uint16_t usX, uint16_t usY )
  629. {
  630.         uint16_t usPixelData;

  631.        
  632.         ILI9341_SetCursor ( usX, usY );
  633.        
  634.         usPixelData = ILI9341_Read_PixelData ();
  635.        
  636.         return usPixelData;
  637.        
  638. }


  639. /**
  640. * @brief  在 ILI9341 显示器上使用 Bresenham 算法画线段
  641. * @param  usX1 :在特定扫描方向下线段的一个端点X坐标
  642. * @param  usY1 :在特定扫描方向下线段的一个端点Y坐标
  643. * @param  usX2 :在特定扫描方向下线段的另一个端点X坐标
  644. * @param  usY2 :在特定扫描方向下线段的另一个端点Y坐标
  645. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  646. * @retval 无
  647. */
  648. void ILI9341_DrawLine ( uint16_t usX1, uint16_t usY1, uint16_t usX2, uint16_t usY2 )
  649. {
  650.         uint16_t us;
  651.         uint16_t usX_Current, usY_Current;
  652.        
  653.         int32_t lError_X = 0, lError_Y = 0, lDelta_X, lDelta_Y, lDistance;
  654.         int32_t lIncrease_X, lIncrease_Y;        
  655.        
  656.        
  657.         lDelta_X = usX2 - usX1; //计算坐标增量
  658.         lDelta_Y = usY2 - usY1;
  659.        
  660.         usX_Current = usX1;
  661.         usY_Current = usY1;
  662.        
  663.        
  664.         if ( lDelta_X > 0 )
  665.                 lIncrease_X = 1; //设置单步方向
  666.        
  667.         else if ( lDelta_X == 0 )
  668.                 lIncrease_X = 0;//垂直线
  669.        
  670.         else
  671.   {
  672.     lIncrease_X = -1;
  673.     lDelta_X = - lDelta_X;
  674.   }

  675.        
  676.         if ( lDelta_Y > 0 )
  677.                 lIncrease_Y = 1;
  678.        
  679.         else if ( lDelta_Y == 0 )
  680.                 lIncrease_Y = 0;//水平线
  681.        
  682.         else
  683.   {
  684.     lIncrease_Y = -1;
  685.     lDelta_Y = - lDelta_Y;
  686.   }

  687.        
  688.         if (  lDelta_X > lDelta_Y )
  689.                 lDistance = lDelta_X; //选取基本增量坐标轴
  690.        
  691.         else
  692.                 lDistance = lDelta_Y;

  693.        
  694.         for ( us = 0; us <= lDistance + 1; us ++ )//画线输出
  695.         {  
  696.                 ILI9341_SetPointPixel ( usX_Current, usY_Current );//画点
  697.                
  698.                 lError_X += lDelta_X ;
  699.                 lError_Y += lDelta_Y ;
  700.                
  701.                 if ( lError_X > lDistance )
  702.                 {
  703.                         lError_X -= lDistance;
  704.                         usX_Current += lIncrease_X;
  705.                 }  
  706.                
  707.                 if ( lError_Y > lDistance )
  708.                 {
  709.                         lError_Y -= lDistance;
  710.                         usY_Current += lIncrease_Y;
  711.                 }
  712.                
  713.         }  
  714.        
  715.        
  716. }   


  717. /**
  718. * @brief  在 ILI9341 显示器上画一个矩形
  719. * @param  usX_Start :在特定扫描方向下矩形的起始点X坐标
  720. * @param  usY_Start :在特定扫描方向下矩形的起始点Y坐标
  721. * @param  usWidth:矩形的宽度(单位:像素)
  722. * @param  usHeight:矩形的高度(单位:像素)
  723. * @param  ucFilled :选择是否填充该矩形
  724.   *   该参数为以下值之一:
  725.   *     @arg 0 :空心矩形
  726.   *     @arg 1 :实心矩形
  727. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  728. * @retval 无
  729. */
  730. void ILI9341_DrawRectangle ( uint16_t usX_Start, uint16_t usY_Start, uint16_t usWidth, uint16_t usHeight, uint8_t ucFilled )
  731. {
  732.         if ( ucFilled )
  733.         {
  734.                 ILI9341_OpenWindow ( usX_Start, usY_Start, usWidth, usHeight );
  735.                 ILI9341_FillColor ( usWidth * usHeight ,CurrentTextColor);       
  736.         }
  737.         else
  738.         {
  739.                 ILI9341_DrawLine ( usX_Start, usY_Start, usX_Start + usWidth - 1, usY_Start );
  740.                 ILI9341_DrawLine ( usX_Start, usY_Start + usHeight - 1, usX_Start + usWidth - 1, usY_Start + usHeight - 1 );
  741.                 ILI9341_DrawLine ( usX_Start, usY_Start, usX_Start, usY_Start + usHeight - 1 );
  742.                 ILI9341_DrawLine ( usX_Start + usWidth - 1, usY_Start, usX_Start + usWidth - 1, usY_Start + usHeight - 1 );               
  743.         }

  744. }


  745. /**
  746. * @brief  在 ILI9341 显示器上使用 Bresenham 算法画圆
  747. * @param  usX_Center :在特定扫描方向下圆心的X坐标
  748. * @param  usY_Center :在特定扫描方向下圆心的Y坐标
  749. * @param  usRadius:圆的半径(单位:像素)
  750. * @param  ucFilled :选择是否填充该圆
  751.   *   该参数为以下值之一:
  752.   *     @arg 0 :空心圆
  753.   *     @arg 1 :实心圆
  754. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  755. * @retval 无
  756. */
  757. void ILI9341_DrawCircle ( uint16_t usX_Center, uint16_t usY_Center, uint16_t usRadius, uint8_t ucFilled )
  758. {
  759.         int16_t sCurrentX, sCurrentY;
  760.         int16_t sError;
  761.        
  762.        
  763.         sCurrentX = 0; sCurrentY = usRadius;          
  764.        
  765.         sError = 3 - ( usRadius << 1 );     //判断下个点位置的标志
  766.        
  767.        
  768.         while ( sCurrentX <= sCurrentY )
  769.         {
  770.                 int16_t sCountY;
  771.                
  772.                
  773.                 if ( ucFilled )                        
  774.                         for ( sCountY = sCurrentX; sCountY <= sCurrentY; sCountY ++ )
  775.                         {                     
  776.                                 ILI9341_SetPointPixel ( usX_Center + sCurrentX, usY_Center + sCountY );           //1,研究对象
  777.                                 ILI9341_SetPointPixel ( usX_Center - sCurrentX, usY_Center + sCountY );           //2      
  778.                                 ILI9341_SetPointPixel ( usX_Center - sCountY,   usY_Center + sCurrentX );           //3
  779.                                 ILI9341_SetPointPixel ( usX_Center - sCountY,   usY_Center - sCurrentX );           //4
  780.                                 ILI9341_SetPointPixel ( usX_Center - sCurrentX, usY_Center - sCountY );           //5   
  781.         ILI9341_SetPointPixel ( usX_Center + sCurrentX, usY_Center - sCountY );           //6
  782.                                 ILI9341_SetPointPixel ( usX_Center + sCountY,   usY_Center - sCurrentX );           //7        
  783.         ILI9341_SetPointPixel ( usX_Center + sCountY,   usY_Center + sCurrentX );           //0                               
  784.                         }
  785.                
  786.                 else
  787.                 {         
  788.                         ILI9341_SetPointPixel ( usX_Center + sCurrentX, usY_Center + sCurrentY );             //1,研究对象
  789.                         ILI9341_SetPointPixel ( usX_Center - sCurrentX, usY_Center + sCurrentY );             //2      
  790.                         ILI9341_SetPointPixel ( usX_Center - sCurrentY, usY_Center + sCurrentX );             //3
  791.                         ILI9341_SetPointPixel ( usX_Center - sCurrentY, usY_Center - sCurrentX );             //4
  792.                         ILI9341_SetPointPixel ( usX_Center - sCurrentX, usY_Center - sCurrentY );             //5      
  793.                         ILI9341_SetPointPixel ( usX_Center + sCurrentX, usY_Center - sCurrentY );             //6
  794.                         ILI9341_SetPointPixel ( usX_Center + sCurrentY, usY_Center - sCurrentX );             //7
  795.                         ILI9341_SetPointPixel ( usX_Center + sCurrentY, usY_Center + sCurrentX );             //0
  796.     }                       
  797.                
  798.                
  799.                 sCurrentX ++;

  800.                
  801.                 if ( sError < 0 )
  802.                         sError += 4 * sCurrentX + 6;          
  803.                
  804.                 else
  805.                 {
  806.                         sError += 10 + 4 * ( sCurrentX - sCurrentY );   
  807.                         sCurrentY --;
  808.                 }        
  809.                
  810.                
  811.         }
  812.        
  813.        
  814. }

  815. /**
  816. * @brief  在 ILI9341 显示器上显示一个英文字符
  817. * @param  usX :在特定扫描方向下字符的起始X坐标
  818. * @param  usY :在特定扫描方向下该点的起始Y坐标
  819. * @param  cChar :要显示的英文字符
  820. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  821. * @retval 无
  822. */
  823. void ILI9341_DispChar_EN ( uint16_t usX, uint16_t usY, const char cChar )
  824. {
  825.         uint8_t  byteCount, bitCount,fontLength;       
  826.         uint16_t ucRelativePositon;
  827.         uint8_t *Pfont;
  828.        
  829.         //对ascii码表偏移(字模表不包含ASCII表的前32个非图形符号)
  830.         ucRelativePositon = cChar - ' ';
  831.        
  832.         //每个字模的字节数
  833.         fontLength = (LCD_Currentfonts->Width*LCD_Currentfonts->Height)/8;
  834.                
  835.         //字模首地址
  836.         /*ascii码表偏移值乘以每个字模的字节数,求出字模的偏移位置*/
  837.         Pfont = (uint8_t *)&LCD_Currentfonts->table[ucRelativePositon * fontLength];
  838.        
  839.         //设置显示窗口
  840.         ILI9341_OpenWindow ( usX, usY, LCD_Currentfonts->Width, LCD_Currentfonts->Height);
  841.        
  842.         ILI9341_Write_Cmd ( CMD_SetPixel );                       

  843.         //按字节读取字模数据
  844.         //由于前面直接设置了显示窗口,显示数据会自动换行
  845.         for ( byteCount = 0; byteCount < fontLength; byteCount++ )
  846.         {
  847.                         //一位一位处理要显示的颜色
  848.                         for ( bitCount = 0; bitCount < 8; bitCount++ )
  849.                         {
  850.                                         if ( Pfont[byteCount] & (0x80>>bitCount) )
  851.                                                 ILI9341_Write_Data ( CurrentTextColor );                       
  852.                                         else
  853.                                                 ILI9341_Write_Data ( CurrentBackColor );
  854.                         }       
  855.         }       
  856. }


  857. /**
  858. * @brief  在 ILI9341 显示器上显示英文字符串
  859. * @param  line :在特定扫描方向下字符串的起始Y坐标
  860.   *   本参数可使用宏LINE(0)、LINE(1)等方式指定文字坐标,
  861.   *   宏LINE(x)会根据当前选择的字体来计算Y坐标值。
  862.         *                显示中文且使用LINE宏时,需要把英文字体设置成Font8x16
  863. * @param  pStr :要显示的英文字符串的首地址
  864. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  865. * @retval 无
  866. */
  867. void ILI9341_DispStringLine_EN (  uint16_t line,  char * pStr )
  868. {
  869.         uint16_t usX = 0;
  870.        
  871.         while ( * pStr != '\0' )
  872.         {
  873.                 if ( ( usX - ILI9341_DispWindow_X_Star + LCD_Currentfonts->Width ) > LCD_X_LENGTH )
  874.                 {
  875.                         usX = ILI9341_DispWindow_X_Star;
  876.                         line += LCD_Currentfonts->Height;
  877.                 }
  878.                
  879.                 if ( ( line - ILI9341_DispWindow_Y_Star + LCD_Currentfonts->Height ) > LCD_Y_LENGTH )
  880.                 {
  881.                         usX = ILI9341_DispWindow_X_Star;
  882.                         line = ILI9341_DispWindow_Y_Star;
  883.                 }
  884.                
  885.                 ILI9341_DispChar_EN ( usX, line, * pStr);
  886.                
  887.                 pStr ++;
  888.                
  889.                 usX += LCD_Currentfonts->Width;
  890.                
  891.         }
  892.        
  893. }


  894. /**
  895. * @brief  在 ILI9341 显示器上显示英文字符串
  896. * @param  usX :在特定扫描方向下字符的起始X坐标
  897. * @param  usY :在特定扫描方向下字符的起始Y坐标
  898. * @param  pStr :要显示的英文字符串的首地址
  899. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  900. * @retval 无
  901. */
  902. void ILI9341_DispString_EN (         uint16_t usX ,uint16_t usY,  char * pStr )
  903. {
  904.         while ( * pStr != '\0' )
  905.         {
  906.                 if ( ( usX - ILI9341_DispWindow_X_Star + LCD_Currentfonts->Width ) > LCD_X_LENGTH )
  907.                 {
  908.                         usX = ILI9341_DispWindow_X_Star;
  909.                         usY += LCD_Currentfonts->Height;
  910.                 }
  911.                
  912.                 if ( ( usY - ILI9341_DispWindow_Y_Star + LCD_Currentfonts->Height ) > LCD_Y_LENGTH )
  913.                 {
  914.                         usX = ILI9341_DispWindow_X_Star;
  915.                         usY = ILI9341_DispWindow_Y_Star;
  916.                 }
  917.                
  918.                 ILI9341_DispChar_EN ( usX, usY, * pStr);
  919.                
  920.                 pStr ++;
  921.                
  922.                 usX += LCD_Currentfonts->Width;
  923.                
  924.         }
  925.        
  926. }


  927. /**
  928. * @brief  在 ILI9341 显示器上显示英文字符串(沿Y轴方向)
  929. * @param  usX :在特定扫描方向下字符的起始X坐标
  930. * @param  usY :在特定扫描方向下字符的起始Y坐标
  931. * @param  pStr :要显示的英文字符串的首地址
  932. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  933. * @retval 无
  934. */
  935. void ILI9341_DispString_EN_YDir (         uint16_t usX,uint16_t usY ,  char * pStr )
  936. {       
  937.         while ( * pStr != '\0' )
  938.         {
  939.                 if ( ( usY - ILI9341_DispWindow_Y_Star + LCD_Currentfonts->Height ) >LCD_Y_LENGTH  )
  940.                 {
  941.                         usY = ILI9341_DispWindow_Y_Star;
  942.                         usX += LCD_Currentfonts->Width;
  943.                 }
  944.                
  945.                 if ( ( usX - ILI9341_DispWindow_X_Star + LCD_Currentfonts->Width ) >  LCD_X_LENGTH)
  946.                 {
  947.                         usX = ILI9341_DispWindow_X_Star;
  948.                         usY = ILI9341_DispWindow_Y_Star;
  949.                 }
  950.                
  951.                 ILI9341_DispChar_EN ( usX, usY, * pStr);
  952.                
  953.                 pStr ++;
  954.                
  955.                 usY += LCD_Currentfonts->Height;               
  956.         }       
  957. }

  958. /**
  959. * @brief  在 ILI9341 显示器上显示一个中文字符
  960. * @param  usX :在特定扫描方向下字符的起始X坐标
  961. * @param  usY :在特定扫描方向下字符的起始Y坐标
  962. * @param  usChar :要显示的中文字符(国标码)
  963. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  964. * @retval 无
  965. */
  966. void ILI9341_DispChar_CH ( uint16_t usX, uint16_t usY, uint16_t usChar )
  967. {
  968.         uint8_t rowCount, bitCount;
  969.         uint8_t ucBuffer [ WIDTH_CH_CHAR*HEIGHT_CH_CHAR/8 ];       
  970.   uint16_t usTemp;        

  971.         //设置显示窗口
  972.         ILI9341_OpenWindow ( usX, usY, WIDTH_CH_CHAR, HEIGHT_CH_CHAR );
  973.        
  974.         ILI9341_Write_Cmd ( CMD_SetPixel );
  975.        
  976.         //取字模数据  
  977.   GetGBKCode ( ucBuffer, usChar );       
  978.        
  979.         for ( rowCount = 0; rowCount < HEIGHT_CH_CHAR; rowCount++ )
  980.         {
  981.     /* 取出两个字节的数据,在lcd上即是一个汉字的一行 */
  982.                 usTemp = ucBuffer [ rowCount * 2 ];
  983.                 usTemp = ( usTemp << 8 );
  984.                 usTemp |= ucBuffer [ rowCount * 2 + 1 ];
  985.                
  986.                 for ( bitCount = 0; bitCount < WIDTH_CH_CHAR; bitCount ++ )
  987.                 {                       
  988.                         if ( usTemp & ( 0x8000 >> bitCount ) )  //高位在前
  989.                           ILI9341_Write_Data ( CurrentTextColor );                               
  990.                         else
  991.                                 ILI9341_Write_Data ( CurrentBackColor );                       
  992.                 }               
  993.         }
  994.        
  995. }


  996. /**
  997. * @brief  在 ILI9341 显示器上显示中文字符串
  998. * @param  line :在特定扫描方向下字符串的起始Y坐标
  999.   *   本参数可使用宏LINE(0)、LINE(1)等方式指定文字坐标,
  1000.   *   宏LINE(x)会根据当前选择的字体来计算Y坐标值。
  1001.         *                显示中文且使用LINE宏时,需要把英文字体设置成Font8x16
  1002. * @param  pStr :要显示的英文字符串的首地址
  1003. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  1004. * @retval 无
  1005. */
  1006. void ILI9341_DispString_CH (         uint16_t usX , uint16_t usY, char * pStr )
  1007. {       
  1008.         uint16_t usCh;

  1009.        
  1010.         while( * pStr != '\0' )
  1011.         {               
  1012.                 if ( ( usX - ILI9341_DispWindow_X_Star + WIDTH_CH_CHAR ) > LCD_X_LENGTH )
  1013.                 {
  1014.                         usX = ILI9341_DispWindow_X_Star;
  1015.                         usY += HEIGHT_CH_CHAR;
  1016.                 }
  1017.                
  1018.                 if ( ( usY - ILI9341_DispWindow_Y_Star + HEIGHT_CH_CHAR ) > LCD_Y_LENGTH )
  1019.                 {
  1020.                         usX = ILI9341_DispWindow_X_Star;
  1021.                         usY = ILI9341_DispWindow_Y_Star;
  1022.                 }       
  1023.                
  1024.                 usCh = * ( uint16_t * ) pStr;       
  1025.           usCh = ( usCh << 8 ) + ( usCh >> 8 );

  1026.                 ILI9341_DispChar_CH ( usX, usY, usCh );
  1027.                
  1028.                 usX += WIDTH_CH_CHAR;
  1029.                
  1030.                 pStr += 2;           //一个汉字两个字节

  1031.         }          
  1032.        
  1033. }


  1034. /**
  1035. * @brief  在 ILI9341 显示器上显示中英文字符串
  1036. * @param  line :在特定扫描方向下字符串的起始Y坐标
  1037.   *   本参数可使用宏LINE(0)、LINE(1)等方式指定文字坐标,
  1038.   *   宏LINE(x)会根据当前选择的字体来计算Y坐标值。
  1039.         *                显示中文且使用LINE宏时,需要把英文字体设置成Font8x16
  1040. * @param  pStr :要显示的字符串的首地址
  1041. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  1042. * @retval 无
  1043. */
  1044. void ILI9341_DispStringLine_EN_CH (  uint16_t line, char * pStr )
  1045. {
  1046.         uint16_t usCh;
  1047.         uint16_t usX = 0;
  1048.        
  1049.         while( * pStr != '\0' )
  1050.         {
  1051.                 if ( * pStr <= 126 )                           //英文字符
  1052.                 {
  1053.                         if ( ( usX - ILI9341_DispWindow_X_Star + LCD_Currentfonts->Width ) > LCD_X_LENGTH )
  1054.                         {
  1055.                                 usX = ILI9341_DispWindow_X_Star;
  1056.                                 line += LCD_Currentfonts->Height;
  1057.                         }
  1058.                        
  1059.                         if ( ( line - ILI9341_DispWindow_Y_Star + LCD_Currentfonts->Height ) > LCD_Y_LENGTH )
  1060.                         {
  1061.                                 usX = ILI9341_DispWindow_X_Star;
  1062.                                 line = ILI9341_DispWindow_Y_Star;
  1063.                         }                       
  1064.                
  1065.                   ILI9341_DispChar_EN ( usX, line, * pStr );
  1066.                        
  1067.                         usX +=  LCD_Currentfonts->Width;
  1068.                
  1069.                   pStr ++;

  1070.                 }
  1071.                
  1072.                 else                                    //汉字字符
  1073.                 {
  1074.                         if ( ( usX - ILI9341_DispWindow_X_Star + WIDTH_CH_CHAR ) > LCD_X_LENGTH )
  1075.                         {
  1076.                                 usX = ILI9341_DispWindow_X_Star;
  1077.                                 line += HEIGHT_CH_CHAR;
  1078.                         }
  1079.                        
  1080.                         if ( ( line - ILI9341_DispWindow_Y_Star + HEIGHT_CH_CHAR ) > LCD_Y_LENGTH )
  1081.                         {
  1082.                                 usX = ILI9341_DispWindow_X_Star;
  1083.                                 line = ILI9341_DispWindow_Y_Star;
  1084.                         }       
  1085.                        
  1086.                         usCh = * ( uint16_t * ) pStr;       
  1087.                        
  1088.                         usCh = ( usCh << 8 ) + ( usCh >> 8 );               

  1089.                         ILI9341_DispChar_CH ( usX, line, usCh );
  1090.                        
  1091.                         usX += WIDTH_CH_CHAR;
  1092.                        
  1093.                         pStr += 2;           //一个汉字两个字节
  1094.                
  1095.     }
  1096.                
  1097.   }       
  1098. }

  1099. /**
  1100. * @brief  在 ILI9341 显示器上显示中英文字符串
  1101. * @param  usX :在特定扫描方向下字符的起始X坐标
  1102. * @param  usY :在特定扫描方向下字符的起始Y坐标
  1103. * @param  pStr :要显示的字符串的首地址
  1104. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  1105. * @retval 无
  1106. */
  1107. void ILI9341_DispString_EN_CH (         uint16_t usX , uint16_t usY, char * pStr )
  1108. {
  1109.         uint16_t usCh;
  1110.        
  1111.         while( * pStr != '\0' )
  1112.         {
  1113.                 if ( * pStr <= 126 )                           //英文字符
  1114.                 {
  1115.                         if ( ( usX - ILI9341_DispWindow_X_Star + LCD_Currentfonts->Width ) > LCD_X_LENGTH )
  1116.                         {
  1117.                                 usX = ILI9341_DispWindow_X_Star;
  1118.                                 usY += LCD_Currentfonts->Height;
  1119.                         }
  1120.                        
  1121.                         if ( ( usY - ILI9341_DispWindow_Y_Star + LCD_Currentfonts->Height ) > LCD_Y_LENGTH )
  1122.                         {
  1123.                                 usX = ILI9341_DispWindow_X_Star;
  1124.                                 usY = ILI9341_DispWindow_Y_Star;
  1125.                         }                       
  1126.                
  1127.                   ILI9341_DispChar_EN ( usX, usY, * pStr );
  1128.                        
  1129.                         usX +=  LCD_Currentfonts->Width;
  1130.                
  1131.                   pStr ++;

  1132.                 }
  1133.                
  1134.                 else                                    //汉字字符
  1135.                 {
  1136.                         if ( ( usX - ILI9341_DispWindow_X_Star + WIDTH_CH_CHAR ) > LCD_X_LENGTH )
  1137.                         {
  1138.                                 usX = ILI9341_DispWindow_X_Star;
  1139.                                 usY += HEIGHT_CH_CHAR;
  1140.                         }
  1141.                        
  1142.                         if ( ( usY - ILI9341_DispWindow_Y_Star + HEIGHT_CH_CHAR ) > LCD_Y_LENGTH )
  1143.                         {
  1144.                                 usX = ILI9341_DispWindow_X_Star;
  1145.                                 usY = ILI9341_DispWindow_Y_Star;
  1146.                         }       
  1147.                        
  1148.                         usCh = * ( uint16_t * ) pStr;       
  1149.                        
  1150.                         usCh = ( usCh << 8 ) + ( usCh >> 8 );               

  1151.                         ILI9341_DispChar_CH ( usX, usY, usCh );
  1152.                        
  1153.                         usX += WIDTH_CH_CHAR;
  1154.                        
  1155.                         pStr += 2;           //一个汉字两个字节
  1156.                
  1157.     }
  1158.                
  1159.   }       
  1160. }

  1161. /**
  1162. * @brief  在 ILI9341 显示器上显示中英文字符串(沿Y轴方向)
  1163. * @param  usX :在特定扫描方向下字符的起始X坐标
  1164. * @param  usY :在特定扫描方向下字符的起始Y坐标
  1165. * @param  pStr :要显示的中英文字符串的首地址
  1166. * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  1167. * @retval 无
  1168. */
  1169. void ILI9341_DispString_EN_CH_YDir (  uint16_t usX,uint16_t usY , char * pStr )
  1170. {
  1171.         uint16_t usCh;
  1172.        
  1173.         while( * pStr != '\0' )
  1174.         {                       
  1175.                         //统一使用汉字的宽高来计算换行
  1176.                         if ( ( usY - ILI9341_DispWindow_Y_Star + HEIGHT_CH_CHAR ) >LCD_Y_LENGTH  )
  1177.                         {
  1178.                                 usY = ILI9341_DispWindow_Y_Star;
  1179.                                 usX += WIDTH_CH_CHAR;
  1180.                         }                       
  1181.                         if ( ( usX - ILI9341_DispWindow_X_Star + WIDTH_CH_CHAR ) >  LCD_X_LENGTH)
  1182.                         {
  1183.                                 usX = ILI9341_DispWindow_X_Star;
  1184.                                 usY = ILI9341_DispWindow_Y_Star;
  1185.                         }
  1186.                        
  1187.                 //显示       
  1188.                 if ( * pStr <= 126 )                           //英文字符
  1189.                 {                       
  1190.                         ILI9341_DispChar_EN ( usX, usY, * pStr);
  1191.                        
  1192.                         pStr ++;
  1193.                        
  1194.                         usY += HEIGHT_CH_CHAR;               
  1195.                 }
  1196.                 else                                    //汉字字符
  1197.                 {                       
  1198.                         usCh = * ( uint16_t * ) pStr;       
  1199.                        
  1200.                         usCh = ( usCh << 8 ) + ( usCh >> 8 );               

  1201.                         ILI9341_DispChar_CH ( usX,usY , usCh );
  1202.                        
  1203.                         usY += HEIGHT_CH_CHAR;
  1204.                        
  1205.                         pStr += 2;           //一个汉字两个字节
  1206.                
  1207.     }
  1208.                
  1209.   }       
  1210. }

  1211. /***********************缩放字体****************************/
  1212. #define ZOOMMAXBUFF 16384
  1213. uint8_t zoomBuff[ZOOMMAXBUFF] = {0};        //用于缩放的缓存,最大支持到128*128
  1214. uint8_t zoomTempBuff[1024] = {0};

  1215. /**
  1216. * @brief  缩放字模,缩放后的字模由1个像素点由8个数据位来表示
  1217.                                                                                 0x01表示笔迹,0x00表示空白区
  1218. * @param  in_width :原始字符宽度
  1219. * @param  in_heig :原始字符高度
  1220. * @param  out_width :缩放后的字符宽度
  1221. * @param  out_heig:缩放后的字符高度
  1222. * @param  in_ptr :字库输入指针        注意:1pixel 1bit
  1223. * @param  out_ptr :缩放后的字符输出指针 注意: 1pixel 8bit
  1224. *                out_ptr实际上没有正常输出,改成了直接输出到全局指针zoomBuff中
  1225. * @param  en_cn :0为英文,1为中文
  1226. * @retval 无
  1227. */
  1228. void ILI9341_zoomChar(uint16_t in_width,        //原始字符宽度
  1229.                                                                         uint16_t in_heig,                //原始字符高度
  1230.                                                                         uint16_t out_width,        //缩放后的字符宽度
  1231.                                                                         uint16_t out_heig,        //缩放后的字符高度
  1232.                                                                         uint8_t *in_ptr,        //字库输入指针        注意:1pixel 1bit
  1233.                                                                         uint8_t *out_ptr, //缩放后的字符输出指针 注意: 1pixel 8bit
  1234.                                                                         uint8_t en_cn)                //0为英文,1为中文       
  1235. {
  1236.         uint8_t *pts,*ots;
  1237.         //根据源字模及目标字模大小,设定运算比例因子,左移16是为了把浮点运算转成定点运算
  1238.         unsigned int xrIntFloat_16=(in_width<<16)/out_width+1;
  1239.   unsigned int yrIntFloat_16=(in_heig<<16)/out_heig+1;
  1240.        
  1241.         unsigned int srcy_16=0;
  1242.         unsigned int y,x;
  1243.         uint8_t *pSrcLine;
  1244.        
  1245.         uint16_t byteCount,bitCount;
  1246.        
  1247.         //检查参数是否合法
  1248.         if(in_width >= 32) return;                                                                                                //字库不允许超过32像素
  1249.         if(in_width * in_heig == 0) return;       
  1250.         if(in_width * in_heig >= 1024 ) return;                                         //限制输入最大 32*32
  1251.        
  1252.         if(out_width * out_heig == 0) return;       
  1253.         if(out_width * out_heig >= ZOOMMAXBUFF ) return; //限制最大缩放 128*128
  1254.         pts = (uint8_t*)&zoomTempBuff;
  1255.        
  1256.         //为方便运算,字库的数据由1 pixel/1bit 映射到1pixel/8bit
  1257.         //0x01表示笔迹,0x00表示空白区
  1258.         if(en_cn == 0x00)//英文
  1259.         {
  1260.                 //英文和中文字库上下边界不对,可在此处调整。需要注意tempBuff防止溢出
  1261.                         for(byteCount=0;byteCount<in_heig*in_width/8;byteCount++)       
  1262.                         {
  1263.                                 for(bitCount=0;bitCount<8;bitCount++)
  1264.                                         {                                               
  1265.                                                 //把源字模数据由位映射到字节
  1266.                                                 //in_ptr里bitX为1,则pts里整个字节值为1
  1267.                                                 //in_ptr里bitX为0,则pts里整个字节值为0
  1268.                                                 *pts++ = (in_ptr[byteCount] & (0x80>>bitCount))?1:0;
  1269.                                         }
  1270.                         }                               
  1271.         }
  1272.         else //中文
  1273.         {                       
  1274.                         for(byteCount=0;byteCount<in_heig*in_width/8;byteCount++)       
  1275.                         {
  1276.                                 for(bitCount=0;bitCount<8;bitCount++)
  1277.                                         {                                               
  1278.                                                 //把源字模数据由位映射到字节
  1279.                                                 //in_ptr里bitX为1,则pts里整个字节值为1
  1280.                                                 //in_ptr里bitX为0,则pts里整个字节值为0
  1281.                                                 *pts++ = (in_ptr[byteCount] & (0x80>>bitCount))?1:0;
  1282.                                         }
  1283.                         }               
  1284.         }

  1285.         //zoom过程
  1286.         pts = (uint8_t*)&zoomTempBuff;        //映射后的源数据指针
  1287.         ots = (uint8_t*)&zoomBuff;        //输出数据的指针
  1288.         for (y=0;y<out_heig;y++)        /*行遍历*/
  1289.     {
  1290.                                 unsigned int srcx_16=0;
  1291.         pSrcLine=pts+in_width*(srcy_16>>16);                               
  1292.         for (x=0;x<out_width;x++) /*行内像素遍历*/
  1293.         {
  1294.             ots[x]=pSrcLine[srcx_16>>16]; //把源字模数据复制到目标指针中
  1295.             srcx_16+=xrIntFloat_16;                        //按比例偏移源像素点
  1296.         }
  1297.         srcy_16+=yrIntFloat_16;                                  //按比例偏移源像素点
  1298.         ots+=out_width;                                               
  1299.     }
  1300.         /*!!!缩放后的字模数据直接存储到全局指针zoomBuff里了*/
  1301.         out_ptr = (uint8_t*)&zoomBuff;        //out_ptr没有正确传出,后面调用直接改成了全局变量指针!
  1302.        
  1303.         /*实际中如果使用out_ptr不需要下面这一句!!!
  1304.                 只是因为out_ptr没有使用,会导致warning。强迫症*/
  1305.         out_ptr++;
  1306. }                       


  1307. /**
  1308. * @brief  利用缩放后的字模显示字符
  1309. * @param  Xpos :字符显示位置x
  1310. * @param  Ypos :字符显示位置y
  1311. * @param  Font_width :字符宽度
  1312. * @param  Font_Heig:字符高度
  1313. * @param  c :要显示的字模数据
  1314. * @param  DrawModel :是否反色显示
  1315. * @retval 无
  1316. */
  1317. void ILI9341_DrawChar_Ex(uint16_t usX, //字符显示位置x
  1318.                                                                                                 uint16_t usY, //字符显示位置y
  1319.                                                                                                 uint16_t Font_width, //字符宽度
  1320.                                                                                                 uint16_t Font_Height,  //字符高度
  1321.                                                                                                 uint8_t *c,                                                //字模数据
  1322.                                                                                                 uint16_t DrawModel)                //是否反色显示
  1323. {
  1324.   uint32_t index = 0, counter = 0;

  1325.         //设置显示窗口
  1326.         ILI9341_OpenWindow ( usX, usY, Font_width, Font_Height);
  1327.        
  1328.         ILI9341_Write_Cmd ( CMD_SetPixel );               
  1329.        
  1330.         //按字节读取字模数据
  1331.         //由于前面直接设置了显示窗口,显示数据会自动换行
  1332.         for ( index = 0; index < Font_Height; index++ )
  1333.         {
  1334.                         //一位一位处理要显示的颜色
  1335.                         for ( counter = 0; counter < Font_width; counter++ )
  1336.                         {
  1337.                                         //缩放后的字模数据,以一个字节表示一个像素位
  1338.                                         //整个字节值为1表示该像素为笔迹
  1339.                                         //整个字节值为0表示该像素为背景
  1340.                                         if ( *c++ == DrawModel )
  1341.                                                 ILI9341_Write_Data ( CurrentBackColor );                       
  1342.                                         else
  1343.                                                 ILI9341_Write_Data ( CurrentTextColor );
  1344.                         }       
  1345.         }       
  1346. }


  1347. /**
  1348. * @brief  利用缩放后的字模显示字符串
  1349. * @param  Xpos :字符显示位置x
  1350. * @param  Ypos :字符显示位置y
  1351. * @param  Font_width :字符宽度,英文字符在此基础上/2。注意为偶数
  1352. * @param  Font_Heig:字符高度,注意为偶数
  1353. * @param  c :要显示的字符串
  1354. * @param  DrawModel :是否反色显示
  1355. * @retval 无
  1356. */
  1357. void ILI9341_DisplayStringEx(uint16_t x,                 //字符显示位置x
  1358.                                                                                                                  uint16_t y,                                 //字符显示位置y
  1359.                                                                                                                  uint16_t Font_width,        //要显示的字体宽度,英文字符在此基础上/2。注意为偶数
  1360.                                                                                                                  uint16_t Font_Height,        //要显示的字体高度,注意为偶数
  1361.                                                                                                                  uint8_t *ptr,                                        //显示的字符内容
  1362.                                                                                                                  uint16_t DrawModel)  //是否反色显示



  1363. {
  1364.         uint16_t Charwidth = Font_width; //默认为Font_width,英文宽度为中文宽度的一半
  1365.         uint8_t *psr;
  1366.         uint8_t Ascii;        //英文
  1367.         uint16_t usCh;  //中文
  1368.         uint8_t ucBuffer [ WIDTH_CH_CHAR*HEIGHT_CH_CHAR/8 ];       
  1369.        
  1370.         while ( *ptr != '\0')
  1371.         {
  1372.                         /****处理换行*****/
  1373.                         if ( ( x - ILI9341_DispWindow_X_Star + Charwidth ) > LCD_X_LENGTH )
  1374.                         {
  1375.                                 x = ILI9341_DispWindow_X_Star;
  1376.                                 y += Font_Height;
  1377.                         }
  1378.                        
  1379.                         if ( ( y - ILI9341_DispWindow_Y_Star + Font_Height ) > LCD_Y_LENGTH )
  1380.                         {
  1381.                                 x = ILI9341_DispWindow_X_Star;
  1382.                                 y = ILI9341_DispWindow_Y_Star;
  1383.                         }       
  1384.                        
  1385.                 if(*ptr > 0x80) //如果是中文
  1386.                 {                       
  1387.                         Charwidth = Font_width;
  1388.                         usCh = * ( uint16_t * ) ptr;                               
  1389.                         usCh = ( usCh << 8 ) + ( usCh >> 8 );
  1390.                         GetGBKCode ( ucBuffer, usCh );        //取字模数据
  1391.                         //缩放字模数据,源字模为16*16
  1392.                         ILI9341_zoomChar(WIDTH_CH_CHAR,HEIGHT_CH_CHAR,Charwidth,Font_Height,(uint8_t *)&ucBuffer,psr,1);
  1393.                         //显示单个字符
  1394.                         ILI9341_DrawChar_Ex(x,y,Charwidth,Font_Height,(uint8_t*)&zoomBuff,DrawModel);
  1395.                         x+=Charwidth;
  1396.                         ptr+=2;
  1397.                 }
  1398.                 else
  1399.                 {
  1400.                                 Charwidth = Font_width / 2;
  1401.                                 Ascii = *ptr - 32;
  1402.                                 //使用16*24字体缩放字模数据
  1403.                                 ILI9341_zoomChar(16,24,Charwidth,Font_Height,(uint8_t *)&Font16x24.table[Ascii * Font16x24.Height*Font16x24.Width/8],psr,0);
  1404.                           //显示单个字符
  1405.                                 ILI9341_DrawChar_Ex(x,y,Charwidth,Font_Height,(uint8_t*)&zoomBuff,DrawModel);
  1406.                                 x+=Charwidth;
  1407.                                 ptr++;
  1408.                 }
  1409.         }
  1410. }


  1411. /**
  1412. * @brief  利用缩放后的字模显示字符串(沿Y轴方向)
  1413. * @param  Xpos :字符显示位置x
  1414. * @param  Ypos :字符显示位置y
  1415. * @param  Font_width :字符宽度,英文字符在此基础上/2。注意为偶数
  1416. * @param  Font_Heig:字符高度,注意为偶数
  1417. * @param  c :要显示的字符串
  1418. * @param  DrawModel :是否反色显示
  1419. * @retval 无
  1420. */
  1421. void ILI9341_DisplayStringEx_YDir(uint16_t x,                 //字符显示位置x
  1422.                                                                                                                                                  uint16_t y,                                 //字符显示位置y
  1423.                                                                                                                                                  uint16_t Font_width,        //要显示的字体宽度,英文字符在此基础上/2。注意为偶数
  1424.                                                                                                                                                  uint16_t Font_Height,        //要显示的字体高度,注意为偶数
  1425.                                                                                                                                                  uint8_t *ptr,                                        //显示的字符内容
  1426.                                                                                                                                                  uint16_t DrawModel)  //是否反色显示
  1427. {
  1428.         uint16_t Charwidth = Font_width; //默认为Font_width,英文宽度为中文宽度的一半
  1429.         uint8_t *psr;
  1430.         uint8_t Ascii;        //英文
  1431.         uint16_t usCh;  //中文
  1432.         uint8_t ucBuffer [ WIDTH_CH_CHAR*HEIGHT_CH_CHAR/8 ];       
  1433.        
  1434.         while ( *ptr != '\0')
  1435.         {                       
  1436.                         //统一使用汉字的宽高来计算换行
  1437.                         if ( ( y - ILI9341_DispWindow_X_Star + Font_width ) > LCD_X_LENGTH )
  1438.                         {
  1439.                                 y = ILI9341_DispWindow_X_Star;
  1440.                                 x += Font_width;
  1441.                         }
  1442.                        
  1443.                         if ( ( x - ILI9341_DispWindow_Y_Star + Font_Height ) > LCD_Y_LENGTH )
  1444.                         {
  1445.                                 y = ILI9341_DispWindow_X_Star;
  1446.                                 x = ILI9341_DispWindow_Y_Star;
  1447.                         }       
  1448.                        
  1449.                 if(*ptr > 0x80) //如果是中文
  1450.                 {                       
  1451.                         Charwidth = Font_width;
  1452.                         usCh = * ( uint16_t * ) ptr;                               
  1453.                         usCh = ( usCh << 8 ) + ( usCh >> 8 );
  1454.                         GetGBKCode ( ucBuffer, usCh );        //取字模数据
  1455.                         //缩放字模数据,源字模为16*16
  1456.                         ILI9341_zoomChar(WIDTH_CH_CHAR,HEIGHT_CH_CHAR,Charwidth,Font_Height,(uint8_t *)&ucBuffer,psr,1);
  1457.                         //显示单个字符
  1458.                         ILI9341_DrawChar_Ex(x,y,Charwidth,Font_Height,(uint8_t*)&zoomBuff,DrawModel);
  1459.                         y+=Font_Height;
  1460.                         ptr+=2;
  1461.                 }
  1462.                 else
  1463.                 {
  1464.                                 Charwidth = Font_width / 2;
  1465.                                 Ascii = *ptr - 32;
  1466.                                 //使用16*24字体缩放字模数据
  1467.                                 ILI9341_zoomChar(16,24,Charwidth,Font_Height,(uint8_t *)&Font16x24.table[Ascii * Font16x24.Height*Font16x24.Width/8],psr,0);
  1468.                           //显示单个字符
  1469.                                 ILI9341_DrawChar_Ex(x,y,Charwidth,Font_Height,(uint8_t*)&zoomBuff,DrawModel);
  1470.                                 y+=Font_Height;
  1471.                                 ptr++;
  1472.                 }
  1473.         }
  1474. }


  1475. /**
  1476.   * @brief  设置英文字体类型
  1477.   * @param  fonts: 指定要选择的字体
  1478.         *                参数为以下值之一
  1479.   *         @arg:Font24x32;
  1480.   *         @arg:Font16x24;
  1481.   *         @arg:Font8x16;
  1482.   * @retval None
  1483.   */
  1484. void LCD_SetFont(sFONT *fonts)
  1485. {
  1486.   LCD_Currentfonts = fonts;
  1487. }

  1488. /**
  1489.   * @brief  获取当前字体类型
  1490.   * @param  None.
  1491.   * @retval 返回当前字体类型
  1492.   */
  1493. sFONT *LCD_GetFont(void)
  1494. {
  1495.   return LCD_Currentfonts;
  1496. }


  1497. /**
  1498.   * @brief  设置LCD的前景(字体)及背景颜色,RGB565
  1499.   * @param  TextColor: 指定前景(字体)颜色
  1500.   * @param  BackColor: 指定背景颜色
  1501.   * @retval None
  1502.   */
  1503. void LCD_SetColors(uint16_t TextColor, uint16_t BackColor)
  1504. {
  1505.   CurrentTextColor = TextColor;
  1506.   CurrentBackColor = BackColor;
  1507. }

  1508. /**
  1509.   * @brief  获取LCD的前景(字体)及背景颜色,RGB565
  1510.   * @param  TextColor: 用来存储前景(字体)颜色的指针变量
  1511.   * @param  BackColor: 用来存储背景颜色的指针变量
  1512.   * @retval None
  1513.   */
  1514. void LCD_GetColors(uint16_t *TextColor, uint16_t *BackColor)
  1515. {
  1516.   *TextColor = CurrentTextColor;
  1517.   *BackColor = CurrentBackColor;
  1518. }

  1519. /**
  1520.   * @brief  设置LCD的前景(字体)颜色,RGB565
  1521.   * @param  Color: 指定前景(字体)颜色
  1522.   * @retval None
  1523.   */
  1524. void LCD_SetTextColor(uint16_t Color)
  1525. {
  1526.   CurrentTextColor = Color;
  1527. }

  1528. /**
  1529.   * @brief  设置LCD的背景颜色,RGB565
  1530.   * @param  Color: 指定背景颜色
  1531.   * @retval None
  1532.   */
  1533. void LCD_SetBackColor(uint16_t Color)
  1534. {
  1535.   CurrentBackColor = Color;
  1536. }

  1537. /**
  1538.   * @brief  清除某行文字
  1539.   * @param  Line: 指定要删除的行
  1540.   *   本参数可使用宏LINE(0)、LINE(1)等方式指定要删除的行,
  1541.   *   宏LINE(x)会根据当前选择的字体来计算Y坐标值,并删除当前字体高度的第x行。
  1542.   * @retval None
  1543.   */
  1544. void LCD_ClearLine(uint16_t Line)
  1545. {
  1546.   ILI9341_Clear(0,Line,LCD_X_LENGTH,((sFONT *)LCD_GetFont())->Height);        /* 清屏,显示全黑 */

  1547. }
  1548. /*********************end of file*************************/



复制代码
  1. #ifndef      __BSP_ILI9341_LCD_H
  2. #define             __BSP_ILI9341_LCD_H


  3. #include "stm32f10x.h"
  4. #include "./font/fonts.h"


  5. /***************************************************************************************
  6. 2^26 =0X0400 0000 = 64MB,每个 BANK 有4*64MB = 256MB
  7. 64MB:FSMC_Bank1_NORSRAM1:0X6000 0000 ~ 0X63FF FFFF
  8. 64MB:FSMC_Bank1_NORSRAM2:0X6400 0000 ~ 0X67FF FFFF
  9. 64MB:FSMC_Bank1_NORSRAM3:0X6800 0000 ~ 0X6BFF FFFF
  10. 64MB:FSMC_Bank1_NORSRAM4:0X6C00 0000 ~ 0X6FFF FFFF

  11. 选择BANK1-BORSRAM4 连接 TFT,地址范围为0X6C00 0000 ~ 0X6FFF FFFF
  12. FSMC_A23 接LCD的DC(寄存器/数据选择)脚
  13. 寄存器基地址 = 0X6C00 0000
  14. RAM基地址 = 0X6D00 0000 = 0X6C00 0000+2^23*2 = 0X6C00 0000 + 0X100 0000 = 0X6D00 0000
  15. 当选择不同的地址线时,地址要重新计算  
  16. ****************************************************************************************/

  17. /******************************* ILI9341 显示屏的 FSMC 参数定义 ***************************/
  18. //FSMC_Bank1_NORSRAM用于LCD命令操作的地址
  19. #define      FSMC_Addr_ILI9341_CMD         ( ( uint32_t ) 0x6C000000 )

  20. //FSMC_Bank1_NORSRAM用于LCD数据操作的地址      
  21. #define      FSMC_Addr_ILI9341_DATA        ( ( uint32_t ) 0x6D000000 )

  22. //由片选引脚决定的NOR/SRAM块
  23. #define      FSMC_Bank1_NORSRAMx           FSMC_Bank1_NORSRAM4



  24. /******************************* ILI9341 显示屏8080通讯引脚定义 ***************************/
  25. /******控制信号线******/
  26. //片选,选择NOR/SRAM块
  27. #define      ILI9341_CS_CLK                RCC_APB2Periph_GPIOG   
  28. #define      ILI9341_CS_PORT               GPIOG
  29. #define      ILI9341_CS_PIN                GPIO_Pin_12

  30. //DC引脚,使用FSMC的地址信号控制,本引脚决定了访问LCD时使用的地址
  31. //PE2为FSMC_A23
  32. #define      ILI9341_DC_CLK                RCC_APB2Periph_GPIOE   
  33. #define      ILI9341_DC_PORT               GPIOE
  34. #define      ILI9341_DC_PIN                GPIO_Pin_2

  35. //写使能
  36. #define      ILI9341_WR_CLK                RCC_APB2Periph_GPIOD   
  37. #define      ILI9341_WR_PORT               GPIOD
  38. #define      ILI9341_WR_PIN                GPIO_Pin_5

  39. //读使能
  40. #define      ILI9341_RD_CLK                RCC_APB2Periph_GPIOD   
  41. #define      ILI9341_RD_PORT               GPIOD
  42. #define      ILI9341_RD_PIN                GPIO_Pin_4

  43. //复位引脚
  44. #define      ILI9341_RST_CLK               RCC_APB2Periph_GPIOG
  45. #define      ILI9341_RST_PORT              GPIOG
  46. #define      ILI9341_RST_PIN               GPIO_Pin_11

  47. //背光引脚
  48. #define      ILI9341_BK_CLK                RCC_APB2Periph_GPIOG   
  49. #define      ILI9341_BK_PORT               GPIOG
  50. #define      ILI9341_BK_PIN                GPIO_Pin_6

  51. /********数据信号线***************/
  52. #define      ILI9341_D0_CLK                RCC_APB2Periph_GPIOD   
  53. #define      ILI9341_D0_PORT               GPIOD
  54. #define      ILI9341_D0_PIN                GPIO_Pin_14

  55. #define      ILI9341_D1_CLK                RCC_APB2Periph_GPIOD   
  56. #define      ILI9341_D1_PORT               GPIOD
  57. #define      ILI9341_D1_PIN                GPIO_Pin_15

  58. #define      ILI9341_D2_CLK                RCC_APB2Periph_GPIOD   
  59. #define      ILI9341_D2_PORT               GPIOD
  60. #define      ILI9341_D2_PIN                GPIO_Pin_0

  61. #define      ILI9341_D3_CLK                RCC_APB2Periph_GPIOD  
  62. #define      ILI9341_D3_PORT               GPIOD
  63. #define      ILI9341_D3_PIN                GPIO_Pin_1

  64. #define      ILI9341_D4_CLK                RCC_APB2Periph_GPIOE   
  65. #define      ILI9341_D4_PORT               GPIOE
  66. #define      ILI9341_D4_PIN                GPIO_Pin_7

  67. #define      ILI9341_D5_CLK                RCC_APB2Periph_GPIOE   
  68. #define      ILI9341_D5_PORT               GPIOE
  69. #define      ILI9341_D5_PIN                GPIO_Pin_8

  70. #define      ILI9341_D6_CLK                RCC_APB2Periph_GPIOE   
  71. #define      ILI9341_D6_PORT               GPIOE
  72. #define      ILI9341_D6_PIN                GPIO_Pin_9

  73. #define      ILI9341_D7_CLK                RCC_APB2Periph_GPIOE  
  74. #define      ILI9341_D7_PORT               GPIOE
  75. #define      ILI9341_D7_PIN                GPIO_Pin_10

  76. #define      ILI9341_D8_CLK                RCC_APB2Periph_GPIOE   
  77. #define      ILI9341_D8_PORT               GPIOE
  78. #define      ILI9341_D8_PIN                GPIO_Pin_11

  79. #define      ILI9341_D9_CLK                RCC_APB2Periph_GPIOE   
  80. #define      ILI9341_D9_PORT               GPIOE
  81. #define      ILI9341_D9_PIN                GPIO_Pin_12

  82. #define      ILI9341_D10_CLK                RCC_APB2Periph_GPIOE   
  83. #define      ILI9341_D10_PORT               GPIOE
  84. #define      ILI9341_D10_PIN                GPIO_Pin_13

  85. #define      ILI9341_D11_CLK                RCC_APB2Periph_GPIOE   
  86. #define      ILI9341_D11_PORT               GPIOE
  87. #define      ILI9341_D11_PIN                GPIO_Pin_14

  88. #define      ILI9341_D12_CLK                RCC_APB2Periph_GPIOE   
  89. #define      ILI9341_D12_PORT               GPIOE
  90. #define      ILI9341_D12_PIN                GPIO_Pin_15

  91. #define      ILI9341_D13_CLK                RCC_APB2Periph_GPIOD   
  92. #define      ILI9341_D13_PORT               GPIOD
  93. #define      ILI9341_D13_PIN                GPIO_Pin_8

  94. #define      ILI9341_D14_CLK                RCC_APB2Periph_GPIOD   
  95. #define      ILI9341_D14_PORT               GPIOD
  96. #define      ILI9341_D14_PIN                GPIO_Pin_9

  97. #define      ILI9341_D15_CLK                RCC_APB2Periph_GPIOD   
  98. #define      ILI9341_D15_PORT               GPIOD
  99. #define      ILI9341_D15_PIN                GPIO_Pin_10

  100. /*************************************** 调试预用 ******************************************/
  101. #define      DEBUG_DELAY()               

  102. /***************************** ILI934 显示区域的起始坐标和总行列数 ***************************/
  103. #define      ILI9341_DispWindow_X_Star                    0     //起始点的X坐标
  104. #define      ILI9341_DispWindow_Y_Star                    0     //起始点的Y坐标

  105. #define                         ILI9341_LESS_PIXEL                                                                  240                        //液晶屏较短方向的像素宽度
  106. #define                         ILI9341_MORE_PIXEL                                                                         320                        //液晶屏较长方向的像素宽度

  107. //根据液晶扫描方向而变化的XY像素宽度
  108. //调用ILI9341_GramScan函数设置方向时会自动更改
  109. extern uint16_t LCD_X_LENGTH,LCD_Y_LENGTH;

  110. //液晶屏扫描模式
  111. //参数可选值为0-7
  112. extern uint8_t LCD_SCAN_MODE;

  113. /******************************* 定义 ILI934 显示屏常用颜色 ********************************/
  114. #define      BACKGROUND                                BLACK   //默认背景颜色

  115. #define      WHITE                                                   0xFFFF           //白色
  116. #define      BLACK                         0x0000           //黑色
  117. #define      GREY                          0xF7DE           //灰色
  118. #define      BLUE                          0x001F           //蓝色
  119. #define      BLUE2                         0x051F           //浅蓝色
  120. #define      RED                           0xF800           //红色
  121. #define      MAGENTA                       0xF81F           //红紫色,洋红色
  122. #define      GREEN                         0x07E0           //绿色
  123. #define      CYAN                          0x7FFF           //蓝绿色,青色
  124. #define      YELLOW                        0xFFE0           //黄色
  125. #define      BRED                          0xF81F
  126. #define      GRED                          0xFFE0
  127. #define      GBLUE                         0x07FF



  128. /******************************* 定义 ILI934 常用命令 ********************************/
  129. #define      CMD_SetCoordinateX                                     0x2A             //设置X坐标
  130. #define      CMD_SetCoordinateY                                     0x2B             //设置Y坐标
  131. #define      CMD_SetPixel                                           0x2C             //填充像素




  132. /********************************** 声明 ILI934 函数 ***************************************/
  133. void                     ILI9341_Init                    ( void );
  134. void                     ILI9341_Rst                     ( void );
  135. void                     ILI9341_BackLed_Control         ( FunctionalState enumState );
  136. void                     ILI9341_GramScan                ( uint8_t ucOtion );
  137. void                     ILI9341_OpenWindow              ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight );
  138. void                     ILI9341_Clear                   ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight );
  139. void                     ILI9341_SetPointPixel           ( uint16_t usX, uint16_t usY );
  140. uint16_t                 ILI9341_GetPointPixel           ( uint16_t usX , uint16_t usY );
  141. void                     ILI9341_DrawLine                ( uint16_t usX1, uint16_t usY1, uint16_t usX2, uint16_t usY2 );
  142. void                     ILI9341_DrawRectangle           ( uint16_t usX_Start, uint16_t usY_Start, uint16_t usWidth, uint16_t usHeight,uint8_t ucFilled );
  143. void                     ILI9341_DrawCircle              ( uint16_t usX_Center, uint16_t usY_Center, uint16_t usRadius, uint8_t ucFilled );
  144. void                     ILI9341_DispChar_EN             ( uint16_t usX, uint16_t usY, const char cChar );
  145. void                     ILI9341_DispStringLine_EN      ( uint16_t line, char * pStr );
  146. void                     ILI9341_DispString_EN                              ( uint16_t usX, uint16_t usY, char * pStr );
  147. void                     ILI9341_DispChar_CH             ( uint16_t usX, uint16_t usY, uint16_t usChar );
  148. void                     ILI9341_DispString_CH           ( uint16_t usX, uint16_t usY,  char * pStr );
  149. void                     ILI9341_DispString_EN_CH        (        uint16_t usX, uint16_t usY,  char * pStr );
  150. void                                                                                         ILI9341_DispStringLine_EN_CH         (  uint16_t line, char * pStr );
  151. void                                                                                         ILI9341_DispString_EN_YDir                 (   uint16_t usX,uint16_t usY ,  char * pStr );
  152. void                                                                                         ILI9341_DispString_EN_CH_YDir         (   uint16_t usX,uint16_t usY , char * pStr );

  153. void                                                                                         LCD_SetFont                                                                                        (sFONT *fonts);
  154. sFONT                                                                                 *LCD_GetFont                                                                                        (void);
  155. void                                                                                         LCD_ClearLine                                                                                (uint16_t Line);
  156. void                                                                                         LCD_SetBackColor                                                                (uint16_t Color);
  157. void                                                                                         LCD_SetTextColor                                                                (uint16_t Color)        ;
  158. void                                                                                         LCD_SetColors                                                                                (uint16_t TextColor, uint16_t BackColor);
  159. void                                                                                         LCD_GetColors                                                                                (uint16_t *TextColor, uint16_t *BackColor);

  160. void ILI9341_DisplayStringEx(uint16_t x,                 //字符显示位置x
  161.                                                                                                                                  uint16_t y,                                 //字符显示位置y
  162.                                                                                                                                  uint16_t Font_width,        //要显示的字体宽度,英文字符在此基础上/2。注意为偶数
  163.                                                                                                                                  uint16_t Font_Height,        //要显示的字体高度,注意为偶数
  164.                                                                                                                                  uint8_t *ptr,                                        //显示的字符内容
  165.                                                                                                                                  uint16_t DrawModel);  //是否反色显示

  166. void ILI9341_DisplayStringEx_YDir(uint16_t x,                 //字符显示位置x
  167.                                                                                                                                                          uint16_t y,                                 //字符显示位置y
  168.                                                                                                                                                          uint16_t Font_width,        //要显示的字体宽度,英文字符在此基础上/2。注意为偶数
  169.                                                                                                                                                          uint16_t Font_Height,        //要显示的字体高度,注意为偶数
  170.                                                                                                                                                          uint8_t *ptr,                                        //显示的字符内容
  171.                                                                                                                                                          uint16_t DrawModel);  //是否反色显示

  172. #endif /* __BSP_ILI9341_ILI9341_H */


复制代码






使用特权

评论回复
来自 5楼
 楼主 | 2019-6-17 14:01 | 只看该作者
本帖最后由 一路向北lm 于 2019-6-21 14:44 编辑

波形发生器PC端软件开发部分

采用Qt开发了一个可以在PC端运行,通过串口转485和开发板通讯,采用modbus通讯协议来控制板卡产生不同的波形,上位机打算在自己以前开发串口助手上面进行改进。



使用特权

评论回复
6
| 2019-5-31 19:12 | 只看该作者
期待大作!

使用特权

评论回复
7
| 2019-5-31 21:32 | 只看该作者
连心理战都用上了  牛叉

使用特权

评论回复
8
 楼主 | 2019-6-2 20:42 | 只看该作者

一起来,参与下

使用特权

评论回复

评论

zhanzr21 2019-6-2 23:11 回复TA
我是评委之一, 为了避嫌, 不能参与, 呵呵 
9
 楼主 | 2019-6-2 20:42 | 只看该作者
王栋春 发表于 2019-5-31 21:32
连心理战都用上了  牛叉

气势上压倒他们

使用特权

评论回复
10
| 2019-6-2 20:57 | 只看该作者
支持各种波形调制吗?

使用特权

评论回复
11
| 2019-6-2 21:24 | 只看该作者

期待你具体的资料分享

使用特权

评论回复
12
 楼主 | 2019-6-4 17:39 | 只看该作者
王栋春 发表于 2019-6-2 21:24
期待你具体的资料分享

哈哈,

使用特权

评论回复
13
| 2019-6-13 17:33 | 只看该作者
相关资料呢

使用特权

评论回复
14
 楼主 | 2019-6-14 13:21 | 只看该作者

后续更新

使用特权

评论回复
15
| 2019-6-17 18:28 | 只看该作者
哈哈,我还是慢了一步,楼主很厉害的,还加上了上位机还有LCD屏,绝对是大作,本人还是准备考试吧

使用特权

评论回复
16
 楼主 | 2019-6-17 20:06 | 只看该作者
enderman1 发表于 2019-6-17 18:28
哈哈,我还是慢了一步,楼主很厉害的,还加上了上位机还有LCD屏,绝对是大作,本人还是准备考试吧[e ...

不要放弃哈,加油

使用特权

评论回复
17
| 2019-6-17 20:34 | 只看该作者
能做到任意频率否?

使用特权

评论回复

评论

zhanzr21 2019-6-19 22:18 回复TA
任何发生信号的装置都有带宽的啊, MCU这种低端芯片也是如此. 题目中要求也是给出频率发生范围. 
18
 楼主 | 2019-6-17 21:13 | 只看该作者
gujiamao12345 发表于 2019-6-17 20:34
能做到任意频率否?

频率有上限,而且stm32 DA精度不够

使用特权

评论回复
19
| 2019-6-19 17:08 | 只看该作者
一路向北lm 发表于 2019-6-17 21:13
频率有上限,而且stm32 DA精度不够

楼主的作品不错,来学习下,方波,锯齿波,三角波的生成

使用特权

评论回复
20
| 2019-6-19 17:32 | 只看该作者
这个做一个简单的示波器挺好的

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

关闭

热门推荐上一条 /4 下一条

在线客服 快速回复 返回顶部 返回列表
全民彩票