我们知道阻塞模式的程序存在代码简洁、逻辑性强、容易理解等优点。但是阻塞模式的代码也存在效率不高,不适合多任务等缺点。在此我们用ST7735显示用阻塞模式和查询模式分别显示特定图象,对它们之间的性能进
选择硬件为CPU:stm32f103c8t6,显示屏为128X128pix。比较SPI16bit方式的阻塞与查询模式的显示效果。话不多说贴上两者的代码。首先上阻塞模式的代码:
//code by pmason_rose@qq.com
#include "stm32f10x.h"
#include "stm32f10x_spi.h"
#define LED_PORT GPIOC
#define LED_PIN GPIO_Pin_13
#define LCD_CTRL GPIOB //定义TFT数据端口
#define LCD_SCL GPIO_Pin_13 //PB13连接至TFT -- CLK
#define LCD_SDA GPIO_Pin_15 //PB15连接至TFT - SDI
#define LCD_LED GPIO_Pin_9 //PB9 连接至TFT -LED
#define LCD_RS GPIO_Pin_10 //PB10连接至TFT --RS
#define LCD_CS GPIO_Pin_11 //PB11 连接至TFT --CS
#define LCD_RST GPIO_Pin_12 //PB12连接至TFT --RST
//////////////////////////////////////////////////////////////////////
//液晶控制口置1操作语句宏定义
#define LCD_CS_SET LCD_CTRL->BSRR=LCD_CS
#define LCD_RS_SET LCD_CTRL->BSRR=LCD_RS
#define LCD_SDA_SET LCD_CTRL->BSRR=LCD_SDA
#define LCD_SCL_SET LCD_CTRL->BSRR=LCD_SCL
#define LCD_RST_SET LCD_CTRL->BSRR=LCD_RST
#define LCD_LED_SET LCD_CTRL->BSRR=LCD_LED
//液晶控制口置0操作语句宏定义
#define LCD_CS_CLR LCD_CTRL->BRR=LCD_CS
#define LCD_RS_CLR LCD_CTRL->BRR=LCD_RS
#define LCD_SDA_CLR LCD_CTRL->BRR=LCD_SDA
#define LCD_SCL_CLR LCD_CTRL->BRR=LCD_SCL
#define LCD_RST_CLR LCD_CTRL->BRR=LCD_RST
#define LCD_LED_CLR LCD_CTRL->BRR=LCD_LED
/****************************************************************************
* 名 称:SPI2_Init(void)
* 功 能:STM32_SPI2硬件配置初始化
* 入口参数:无
* 出口参数:无
* 说 明:STM32_SPI2硬件配置初始化
****************************************************************************/
void SPI2_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//配置SPI2管脚
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10| GPIO_Pin_11| GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
#define LED_PORT GPIOC
#define LED_PIN GPIO_Pin_13
GPIO_InitStructure.GPIO_Pin = LED_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(LED_PORT, GPIO_Pin_13); // LED
//SPI2配置选项
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 ,ENABLE);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
//使能SPI2
SPI_Cmd(SPI2, ENABLE);
}
/****************************************************************************
* 名 称:u8 SPI_WriteByte(SPI_TypeDef* SPIx,u8 Byte)
* 功 能:STM32_硬件SPI读写一个字节数据底层函数
* 入口参数:SPIx,Byte
* 出口参数:返回总线收到的数据
* 说 明:STM32_硬件SPI读写一个字节数据底层函数
****************************************************************************/
u16 SPI_WriteData(SPI_TypeDef* SPIx,u16 data)
{
while((SPIx->SR&SPI_I2S_FLAG_TXE)==RESET); //等待发送区空
SPIx->DR=data; //发送一个字节
while((SPIx->SR&SPI_I2S_FLAG_RXNE)==RESET);//等待接收完成
return SPIx->DR; //返回收到的数据
}
//******************************************************************
//函数名: LCD_WR_REG
//功能: 向液晶屏总线写入写16位指令
//输入参数:Reg:待写入的指令值
//返回值: 无
//修改记录:无
//******************************************************************
void LCD_WR_REG_16b(u16 data)
{
LCD_CS_CLR;
LCD_RS_CLR;
SPI_WriteData(SPI2,data);
LCD_CS_SET;
}
//******************************************************************
//函数名: LCD_WR_DATA
//功能: 向液晶屏总线写入写8位数据
//输入参数:Data:待写入的数据
//返回值: 无
//修改记录:无
//******************************************************************
void LCD_WR_DATA_16b(u16 data)
{
LCD_CS_CLR;
LCD_RS_SET;
SPI_WriteData(SPI2,data);
LCD_CS_SET;
}
/*************************************************
函数名:LCD_SetWindows
功能:设置lcd显示窗口,在此区域写点数据自动换行
入口参数:xy起点和终点
返回值:无
*************************************************/
void LCD_SetWindows(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd)
{
LCD_WR_REG_16b(0x002a);
LCD_WR_DATA_16b(yStar+2);
LCD_WR_DATA_16b(yEnd+2);
LCD_WR_REG_16b(0x002b);
LCD_WR_DATA_16b(yStar+3);
LCD_WR_DATA_16b(yEnd+3);
LCD_WR_REG_16b(0x002C);
}
/*************************************************
函数名:DelayS
功能:阻塞模式的延时函数
入口参数:延时大小
返回值:无
*************************************************/
void DelayS(u32 nCount)
{
for(;nCount!=0;nCount--);
}
//******************************************************************
//函数名: LCD_Init
//功能: LCD初始化
//输入参数:无
//返回值: 无
//修改记录:无
//******************************************************************
void LCD_Init(void)
{
SPI2_Init();
LCD_RST_CLR;
DelayS(100);
LCD_RST_SET;
DelayS(500);
LCD_WR_REG_16b(0x0011);
LCD_WR_REG_16b(0x00B1);
LCD_WR_DATA_16b(0x012C);
LCD_WR_DATA_16b(0x2D00);
LCD_WR_REG_16b(0x00B2);
LCD_WR_DATA_16b(0x012C);
LCD_WR_DATA_16b(0x2D00);
LCD_WR_REG_16b(0x00B3);
LCD_WR_DATA_16b(0x012C);
LCD_WR_DATA_16b(0x2D01);
LCD_WR_DATA_16b(0x2C2D);
LCD_WR_REG_16b(0x00B4);
LCD_WR_DATA_16b(0x0700);
LCD_WR_REG_16b(0x00C0);
LCD_WR_DATA_16b(0xA202);
LCD_WR_DATA_16b(0x8400);
LCD_WR_REG_16b(0x00C1);
LCD_WR_DATA_16b(0xC500);
LCD_WR_REG_16b(0x00C2);
LCD_WR_DATA_16b(0x0A00);
LCD_WR_REG_16b(0x00C3);
LCD_WR_DATA_16b(0x8A2A);
LCD_WR_REG_16b(0x00C4);
LCD_WR_DATA_16b(0x8AEE);
LCD_WR_REG_16b(0x00C5);
LCD_WR_DATA_16b(0x0E00);
LCD_WR_REG_16b(0x0036);
LCD_WR_DATA_16b(0xC800);
LCD_WR_REG_16b(0x00e0);
LCD_WR_DATA_16b(0x0f1a);
LCD_WR_DATA_16b(0x0f18);
LCD_WR_DATA_16b(0x2f28);
LCD_WR_DATA_16b(0x2022);
LCD_WR_DATA_16b(0x1f1b);
LCD_WR_DATA_16b(0x2337);
LCD_WR_DATA_16b(0x0007);
LCD_WR_DATA_16b(0x0210);
LCD_WR_DATA_16b(0x0f1b);
LCD_WR_DATA_16b(0x0f17);
LCD_WR_DATA_16b(0x332c);
LCD_WR_DATA_16b(0x292e);
LCD_WR_DATA_16b(0x3030);
LCD_WR_DATA_16b(0x393f);
LCD_WR_DATA_16b(0x0007);
LCD_WR_DATA_16b(0x0310);
LCD_WR_REG_16b(0x002a);
LCD_WR_DATA_16b(0x0000);
LCD_WR_DATA_16b(0x007f);
LCD_WR_REG_16b(0x0026);
LCD_WR_DATA_16b(0x0000);
LCD_WR_DATA_16b(0x009f);
LCD_WR_REG_16b(0x00F0);
LCD_WR_DATA_16b(0x0100);
LCD_WR_REG_16b(0x00F6);
LCD_WR_DATA_16b(0x0000);
LCD_WR_REG_16b(0x003A);
LCD_WR_DATA_16b(0x0500);
LCD_WR_REG_16b(0x2936);
LCD_WR_DATA_16b(0xC800);
}
void LCD_Clear(u16 Color)
{
u32 Lcd_Index=0;
LCD_SetWindows(0,0,127,127);
for(Lcd_Index=0;Lcd_Index<(128*128);Lcd_Index++)
{
LCD_WR_DATA_16b(Color);
}
} |