找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1391|回复: 22
收起左侧

0.96oled显示滚动条怎么写反显函数

[复制链接]
ID:302293 发表于 2023-10-16 10:30 | 显示全部楼层 |阅读模式
   iic的例程里面的反显函数,都是字体反白的,怎么写滚动条,在菜单里面滚动显示。
回复

使用道具 举报

ID:69038 发表于 2023-10-16 14:27 | 显示全部楼层
在调的显示字符串函数中,传递一个反白显示的参数,并层层传递到打点显示的函数里,把字符数据取反就成了。
回复

使用道具 举报

ID:302293 发表于 2023-10-17 15:42 | 显示全部楼层
请教一下,哪个函数可以实现反显,移动菜单项目显示滚动条
#include "OLED_I2C.h"
#include "delay.h"
#include "codetab.h"
u8 OLED_GRAM[128][8];
extern unsigned char character[];

void IIC_Start()
{

        OLED_SCLK_Set() ;
        OLED_SDIN_Set();
        OLED_SDIN_Clr();
        OLED_SCLK_Clr();
}

/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
    OLED_SCLK_Set() ;
//        OLED_SCLK_Clr();
        OLED_SDIN_Clr();
        OLED_SDIN_Set();
       
}

void IIC_Wait_Ack()
{

        //GPIOB->CRH &= 0XFFF0FFFF;        //设置PB12为上拉输入模式
        //GPIOB->CRH |= 0x00080000;
//        OLED_SDA = 1;
//        delay_us(1);
        //OLED_SCL = 1;
        //delay_us(50000);
/*        while(1)
        {
                if(!OLED_SDA)                                //判断是否接收到OLED 应答信号
                {
                        //GPIOB->CRH &= 0XFFF0FFFF;        //设置PB12为通用推免输出模式
                        //GPIOB->CRH |= 0x00030000;
                        return;
                }
        }
*/
        OLED_SCLK_Set() ;
        OLED_SCLK_Clr();
}
/**********************************************
// IIC Write byte
**********************************************/

void Write_IIC_Byte(unsigned char IIC_Byte)
{
        unsigned char i;
        unsigned char m,da;
        da=IIC_Byte;
        OLED_SCLK_Clr();
        for(i=0;i<8;i++)               
        {
                        m=da;
        OLED_SCLK_Clr();
                m=m&0x80;
                if(m==0x80)
                {
               
                 OLED_SDIN_Set();
               
                }
                else OLED_SDIN_Clr();
                        da=da<<1;
                OLED_SCLK_Set();
                OLED_SCLK_Clr();
                }


}
/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
   IIC_Start();
   Write_IIC_Byte(0x78);            //Slave address,SA0=0
         IIC_Wait_Ack();       
   Write_IIC_Byte(0x00);                        //write command
         IIC_Wait_Ack();       
   Write_IIC_Byte(IIC_Command);
         IIC_Wait_Ack();       
   IIC_Stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
   IIC_Start();
   Write_IIC_Byte(0x78);                        //D/C#=0; R/W#=0
         IIC_Wait_Ack();       
   Write_IIC_Byte(0x40);                        //write data
         IIC_Wait_Ack();       
   Write_IIC_Byte(IIC_Data);
         IIC_Wait_Ack();       
   IIC_Stop();
}

void WriteCmd(unsigned char I2C_Command)//写命令
{
        Write_IIC_Command(I2C_Command);
}

void WriteDat(unsigned char I2C_Data)//写数据
{
        Write_IIC_Data(I2C_Data);
}

void OLED_Init(void)
{
   
  GPIO_InitTypeDef  GPIO_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);         //使能A端口时钟
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;         
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
        GPIO_Init(GPIOC, &GPIO_InitStructure);          //初始化GPIOD3,6
        GPIO_SetBits(GPIOC,GPIO_Pin_13|GPIO_Pin_14);       
   
        delay_ms(100); //这里的延时很重要
       
        WriteCmd(0xAE); //display off
        WriteCmd(0x20);        //Set Memory Addressing Mode       
        WriteCmd(0x10);        //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
        WriteCmd(0xb0);        //Set Page Start Address for Page Addressing Mode,0-7
        WriteCmd(0xc8);        //Set COM Output Scan Direction
        WriteCmd(0x00); //---set low column address
        WriteCmd(0x10); //---set high column address
        WriteCmd(0x40); //--set start line address
        WriteCmd(0x81); //--set contrast control register
        WriteCmd(0x0f); //亮度调节 0x00~0xff
        WriteCmd(0xa1); //--set segment re-map 0 to 127
        WriteCmd(0xa6); //--set normal display
        WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
        WriteCmd(0x3F); //
        WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
        WriteCmd(0xd3); //-set display offset
        WriteCmd(0x00); //-not offset
        WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
        WriteCmd(0xf0); //--set divide ratio
        WriteCmd(0xd9); //--set pre-charge period
        WriteCmd(0x22); //
        WriteCmd(0xda); //--set com pins hardware configuration
        WriteCmd(0x12);
        WriteCmd(0xdb); //--set vcomh
        WriteCmd(0x20); //0x20,0.77xVcc
        WriteCmd(0x8d); //--set DC-DC enable
        WriteCmd(0x14); //
        WriteCmd(0xaf); //--turn on oled panel
}

void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标
{
        WriteCmd(0xb0+y);
        WriteCmd(((x&0xf0)>>4)|0x10);
        WriteCmd((x&0x0f)|0x01);
}

void OLED_Fill(unsigned char fill_Data)//全屏填充
{
        unsigned char m,n;
        for(m=0;m<8;m++)
        {
                WriteCmd(0xb0+m);                //page0-page1
                WriteCmd(0x00);                //low column start address
                WriteCmd(0x10);                //high column start address
                for(n=0;n<128;n++)
                        {
                                WriteDat(fill_Data);
                        }
        }
}

void OLED_CLS(void)//清屏
{
        OLED_Fill(0x00);
}

//--------------------------------------------------------------
// Prototype      : void OLED_ON(void)
// Calls          :
// Parameters     : none
// Description    : 将OLED从休眠中唤醒
//--------------------------------------------------------------
void OLED_ON(void)
{
        WriteCmd(0X8D);  //设置电荷泵
        WriteCmd(0X14);  //开启电荷泵
        WriteCmd(0XAF);  //OLED唤醒
}

//--------------------------------------------------------------
// Prototype      : void OLED_OFF(void)
// Calls          :
// Parameters     : none
// Description    : 让OLED休眠 -- 休眠模式下,OLED功耗不到10uA
//--------------------------------------------------------------
void OLED_OFF(void)
{
        WriteCmd(0X8D);  //设置电荷泵
        WriteCmd(0X10);  //关闭电荷泵
        WriteCmd(0XAE);  //OLED休眠
}
void OLED_Set_Pos(unsigned char x, unsigned char y)
{                 WriteCmd(0xb0+y);
                  WriteCmd(((x&0xf0)>>4)|0x10);
            WriteCmd((x&0x0f));
}       
//--------------------------------------------------------------
// Prototype      : void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
// Calls          :
// Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); ch[] -- 要显示的字符串; TextSize -- 字符大小(1:6*8 ; 2:8*16)
// Description    : 显示codetab.h中的ASCII字符,有6*8和8*16可选择
//--------------------------------------------------------------
void OLED_ShowStr(unsigned char x, unsigned char y,  char ch[], unsigned char TextSize)
{
        unsigned char c = 0,i = 0,j = 0;
        switch(TextSize)
        {
                case 1:
                {
                        while(ch[j] != '\0')
                        {
                                c = ch[j] - 32;
                                if(x > 126)
                                {
                                        x = 0;
                                        y++;
                                }
                                OLED_SetPos(x,y);
                                for(i=0;i<6;i++)
                                        WriteDat(F6x8[c][i]);
                                x += 6;
                                j++;
                        }
                }break;
                case 2:
                {
                        while(ch[j] != '\0')
                        {
                                c = ch[j] - 32;
                                if(x > 120)
                                {
                                        x = 0;
                                        y++;
                                }
                                OLED_SetPos(x,y);
                                for(i=0;i<8;i++)
                                        WriteDat(F8X16[c*16+i]);
                                OLED_SetPos(x,y+1);
                                for(i=0;i<8;i++)
                                        WriteDat(F8X16[c*16+i+8]);
                                x += 8;
                                j++;
                        }
                }break;
        }
}
void OLED_ShowStr1(unsigned char x, unsigned char y,  char ch[], unsigned char TextSize)
{
        unsigned char c = 0,i = 0,j = 0;
        switch(TextSize)
        {
                case 1:
                {
                        while(ch[j] != '\0')
                        {
                                c = ch[j] - 32;
                                if(x > 126)
                                {
                                        x = 0;
                                        y++;
                                }
                                OLED_SetPos(x,y);
                                for(i=0;i<6;i++)
                                        WriteDat(F6x8[c][i]);
                                x += 6;
                                j++;
                        }
                }break;
                case 2:
                {
                        while(ch[j] != '\0')
                        {
                                c = ch[j] - 32;
                                if(x > 120)
                                {
                                        x = 0;
                                        y++;
                                }
                                OLED_SetPos(x,y);
                                for(i=0;i<8;i++)
                                        WriteDat(~F8X16[c*16+i]);
                                OLED_SetPos(x,y+1);
                                for(i=0;i<8;i++)
                                        WriteDat(~F8X16[c*16+i+8]);
                                x += 8;
                                j++;
                        }
                }break;
        }
}
void OLED_ShowoneStr(unsigned char x, unsigned char y,char ch)
{
        unsigned char c = 0,i = 0;
        c = ch - 32;
        OLED_SetPos(x,y);
        for(i=0;i<8;i++)
        WriteDat(F8X16[c*16+i]);
        OLED_SetPos(x,y+1);
        for(i=0;i<8;i++)
        WriteDat(F8X16[c*16+i+8]);
}

//--------------------------------------------------------------
// Prototype      : void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
// Calls          :
// Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); N:汉字在codetab.h中的索引
// Description    : 显示codetab.h中的汉字,16*16点阵
//--------------------------------------------------------------
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{
        unsigned char wm=0;
        unsigned int  adder=32*N;
        OLED_SetPos(x , y);
        for(wm = 0;wm < 16;wm++)
        {
                WriteDat(F16x16[adder]);
                adder += 1;
        }
        OLED_SetPos(x,y + 1);
        for(wm = 0;wm < 16;wm++)
        {
                WriteDat(F16x16[adder]);
                adder += 1;
        }
}
u8 OLED_findoneCN(u8 ch1,u8 ch2)
{
        u8 j=0;
        while(character[j]!='\0')
        {
                if(ch1==character[j]&&ch2==character[j+1])
                        return j/2+1;
                j+=2;
        }
        return 0;
}

void OLED_Show(u8 x, u8 y,u8 ch[])
{
        int j=0,k;       
        while(ch[j] != '\0')
        {
                if(ch[j]>0x80)//汉字
                {
                        k=OLED_findoneCN(ch[j],ch[j+1]);
                        if(k!=0)OLED_ShowCN(j*8+x,y,k-1);
                        j+=2;               
                }
                else//ASCLL
                {
                        OLED_ShowoneStr(j*8+x,y,ch[j]);
                        j++;
                }               
        }
}
void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
        u8 pos,bx,temp=0;
        if(x>127||y>63)return;//超出范围了.
        pos=7-y/8;                        //这段代码可以写成以下样子
        bx=y%8;                           //if(t)OLED_GRAM[x][7-y/8]|=1<<(7-y%8);
        temp=1<<(7-bx);                   //if(t)OLED_GRAM[x][7-y/8]|=~(1<<(7-y%8));
        if(t)OLED_GRAM[x][pos]|=temp;
        else OLED_GRAM[x][pos]&=~temp;            
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示                                 
//size:选择字体 16/12
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)
{                                  
        u8 temp,t,t1;
        u8 y0=y;
        u8 csize=(size/8+((size%8)?1:0))*(size/2);                //得到字体一个字符对应点阵集所占的字节数
        chr=chr-' ';//得到偏移后的值                 
    for(t=0;t<csize;t++)
    {   
                if(size==12)temp=F6x8[chr][t];                  //调用1206字体
//                else if(size==16)temp=asc2_1608[chr][t];        //调用1608字体
//                else if(size==24)temp=asc2_2412[chr][t];        //调用2412字体
                else return;                                                                //没有的字库
        for(t1=0;t1<8;t1++)
                {
                        if(temp&0x80)OLED_DrawPoint(x,y,mode);
                        else OLED_DrawPoint(x,y,!mode);
                        temp<<=1;
                        y++;
                        if((y-y0)==size)
                        {
                                y=y0;
                                x++;
                                break;
                        }
                }           
    }         
}


回复

使用道具 举报

ID:69038 发表于 2023-10-18 09:41 | 显示全部楼层
sr861126 发表于 2023-10-17 15:42
请教一下,哪个函数可以实现反显,移动菜单项目显示滚动条
#include "OLED_I2C.h"
#include "delay.h"

void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
        u8 pos,bx,temp=0;
        if(x>127||y>63)return;//超出范围了.
        pos=7-y/8;                        //这段代码可以写成以下样子
        bx=y%8;                           //if(t)OLED_GRAM[x][7-y/8]|=1<<(7-y%8);
        temp=1<<(7-bx);                   //if(t)OLED_GRAM[x][7-y/8]|=~(1<<(7-y%8));
       if(t)OLED_GRAM[x][pos]|=temp;    //这2行就是正反显了
        else OLED_GRAM[x][pos]&=~temp;  //这2行就是正反显了

回复

使用道具 举报

ID:1034262 发表于 2023-10-18 15:42 | 显示全部楼层
取反一下就行了
回复

使用道具 举报

ID:302293 发表于 2023-10-18 17:57 | 显示全部楼层
zhuls 发表于 2023-10-18 09:41
void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
        u8 pos,bx,temp=0;

按键控制索引号上下移动,这个函数怎么添加变量呢?
回复

使用道具 举报

ID:69038 发表于 2023-10-19 09:10 | 显示全部楼层
sr861126 发表于 2023-10-18 17:57
按键控制索引号上下移动,这个函数怎么添加变量呢?

这个要刷新显示数据的,
从:
〖1、00000〗
〖2、00000〗
〖3、00000〗
【4、00000】
到:
〖1、00000〗
【2、00000】
〖3、00000〗
〖4、00000〗
就要刷新第2行和第4行的当数据
回复

使用道具 举报

ID:651494 发表于 2023-10-19 10:22 | 显示全部楼层
发个武功秘籍给你,用这个GUI,基本你能想到的都可以实现

ZLG_GUI.rar

34.51 KB, 下载次数: 14

回复

使用道具 举报

ID:302293 发表于 2023-10-20 18:11 | 显示全部楼层
feeling1791 发表于 2023-10-19 10:22
发个武功秘籍给你,用这个GUI,基本你能想到的都可以实现

多谢,我看看,不明白的再请教了
回复

使用道具 举报

ID:302293 发表于 2023-10-20 18:25 | 显示全部楼层
zhuls 发表于 2023-10-19 09:10
这个要刷新显示数据的,
从:
〖1、00000〗

  刷新就是清空上一次显示的吗?
回复

使用道具 举报

ID:69038 发表于 2023-10-21 09:10 | 显示全部楼层
sr861126 发表于 2023-10-20 18:25
刷新就是清空上一次显示的吗?

就“刷新”而言,如果新的内容占位(字符串长度)大于旧的内容,直接写入就行了。反之要先清除旧内容,再写入新内容。否则会出现显示残留、花屏、乱码==。
回复

使用道具 举报

ID:302293 发表于 2023-10-23 08:24 | 显示全部楼层

  师傅,我的意思是光标显示位置反白,不是字体反白
回复

使用道具 举报

ID:302293 发表于 2023-10-23 09:12 | 显示全部楼层
zhuls 发表于 2023-10-16 14:27
在调的显示字符串函数中,传递一个反白显示的参数,并层层传递到打点显示的函数里,把字符数据取反就成了。

我要显示光标上下翻动,显示白色滚动条,该怎么设置函数
回复

使用道具 举报

ID:69038 发表于 2023-10-23 13:40 | 显示全部楼层
sr861126 发表于 2023-10-23 09:12
我要显示光标上下翻动,显示白色滚动条,该怎么设置函数

不太明白你说的意思。
比如12864,只能显示汉字 4行*8字,你想要的:
是有5行*8字的内容,通过按键,显示一、二、三、四行或二、三、四、五行的内容?
还是当有5行*8字的内容,在屏幕的右侧出现类似WINDOWS的滚动条,少于5行则不显示?
还是光标在第一行时,第一行字符反显,通过按键移动到第二行时,第二行字符反显,第一行变回正显?
还是就光标所在的位置闪烁(反显+正显交替)?
还是其它什么的,能配图说明一下吗?
回复

使用道具 举报

ID:302293 发表于 2023-10-24 10:50 | 显示全部楼层
zhuls 发表于 2023-10-23 13:40
不太明白你说的意思。
比如12864,只能显示汉字 4行*8字,你想要的:
是有5行*8字的内容,通过按键,显 ...

光标发白是,光标移动到菜单项反白,字体不反白还是黑色的
回复

使用道具 举报

ID:1097071 发表于 2023-10-24 11:01 | 显示全部楼层
zhuls 发表于 2023-10-16 14:27
在调的显示字符串函数中,传递一个反白显示的参数,并层层传递到打点显示的函数里,把字符数据取反就成了。

是的是的
回复

使用道具 举报

ID:1097071 发表于 2023-10-24 11:02 | 显示全部楼层
sr861126 发表于 2023-10-18 17:57
按键控制索引号上下移动,这个函数怎么添加变量呢?

用iCloud
回复

使用道具 举报

ID:302293 发表于 2023-10-24 11:22 | 显示全部楼层
zhuls 发表于 2023-10-23 13:40
不太明白你说的意思。
比如12864,只能显示汉字 4行*8字,你想要的:
是有5行*8字的内容,通过按键,显 ...

   中景园的反白,有图片。具体是怎么执行的可以写个函数吗?

滚动反白如图

滚动反白如图
回复

使用道具 举报

ID:69038 发表于 2023-10-24 11:42 | 显示全部楼层
sr861126 发表于 2023-10-24 11:22
中景园的反白,有图片。具体是怎么执行的可以写个函数吗?

如果只是这样,那就依我之前说的:
“在调的显示字符串函数中,传递一个反白显示的参数,并层层传递到打点显示的函数里,把字符数据取反就成了。”
在汉显函数“中景园电子科技”时,把反白标志置位,并原样传送到最底层的打点函数里就可以了。
回复

使用道具 举报

ID:69038 发表于 2023-10-24 14:00 | 显示全部楼层
这段代码给你参考一下,改自你贴上来的代码:
  1. //--------------------------------------------------------------
  2. // 描述    :  显示一个中文字符,字符数据在codetab.h中的F16x16[]数组,16*16点阵
  3. // 参数 x,y:  起始点坐标,取值范围x:0~119, y:0~6, 16*16汉字,占用2个页所以y只能到6页,7页会出错,x同理。
  4. // 参数   N:  汉字在codetab.h中的索引;
  5. // 参数 inv:  反显标志,0为正显,1为反显
  6. //--------------------------------------------------------------
  7. void OLED_Show_Chinese_char(unsigned char x, unsigned char y, unsigned char N, bit inv)
  8. {
  9.         unsigned char wm=0;
  10.         unsigned int  adder=32*N;
  11.         OLED_SetPos(x , y);
  12.         for(wm = 0;wm < 16;wm++)
  13.         {
  14.                 if(inv) WriteDat(~(F16x16[adder])); //反显
  15.                 else    WriteDat(F16x16[adder]);    //正显
  16.                 adder += 1;
  17.         }
  18.         OLED_SetPos(x,y + 1);
  19.         for(wm = 0;wm < 16;wm++)
  20.         {
  21.                 if(inv) WriteDat(~(F16x16[adder]));//反显
  22.                 else    WriteDat(F16x16[adder]);   //正显
  23.                 adder += 1;
  24.         }
  25. }
复制代码


回复

使用道具 举报

ID:1097455 发表于 2023-10-27 10:25 | 显示全部楼层
你查一下OLED的显示屏指令集,指令集是有的
回复

使用道具 举报

ID:302293 发表于 2024-1-17 14:22 | 显示全部楼层
zhuls 发表于 2023-10-23 13:40
不太明白你说的意思。
比如12864,只能显示汉字 4行*8字,你想要的:
是有5行*8字的内容,通过按键,显 ...

  楼主,我发了一张图,就是光标索引上下移动,显示反白
回复

使用道具 举报

ID:302293 发表于 2024-2-27 15:15 | 显示全部楼层
zhuls 发表于 2023-10-21 09:10
就“刷新”而言,如果新的内容占位(字符串长度)大于旧的内容,直接写入就行了。反之要先清除旧内容,再写 ...

  按键按下,索引反白显示上下移动,不刷新可以正常显示,有些是做到了,函数该怎么写
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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