class Gezi { private int x; private int y; private boolean filled; private boolean searched; private boolean colored; private boolean go; private boolean start; private boolean end; public boolean isStart() { return start; } public void setStart(boolean start) { this.start = start; } public boolean isEnd() { return end; } public void setEnd(boolean end) { this.end = end; } public boolean isGo() { return go; } public void setGo(boolean go) { this.go = go; } public boolean isColored() { return colored; } public void setColored(boolean colored) { this.colored = colored; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public boolean isFilled() { return filled; } public void setFilled(boolean filled) { this.filled = filled; } public boolean isSearched() { return searched; } public void setSearched(boolean searched) { this.searched = searched; } public Gezi() { } public Gezi(int x,int y,boolean filled,boolean searched) { this.filled = filled; this.x = x; this.y = y; this.searched = searched; } }
时间: 2024-04-21 14:29:05 浏览: 117
这是一个Gezi类,它定义了8个私有属性和8个公共方法。其中,x和y表示该Gezi对象在平面上的位置,filled和colored是布尔类型的属性,表示该Gezi对象是否被填充和是否被染色,searched和go也是布尔类型的属性,表示该Gezi对象是否被访问过和是否可以通过。start和end也是布尔类型的属性,表示该Gezi对象是否为起点和终点。这个类可以用于表示平面上的一个格子,并记录格子是否被填充、染色、访问过,以及是否可以通过和是否为起点或终点。
相关问题
for (int i = 0; i < this.Xs.Count; i++) draw gezi(this.Xs[i], this.Yslil);
这是一个使用 C# 编程语言的循环语句,其目的是根据类中的 Xs 属性中的值来绘制一个名为 "gezi" 的图形。具体来说,这个循环会依次遍历 Xs 数组中的每一个元素,将它作为参数传递给 gezi 函数,同时将类中的属性 Yslil 作为另一个参数传递给该函数。在每次循环中,都会绘制一个新的 gezi 图形,直到遍历完所有的 Xs 元素为止。
/********************************************************************************************** Copyright 2008 - 2019 深圳市信盈达电子有限公司. All rights reserved. 描述 : 作者 : 何文宾 版本 : V1.0 修改 : 完成日期: 2019年2月17日 信盈达官网:http://www.edu118.com/ 信盈达网校:http://www.edu118.cn/ 信盈达技术论坛:http://bbs.edu118.com/ Notice :本程序只供学习使用,未经作者许可,不得用于其它任何用途。版权所有,盗版必究 ***********************************************************************************************/ /********************************************************************************************** * INCLUDES */ #include "oled.h" #include "systick.h" #include "font.h" #include "rtc.h" /********************************************************************************************** * CONSTANTS */ /********************************************************************************************** * TYPEDEFS */ /********************************************************************************************** * LOCAL VARIABLES */ /********************************************************************************************** * LOCAL FUNCTIONS DECLARE */ /********************************************************************************************** * LOCAL FUNCTIONS */ /********************************************************************************************** * PUBLIC FUNCTIONS */ /******************************************************************* * 函数名: OLED_Init() * 功能描述 : 初始化oled * 作者: 何文宾 * 参数说明: 无 * 返回值说明: 无 * 修改记录: * 其他: *******************************************************************/ /** SCK----PB13 MOSI---PB15 CS-----PA15 DC-----PA11 RES----PA12 */ void OLED_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; SPI_InitTypeDef SPI_InitStruct; /***********************管脚定义********************************************/ if(SPI_MODE) { /*************************硬件SPI*********************************************/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);//使能A&&B时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);//SPI2时钟使能 /*CS-----PA15*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_CS_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(OLED_GPIO,&GPIO_InitStruct); /*DC-----PA11*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_DC_PIN; GPIO_Init(OLED_GPIO,&GPIO_InitStruct); /*RES-----PA12*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_RES_PIN; GPIO_Init(OLED_GPIO,&GPIO_InitStruct); OLED_RES_H; /*SCK----PB13*/ //复用推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_SCK_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(OLED_SPI_GPIO,&GPIO_InitStruct); /*MOSI---PB15*/ //复用推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_MOSI_PIN; GPIO_Init(OLED_SPI_GPIO,&GPIO_InitStruct); /*MISO---PB14*/ //浮空输入 GPIO_InitStruct.GPIO_Pin = OLED_MISO_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(OLED_SPI_GPIO,&GPIO_InitStruct); SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//波特率 SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;//在时钟第二个电平发送数据 SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;//时钟空闲状态为高电平 SPI_InitStruct.SPI_CRCPolynomial = DISABLE; SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;//8位数据帧 SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线双向模式 SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;//先发高位 SPI_InitStruct.SPI_Mode = SPI_Mode_Master;//主机模式 SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;//软件从设备管理 SPI_Init(SPI2,&SPI_InitStruct); SPI_Cmd(SPI2,ENABLE); spi_read_write(0xff); } else { /*软件模拟SPI*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);//使能A&&B时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); /*SCK----PB13*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_SCK_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(OLED_SPI_GPIO,&GPIO_InitStruct); /*MOSI---PB15*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_MOSI_PIN; GPIO_Init(OLED_SPI_GPIO,&GPIO_InitStruct); /*CS-----PA15*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_CS_PIN; GPIO_Init(OLED_GPIO,&GPIO_InitStruct); /*DC-----PA11*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_DC_PIN; GPIO_Init(OLED_GPIO,&GPIO_InitStruct); /*RES-----PA12*/ //推挽输出 50MHZ GPIO_InitStruct.GPIO_Pin = OLED_RES_PIN; GPIO_Init(OLED_GPIO,&GPIO_InitStruct); OLED_RES_H; } /***********************初始化时序********************************************/ delay_ms(200); Oled_Write_Cmd(0xAE); //关闭显示 Oled_Write_Cmd(0xD5); //设置时钟分频因子,震荡频率 Oled_Write_Cmd(80); //[3:0],分频因子;[7:4],震荡频率 Oled_Write_Cmd(0xA8); //设置驱动路数 Oled_Write_Cmd(0X3F); //默认0X3F(1/64) Oled_Write_Cmd(0xD3); //设置显示偏移 Oled_Write_Cmd(0X00); //默认为0 Oled_Write_Cmd(0x40); //设置显示开始行 [5:0],行数. Oled_Write_Cmd(0x8D); //电荷泵设置 Oled_Write_Cmd(0x14); //bit2,开启/关闭 Oled_Write_Cmd(0x20); //设置内存地址模式 Oled_Write_Cmd(0x02); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10; Oled_Write_Cmd(0xA1); //段重定义设置,bit0:0,0->0;1,0->127; Oled_Write_Cmd(0xC8); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数 Oled_Write_Cmd(0xDA); //设置COM硬件引脚配置 Oled_Write_Cmd(0x12); //[5:4]配置 Oled_Write_Cmd(0x81); //对比度设置 Oled_Write_Cmd(0xEF); //1~255;默认0X7F (亮度设置,越大越亮) Oled_Write_Cmd(0xD9); //设置预充电周期 Oled_Write_Cmd(0xf1); //[3:0],PHASE 1;[7:4],PHASE 2; Oled_Write_Cmd(0xDB); //设置VCOMH 电压倍率 Oled_Write_Cmd(0x30); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc; Oled_Write_Cmd(0xA4); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏) Oled_Write_Cmd(0xA6); //设置显示方式;bit0:1,反相显示;0,正常显示 Oled_Write_Cmd(0xAF); //开启显示 OLED_Clear(0,128,0,8,0x00); } /******************************************************************* * 函数名: spi_read_write() * 功能描述 : SPI读写数据 * 作者: 何文宾 * 参数说明: 待发送的数据 * 返回值说明: 读取的值 * 修改记录: * 其他: *******************************************************************/ //SPI读写数据 u8 spi_read_write(u8 dat) { if (SPI_MODE) { while(!SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)); //等待发送缓冲为空 SPI_I2S_SendData(SPI2,dat); while(!SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)); //等待接收缓冲不为空 return SPI_I2S_ReceiveData(SPI2); //返回收到的数据 } else { u8 i; OLED_CS_L; for(i=0;i<8;i++) { OLED_SCK_L; if((dat&0x80)) { OLED_MOSI_H; } else OLED_MOSI_L; OLED_SCK_H; dat<<=1; } OLED_CS_H; return dat; } } /******************************************************************* * 函数名: Oled_Write_Data() * 功能描述 : OLED写数据 * 作者: 何文宾 * 参数说明: 待发送的指令 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void Oled_Write_Data(u8 dat) { OLED_DC_H; OLED_CS_L; spi_read_write(dat); OLED_CS_H; } /******************************************************************* * 函数名: Oled_Write_Cmd() * 功能描述 : OLED写指令 * 作者: 何文宾 * 参数说明: 待发送的指令 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void Oled_Write_Cmd(u8 cmd) { OLED_DC_L; OLED_CS_L; spi_read_write(cmd); OLED_CS_H; } /******************************************************************* * 函数名: OLED_Setpos() * 功能描述 : OLED设置位置 * 作者: 何文宾 * 参数说明: 待发送的指令 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_Setpos(u8 sx,u8 sy) { Oled_Write_Cmd(0xb0+sy); //哪一页 Oled_Write_Cmd(0x10+(sx>>4)); //高4位地址 Oled_Write_Cmd(0x00+(sx&0x0f));//低4位地址 } /******************************************************************* * 函数名: OLED_Clear() * 功能描述 : OLED设置位置 * 作者: 何文宾 * 参数说明: 待发送的指令 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_Clear(u8 sx,u8 ex,u8 sy,u8 ey,u8 data) { u8 i,j; for(i=sy;i<ey;i++) //页 { Oled_Write_Cmd(0xb0+i); //哪一页 Oled_Write_Cmd(0x10+(sx>>4)); //高4位地址 Oled_Write_Cmd(0x00+(sx&0x0f));//低4位地址 for(j=0;j<(ex-sx);j++) //列 { Oled_Write_Data(data); } } } /******************************************************************* * 函数名: OLED_ShowChar() * 功能描述 : 显示字符 * 作者: 何文宾 * 参数说明: x:X坐标,y:Y坐标,p:显示的字符,size:字符大小 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_ShowChar(u8 x,u8 y,u8 p,u8 size) { u8 i; u8 ex,ey; u8 res=p-' '; ex=x;ey=y; if(size==16) { OLED_Setpos(ex,ey); for(i=0;i<16;i++) { if(((i%8)==0)&&(i!=0)) { ex=x; ey+=1; OLED_Setpos(ex,ey); } Oled_Write_Data(char16X16[res][i]); } } else if(size==12) { OLED_Setpos(ex,ey); for(i=0;i<12;i++) { if(((i%6)==0)&&(i!=0)) { ex=x; ey+=1; OLED_Setpos(ex,ey); } Oled_Write_Data(char12X12[res][i]); } } else if(size==24) { OLED_Setpos(ex,ey); for(i=0;i<36;i++) { if(((i%12)==0)&&(i!=0)) { ex=x; ey+=1; OLED_Setpos(ex,ey); } Oled_Write_Data(char24X24[res][i]); } } } /******************************************************************* * 函数名: OLED_ShowString() * 功能描述 : 显示字符串 * 作者: 何文宾 * 参数说明: x:X坐标,y:Y坐标,p:显示的字符串,size:字符串大小 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_ShowString(u8 x,u8 y,u8 *p,u8 size) { while(*p!='\0') { OLED_ShowChar(x,y,*p,size); p+=1; x+=(size/2); } } /******************************************************************* * 函数名: OLED_ShowNum() * 功能描述 : 显示数字 * 作者: 何文宾 * 参数说明: x:X坐标,y:Y坐标,num:显示的数字,size:数字大小,len:长度 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_ShowNum(u8 x,u8 y,u32 num,u8 size) { u8 cnum,cnum2; u8 nn; u8 i; u8 length=0; nn=1; cnum=num; cnum2=num; if(num!=0) { while(num>0) { length+=1; num/=10; } } else { length=1; } while(length) { for(i=0;i<(length-1);i++) { nn=nn*10; } cnum=cnum/nn; OLED_ShowChar(x,y,cnum+48,size); x+=(size/2); cnum=cnum2%nn; nn=1; length--; } } /******************************************************************* * 函数名: OLED_ShowTime() * 功能描述 : 显示当前时间 * 作者: 何文宾 * 参数说明: x:X坐标,y:Y坐标,size:数字大小 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_ShowTime(u8 x,u8 y,u8 size) { u8 sx=x; /*显示当前时间*/ RTC_Get_Time(); OLED_ShowNum(sx,y,my_time.hour,16); sx+=size; OLED_ShowChar(sx,y,':',16); sx+=(size/2); OLED_ShowNum(sx,y,my_time.min,16); sx+=size; OLED_ShowChar(sx,y,':',16); sx+=(size/2); OLED_ShowNum(sx,y,my_time.sec ,16); } /******************************************************************* * 函数名: OLED_Showpic() * 功能描述 : 显示图片 * 作者: 何文宾 * 参数说明: * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_Showpic(u8 sx,u8 sy,u8 ex,u8 ey,const unsigned char * p) { u8 i,j; for(j=0;j<(ey-sy);j++) { OLED_Setpos(sx,sy+j); for(i=0;i<(ex-sx);i++) { Oled_Write_Data(*p); p++; } } } /******************************************************************* * 函数名: OLED_Show_Font() * 功能描述 : 显示单个汉字 * 作者: 何文宾 * 参数说明: * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_Show_Font(u8 x,u8 y,u8 size,u8 num) { u8 i; u8 temp; u8 ssize; u8 x0=x; u8 *zk; ssize=size*(size/8+(size%8?1:0)); //计算不同字体大小所占用的字节数 switch(size) { case 12: zk=(u8*)F12X12[num]; //得到汉字编号对应的点阵库 for(i=0;i<ssize;i++) { if(i==size) { x=x0; y++; } temp=zk[i]; //得到点阵数据 OLED_Setpos(x,y); Oled_Write_Data(temp); x++; } break; case 16: zk=(u8*)F16X16[num]; //得到汉字编号对应的点阵库 for(i=0;i<ssize;i++) { if(i==size) { x=x0; y++; } temp=zk[i]; //得到点阵数据 OLED_Setpos(x,y); Oled_Write_Data(temp); x++; } break; case 24: zk=(u8*)F24X24[num]; //得到汉字编号对应的点阵库 for(i=0;i<ssize;i++) { if(i==size) { x=x0; y++; } temp=zk[i]; //得到点阵数据 OLED_Setpos(x,y); Oled_Write_Data(temp); x++; } break; default:break; } } /******************************************************************* * 函数名: OLED_Show_Font() * 功能描述 : 显示多个汉字 * 作者: 何文宾 * 参数说明: * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_ShowMultiple_Font(u8 x,u8 y,u8 size,u8 *p) { while(*p!=0) { OLED_Show_Font(x,y,size,*p); p++; x+=size; } } /******************************************************************* * 函数名: OLED_Show_gezi() * 功能描述 : 显示下划线 * 作者: 何文宾 * 参数说明: mode:1 密码格子 0:时间格子 * 返回值说明: * 修改记录: * 其他: *******************************************************************/ void OLED_Show_gezi(u8 sx,u8 sy,u8 ex,u8 ey) { u8 i; for(i=0;i<6;i++) { OLED_Showpic(sx,sy,ex,ey,&gezi[0]); sx+=15; ex+=15; } } void show_voice(u8 sx,u8 sy,u8 vol) { u8 i=0; u8 x=sx; OLED_Clear(sx,sx+80,sy,sy+1,0x00); for(i=0;i<vol;i++) { OLED_Showpic(x,sy,x+8,sy+1,&voice[i][0]); x+=10; } } /*********************************************************************************************** ***********************************************************************************************/ 我想在此基础上添加切换屏幕的功能,并且屏幕显示请输入密码
<think>我们需要添加一个功能,即切换屏幕并显示“请输入密码”。这通常意味着我们可能需要在OLED上显示一个密码输入界面。考虑到OLED的显示特性,我们可以设计一个初始界面(比如主菜单)和密码输入界面,并能够通过某个按键(比如某个GPIO按键)来切换屏幕。但是,原代码中并没有按键处理相关的部分,因此我们需要在外部(比如主循环中)检测按键,然后调用一个切换屏幕的函数。由于原代码已经提供了显示字符串、清屏等功能,我们可以利用这些函数来实现。步骤:1.定义一个全局变量,用于记录当前显示的屏幕(例如,0表示主屏幕,1表示密码输入屏幕)。2.编写一个函数,根据当前屏幕标志绘制对应的屏幕。3.在主循环中检测按键,当检测到切换按键时,改变屏幕标志,并重新绘制屏幕。由于我们只关注显示部分,这里只考虑如何绘制密码输入屏幕。例如,在密码输入屏幕上,我们可能希望显示“请输入密码:”的提示,以及一些用于输入密码的格子(或者星号)来表示已经输入的密码位数。但是,由于我们还没有密码输入和验证的功能,所以这里先实现显示提示和几个空格(或者等待输入的状态)。由于原代码中已经有一个显示格子的函数(OLED_Show_gezi),我们可以利用它来显示密码输入位置。修改计划:首先,我们添加一个全局变量来记录当前屏幕状态:u8currentScreen=0;//0:主屏幕,1:密码输入屏幕然后,我们添加一个切换屏幕的函数,比如:voidswitchScreen(u8screenIndex);但是,这个函数实际上就是根据传入的索引去绘制对应的屏幕。因此,我们也可以不单独写switchScreen,而是直接在检测到按键时改变currentScreen,然后重新绘制。其次,我们需要修改主循环,在循环中不断检测按键并更新屏幕(但注意,更新屏幕不宜过于频繁,否则可能导致闪烁,一般可以在状态改变时更新一次)。由于我们没有添加具体的按键,所以这里先假设我们通过一个外部中断或者扫描按键的方式得到一个切换屏幕的触发信号。为了简单,我们可以在主循环中模拟:当按下某个按键(比如PA0连接的按键)时,切换屏幕。下面,我们修改代码:1.在文件开头(全局变量部分)定义一个变量:u8current_screen=0;//0:初始屏幕(可能是主菜单)1:密码输入屏幕2.编写一个刷新屏幕的函数,根据current_screen的值来绘制不同的内容:voidrefresh_screen(void){OLED_Clear(0,128,0,8,0x00);//清除整个屏幕if(current_screen==0){//显示主菜单,这里简单显示一个主界面OLED_ShowString(0,0,"MainMenu:",16);//其他主菜单内容}elseif(current_screen==1){//显示密码输入界面OLED_ShowString(0,0,"PleaseInput",16);OLED_ShowString(0,2,"Password:",16);//显示6个密码输入格子(原函数是在指定位置显示一个格子图案,但原函数是连续显示6个格子,所以需要调整位置)//原函数:voidOLED_Show_gezi(u8sx,u8sy,u8ex,u8ey)//这里调用它来显示6个格子,位置从(0,4)开始,每个格子15像素宽,8像素高(根据实际图片)OLED_Show_gezi(0,4,8,5);//注意:原函数显示6个格子,每个格子宽度15,所以这里sx=0,ex=8(因为图片宽度为8)?//但实际原函数中gezi图片的大小是多少?原函数显示图片时,参数是起始和结束坐标,图片数据指针指向gezi[0]。//原函数中,gezi是一个数组,但大小没有给出。所以我们可能需要调整参数。//或者,我们可以用另一种方式:显示6个下划线(或者用矩形框)表示等待输入。//由于原函数OLED_Show_gezi的实现是连续显示6个格子(每个格子15宽,1高,起始位置sx,sy,结束位置ex,ey,实际上是每画一个格子,x方向增加15,然后画下一个)//而我们希望从(0,4)开始画,所以参数sx=0,sy=4,ex=8(图片宽度8),ey=5(图片高度1)?但是原函数内部会循环6次,每次x增加15?那这个函数会画出6个格子,每个格子从(sx+i*15,sy)到(sx+i*15+8,sy+1)的位置。//但是看原函数://voidOLED_Show_gezi(u8sx,u8sy,u8ex,u8ey)//{//u8i;//for(i=0;i<6;i++)//{//OLED_Showpic(sx,sy,ex,ey,&gezi[0]);//sx+=15;//ex+=15;//}//}//所以,我们调用时,sx和ex应该是第一个格子的起始和结束列坐标,并且函数会连续画6个格子,每个格子之间间隔15列(包括格子本身宽度,所以格子宽度应该是ex-sx,高度为ey-sy)。//因此,如果我们希望第一个格子从列0开始,结束列7(8列宽),那么sx=0,ex=7(注意,OLED_Showpic的ex是结束列+1?因为原函数中OLED_Showpic内部循环是从sx到ex-1?实际上原函数中,OLED_Showpic的参数ex是结束列坐标(不包含,即下一个列位置),所以实际上显示的区域是[sx,ex-1](列)和[sy,ey-1](行)。因此,我们这里希望一个格子宽8,高1,所以sx=0,ex=8(这样显示8列),高度上sy=4,ey=5(即1行)。//所以调用:OLED_Show_gezi(0,4,8,5);}}3.在main函数初始化完OLED后,先调用一次刷新屏幕:refresh_screen();4.在主循环中,检测按键(假设按键连接在PA0,且已经配置为输入):if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0)//按键按下{delay_ms(10);//消抖if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0){current_screen=(current_screen+1)%2;//切换屏幕0和1refresh_screen();while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0);//等待松开}}但是,我们还没有配置按键的GPIO。因此,我们需要初始化按键的GPIO。5.初始化按键的GPIO(以PA0为例):voidKey_Init(void){GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入GPIO_Init(GPIOA,&GPIO_InitStructure);}6.在main函数中,初始化按键:Key_Init();注意:以上是一个简单的示例,实际项目可能需要更复杂的按键处理(例如使用中断、消抖等)。由于我们的目标是在屏幕上显示“请输入密码”并切换,因此这里只修改了OLED相关的部分,并添加了按键检测。但是,我们也要注意,原代码中没有提供gezi图片的具体内容,所以OLED_Show_gezi可能无法正常显示。如果需要,我们可以自己设计一个格子(例如一个矩形框)的图片数据,大小是8x1(因为上面我们调用时,显示高度为1,宽度为8),那么就需要一个8个字节的数组(因为每行8个点,而高度1行,所以8个字节)。或者,我们可以直接用下划线代替:在需要的位置显示一串下划线字符,或者画横线。另一种方案:我们可以修改显示字符串的方式,在密码输入位置显示6个下划线,每个下划线用字符'_',位置可以通过OLED_ShowString显示。因此,在密码输入界面,我们可以这样做:OLED_ShowString(0,4,"______",16);//用6个下划线代表输入位置这样更简单,而且不需要使用图片。所以,我们修改refresh_screen函数中的密码输入界面部分:elseif(current_screen==1){OLED_ShowString(0,0,"PleaseInput",16);OLED_ShowString(0,2,"Password:",16);OLED_ShowString(0,4,"______",16);//显示6个下划线,每个字符占8个像素,所以6*8=48像素}但是,这样显示的下划线是连续的,没有间隔。如果希望有间隔,可以这样:OLED_ShowString(0,4,"______",16);//每个下划线之间加一个空格或者,我们可以使用OLED_ShowChar函数在指定位置显示多个下划线,每个之间空一个字符位。根据需求,我们显示六个下划线,每个下划线之间有一定的间隔。为了方便,我们直接显示字符串。由于我们没有修改主循环的按键检测,所以这里我们只给出刷新屏幕和切换屏幕的代码框架。注意:我们还需要在显示密码输入界面后,能够通过按键(比如数字键)输入密码,但这需要另外的模块,不属于本题要求。因此,我们按照要求,在原有工程基础上添加切换屏幕功能,并在密码输入屏幕上显示“请输入密码”的提示。下面,我们添加代码:注意:以下代码需要根据实际硬件调整,特别是按键部分。这里只给出关键部分。</think>
基于您提供的OLED驱动程序代码,我将添加切换屏幕功能并实现"请输入密码"的显示。以下是修改后的代码:
```c
// 在文件开头添加宏定义和全局变量
#define MAX_SCREENS 3 // 最大屏幕数量
u8 current_screen = 0; // 当前屏幕索引
/*******************************************************************
* 函数名: show_password_screen()
* 功能描述: 显示密码输入界面
* 作者: 何文宾
* 参数说明: 无
* 返回值说明: 无
* 修改记录:
*******************************************************************/
void show_password_screen(void) {
OLED_Clear(0, 128, 0, 8, 0x00); // 清屏
OLED_ShowMultiple_Font(0, 1, 16, "请输入密码"); // 显示中文提示
OLED_Show_gezi(0, 4, 8, 5); // 显示密码输入格子
}
/*******************************************************************
* 函数名: show_main_screen()
* 功能描述: 显示主界面
* 作者: 何文宾
* 参数说明: 无
* 返回值说明: 无
* 修改记录:
*******************************************************************/
void show_main_screen(void) {
OLED_Clear(0, 128, 0, 8, 0x00); // 清屏
OLED_ShowString(0, 0, "Main Screen", 16);
OLED_ShowTime(0, 2, 16); // 显示时间
}
/*******************************************************************
* 函数名: switch_screen()
* 功能描述: 切换屏幕显示
* 作者: 何文宾
* 参数说明: screen_index: 要切换的屏幕索引
* 返回值说明: 无
* 修改记录:
*******************************************************************/
void switch_screen(u8 screen_index) {
if(screen_index >= MAX_SCREENS) return;
current_screen = screen_index;
switch(screen_index) {
case 0: // 主界面
show_main_screen();
break;
case 1: // 密码输入界面
show_password_screen();
break;
// 可以添加更多界面
default:
show_main_screen();
}
}
/*******************************************************************
* 函数名: main()
* 功能描述: 主函数(示例调用)
* 作者: 何文宾
* 参数说明: 无
* 返回值说明: 无
* 修改记录:
*******************************************************************/
// 在main函数中调用示例:
int main(void) {
// 初始化代码...
OLED_Init();
// 初始显示主界面
switch_screen(0);
while(1) {
// 检测按键或其他事件来切换屏幕
if(some_button_pressed) {
// 切换到密码输入界面
switch_screen(1);
}
}
}
```
### 代码说明:
1. **多屏幕管理机制**:
- 添加了全局变量 `current_screen` 跟踪当前显示界面
- 使用宏 `MAX_SCREENS` 定义支持的最大屏幕数量
- `switch_screen()` 函数作为切换入口,根据索引调用具体显示函数
2. **屏幕显示功能**:
- `show_password_screen()` 专门显示密码输入界面
- `show_main_screen()` 显示主界面(包含时间信息)
- 两个函数都先清屏再绘制新内容,避免内容重叠
3. **界面元素**:
- 使用 `OLED_ShowMultiple_Font()` 显示中文"请输入密码"
- 复用现有的 `OLED_Show_gezi()` 显示密码输入格子
- 主界面显示时间作为示例内容
4. **扩展性**:
- 模块化设计便于添加新界面(只需扩展switch_screen中的case)
- 清晰的函数分工使维护更简单
### 使用建议:
1. **添加更多界面**:
```c
case 2: // 添加新界面
show_settings_screen();
break;
```
2. **按键处理**:
在实际应用中,需要通过按键事件切换屏幕,例如:
```c
if(KEY_OK_Pressed) {
switch_screen((current_screen + 1) % MAX_SCREENS);
}
```
3. **界面布局优化**:
可根据实际屏幕尺寸调整文字和输入框位置,例如:
```c
// 显示密码提示在屏幕顶部
OLED_ShowMultiple_Font(15, 1, 16, "请输入密码");
```
阅读全文
相关推荐










