📄 clcd.c
字号:
/**********************************************************
Project : avr_lcd
Version : 1.0
Date : 2004-2-13
Author : Bleeding
Company :
Comments :
Compiler : CodeWizardAVR V1.23.8c Professional
Chip type : ATMEGA8515
Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
LCD : HD61202, 128x64
Input : 2 X 6 KeyBoard
Output : RD0--RD9 10 I/O
**********************************************************/
//#include <90s8515.h>
#include <mega8515.h>
#include <delay.h>
#include <stdio.h>
#include <math.h>
#include "clcd_hz.h"
/*LCD引脚定义 PB0-7对应LCD DB0-DB7*/
#define DI PORTB.0
#define E PORTB.1
#define RW PORTB.2
#define CS1 PORTB.6
#define CS2 PORTB.5
//#define busy PINA.7
//#define LD PORTA //lcd data
// 继电器控制引脚定义
#define RD0 PORTC.7
#define RD1 PORTC.6
#define RD2 PORTC.5
#define RD3 PORTC.4
#define RD4 PORTC.3
#define RD5 PORTC.2
#define RD6 PORTC.1
#define RD7 PORTC.0
#define RD8 PORTB.4
#define RD9 PORTB.3
#define RD (RD9*512+RD8*256+PORTC)
//键盘定义
#define Key0 PIND.0 //取消
#define Key1 PIND.1 //确认
#define Key2 PIND.4 //上
#define Key3 PIND.5 //下
#define Key4 PIND.6 //左
#define Key5 PIND.7 //右
#define sup !PIND.2 // Up status
#define sdown !PIND.3 // Down status
#define ssp !PINB.7 // Stop point
#define KO PORTD.2 //键盘输出
#define SO PORTD.3 //开关触点输出
#define KOC DDRD.2 //键盘输出
#define SOC DDRD.3 //开关触点输出
#define Key_In (PIND&0xF3)
bit M3Done,busy,test,s_up,s_down,s_sp;
unsigned char roll,old_Key,Step,old_Step,hMenu,Crusor,oldcru,KT1,KT2,Err_Msg;
unsigned char T25=24; //,lcdstatusL,lcdstatusR;
unsigned int KeyTemp;
//eeprom unsigned int kkkk;
//eeprom unsigned char lcdl,lcdr,error,mm,cc;
eeprom unsigned char empty[]={0xC3,0xBB,0xCA,0xC2,0xCD,0xB5,0xD7,0xC5,0xC0,0xD6};
eeprom unsigned int E_Time[8]={0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030};
unsigned int Time[9]={0,0,0,0,0,0,0,0,0};
unsigned int Timeset[8],tset[8];
unsigned int temp;
// unsigned char eeprom *ptr_to_eeprom;
/****************************************************************
HD61202及其兼容控制驱动器的指令系统
1 显示开/关指令
R/W D/I DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 0 0 1 1 1 1 1 1/0 3e关/3F开
当DB0=1时LCD显示RAM中的内容DB0=0时关闭显示
2 显示起始行ROW 设置指令
R/W D/I DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 1 1 显示起始行0 63
该指令设置了对应液晶屏最上一行的显示RAM的行号
有规律地改变显示起始行可以使LCD实现显示滚屏的效果
3 页PAGE 设置指令
R/W D/I DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 1 0 1 1 1 页号0 7
显示RAM共64行分8页每页8行
4 列地址Y Address 设置指令
R/W D/I DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 0 1 显示列地址0 63
设置了页地址和列地址就唯一确定了显示RAM中的一个单元,这样MPU就
可以用读写指令读出该单元中的内容或向该单元写进一个字节数据
5 读状态指令
R/W D/I DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
1 0 BUSY 0 ON/OFF REST 0 0 0 0
该指令用来查询HD61202 及其兼容控制驱动器的状态各参量含义如下
BUSY 1-内部在工作0-正常状态
ON/OFF 1-显示关闭0-显示打开
REST 1-复位状态0-正常状态
在BUSY和REST状态时除读状态指令外其它指令均不对HD61202
及其兼容控制驱动器产生作用,在对HD61202及其兼容控制驱动器操作之前
要查询BUSY状态以确定是否可以对HD61202及其兼容控制驱动器进行操作
6 写数据指令
R/W D/I DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 1 写数据
7 读数据指令
R/W D/I DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
1 1 读显示数据
读写数据指令每执行完一次读写操作,列地址就自动增一,必须注意的是
进行读操作之前必须有一次空读操作紧接着再读才会读出所要读的单元中的数据
**********************************************************************/
void LCD_NOP(void)
{
unsigned char i;
for(i=0;i<5;i++);
}
/*
void Delay(int x)
{
int i,j;
for(j=0;j<x;j++)
{
for(i=0;i<250;i++);
}
}
*/
/*
//------------ LCD左半屏读命令字 ------------//
unsigned char LCD_Read_ComL(void)
{
unsigned char x;
DDRA=0;
CS1=0;
CS2=1;
DI=0;
E=0;
LCD_NOP();
RW=1;
E=1;
LCD_NOP();
x=PINA;
E=0;
LCD_NOP();
CS1=1;
CS2=1;
// DDRA=0x00;
return x;
}
//------------ LCD右半屏读命令字 ------------//
unsigned char LCD_Read_ComR(void)
{
unsigned char x;
DDRA=0;
CS1=1;
CS2=0;
DI=0;
E=0;
RW=1;
LCD_NOP();
E=1;
LCD_NOP();
x=PINA;
E=0;
CS1=1;
CS2=1;
// DDRA=0x00;
return x;
}
//------------ LCD右半屏读数据字 ------------//
unsigned char LCD_Read_DatR(void)
{
unsigned char x;
DDRA=0;
CS1=1;
CS2=0;
DI=1;
E=0;
RW=1;
LCD_NOP();
E=1;
LCD_NOP();
x=PINA;
E=0;
LCD_NOP();
CS1=1;
CS2=1;
// DDRA=0xFF;
return x;
}
*/
//------------ LCD左半屏写命令字 ------------//
void LCD_Write_ComL(unsigned char x)
{
CS1=0;
CS2=1;
DI=0;
RW=1;
busy=1;
while(busy)
{
E=1;
LCD_NOP();
busy=PINA.7;
E=0;
LCD_NOP();
}
RW=0;
// E=1;
// LCD_NOP();
DDRA=0xFF;
E=1;
PORTA=x;
LCD_NOP();
E=0;
LCD_NOP();
CS1=1;
// CS2=1;
DDRA=0;
}
//------------ LCD左半屏写数据 ------------//
void LCD_Write_DatL(unsigned char x)
{
CS1=0;
CS2=1;
DI=0;
RW=1;
busy=1;
while(busy)
{
E=1;
LCD_NOP();
busy=PINA.7;
E=0;
LCD_NOP();
}
RW=0;
DI=1;
// E=1;
// LCD_NOP();
DDRA=0xFF;
E=1;
PORTA=x;
LCD_NOP();
E=0;
LCD_NOP();
CS1=1;
// CS2=1;
DDRA=0;
}
//------------ LCD右半屏写命令字 ------------//
void LCD_Write_ComR(unsigned char x)
{
CS1=1;
CS2=0;
DI=0;
RW=1;
busy=1;
while(busy)
{
E=1;
LCD_NOP();
busy=PINA.7;
E=0;
LCD_NOP();
}
RW=0;
// E=1;
// LCD_NOP();
DDRA=0xFF;
E=1;
PORTA=x;
LCD_NOP();
E=0;
LCD_NOP();
// CS1=1;
CS2=1;
DDRA=0;
}
//------------ LCD右半屏写数据 ------------//
void LCD_Write_DatR(unsigned char x)
{
CS1=1;
CS2=0;
DI=0;
RW=1;
busy=1;
while(busy)
{
E=1;
LCD_NOP();
busy=PINA.7;
E=0;
LCD_NOP();
}
RW=0;
DI=1;
// E=1;
// LCD_NOP();
DDRA=0xFF;
E=1;
PORTA=x;
LCD_NOP();
E=0;
LCD_NOP();
// CS1=1;
CS2=1;
DDRA=0;
}
//------------ LCD初始化 ------------//
void LCD_Init(void)
{
// LCD_Write_ComL(0x3E); //显示关指令
// LCD_Write_ComR(0x3E); //显示关指令
LCD_Write_ComL(0xC0); //显示起始行ROW 0
LCD_Write_ComR(0xC0); //显示起始行ROW 0
LCD_Write_ComL(0x3F); //显示开指令
LCD_Write_ComR(0x3F); //显示开指令
}
//------------ LCD清屏 ------------//
void LCD_Clr(void)
{
unsigned char i,j;
for(j=0;j<8;j++)
{
LCD_Write_ComL(0xb8|j); //页PAGE(j) 设置指令
LCD_Write_ComL(0x40); //列地址Y(0) Address 设置指令
LCD_Write_ComR(0xb8|j);
LCD_Write_ComR(0x40);
for(i=0;i<64;i++) //64列清0
{
LCD_Write_DatL(0x00);
LCD_Write_DatR(0x00);
}
}
}
//显示4x16字符,位置按一个点来定 x:列坐标 y:行坐标 chrx:显示字符
LCD_WrCHr4x16(unsigned char x,unsigned char y,unsigned char chrx)
{
unsigned char i;
unsigned int chr_m;
chr_m=chrx;
chr_m=chr_m*8;
if(y>=64)
{
y=y-64;
LCD_Write_ComR(0xb8|x); //页PAGE(x) 设置指令
LCD_Write_ComR(0x40|y); //列地址Y(0) Address 设置指令
for(i=0;i<4;i++)
{
LCD_Write_DatR(sym[chr_m+i]);
}
LCD_Write_ComR(0xb9|x); //页PAGE 设置指令
LCD_Write_ComR(0x40|y);
for(i=4;i<8;i++)
{
LCD_Write_DatR(sym[chr_m+i]);
}
}
else
{
LCD_Write_ComL(0xb8|x);
LCD_Write_ComL(0x40|y);
for(i=0;i<4;i++)
{
LCD_Write_DatL(sym[chr_m+i]);
}
LCD_Write_ComL(0xb9|x);
LCD_Write_ComL(0x40|y);
for(i=4;i<8;i++)
{
LCD_Write_DatL(sym[chr_m+i]);
}
}
}
//显示6x16字符,位置按一个点来定 x:列坐标 y:行坐标 chrx:显示字符
LCD_WrCHr6x16(unsigned char x,unsigned char y,unsigned char chrx)
{
unsigned char i;
unsigned int chr_m;
chr_m=chrx;
chr_m=chr_m*12;
if(y>=64)
{
y=y-64;
LCD_Write_ComR(0xb8|x); //页PAGE(x) 设置指令
LCD_Write_ComR(0x40|y); //列地址Y(0) Address 设置指令
for(i=0;i<6;i++)
{
LCD_Write_DatR(nmb[chr_m+i]);
}
LCD_Write_ComR(0xb9|x); //页PAGE 设置指令
LCD_Write_ComR(0x40|y);
for(i=6;i<12;i++)
{
LCD_Write_DatR(nmb[chr_m+i]);
}
}
else
{
LCD_Write_ComL(0xb8|x);
LCD_Write_ComL(0x40|y);
for(i=0;i<6;i++)
{
LCD_Write_DatL(nmb[chr_m+i]);
}
LCD_Write_ComL(0xb9|x);
LCD_Write_ComL(0x40|y);
for(i=6;i<12;i++)
{
LCD_Write_DatL(nmb[chr_m+i]);
}
}
}
//显示8x16字符,位置按8x8一个点来定 x:列坐标 y:行坐标 chrx:显示字符
LCD_WrCHr8x16(unsigned char x,unsigned char y,unsigned char chrx)
{
unsigned char i;
unsigned int chr_m;
chr_m=chrx;
chr_m=chr_m*16;
if(y>=8)
{
y=y-8;
LCD_Write_ComR(0xb8|x); //页PAGE(x) 设置指令
LCD_Write_ComR(0x40|y<<3); //列地址Y(0) Address 设置指令
for(i=0;i<8;i++)
{
LCD_Write_DatR(Ezk[chr_m+i]);
}
LCD_Write_ComR(0xb9|x); //页PAGE 设置指令
LCD_Write_ComR(0x40|y<<3);
for(i=8;i<16;i++)
{
LCD_Write_DatR(Ezk[chr_m+i]);
}
}
else
{
LCD_Write_ComL(0xb8|x);
LCD_Write_ComL(0x40|y<<3);
for(i=0;i<8;i++)
{
LCD_Write_DatL(Ezk[chr_m+i]);
}
LCD_Write_ComL(0xb9|x);
LCD_Write_ComL(0x40|y<<3);
for(i=8;i<16;i++)
{
LCD_Write_DatL(Ezk[chr_m+i]);
}
}
}
//显示16x16字符,位置按8x8一个点来定 x:列坐标 y:行坐标 chrx:显示字符*/
LCD_WrCHr16x16(unsigned char x,unsigned char y,unsigned char chrx)
{
unsigned char i;
unsigned int chr_m;
chr_m=chrx;
chr_m=chr_m*32;
if(y>=8)
{
y=y-8;
LCD_Write_ComR(0xb8|x);
LCD_Write_ComR(0x40|y<<3);
for(i=0;i<8;i++)
{
LCD_Write_DatR(Hzk[chr_m+i]);
}
LCD_Write_ComR(0xb8|x);
LCD_Write_ComR(0x48|y<<3);
for(i=8;i<16;i++)
{
LCD_Write_DatR(Hzk[chr_m+i]);
}
LCD_Write_ComR(0xb9|x);
LCD_Write_ComR(0x40|y<<3);
for(i=16;i<24;i++)
{
LCD_Write_DatR(Hzk[chr_m+i]);
}
LCD_Write_ComR(0xb9|x);
LCD_Write_ComR(0x48|y<<3);
for(i=24;i<32;i++)
{
LCD_Write_DatR(Hzk[chr_m+i]);
}
}
else
{
LCD_Write_ComL(0xb8|x); //页PAGE(x) 设置指令
LCD_Write_ComL(0x40|y<<3);
for(i=0;i<16;i++)
{
LCD_Write_DatL(Hzk[chr_m+i]);
}
/*
LCD_Write_ComL(0xb8|x);
LCD_Write_ComL(0x48|y<<3);
for(i=8;i<16;i++)
{
LCD_Write_DatL(Hzk[chr_m+i]);
}
*/
LCD_Write_ComL(0xb9|x);
LCD_Write_ComL(0x40|y<<3);
for(i=16;i<32;i++)
{
LCD_Write_DatL(Hzk[chr_m+i]);
}
/*
LCD_Write_ComL(0xb9|x);
LCD_Write_ComL(0x48|y<<3);
for(i=24;i<32;i++)
{
LCD_Write_DatL(Hzk[chr_m+i]);
}
*/
}
}
//------------ 显示时间参数框架 ------------//
void DispFrame(void)
{
unsigned char i;
for (i=0;i<4;i++)
{
LCD_WrCHr8x16(2*i,0,6); //write T
LCD_WrCHr8x16(2*i,8,6); //write T
LCD_WrCHr16x16(2*i,6,24); //write 秒
LCD_WrCHr16x16(2*i,14,24); //write 秒
LCD_WrCHr4x16(2*i,14,0); //write :
LCD_WrCHr4x16(2*i,78,0); //write :
LCD_WrCHr4x16(2*i,34,1); //write .
LCD_WrCHr4x16(2*i,98,1); //write .
LCD_WrCHr6x16(2*i,8,2*i+1); //write 1357
LCD_WrCHr6x16(2*i,72,2*i+2); //write 2468
}
}
//------------ 显示时间参数 ------------//
// cru 光标,crus取值10,0;10带下划线 //
void DispTime(unsigned char cru,unsigned char crus)
{
unsigned char xx,yy,tt,pp,cc;
//xx:对应时间数组
//yy:对应百\拾\个位
//tt:对应大小
//pp:PAGE地址
//CC:列地址
xx=ceil(cru/3-0.5);
yy=(2-(cru-xx*3));
tt= (tset[xx]>>(yy*4))&0x0F;
tt+= crus;
pp=2*(ceil(xx/2-0.5));
if (xx==pp)
{
cc=0;
}
else
{
cc=64;
}
switch(yy)
{
case 0: cc+=38; break;
case 1: cc+=28; break;
case 2: cc+=21; break;
default: break;
}
LCD_WrCHr6x16(pp,cc,tt); //write 时间
}
//------------ 显示步骤 ------------//
void DispStep(void)
{
unsigned char x;
if (Step<10)
{
LCD_WrCHr6x16(4,16,Step);
LCD_WrCHr6x16(4,8,0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -