durongze 发表于 2024-9-11 21:25:00

st7920学习记录

本帖最后由 durongze 于 2024-9-12 07:04 编辑

指令表 1


指 令 名 称          RS   R/W   D7D6   D5   D4   D3    D2    D1    D0                   执 行时 间
清除显示             0   0      0    0   0   0      0      0      0       1                     1.6 ms
地址归0               0   0      0    0   0   0      0      0      1       X                     72us
进入设定点          0   0      0    0   0   0      0      1   I/D   S                     72us
显示开关设置       0   0      0    0   0   0      1      D      C      B                     72us
移位控制            0   0      0    0   0   1   S/C   R/L   X   X                     72us
功能设定            0   0      0    0   1    DL    X      /RE    X      X                     72us
设定 CGRAM 地址 0   0      0    1   A5   A4   A3   A2   A1    A0                  72us
设定 DDRAM 地址 0   0      1    0   A5   A4   A3   A2   A1    A0                     72us

读忙标志和地址    0   1      BF   A6   A5   A4   A3   A2   A1    A0                  72us
写显示数据          1   0            显 示 数 据                                                      72us
读显示数据          1   1            显 示 数 据                                                      72us

durongze 发表于 2024-9-11 21:36:35

本帖最后由 durongze 于 2024-9-12 08:33 编辑

指 令 名 称          RS             R/W            D7                D6                     D5                D4                D3                D2                D1                  D0          执行时间
待命模式            0                0                   0                  0                        0                  0                  0                  0                  0                      1            72us
卷动RAM地址      0               0                   0                   0                     0                  0               0                   0               1                     SR         72us
反白显示            0                0                   0                  0                        0                   0               0                   1                R1                   R0            72us
睡眠模式            0               0                  0                   0                     0                   0               1                  SL                X                     X             72us
扩充功能设定      0                0                  0                   0                     1                  DL               X                   1/RE             G                  0            72us
IRAM 卷动地址    0                0                   0                  1                      A5                   A4               A3                  A2            A1                   A0         72us
                                                                                 0                     0                     0               A3               A2               A1                  A0
设定绘图 RAM 地址 0            0                  1                  A6                  A5                   A4                A3               A2               A1                  A0             72us

durongze 发表于 2024-9-12 07:04:24

楼1是基本指令,总共11条, 楼2是扩展指令,总共7条。

durongze 发表于 2024-9-12 08:15:15

本帖最后由 durongze 于 2024-9-12 09:18 编辑

先看管脚的连接方式:
#define LCD_Data P2    这个是数据传输的管脚,是p2端口,也就是p2的8个引脚。本例子不一定用的到,但是接上没坏处。对应8位并口模式下的db0-db7.其实4位并口模式也会用到,只是用了一半,比如db0-db3,具体怎么使用,我还不是特别理解。我们先有个印象吧。

sbit    LCD_RS = P0^1;       这个是寄存器选择配置。 这个是分两种情况的,一种是并口模式,一种是串口模式。并口模式下拉高,是指准备往db0-db7写数据,拉低是准备写命令。串口模式下拉低,代表有效
sbit    LCD_RW = P0^2;      也是分模式的,并口模式拉高是读,拉低是写。串口模式是数据线。
sbit    LCD_E= P0^3;      并口模式是使能。      串口模式是时钟线。
sbit    PSB    = P0^4;               //PSB 接高时选择并口,接低时选择串口。 这个其实放在第一个位置比较好,它控制着其他所有管脚存在的意义。
sbit    LCD_RESET   =   P4^5;   //17---RESETL-->Enable    复位信号,

#define LCD12864_SID   LCD_RW   // 见上面
#define LCD12864_SCLKLCD_E    // 见上面

然后看st7920 的初始化:
      P2 = 0;   //数据管脚p2端口的7个脚
      LCD_RS = 1; //并口模式下拉高,是指准备往db0-db7写数据,拉低是准备写命令。串口模式下拉低,代表有效
      PSB = 0;    //PSB 接高时选择并口,接低时选择串口。 这个其实放在第一个位置比较好,它控制着其他所有管脚存在的意义。
      LCD_RESET = 1;

      Delay_x10ms(4);                        
      LCD12864_Write(Write_Command,Setting_Basic_Instruction_Set);// 0x30             这个可能是功能设定,在基本指令里有功能设定,在扩展指令里也有功能设定。这个取决于当前的模式。
      Delay_x10us(10);               
      LCD12864_Write(Write_Command,Setting_Basic_Instruction_Set);// 0x30
      Delay_x10us(4);                        
      LCD12864_Write(Write_Command,Clear_Display);         // 0x01   这个对应的指令名称应该是清除显示
      Delay_x10us(10);               
      LCD12864_Write(Write_Command,Clear_Display);         // 0x01同上
      Delay_x10ms(1);                        
      LCD12864_Write(Write_Command,Entry_Mode_Cursor_Right);            // 0x06      基本命令模式下,是进入设定点,扩展模式下,是反白模式
      Delay_x10us(10);               
      LCD12864_Write(Write_Command,Display_On_Cursor_Off_Inverse_Off);    // 0x0c    基本命令模式下,是显示开关设置
      Delay_x10us(10);               
      Clear_GDRAM();                  
      Delay_x10us(10);         

durongze 发表于 2024-9-12 10:10:41

本帖最后由 durongze 于 2024-9-12 11:17 编辑

GDRAM 提供 64×32 个字节的空间(由扩充指令设定绘图 RAM 地址),最多可以控制
256×64 点阵的二维绘图缓冲空间,在更改绘图 RAM 是,由扩充指令设置 GDRAM
地址先垂直地址后水平地址(连续 2 个字节的数据来定义垂直和水平地址,其实就是先行后列),再
2 个字节的数据给绘图 RAM(先高 8 位后低 8 位)。

国学芯用 发表于 2024-9-12 10:45:01

优秀!!

晓飛飛 发表于 2024-9-12 11:05:00

这个屏还是很好用的,自带16x16汉字库、支持CGRAM自定义字符、支持反白和绘图指令

durongze 发表于 2024-9-12 11:37:47

本帖最后由 durongze 于 2024-9-12 11:38 编辑

void Clear_GDRAM(void)
{
      unsigned char i,j,k;
      LCD12864_Write(Write_Command,Setting_Extended_Instruction_Set_Drawing_Off);   // 0x34   功能设定。 高4bit是3都是功能设定。前面第一条指令是0x30,这里是0x34,注意区别。后面详细分析。
      k=0x80;
      for(i=0; i<32; i++) {
                LCD12864_Write(Write_Command,k++);//从0x80开始循环,循环32次,也就是小于0xA0, 其实就是垂直地址,也就是行。
                LCD12864_Write(Write_Command,0x80);//其实就是水平地址,也就是列
                for(j=0; j<16; j++) {
                        LCD12864_Write(Write_Data,0x00); // 8个 2 字节的数据给绘图 RAM(先高 8 位后低 8 位),也就是总共16字节, 但是为啥写的都是0x00, 算是清屏?
                }
      }
      k=0x80;
      for(i=0; i<32; i++) {
                LCD12864_Write(Write_Command,k++);//从0x80开始循环,循环32次,也就是小于0xA0, 其实就是垂直地址,也就是行。
                LCD12864_Write(Write_Command,0x88);// 其实就是水平地址,也就是列,这里为什么是0x88? 第一回写用的是0x80, 写了16字节,这里0x88 不会被覆盖吗,因为清屏不影响?
                for(j=0; j<16; j++) {
                        LCD12864_Write(Write_Data,0x00);   // 为啥写的都是0x00?
                }
      }
      LCD12864_Write(Write_Command,Setting_Extended_Instruction_Set_Drawing_On); // 0x36   功能设定。 高4bit是3都是功能设定。前面第一条指令是0x30,这里是0x36,注意区别。后面详细分析。
}

durongze 发表于 2024-9-12 11:53:39

其实上面初始化命令下发完成后,就可以直接显示数据了。现在我们来看下显示文本的流程:
void Display_Text(unsigned char code *addr) // 这个addr其实名称不太恰当,准确的说是str_addr. 不管长度,直接按屏幕长度遍历。
{
        unsigned char i;
        LCD12864_Write(Write_Command,Setting_Basic_Instruction_Set);   //0x30 功能设定, 注意:前面初始化的时候,刚开始也是0x30,但是初始化的最后做了清屏操作,清屏操作应该做了两次功能设定 一次0x34,一次0x36,这里算是切换回基本模式了。
        LCD12864_Write(Write_Command,0x80);      //设定 DDRAM 地址0x80,注意:在初始化时的清屏操作中,也有这个操作,不过当时是遍历了所有垂直地址,也就是所有行,即0x80-0xA0,
        Delay_10us();
        for(i=0; i<16; i++) {
                LCD12864_Write(Write_Data,*addr);
                addr++;
        }
        LCD12864_Write(Write_Command,0x90);      //设定 DDRAM 地址0x90 , 算是第2行。
        Delay_10us();
        for(i=0; i<16; i++) {
                LCD12864_Write(Write_Data,*addr);
                addr++;
        }
        LCD12864_Write(Write_Command,0x88);      //设定 DDRAM 地址0x88, 第一行后一半
        Delay_10us();
        for(i=0; i<16; i++) {
                LCD12864_Write(Write_Data,*addr);
                addr++;
        }
        LCD12864_Write(Write_Command,0x98);      //设定 DDRAM 地址0x98, 第二行后一半
        Delay_10us();
        for(i=0; i<16; i++) {
                LCD12864_Write(Write_Data,*addr);
                addr++;
        }
}

durongze 发表于 2024-9-12 12:33:06

通过上面的清屏和写字功能,可以看出地址的规律。写字时垂直地址(也就是行地址)就4个,第一行是0x80和0x88,第二行是0x90和0x98。而水平操作就是直接写16字节的数据。
不过就是很奇怪0x80-0x88按道理来说是8的字节的空间,却写了16字节数据,很有可能内部做了转换。把两个字节的字符合并成了一个字节的ascii码值?这个是我猜的,不一定对。
页: [1] 2
查看完整版本: st7920学习记录