本帖最后由 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);
}
这些都不重要,我幂才是唯一!
再来看看实际显示效果如何 哈哈,大幂幂很能打呀。 最后附上程序代码,
|