⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd-8bit.c

📁 LM12864LDC 应用程序
💻 C
字号:
/*

 本程序用于图形点阵(含汉字字库)lcd 8BIT控制   
 
 使用方法:
  #asm
      .equ __lcd_data_port=0x18  ;PORTA  
      .equ __lcd_con_port=0x28  ;PORTB
      .equ __lcdcs=3
      .equ __lcdrs=4
      .equ __lcdwr=5
      .equ __lcdrd=6        
      .equ __lcdrst=7
   #endasm
   #include <LCD-8BIT.h>  
*/ 

#asm
    .equ __lcd_data_direction=__lcd_data_port-1    
    .equ __lcd_data_pin=__lcd_data_port-2
    
    .equ __lcd_con_direction=__lcd_con_port-2
    .equ __lcd_con_pin=__lcd_con_port-2
    
    .equ __lcd_cs=__lcdcs
    .equ __lcd_rs=__lcdrs
    .equ __lcd_wr=__lcdwr
    .equ __lcd_rd=__lcdrd        
    .equ __lcd_rst=__lcdrst
#endasm

#include <stdio.h> 

#pragma used+

static unsigned int _lcd_xmax,_lcd_ymax;

#pragma used-

// 延时-----------------------------------------------
void _lcd_delay(void)
{            
#asm   
    nop
    nop
#endasm
}      

void _lcd_out_data(unsigned char data)
{    
#asm
    ld r26,y   
    out __lcd_data_port,r26      
#endasm
_lcd_delay();  

#asm    
    //写使能    
    cbi __lcd_con_port,__lcd_wr
#endasm
_lcd_delay();

#asm    
    //写完成
    sbi __lcd_con_port,__lcd_wr
#endasm
_lcd_delay();
}
  
// 发送命令 --------------------------------------------------
void lcd_cmd(unsigned char reg,signed char com)
{ 
#asm
    //配置引脚为输出
    ldi r26,0xff
    out __lcd_data_direction,r26
    sbi __lcd_con_direction,__lcd_cs
    sbi __lcd_con_direction,__lcd_rs
    sbi __lcd_con_direction,__lcd_wr
    sbi __lcd_con_direction,__lcd_rd
    sbi __lcd_con_direction,__lcd_rst
#endasm 

#asm 
    //设置状态
    cbi __lcd_con_port,__lcd_rs
    sbi __lcd_con_port,__lcd_rd
    sbi __lcd_con_port,__lcd_wr
#endasm

#asm
    //片选
    cbi __lcd_con_port,__lcd_cs
#endasm
    _lcd_delay(); 

    _lcd_out_data(reg);
    _lcd_out_data(com);
    
#asm
    //取消片选
    sbi __lcd_con_port,__lcd_cs
#endasm

}

// 发送数据
void lcd_data(unsigned char data)
{
#asm
    //配置引脚
    ldi r26,0xff
    out __lcd_data_direction,r26
    sbi __lcd_con_direction,__lcd_cs
    sbi __lcd_con_direction,__lcd_rs
    sbi __lcd_con_direction,__lcd_wr
    sbi __lcd_con_direction,__lcd_rd
    sbi __lcd_con_direction,__lcd_rst
#endasm 

#asm 
    //设置状态
    sbi __lcd_con_port,__lcd_rs
    sbi __lcd_con_port,__lcd_rd
    sbi __lcd_con_port,__lcd_wr
#endasm

#asm
    //片选
    cbi __lcd_con_port,__lcd_cs
#endasm
    _lcd_delay(); 
    _lcd_out_data(data);    
#asm
    //取消片选
    sbi __lcd_con_port,__lcd_cs
#endasm
} 

static unsigned char _lcd_read_data0(void)
{ 
#asm
    cbi __lcd_con_port,__lcd_rd
#endasm
_lcd_delay();

#asm
    in r30,__lcd_data_pin 
    sbi __lcd_con_port,__lcd_rd
#endasm
_lcd_delay();  
} 



// 读数据
static unsigned char lcd_read_data()
{
 
#asm
    //配置引脚
    ldi r26,0x00
    out __lcd_data_direction,r26
    sbi __lcd_con_direction,__lcd_cs
    sbi __lcd_con_direction,__lcd_rs
    sbi __lcd_con_direction,__lcd_wr
    sbi __lcd_con_direction,__lcd_rd
    sbi __lcd_con_direction,__lcd_rst
#endasm 
    
#asm
    //片选
    cbi __lcd_con_port,__lcd_cs
#endasm 
    
#asm 
    //设置状态
    sbi __lcd_con_port,__lcd_rs
    sbi __lcd_con_port,__lcd_rd
    sbi __lcd_con_port,__lcd_wr
#endasm
_lcd_delay();

#asm
    cbi __lcd_con_port,__lcd_rd
#endasm
_lcd_delay();

#asm
    in r30,__lcd_data_pin 
    sbi __lcd_con_port,__lcd_rd
    sbi __lcd_con_port,__lcd_cs
#endasm

} 

// 读寄存器
unsigned char lcd_read_com(unsigned char comreg)
{  
//写入地址
unsigned char cmd;
#asm
    //配置引脚
    ldi r26,0xff
    out __lcd_data_direction,r26
    sbi __lcd_con_direction,__lcd_cs
    sbi __lcd_con_direction,__lcd_rs
    sbi __lcd_con_direction,__lcd_wr
    sbi __lcd_con_direction,__lcd_rd
    sbi __lcd_con_direction,__lcd_rst
#endasm 

#asm 
    //设置状态
    cbi __lcd_con_port,__lcd_rs
    sbi __lcd_con_port,__lcd_rd
    sbi __lcd_con_port,__lcd_wr
#endasm

#asm
    //片选
    cbi __lcd_con_port,__lcd_cs
#endasm
    _lcd_delay(); 
    _lcd_out_data(comreg);
    

#asm
    //配置引脚为输出
    ldi r26,0x00
    out __lcd_data_direction,r26
#endasm 

#asm 
    //设置状态
    cbi __lcd_con_port,__lcd_rs
    sbi __lcd_con_port,__lcd_rd
    sbi __lcd_con_port,__lcd_wr
#endasm

    cmd=_lcd_read_data0();
    
#asm
    //取消片选
    sbi __lcd_con_port,__lcd_cs
#endasm

return cmd;
}

//移到坐标
void lcd_gotoxy(unsigned char x,unsigned char y)
{
    lcd_cmd(0x60,x);
    lcd_cmd(0x70,y);
}

// 发送显示SRAM中的数据
void lcd_puts(unsigned char *str)
{
    do
    {   
        lcd_data(*str);
        str++;                        
    }
    while(*str!=0);
}

// 发送显示flash中的数据
void lcd_putsf(unsigned char flash *str)
{
    do
    {   
        lcd_data(*str);
        str++;                         
    }
    while(*str!=0);
}

// 整屏的写入数据
void lcd_fullscreenfill(unsigned char fill_data)
{
    unsigned char i,j;
    lcd_gotoxy(0,0);
    for(i=0;i<_lcd_ymax;i++)
    {
        for(j=0;j<(_lcd_xmax>>3);j++)
        {
            lcd_data(fill_data);
        }
    }
}


// 显示字符C
void lcd_putchar(unsigned char c)
{
    lcd_data(c);
}


// 初始化
void lcd_init(unsigned int x,unsigned int y)
{
unsigned char val=0;
unsigned char awrr,awbr,dwrr,dwbr;
#asm
    //配置引脚为输出
    ldi r26,0xff
    out __lcd_data_direction,r26
    sbi __lcd_con_direction,__lcd_cs
    sbi __lcd_con_direction,__lcd_rs
    sbi __lcd_con_direction,__lcd_wr
    sbi __lcd_con_direction,__lcd_rd
    sbi __lcd_con_direction,__lcd_rst
#endasm 
 
#asm
    //初始状态
    sbi __lcd_con_port,__lcd_rd
    sbi __lcd_con_port,__lcd_wr
    sbi __lcd_con_port,__lcd_rs
    sbi __lcd_con_port,__lcd_rst
#endasm

#asm
    //片选
    cbi __lcd_con_port,__lcd_cs
#endasm
    delay_ms(200);
    
    
    // 复位电平    
#asm
    cbi __lcd_con_port,__lcd_rst
#endasm
    delay_ms(600);
#asm
    sbi __lcd_con_port,__lcd_rst
#endasm
    delay_ms(200);
    
    _lcd_xmax=x;
    _lcd_ymax=y;
    
    // 工作视察参数的设定
    if( (x==160) &  (y==80) ){awrr=0x13;awbr=0x4f;dwrr=0x13;dwbr=0x4f;}    
    if( (x==160) & (y==128) ){awrr=0x13;awbr=0x7f;dwrr=0x13;dwbr=0x80;}    
    if( (x==160) & (y==160) ){awrr=0x13;awbr=0x9f;dwrr=0x13;dwbr=0x9f;}       
    if( (x==240) &  (y==64) ){awrr=0x1d;awbr=0x3f;dwrr=0x1d;dwbr=0x3f;}       
    if( (x==240) & (y==128) ){awrr=0x1d;awbr=0x7f;dwrr=0x1d;dwbr=0x80;}      
    if( (x==240) & (y==160) ){awrr=0x1d;awbr=0x9f;dwrr=0x1d;dwbr=0x9f;}        
    if( (x==320) & (y==240) ){awrr=0x27;awbr=0xef;dwrr=0x27;dwbr=0xef;}       
    
    // 工作窗口设定
    lcd_cmd(0x20,awrr);
    lcd_cmd(0x30,dwbr);    
    lcd_cmd(0x40,0x00);
    lcd_cmd(0x50,0x00);
    
    // 显示窗口设定
    lcd_cmd(0x21,awrr);
    lcd_cmd(0x31,dwbr);
    lcd_cmd(0x41,0x00);
    lcd_cmd(0x51,0x00);
    
    // CPXR X方向光标寄存器
    lcd_cmd(0x60,0x00);    
    
    // CPYR Y方向光标寄存器
    lcd_cmd(0x70,0x00);    
    
        
/*************************************************************************************
 WLCR 控制寄存器

 7/6 电源模式 11-正常,00-关闭
 5 软件复位   1-重置所有缓存器, 0-正常
 4 保留
 3 显示模式   1-文本 0-图形
 2 显示开关   1-开 0-关
 1 闪烁控制   1-整屏闪烁 0-正常
 0 负向显示   1-正常 0-负向显示
*************************************************************************************/
val=0;
val= (0b11<<6)  | (0<<5) | (0<<4) | (1<<3) | (1<<2) | (0<<1)| 1;
lcd_cmd(0x00,val);                                                                    


/*************************************************************************************
 MISC 时钟控制

 7 保留
 6 时钟输出控制 1-允许 0-禁止
 5 保留
 4 中断/忙标志的触发位设定 1-高电平 0-低电平
 3-2 保留
 1-0 系统时钟选择 00-3MHz  01-4MHz  10-8MHz  11-12MHz
*************************************************************************************/
val=0;
val= (0<<6) | (0<<4) | 0b10;
lcd_cmd(0x01,val);                                                                    


/*************************************************************************************     
 WCCR 光标控制寄存器,直接给DDDRAM发送数据,地址自动+1,光标宽度为自动 

 7 读DDRM时光标是否自动移位 1-Y 0-N
 6 中/英文文字对齐 1-Y 0-N
 5 正反相存储数据  1-正相 0-反相
 4 粗体设置        1-粗体 0-正常
 3 写DDRM时光标是否自动移位 1-Y 0-N
 2 光标是否显示   `1-Y 0-N
 1 光标是否闪烁    1-Y 0-N
 0 光标宽度模式 1-自动调整 0-固定8Pixel
*************************************************************************************/ 
val=0;
val= (0<<7) | (0<<6) | (1<<5) | (0<<4) | (1<<3) | (0<<2) | (0<<1)| 1;
lcd_cmd(0x10,val);                                                                     


/*************************************************************************************     
 DWLR 光标大小控制寄存器 
 
 7-4 设定光标高度 
 3-0 设定行与行的距离
*************************************************************************************/ 
val=0;
val =  (2<<4) | 0;
lcd_cmd(0x11,val);  

/*************************************************************************************
 MAMR 
 7 图形模式时,光标自动移位方向 1-先水平 0-先垂直
 6-4 图层显示模式 000-灰阶,001-显示Page1 010-显示Page2 011-同时显示Page1和Page2
 3-2 双层显示时图层逻辑关系 00-OR 01-XOR 10-NOR 11-AND
 1-0 设定读写图层 00-存取Page0 01-存取Page0 10-存取Page1 11-存取Page0/1
*************************************************************************************/ 
val=0;
val = (0<<7) | (0b001<<4) | (0b00<<2) | 0b01;
lcd_cmd(0x12,val);   

/*******************************************************
// BTMR 闪烁时间寄存器                                 
 闪烁时间=[80H] * (1/Frame_Rate) 
 Frame_Rate 的高定是通常依照LCD面板所提供的最佳值
*****************************************************/
lcd_cmd(0x80,0x2e);
 
                  
/***********************************************************************
// SCCR 工作时钟                                            
 SCCR = (SCLK * DW) / (Seg * Com * FRM)           
 SCLK RA8803系统频率 单位:Hz
 DW 驱动器的数据总线宽度 单位:Bit
 Seg 面板的Seg大小 单位:Pixel
 Com 面板的Com大小 单位:Pixel
 FRM 面板的Frame Rate大小 单位:Hz

 限制: 
 DW=0 DW=4时,SCCR>=4
 DW=1 DW=8时,SCCR>=2
*****************************************************/   
lcd_cmd(0x90,0x04);    

// INTR
lcd_cmd(0xa0,0x00);  
                      
/********************************************************
// PNTR 数据模式寄存器                                 
 当F0H中的bit3为'1',将自动读取本缓存器E0H的数据,然后全部填写到DDRAM内,
 之后F0H中的bit3被清除为'0'
 
 在灰阶模式下 bit[6-4]=000,用来控制灰阶显示效果 
*****************************************************/
lcd_cmd(0xe0,0x00); 

/********************************************************
 FNCR 字体控制寄存器
 7 字型ROM转换 1-使能 0-禁止
 6 字型ROM的地址空间选择 1-下部256KB 0-上部256KB
 5-4 字型ROM的选择 00-简体256K  01-繁体256K 10-简体512K
 3 填写PNTR的数据到DDRAM 1-开始写入 0-未动作
 2 强制为ASCII解码 1-是 0-否
 1-0 ASCII区块选择 00-区块0  01-区块1  10-区块2  11-区块3
*****************************************************/
val=0;
val = (1<<7) | (0<<6) | (0b10<<4) | (0<<3) | (0<<2) | 0b00;
lcd_cmd(0xf0,val);          

/********************************************************
 FVHT 字体大小
 7-6 水平方向的大小 00-1倍  00-2倍  00-3倍  00-4倍
 5-4 垂直方向的大小 00-1倍  00-2倍  00-3倍  00-4倍
 3-0 =1111    
****************************************************/
val=0;
val = (0b00<<6) | (0b00<<4) | 0b1111;
lcd_cmd(0xf1,val); 

delay_ms(50);    

}


// 选择工作图层
void lcd_worklayer(unsigned char n)
{
unsigned char a; 
// 读取MAMR
a = lcd_read_com(0x12);
// 清除工作层设置位
a = a & 0b11111100; 
// 重新设置工作层   
lcd_cmd(0x12,a | n); 
}

// 显示图层设置
void lcd_viewlayer(unsigned char m)
{ 
unsigned char a; 
// 读取MAMR
a = lcd_read_com(0x12);
// 清除工作层设置位
a = a & 0b10000011; 
// 重新设置工作层   
lcd_cmd(0x12,(a | m) );                   
}

// LCD清屏
void lcd_cls(unsigned char page)
{
lcd_worklayer(page);
lcd_fullscreenfill(0x00);
}  

// 设置为文本模式
void lcd_asc()
{  
unsigned char a;      
// 读取WLCR
a = lcd_read_com(0x00);

// 重新设置   
lcd_cmd(0x00,a | (1<<3)); 
}

// 设置为图形模式
void lcd_pic()
{            
unsigned char a;
// 读取WLCR
a = lcd_read_com(0x00);

// 重新设置   
lcd_cmd(0x00,a & (~(1<<3)) ); 
}

// 在屏幕中指定位置显示一个点
void lcd_viewpiont(unsigned int x,unsigned char y)
{
unsigned char lx,ly,cx,t; 
if( (x<_lcd_xmax) & (y<_lcd_ymax) )
    {
    lx=x>>3;
    cx=x-(lx<<3);
    ly=y;
    
    lcd_gotoxy(lx,ly);
    t=lcd_read_data();
    lcd_data( t | (0x80>>cx) );
    }
}  

// 在屏幕中清除指定位置的点
void lcd_clspiont(unsigned int x,unsigned char y)
{
unsigned char lx,ly,cx,t; 
if( (x<_lcd_xmax) & (y<_lcd_ymax) )
    {
    lx=x>>3;
    cx=x-(lx<<3);
    ly=y;
    
    lcd_gotoxy(lx,ly);
    t=lcd_read_data();
    lcd_data( t & (~(0x80>>cx)) );
    }

}  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -