本帖最后由 740071911 于 2022-7-11 19:41 编辑
#有奖活动# #申请原创# @安小芯
以前薅羊毛买的合宙LuatOS的LCD屏,因为需要使用Lua,也不支持c底层,所以一直没有玩过,
趁着N32G430活动,先研究一下LCD。
因为官方不支持c底层,所以要自己摸索,不过基于spi通信,想来是不难的,先看原理图
图片不清楚,我在右边整理了一下管脚
再看看实物图
我的硬件连接- BLK-------PB8
- CS--------PB7
- RS--------PB6
- RESET---PB5
- //SPI
- SCL-------PA5
- SDA------PA7
其中用到N32G430---SPI1
- #include "spi.h"
- #define MX_SPI_INDEX 0
- void MX_SPI_Init(void)
- {
- #if MX_SPI_INDEX==0
-
- SPI_InitType SPI_InitStructure;
- SPI_I2S_Reset(SPI_MASTER);
- //SPI_I2S_Reset(SPI_SLAVE);
- /* SPI_MASTER configuration --------------------------------------------------*/
- SPI_Initializes_Structure(&SPI_InitStructure);
- SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
- SPI_InitStructure.SpiMode = SPI_MODE_MASTER;
- SPI_InitStructure.DataLen = SPI_DATA_SIZE_8BITS;
- SPI_InitStructure.CLKPOL = SPI_CLKPOL_LOW;
- SPI_InitStructure.CLKPHA = SPI_CLKPHA_FIRST_EDGE;
- SPI_InitStructure.NSS = SPI_NSS_SOFT;
- /* It is recommended that the SPI master mode of the C version chips should not exceed 18MHz */
- SPI_InitStructure.BaudRatePres = SPI_BR_PRESCALER_8;//64/8
- SPI_InitStructure.FirstBit = SPI_FB_MSB;
- SPI_InitStructure.CRCPoly = 7;
- SPI_Initializes(SPI_MASTER, &SPI_InitStructure);
-
- SPI_Set_Nss_Level(SPI_MASTER, SPI_NSS_HIGH);
- /* Enable SPI_MASTER CRC calculation */
- SPI_CRC_Enable(SPI_MASTER);
-
- #ifdef HARDWARE_NSS
- SPI_NSS_Config(SPI_MASTER, SPI_NSS_HARD);
- SPI_SS_Output_Enable(SPI_MASTER);
- SPI_NSS_Config(SPI_SLAVE, SPI_NSS_HARD);
- #endif
- /* Enable SPI_MASTER */
- SPI_ON(SPI_MASTER);
-
- #elif MX_SPI_INDEX==1
- GPIO_InitType ioConfig;
- /* Enable LCD related GPIO peripheral clock */
- RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA); /*
- RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
- RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOC);
- RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOD); */
- //SPI1: PA4,PA5,PA6,PA7
- GPIO_Structure_Initialize(&ioConfig);
- /* Configure master pins: SCK, MISO and MOSI ---------------------------------*/
- /* Confugure SCK and MOSI pins as Alternate Function Push Pull */
- ioConfig.Pin = SPI_MASTER_MOSI_PIN | SPI_MASTER_CLK_PIN | SPI_MASTER_NSS_PIN;
- ioConfig.GPIO_Mode = GPIO_MODE_OUT_PP;
- ioConfig.GPIO_Slew_Rate = GPIO_SLEW_RATE_SLOW;
- GPIO_Peripheral_Initialize(SPI_MASTER_GPIO_PORT, &ioConfig);
-
- GPIO_Structure_Initialize(&ioConfig);
- /* Confugure MISO pins as Push Pull Input */
- ioConfig.Pin = SPI_MASTER_MISO_PIN;
- ioConfig.GPIO_Mode = GPIO_MODE_INPUT;
- ioConfig.GPIO_Slew_Rate = GPIO_SLEW_RATE_SLOW;
- ioConfig.GPIO_Pull = GPIO_PULL_UP;
- GPIO_Peripheral_Initialize(SPI_MASTER_GPIO_PORT, &ioConfig);
-
- #elif MX_SPI_INDEX==20
- GPIO_InitType ioConfig;
- SPI_InitType spiConfig;
-
- intx_alloc();
- //开启时钟
- intx_disable();
- RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_SPI1 | RCC_APB2_PERIPH_AFIO);
- RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
- intx_enable();
-
- //SPI1: PA4,PA5,PA6,PA7
- GPIO_Structure_Initialize(&ioConfig);
- /* Configure master pins: SCK, MISO and MOSI ---------------------------------*/
- /* Confugure SCK and MOSI pins as Alternate Function Push Pull */
- ioConfig.Pin = SPI_MASTER_MOSI_PIN | SPI_MASTER_CLK_PIN | SPI_MASTER_MISO_PIN | SPI_MASTER_NSS_PIN;
- ioConfig.GPIO_Mode = GPIO_MODE_AF_PP;
- ioConfig.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
- ioConfig.GPIO_Alternate = SPI_MASTER_GPIO_ALTERNATE;
- GPIO_Peripheral_Initialize(SPI_MASTER_GPIO_PORT, &ioConfig);
-
- SPI_I2S_Reset(SPI_MASTER);
- // SPI 配置
- //SPI_DIR_DOUBLELINE_FULLDUPLEX
- //
- spiConfig.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
- spiConfig.SpiMode = SPI_MODE_MASTER;
- spiConfig.DataLen = SPI_DATA_SIZE_8BITS;
- spiConfig.CLKPOL = SPI_CLKPOL_HIGH;
- spiConfig.CLKPHA = SPI_CLKPHA_SECOND_EDGE;
- spiConfig.NSS = SPI_NSS_SOFT;
- spiConfig.FirstBit = SPI_FB_MSB;
- spiConfig.CRCPoly = 7;
- spiConfig.BaudRatePres = SPI_BR_PRESCALER_128;
- SPI_Initializes(LCD_SPI, &spiConfig);
-
- //SPI_SS_Output_Enable(LCD_SPI);
- SPI_Set_Nss_Level(LCD_SPI, SPI_NSS_HIGH);
- SPI_ON(LCD_SPI);
-
- #endif
- }
- /*
- SPI读取字节函数
- */
- u8 SPI_ReadWriteByte(SPI_Module* SPIx, u8 TxData)
- {
- u8 retry=0;
- while (SPI_I2S_Flag_Status_Get(SPIx, SPI_I2S_FLAG_TE) == RESET)
- {
- retry++;
- if(retry>200) return 0;
- }
-
- SPI_I2S_Data_Transmit(SPIx, TxData);
- retry=0;
- while (SPI_I2S_Flag_Status_Get(SPIx, SPI_I2S_FLAG_RNE) == RESET)
- {
- retry++;
- if(retry>200) return 0;
- }
-
- return SPI_I2S_Data_Get(SPIx);
- }
- /*
- SPI读取字节函数
- */
- #if MX_SPI_INDEX==0
- u8 SPI_WriteByte(SPI_Module* SPIx, u8 Byte)
- {
- /* Wait for SPI_MASTER Tx buffer empty */
- while (SPI_I2S_Flag_Status_Get(LCD_SPI, SPI_I2S_FLAG_TE) == RESET);
-
- /* Send SPI_SLAVE data */
- SPI_I2S_Data_Transmit(LCD_SPI, Byte);
-
- /* Wait for SPI_SLAVE data reception */
- while (SPI_I2S_Flag_Status_Get(LCD_SPI, SPI_I2S_FLAG_RNE) == RESET);
-
- return SPIx->DAT; //返回收到的数据
- }
- #elif MX_SPI_INDEX==1
- u8 SPI_WriteByte(SPI_Module* SPIx, u8 Byte)
- {
-
- }
- #elif MX_SPI_INDEX==20
- u8 SPI_WriteByte(SPI_Module* SPIx, u8 Byte)
- {
- while((SPIx->STS & SPI_I2S_FLAG_TE) == RESET); //等待发送区空
-
- SPIx->DAT = Byte; //发送一个byte
-
- while((SPIx->STS & SPI_I2S_FLAG_RNE) == RESET); //等待接收完一个byte
-
- return SPIx->DAT; //返回收到的数据
- }
- #endif
其中需要注意的是,软件片选的时候,必须添加这个函数,使能SPI主模式 - SPI_Set_Nss_Level(SPI_MASTER, SPI_NSS_HIGH);
这是之前国民技术群里前辈踩过的坑,让我们少走弯路,表示感谢。 可以参看产品手册SPI1配置说明: 接下来主要就是对屏幕的操作,基本操作就不贴了,官方是基于lua,所以有不少功能还需要慢慢移植,先来刷图。 - /*----------------------------------------------------------------------------*/
- /*----------------------------------------------------------------------------*/
- //画图
- void LCD_DrawPic(u16 x,u16 y,const unsigned char *p)
- {
- int i;
- unsigned char picH,picL;
-
- LCD_SetWindows(x,y,x+128-1,y+80-1);
-
- for(i=0;i<128*80;i++)
- {
- picL=*(p+i*2);
- picH=*(p+i*2+1);
- Lcd_WriteData_16Bit(picH<<8|picL);
- }
-
- LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);
- }
这些都不重要,我幂才是唯一!
再来看看实际显示效果如何 哈哈,大幂幂很能打呀。 最后附上程序代码,
|