查看: 2308|回复: 5

[分享] 逐飞LPC55S69 IOT开发板之SPI LCD之一个小细节

[复制链接]
  • TA的每日心情

    2024-2-5 12:06
  • 签到天数: 627 天

    [LV.9]以坛为家II

    94

    主题

    1628

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4429

    热心会员

    最后登录
    2024-2-5
    发表于 2020-12-16 16:31:15 | 显示全部楼层 |阅读模式
    今天,用MCUXpresso配置了一下SPI,并驱动LCD屏幕。由于我们屏的硬件结构,只支持接收,实际上配置给SPI的仅仅就SCK和MOSI这2个引脚,其他的
    RST、CS、DC均有GPIO模拟实现。
    配置图如下:
    引脚配置;
    X1.jpg
    时钟配置:
    X2.jpg
    SPI配置(波特率最大不超过50M):
    X3.jpg
    更新代码,添加LCD的驱动代码:
    ili_lcd.h(本想取名LCD的,发现与加载的emwin里面一个文件同名,有冲突)
    1. /*
    2. * lcd.h
    3. *
    4. *  Created on: 2020年12月16日
    5. *      Author: Administrator
    6. */

    7. #ifndef ILI9341_LCD_H_
    8. #define ILI9341_LCD_H_

    9. #include "fsl_common.h"
    10. #include "fsl_gpio.h"
    11. #include "pin_mux.h"
    12. #include "peripherals.h"

    13. #include "fsl_spi.h"
    14. #include "fsl_ili9341.h"

    15. #ifndef ILI9341_SIZE
    16. #define ILI9341_SIZE        1
    17. #define LCD_H                                                320                                // 屏幕高度
    18. #define LCD_W                                                240                                // 屏幕宽度
    19. #endif

    20. #ifndef         COLOUR_FOR_LCD
    21. #define         COLOUR_FOR_LCD        1
    22. #define         WHITE                                        0xFFFF                // 白色
    23. #define         BLACK                                        0x0000                // 黑色
    24. #define         BLUE                                        0x001F                // 蓝色
    25. #define         BRED                                        0xF81F                // 洋紫
    26. #define         GBLUE                                        0x07FF                // 靛青
    27. #define         RED                                                0xF800                // 红色
    28. #define         GREEN                                        0x07E0                // 绿色
    29. #define         CYAN                                        0x7FFF                // 天蓝
    30. #define         YELLOW                                        0xFFE0                // 黄色
    31. #define         BROWN                                        0xBC40                // 棕色
    32. #define         BRRED                                        0xFC07                // 棕红色 接近肤色
    33. #define         GRAY                                        0x8430                // 灰色
    34. #define         DARKBLUE                                0x01CF                // 深蓝色
    35. #define         LIGHTBLUE                                0x7D7C                // 浅蓝色
    36. #define         GRAYBLUE                                0x5458                // 灰蓝色
    37. #define         ORCHID                                        0xF11F                // 紫色
    38. #endif

    39. #define lcd_rst(n)     GPIO_PinWrite(BOARD_INITPINS_lcd_rst_GPIO,BOARD_INITPINS_lcd_rst_PORT, BOARD_INITPINS_lcd_rst_PIN, n)
    40. #define lcd_cs(n)      GPIO_PinWrite(BOARD_INITPINS_lcd_cs_GPIO, BOARD_INITPINS_lcd_cs_PORT,  BOARD_INITPINS_lcd_cs_PIN, n)
    41. #define lcd_dc(n)      GPIO_PinWrite(BOARD_INITPINS_lcd_dc_GPIO, BOARD_INITPINS_lcd_dc_PORT,  BOARD_INITPINS_lcd_dc_PIN, n)

    42. // ========== SPI 发送配置选项 ==========
    43. typedef enum
    44. {
    45.         SPI_FIFO_WIRTE_NOP = 0X0000,
    46.         SPI_FIFO_WIRTE_EOT = 0X0010,
    47.         SPI_FIFO_WIRTE_EOF = 0X0020,
    48.         SPI_FIFO_WIRTE_RXIGNORE = 0X0040,
    49.         SPI_FIFO_WIRTE_TXIGNORE = 0X0080,
    50. }spi_fifo_wirte_list;



    51. void lcd_init                                        (void);
    52. void lcd_writ_bus                                (char data);
    53. void lcd_writ_cmd                                (uint16_t cmd);
    54. void lcd_writ_data                                (uint16_t data);
    55. void lcd_writ_data16                        (uint16_t data);
    56. void lcd_address_set                        (uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
    57. void lcd_set_point_color                (uint16_t color);
    58. void lcd_set_back_color                        (uint16_t color);
    59. void lcd_clear_screen                        (uint16_t Color);
    60. void lcd_draw_point                                (uint16_t x, uint16_t y, uint16_t color);
    61. void lcd_show_char                                (uint16_t x, uint16_t y, uint8_t data);
    62. void lcd_show_string                        (uint16_t x, uint16_t y, uint8_t *data);
    63. void lcd_show_uint8                                (uint16_t x, uint16_t y, uint8_t data);
    64. void lcd_show_int16                                (uint16_t x, uint16_t y, int16_t data);
    65. void lcd_show_uint16                        (uint16_t x, uint16_t y, uint16_t data);
    66. void lcd_show_int32                                (uint16_t x, uint16_t y, int32_t data, uint8_t num);
    67. void lcd_show_float                                (uint16_t x, uint16_t y, double data, int8_t num, int8_t pointnum);
    68. void lcd_show_image                                (uint16_t x, uint16_t y ,uint16_t w, uint16_t l, const unsigned char *p);



    69. #endif /* ILI9341_LCD_H_ */
    复制代码
    ili_lcd.c
    1. /*
    2. * lcd.c
    3. *
    4. *  Created on: 2020年12月16日
    5. *      Author: Administrator
    6. */
    7. #include <ili9341_lcd.h>
    8. #include "font.h"
    9. #include "delay.h"
    10. #include "stdio.h"

    11. static uint16_t lcd_point_color = BLACK;                        // 默认画点颜色
    12. static uint16_t lcd_back_color  = WHITE;                                // 背景色

    13. static volatile uint16_t *FIFOWR_HSPI_H16 = ((volatile uint16_t *)0x4009FE22);                                                        // HSPI FIFOWR

    14. void hspi_master_write_data (uint16_t data, uint16_t config)
    15. {
    16.         *(FIFOWR_HSPI_H16) =                                                                                                                                                                 // 对应 SPI 的 FIFOWR 寄存器地址
    17.         (
    18.                 config | (FLEXCOMM8_config.dataWidth << 8) |                                                                                                        // 设置 帧结束 数据位数
    19.                 (~(0x1 << FLEXCOMM8_config.sselNum) & 0x0f)                                                                                                        // 选择从机
    20.         );

    21.         SPI8->FIFOWR |= data;                                                                                                                                                                // 发送数据
    22. }



    23. static void hspi_Init(void)
    24. {
    25.         RESET_PeripheralReset(kHSLSPI_RST_SHIFT_RSTn);
    26.         /* Initialization function */
    27.         SPI_MasterInit(FLEXCOMM8_PERIPHERAL, &FLEXCOMM8_config, FLEXCOMM8_CLOCK_SOURCE);
    28. }

    29. static void lcd_port_Init(void)
    30. {
    31.         //除SPI之外的 RST CS DC
    32.         /* Enables the clock for the I/O controller.: Enable Clock. */
    33.         CLOCK_EnableClock(kCLOCK_Iocon);

    34.         /* Enables the clock for the GPIO0 module */
    35.         CLOCK_EnableClock(kCLOCK_Gpio0);

    36.         /* Enables the clock for the GPIO1 module */
    37.         CLOCK_EnableClock(kCLOCK_Gpio1);

    38.         gpio_pin_config_t lcd_cs_config = {
    39.            .pinDirection = kGPIO_DigitalOutput,
    40.            .outputLogic = 0U
    41.         };
    42.         /* Initialize GPIO functionality on pin PIO1_1 (pin 59)  */
    43.         GPIO_PinInit(BOARD_INITPINS_lcd_cs_GPIO, BOARD_INITPINS_lcd_cs_PORT, BOARD_INITPINS_lcd_cs_PIN, &lcd_cs_config);

    44.         gpio_pin_config_t lcd_rst_config = {
    45.            .pinDirection = kGPIO_DigitalOutput,
    46.            .outputLogic = 0U
    47.         };
    48.         /* Initialize GPIO functionality on pin PIO1_3 (pin 62)  */
    49.         GPIO_PinInit(BOARD_INITPINS_lcd_rst_GPIO, BOARD_INITPINS_lcd_rst_PORT, BOARD_INITPINS_lcd_rst_PIN, &lcd_rst_config);

    50.         gpio_pin_config_t lcd_dc_config = {
    51.            .pinDirection = kGPIO_DigitalOutput,
    52.            .outputLogic = 0U
    53.         };
    54.         /* Initialize GPIO functionality on pin PIO1_4 (pin 1)  */
    55.         GPIO_PinInit(BOARD_INITPINS_lcd_dc_GPIO, BOARD_INITPINS_lcd_dc_PORT, BOARD_INITPINS_lcd_dc_PIN, &lcd_dc_config);
    56.     //1_1 CS
    57.         IOCON->PIO[1][1] = ((IOCON->PIO[1][1] &
    58.          /* Mask bits to zero which are setting */
    59.          (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK)))

    60.         /* Selects pin function.
    61.          * : PORT11 (pin 59) is configured as PIO1_1. */
    62.         | IOCON_PIO_FUNC(PIO1_1_FUNC_ALT0)

    63.         /* Select Digital mode.
    64.          * : Enable Digital mode.
    65.          * Digital input is enabled. */
    66.         | IOCON_PIO_DIGIMODE(PIO1_1_DIGIMODE_DIGITAL));
    67.         //1_3 RST
    68.         IOCON->PIO[1][3] = ((IOCON->PIO[1][3] &
    69.          /* Mask bits to zero which are setting */
    70.          (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK)))

    71.         /* Selects pin function.
    72.          * : PORT13 (pin 62) is configured as PIO1_3. */
    73.         | IOCON_PIO_FUNC(PIO1_3_FUNC_ALT0)

    74.         /* Select Digital mode.
    75.          * : Enable Digital mode.
    76.          * Digital input is enabled. */
    77.         | IOCON_PIO_DIGIMODE(PIO1_3_DIGIMODE_DIGITAL));
    78.         //1_4   DC
    79.         IOCON->PIO[1][4] = ((IOCON->PIO[1][4] &
    80.          /* Mask bits to zero which are setting */
    81.          (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK)))

    82.         /* Selects pin function.
    83.          * : PORT14 (pin 1) is configured as PIO1_4. */
    84.         | IOCON_PIO_FUNC(PIO1_4_FUNC_ALT0)

    85.         /* Select Digital mode.
    86.          * : Enable Digital mode.
    87.          * Digital input is enabled. */
    88.         | IOCON_PIO_DIGIMODE(PIO1_4_DIGIMODE_DIGITAL));

    89.         //SPI 相关引脚 SCK  MOSI
    90.         //1_2 SCK
    91.         IOCON->PIO[1][2] = ((IOCON->PIO[1][2] &
    92.          /* Mask bits to zero which are setting */
    93.          (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK)))

    94.         /* Selects pin function.
    95.          * : PORT12 (pin 61) is configured as HS_SPI_SCK. */
    96.         | IOCON_PIO_FUNC(PIO1_2_FUNC_ALT6)

    97.         /* Select Digital mode.
    98.          * : Enable Digital mode.
    99.          * Digital input is enabled. */
    100.         | IOCON_PIO_DIGIMODE(PIO1_2_DIGIMODE_DIGITAL));

    101.         //0_26 MOSI
    102.         IOCON->PIO[0][26] = ((IOCON->PIO[0][26] &
    103.         /* Mask bits to zero which are setting */
    104.         (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK)))

    105.         /* Selects pin function.
    106.         * : PORT026 (pin 60) is configured as HS_SPI_MOSI. */
    107.         | IOCON_PIO_FUNC(0x09u)

    108.         /* Select Digital mode.
    109.         * : Enable Digital mode.
    110.         * Digital input is enabled. */
    111.         | IOCON_PIO_DIGIMODE(PIO0_26_DIGIMODE_DIGITAL));

    112.         //TEST CS-->1_1   硬件CS
    113.         //0_26 MOSI
    114.         IOCON->PIO[1][1] = ((IOCON->PIO[1][1] &
    115.         /* Mask bits to zero which are setting */
    116.         (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK)))

    117.         /* Selects pin function.
    118.         * : PORT026 (pin 60) is configured as HS_SPI_MOSI. */
    119.         | IOCON_PIO_FUNC(0x05u)

    120.         /* Select Digital mode.
    121.         * : Enable Digital mode.
    122.         * Digital input is enabled. */
    123.         | IOCON_PIO_DIGIMODE(PIO1_1_DIGIMODE_DIGITAL));

    124.         //SPI 初始化
    125.         hspi_Init();

    126. }

    127. //仅发送,不接收
    128. static void  HSPIWriteByteNoRec(uint8_t tx_data)
    129. {
    130.         //添加了忽略接收的标志
    131.         //SPI_WriteData(FLEXCOMM8_PERIPHERAL, tx_data, kSPI_FrameDelay|SPI_FIFOWR_RXIGNORE_MASK);
    132.         hspi_master_write_data(tx_data, SPI_FIFO_WIRTE_EOF|SPI_FIFO_WIRTE_RXIGNORE);

    133. }

    134. static uint16_t HSPIReadWriteByte(uint8_t tx_data)
    135. {

    136.         SPI_WriteData(FLEXCOMM8_PERIPHERAL, tx_data, kSPI_FrameDelay);

    137.         while (1)
    138.         {
    139.                 //if rxFIFO is not empty
    140.                 if ((FLEXCOMM8_PERIPHERAL->FIFOSTAT & SPI_FIFOSTAT_RXNOTEMPTY_MASK) != 0U)
    141.                 {
    142.                         return SPI_ReadData(FLEXCOMM8_PERIPHERAL);
    143.                 }
    144.         }

    145.         return 0;
    146. }

    147. void lcd_writ_bus(char data)
    148. {
    149.         //HSPIReadWriteByte(data);
    150.         HSPIWriteByteNoRec(data);
    151.         //zf_hspi_master_write_data(data, SPI_FIFO_WIRTE_EOF|SPI_FIFO_WIRTE_RXIGNORE);
    152. }

    153. void lcd_writ_cmd(uint16_t cmd)
    154. {
    155.         lcd_dc(0);
    156.         lcd_writ_bus(cmd);
    157. }

    158. void lcd_writ_data(uint16_t data)
    159. {
    160.         lcd_dc(1);
    161.         lcd_writ_bus(data);
    162. }

    163. void lcd_writ_data16(uint16_t data)
    164. {
    165.         lcd_dc(1);
    166.         lcd_writ_bus(data>>8);
    167.         lcd_writ_bus(data);
    168. }



    169. //-------------------------------------------------------------------------------------------------------------------
    170. //        @brief                ili9341 设置显示位置
    171. //        @param                x1                                起始 x 轴位置 从左往右为 0 - 239
    172. //        @param                y1                                起始 y 轴位置 从上往下为 0 - 319
    173. //        @param                x2                                结束 x 轴位置 从左往右为 0 - 239
    174. //        @param                y2                                结束 y 轴位置 从上往下为 0 - 319
    175. //        Sample usage:                                lcd_address_set(0, 0, 239, 319);
    176. //-------------------------------------------------------------------------------------------------------------------
    177. void lcd_address_set (uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
    178. {
    179.         lcd_writ_cmd(0x2a);
    180.         lcd_writ_data16(x1);
    181.         lcd_writ_data16(x2);

    182.         lcd_writ_cmd(0x2b);
    183.         lcd_writ_data16(y1);
    184.         lcd_writ_data16(y2);

    185.         lcd_writ_cmd(0x2c);
    186. }

    187. //-------------------------------------------------------------------------------------------------------------------
    188. //        @brief                ili9341 设置点颜色
    189. //        @param                Color                        填充颜色
    190. //        Sample usage:                                ili9341_hwspi_set_point_color(WHITE);
    191. //-------------------------------------------------------------------------------------------------------------------
    192. void lcd_set_point_color (uint16_t color)
    193. {
    194.         lcd_point_color = color;
    195. }

    196. //-------------------------------------------------------------------------------------------------------------------
    197. //        @brief                ili9341 设置背景颜色
    198. //        @param                Color                        填充颜色
    199. //        Sample usage:                                ili9341_hwspi_set_back_color(WHITE);
    200. //-------------------------------------------------------------------------------------------------------------------
    201. void lcd_set_back_color (uint16_t color)
    202. {
    203.         lcd_back_color = color;
    204. }

    205. //-------------------------------------------------------------------------------------------------------------------
    206. //        @brief                ili9341 全屏填充
    207. //        @param                Color                        填充颜色
    208. //        Sample usage:                                ili9341_hwspi_clear_screen(WHITE);
    209. //-------------------------------------------------------------------------------------------------------------------
    210. void lcd_clear_screen (uint16_t Color)
    211. {
    212.         uint16_t i,j;
    213.         lcd_address_set(0, 0, LCD_W-1, LCD_H-1);
    214.         for(i=0; i<LCD_W; i++)
    215.         {
    216.                 for (j=0;j<LCD_H;j++)
    217.                 {
    218.                         lcd_writ_data16(Color);
    219.                 }
    220.         }
    221. }

    222. //-------------------------------------------------------------------------------------------------------------------
    223. //        @brief                ili9341 坐标画点
    224. //        @param                x                                点 x 轴位置 从左往右为 0 - 239
    225. //        @param                y                                点 y 轴位置 从上往下为 0 - 319
    226. //        @param                Color                        颜色
    227. //        Sample usage:                                ili9341_hwspi_draw_point(0, 0, WHITE);
    228. //-------------------------------------------------------------------------------------------------------------------
    229. void lcd_draw_point (uint16_t x, uint16_t y, uint16_t color)
    230. {
    231.         lcd_address_set(x, y, x, y);
    232.         lcd_writ_data16(color);
    233. }

    234. //-------------------------------------------------------------------------------------------------------------------
    235. //        @brief                ili9341 坐标显示字符
    236. //        @param                x                                点 x 轴位置 从左往右为 0 - 239
    237. //        @param                y                                点 y 轴位置 从上往下为 0 - 319
    238. //        @param                data                        字符数据
    239. //        Sample usage:                                ili9341_hwspi_show_char(0, 0, dat);
    240. //-------------------------------------------------------------------------------------------------------------------
    241. void lcd_show_char (uint16_t x, uint16_t y, uint8_t data)
    242. {
    243.         uint8_t i,j;
    244.         uint8_t temp;

    245.         for(i=0; i<16; i++)
    246.         {
    247.                 lcd_address_set(x, y+ i, x+ 7, y+ i);
    248.                 temp = tft_ascii[(uint16_t)data-32][i];//减32因为是取模是从空格开始取得 空格在ascii中序号是32
    249.                 for(j=0; j<8; j++)
    250.                 {
    251.                         if(temp&0x01)
    252.                                 lcd_writ_data16(lcd_point_color);
    253.                         else
    254.                                 lcd_writ_data16(lcd_back_color);
    255.                         temp>>=1;
    256.                 }
    257.         }
    258. }

    259. //-------------------------------------------------------------------------------------------------------------------
    260. //        @brief                ili9341 坐标显示字符串
    261. //        @param                x                                点 x 轴位置 从左往右为 0 - 239        这里是像素点                一共 240 像素点
    262. //        @param                y                                点 y 轴位置 从上往下为 0 - 19        这里是字符高度分割        一共 20 行 20*16=320
    263. //        @param                data                        字符数据数组
    264. //        Sample usage:                                ili9341_hwspi_show_string(0, 0, dat);
    265. //-------------------------------------------------------------------------------------------------------------------
    266. void lcd_show_string (uint16_t x, uint16_t y, uint8_t *data)
    267. {
    268.         uint16_t j;

    269.         j = 0;
    270.         while(data[j] != '\0')
    271.         {
    272.                 lcd_show_char(x+ 8* j, y* 16, data[j]);
    273.                 j++;
    274.         }
    275. }

    276. //-------------------------------------------------------------------------------------------------------------------
    277. //        @brief                ili9341 坐标显示 uint8_t 数字
    278. //        @param                x                                点 x 轴位置 从左往右为 0 - 239        这里是像素点                一共 240 像素点
    279. //        @param                y                                点 y 轴位置 从上往下为 0 - 19        这里是字符高度分割        一共 20 行 20*16=320
    280. //        @param                data                        uint8_t 数字
    281. //        Sample usage:                                ili9341_hwspi_show_uint8(0, 0, dat);
    282. //-------------------------------------------------------------------------------------------------------------------
    283. void lcd_show_uint8 (uint16_t x, uint16_t y, uint8_t data)
    284. {
    285.         uint8_t a[3];
    286.         uint8_t i;

    287.         a[0] = data/100;
    288.         a[1] = data/10%10;
    289.         a[2] = data%10;
    290.         i = 0;
    291.         while(i<3)
    292.         {
    293.                 lcd_show_char(x+ (8* i), y* 16, '0'+ a[i]);
    294.                 i++;
    295.         }
    296. }

    297. //-------------------------------------------------------------------------------------------------------------------
    298. //        @brief                ili9341 坐标显示 int16_t 数字
    299. //        @param                x                                点 x 轴位置 从左往右为 0 - 239        这里是像素点                一共 240 像素点
    300. //        @param                y                                点 y 轴位置 从上往下为 0 - 19        这里是字符高度分割        一共 20 行 20*16=320
    301. //        @param                data                        int16_t 数字
    302. //        Sample usage:                                ili9341_hwspi_show_int16(0, 0, dat);
    303. //-------------------------------------------------------------------------------------------------------------------
    304. void lcd_show_int16 (uint16_t x, uint16_t y, int16_t data)
    305. {
    306.         uint8_t a[5];
    307.         uint8_t i;
    308.         uint16_t u_dat;

    309.         if(data<0)
    310.         {
    311.                 lcd_show_char(x, y* 16, '-');
    312.                 u_dat = (uint16_t)data;
    313.                 u_dat -= 1;
    314.                 u_dat = ~data;
    315.         }
    316.         else
    317.         {
    318.                 lcd_show_char(x, y* 16, ' ');
    319.                 u_dat = data;
    320.         }

    321.         a[0] = u_dat/10000;
    322.         a[1] = u_dat/1000%10;
    323.         a[2] = u_dat/100%10;
    324.         a[3] = u_dat/10%10;
    325.         a[4] = u_dat%10;

    326.         i = 0;
    327.         while(i<5)
    328.         {
    329.                 lcd_show_char(x+ (8* (i+ 1)), y* 16, '0'+ a[i]);
    330.                 i++;
    331.         }
    332. }

    333. //-------------------------------------------------------------------------------------------------------------------
    334. //        @brief                ili9341 坐标显示 uint16_t 数字
    335. //        @param                x                                点 x 轴位置 从左往右为 0 - 239        这里是像素点                一共 240 像素点
    336. //        @param                y                                点 y 轴位置 从上往下为 0 - 19        这里是字符高度分割        一共 20 行 20*16=320
    337. //        @param                data                        uint16_t 数字
    338. //        Sample usage:                                ili9341_hwspi_show_uint16(0, 0, dat);
    339. //-------------------------------------------------------------------------------------------------------------------
    340. void lcd_show_uint16 (uint16_t x, uint16_t y, uint16_t data)
    341. {
    342.         uint8_t a[5];
    343.         uint8_t i;

    344.         a[0] = data/10000;
    345.         a[1] = data/1000%10;
    346.         a[2] = data/100%10;
    347.         a[3] = data/10%10;
    348.         a[4] = data%10;

    349.         i = 0;
    350.         while(i<5)
    351.         {
    352.                 lcd_show_char(x+ (8* i), y* 16, '0' +a[i]);
    353.                 i++;
    354.         }
    355. }

    356. //-------------------------------------------------------------------------------------------------------------------
    357. //        @brief                ili9341 坐标显示 int32_t 数字
    358. //        @param                x                                点 x 轴位置 从左往右为 0 - 239        这里是像素点                一共 240 像素点
    359. //        @param                y                                点 y 轴位置 从上往下为 0 - 19        这里是字符高度分割        一共 20 行 20*16=320
    360. //        @param                data                        int32_t 数字
    361. //        @param                num                                int32_t 数字位数
    362. //        Sample usage:                                ili9341_hwspi_show_int32(0, 0, 100, 3);
    363. //-------------------------------------------------------------------------------------------------------------------
    364. void lcd_show_int32 (uint16_t x, uint16_t y, int32_t data, uint8_t num)
    365. {
    366.         char                buff[34];
    367.         uint8_t                length;

    368.         if(10<num)
    369.                 num = 10;

    370.         num++;
    371.         if(0>data)
    372.                 length = sprintf(&buff[0], "%d", data);//负数
    373.         else
    374.         {
    375.                 buff[0] = ' ';
    376.                 length = sprintf(&buff[1], "%d", data);
    377.                 length++;
    378.         }
    379.         while(length < num)
    380.         {
    381.                 buff[length] = ' ';
    382.                 length++;
    383.         }
    384.         buff[num] = '\0';

    385.         lcd_show_string(x, y, (uint8_t *)buff);        //显示数字
    386. }

    387. //-------------------------------------------------------------------------------------------------------------------
    388. //        @brief                ili9341 坐标显示 float 数字
    389. //        @param                x                                点 x 轴位置 从左往右为 0 - 239        这里是像素点                一共 240 像素点
    390. //        @param                y                                点 y 轴位置 从上往下为 0 - 19        这里是字符高度分割        一共 20 行 20*16=320
    391. //        @param                data                        float 数字
    392. //        @param                num                                float 数字整数位数
    393. //        @param                pointnum                float 数字小数位数
    394. //        Sample usage:                                ili9341_hwspi_show_float(0, 0, 3.14, 1, 2);
    395. //-------------------------------------------------------------------------------------------------------------------
    396. void lcd_show_float (uint16_t x, uint16_t y, double dat, int8_t num, int8_t pointnum)
    397. {
    398.         uint8_t                length;
    399.         char                buff[34];
    400.         int8_t                start, end, point;

    401.         if(6<pointnum)
    402.                 pointnum = 6;
    403.         if(10<num)
    404.                 num = 10;

    405.         if(0>dat)
    406.                 length = sprintf(&buff[0], "%f", dat);//负数
    407.         else
    408.         {
    409.                 length = sprintf(&buff[1], "%f", dat);
    410.                 length++;
    411.         }
    412.         point = length - 7;         //计算小数点位置
    413.         start = point - num - 1;    //计算起始位
    414.         end = point + pointnum + 1; //计算结束位
    415.         while(0>start)//整数位不够  末尾应该填充空格
    416.         {
    417.                 buff[end] = ' ';
    418.                 end++;
    419.                 start++;
    420.         }

    421.         if(0>dat)
    422.                 buff[start] = '-';
    423.         else
    424.                 buff[start] = ' ';

    425.         buff[end] = '\0';

    426.         lcd_show_string(x, y, (uint8_t *)buff);        //显示数字
    427. }

    428. //-------------------------------------------------------------------------------------------------------------------
    429. //        @brief                ili9341 坐标显示 图片
    430. //        @param                x                                点 x 轴位置 从左往右为 0 - 239
    431. //        @param                y                                点 y 轴位置 从上往下为 0 - 319
    432. //        @param                w                                图像宽度
    433. //        @param                l                                图像高度
    434. //        @param                *p                                图像指针
    435. //        Sample usage:                                ili9341_hwspi_show_image(0, 0, 240, 320, big_image);
    436. //-------------------------------------------------------------------------------------------------------------------
    437. void lcd_show_image (uint16_t x, uint16_t y, uint16_t w, uint16_t l, const unsigned char *p)
    438. {
    439.         int i;
    440.         unsigned char picH,picL;
    441.         lcd_address_set(x, y, x+ w- 1, y+ l- 1);
    442.         for(i=0; i < w*l; i++)
    443.         {
    444.                 picL=*(p+ i* 2);
    445.                 picH=*(p+ i* 2+ 1);
    446.                 lcd_writ_data16(picH<< 8| picL);
    447.         }
    448. }


    449. void lcd_init(void)
    450. {
    451.         lcd_port_Init();
    452.         delay_ms(120);

    453.         lcd_dc(1);

    454.         lcd_cs(0);
    455.         lcd_rst(0);
    456.         delay_ms(50);
    457.         lcd_rst(1);
    458.         delay_ms(100);

    459.         lcd_writ_cmd(0xCF);
    460.         lcd_writ_data(0x00);
    461.         lcd_writ_data(0xD9);
    462.         lcd_writ_data(0X30);

    463.         lcd_writ_cmd(0xED);
    464.         lcd_writ_data(0x64);
    465.         lcd_writ_data(0x03);
    466.         lcd_writ_data(0X12);
    467.         lcd_writ_data(0X81);

    468.         lcd_writ_cmd(0xE8);
    469.         lcd_writ_data(0x85);
    470.         lcd_writ_data(0x10);
    471.         lcd_writ_data(0x78);

    472.         lcd_writ_cmd(0xCB);
    473.         lcd_writ_data(0x39);
    474.         lcd_writ_data(0x2C);
    475.         lcd_writ_data(0x00);
    476.         lcd_writ_data(0x34);
    477.         lcd_writ_data(0x02);

    478.         lcd_writ_cmd(0xF7);
    479.         lcd_writ_data(0x20);

    480.         lcd_writ_cmd(0xEA);
    481.         lcd_writ_data(0x00);
    482.         lcd_writ_data(0x00);

    483.         lcd_writ_cmd(0xC0);                //Power control
    484.         lcd_writ_data(0x21);        //VRH[5:0]

    485.         lcd_writ_cmd(0xC1);                //Power control
    486.         lcd_writ_data(0x12);        //SAP[2:0];BT[3:0]

    487.         lcd_writ_cmd(0xC5);                //VCM control
    488.         lcd_writ_data(0x32);
    489.         lcd_writ_data(0x3C);

    490.         lcd_writ_cmd(0xC7);                //VCM control2
    491.         lcd_writ_data(0XC1);

    492.         lcd_writ_cmd(0x36);    // Memory Access Control
    493.         lcd_writ_data(0x08);

    494.         lcd_writ_cmd(0x3A);
    495.         lcd_writ_data(0x55);

    496.         lcd_writ_cmd(0xB1);
    497.         lcd_writ_data(0x00);
    498.         lcd_writ_data(0x18);

    499.         lcd_writ_cmd(0xB6);                // Display Function Control
    500.         lcd_writ_data(0x0A);
    501.         lcd_writ_data(0xA2);

    502.         lcd_writ_cmd(0xF2);                // 3Gamma Function Disable
    503.         lcd_writ_data(0x00);

    504.         lcd_writ_cmd(0x26);                //Gamma curve selected
    505.         lcd_writ_data(0x01);

    506.         lcd_writ_cmd(0xE0);                //Set Gamma
    507.         lcd_writ_data(0x0F);
    508.         lcd_writ_data(0x20);
    509.         lcd_writ_data(0x1E);
    510.         lcd_writ_data(0x09);
    511.         lcd_writ_data(0x12);
    512.         lcd_writ_data(0x0B);
    513.         lcd_writ_data(0x50);
    514.         lcd_writ_data(0XBA);
    515.         lcd_writ_data(0x44);
    516.         lcd_writ_data(0x09);
    517.         lcd_writ_data(0x14);
    518.         lcd_writ_data(0x05);
    519.         lcd_writ_data(0x23);
    520.         lcd_writ_data(0x21);
    521.         lcd_writ_data(0x00);

    522.         lcd_writ_cmd(0XE1);                //Set Gamma
    523.         lcd_writ_data(0x00);
    524.         lcd_writ_data(0x19);
    525.         lcd_writ_data(0x19);
    526.         lcd_writ_data(0x00);
    527.         lcd_writ_data(0x12);
    528.         lcd_writ_data(0x07);
    529.         lcd_writ_data(0x2D);
    530.         lcd_writ_data(0x28);
    531.         lcd_writ_data(0x3F);
    532.         lcd_writ_data(0x02);
    533.         lcd_writ_data(0x0A);
    534.         lcd_writ_data(0x08);
    535.         lcd_writ_data(0x25);
    536.         lcd_writ_data(0x2D);
    537.         lcd_writ_data(0x0F);

    538.         lcd_writ_cmd(0x11);                //Exit Sleep
    539.         delay_ms(120);
    540.         lcd_writ_cmd(0x29);                //Display on


    541. }
    复制代码
    显示颜色正常,但我感觉速度怎么这么慢呢!之前的SPI发送接收函数是一问一答的形式。后来看了官方的程序,它直接屏蔽了REC的功能。这样就能节省些时间了。
    之前的SPI单个发送接收函数:
    1. static uint16_t HSPIReadWriteByte(uint8_t tx_data)
    2. {

    3.         SPI_WriteData(FLEXCOMM8_PERIPHERAL, tx_data, kSPI_FrameDelay);

    4.         while (1)
    5.         {
    6.                 //if rxFIFO is not empty
    7.                 if ((FLEXCOMM8_PERIPHERAL->FIFOSTAT & SPI_FIFOSTAT_RXNOTEMPTY_MASK) != 0U)
    8.                 {
    9.                         return SPI_ReadData(FLEXCOMM8_PERIPHERAL);
    10.                 }
    11.         }

    12.         return 0;
    13. }
    复制代码
    后面参考修改的仅接收的函数:
    1. <blockquote>// ========== SPI 发送配置选项 ==========
    复制代码
    static volatile uint16_t *FIFOWR_HSPI_H16 = ((volatile uint16_t *)0x4009FE22);                                                        // HSPI FIFOWR

    void hspi_master_write_data (uint16_t data, uint16_t config)
    {
            *(FIFOWR_HSPI_H16) =                                                                                                                                                                 // 对应 SPI 的 FIFOWR 寄存器地址
            (
                    config | (FLEXCOMM8_config.dataWidth << 8) |                                                                                                        // 设置 帧结束 数据位数
                    (~(0x1 << FLEXCOMM8_config.sselNum) & 0x0f)                                                                                                        // 选择从机
            );

            SPI8->FIFOWR |= data;                                                                                                                                                                // 发送数据
    }
    理论上用
    SPI_WriteData(FLEXCOMM8_PERIPHERAL, tx_data, kSPI_FrameDelay|SPI_FIFOWR_RXIGNORE_MASK);
    也是同等的,但我感觉就是慢一拍。

    关于寄存器的地址及选项,我们看参考手册: Z1.jpg
    Z3.jpg
    Z2.jpg
    Z4.jpg
    Z6.jpg
    Z5.jpg
    Z7.jpg
    SPI8 基准地址 0x4009F000 + FIFOWR的偏移 0xe20  然后FIFOWR是32bit 一个字,有2个16BIT的半字,所以后面的16BIT的其实地址还要+2.就是
    0x4009FE22。这样我们就多操作发送选项寄存器地址的由来,和选项大概了解。
    官方库给的选项其实还不过多,最后将所以的发送选项都放上去:
    NXP sdk 库的:
    1. /*! @brief SPI transfer option.*/
    2. typedef enum _spi_xfer_option
    3. {
    4.     kSPI_FrameDelay  = (SPI_FIFOWR_EOF_MASK), /*!< A delay may be inserted, defined in the DLY register.*/
    5.     kSPI_FrameAssert = (SPI_FIFOWR_EOT_MASK), /*!< SSEL will be deasserted at the end of a transfer */
    6. } spi_xfer_option_t;
    复制代码
    Seekfree 的:
    1. // ========== SPI 发送配置选项 ==========
    2. typedef enum
    3. {
    4.         SPI_FIFO_WIRTE_NOP = 0X0000,
    5.         SPI_FIFO_WIRTE_EOT = 0X0010,
    6.         SPI_FIFO_WIRTE_EOF = 0X0020,
    7.         SPI_FIFO_WIRTE_RXIGNORE = 0X0040,
    8.         SPI_FIFO_WIRTE_TXIGNORE = 0X0080,
    9. }spi_fifo_wirte_list;
    复制代码
    刷屏函数调用单发,比之前速度好像好了些,但是还是没有ZF的官方例子速度快。不知道为啥,哪位大侠试下,帮看看原因。
    好了.LCD刷屏目前先到这。请哪位大侠试下,并告知原因。

    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3298

    主题

    6545

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32014
    最后登录
    2024-4-9
    发表于 2020-12-16 16:54:53 | 显示全部楼层
    感谢分享,等着大侠试试最后的问题
    签到签到
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-10-28 09:18
  • 签到天数: 1 天

    [LV.1]初来乍到

    4

    主题

    35

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    357
    最后登录
    2022-9-29
    发表于 2020-12-17 23:17:15 | 显示全部楼层
    你这刷屏一个字节一个字节刷,当然慢啊。
    得用DMA一堆一堆的刷,把每个时钟都连续起来。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2024-2-5 12:06
  • 签到天数: 627 天

    [LV.9]以坛为家II

    94

    主题

    1628

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4429

    热心会员

    最后登录
    2024-2-5
     楼主| 发表于 2020-12-19 12:58:44 | 显示全部楼层
    realjace 发表于 2020-12-17 23:17
    你这刷屏一个字节一个字节刷,当然慢啊。
    得用DMA一堆一堆的刷,把每个时钟都连续起来。 ...

    兄弟,我这个代码移植到MDK上面,完全正常显示。就是不要DMA也不应该这么慢啊。其实我就想问问是不是MCUXPresso IDE本身的一些什么问题导致的。
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-10-28 09:18
  • 签到天数: 1 天

    [LV.1]初来乍到

    4

    主题

    35

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    357
    最后登录
    2022-9-29
    发表于 2020-12-22 23:32:01 | 显示全部楼层
    胤幻1988 发表于 2020-12-19 12:58
    兄弟,我这个代码移植到MDK上面,完全正常显示。就是不要DMA也不应该这么慢啊。其实我就想问问是不是MCUX ...

    测量一下时钟就知道速度了
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    昨天 11:10
  • 签到天数: 678 天

    [LV.9]以坛为家II

    12

    主题

    3032

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    3658
    最后登录
    2024-4-23
    发表于 2023-10-14 09:10:18 | 显示全部楼层
    好家伙,SPI能达到50M?不错啊。
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-24 07:36 , Processed in 0.132383 second(s), 25 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表