📄 hzmmi._c
字号:
#include "hzmmi.h"
#define __main__
#define T_RELOAD (10000-1) //1.000ms @10MHz,毫秒定时器用
void init1(void); //初始化子程序
void run_1s(void); //1秒任务
void dlyms(word ms); //毫秒级延时函数
void delly(word ns); //毫秒级延时函数
void str_hz(byte row,byte col,byte *str); //显示汉字串及大ASCII串
void wait_disp(void); //液晶忙等待
void write_order(byte order); //对液晶发送命令码
void write_data(byte data); //向LCD送数据码(ASCII码)
void init_disp_nocls(void); //对液晶初始化,不清屏
void cls(void); //清屏
void init_disp(void); //对液晶初始化,清屏
void str_sasc(byte row,byte col,byte *str); //显示小ASCII串
void disp_face(void); //显示首页
void full(void);
void write_data(byte data);
void write_data_auto(byte data);
void wait_disp_auto(void);
word sec_num; //1秒任务计时器
word mstimer1; //毫秒延时计数
word mstimer3; //串口发送延时
byte ctl_data;
LIB_ADDR lib_addr;
byte disp_buffer[128]; //显示缓冲区
byte flag;
//主程序调用了上电复位进程,键盘进程,事件进程;
void main(void)
{
word i,j;
byte *pt;
flag=1;
init1();
init_disp();
disp_face();
// dlyms(4000);
for(;;){
if(sec_num>1000) {
if(flag){
flag=0;
disp_face();
}
else{
flag=1;
cls();
}
run_1s();
}
asm("wdr"); //软看门狗复位
}
}
//1秒任务
void run_1s(void)
{
sec_num=0;
PORTE^=RUN_LAMP;
PORTG|=EL_ON;
}
//初始化
void init1(void)
{
//定时器初始化
MCUCR=0x80;//enable the External Memory
XMCRA=0x0e;
XMCRB=0x80;
TCCR1A=0;
TCCR1B=0x09; // ctc1=1,ck/1
TIMSK=0x10; // TIME1B COMPEAR INT OK
OCR1AH=(byte)(T_RELOAD/256);
OCR1AL=(byte)T_RELOAD;
//液晶口初始化
DDRB=0x00; //键盘输入
DDRD=0xff; //LCD控制
DDRE=0x0f;
DDRF=0x0f; //LIB为输出
DDRG=0x18;
asm("sei");
}
#pragma interrupt_handler int_timer0:13 //定义中断向量
void int_timer0(void) //定时器延时器中断,1ms中断一次
{
asm("cli"); //关中断
OCR1AH=(byte)(T_RELOAD/256);
OCR1AL=(byte)T_RELOAD;
sec_num++; //秒计时+1
if(mstimer1>0) mstimer1--;
// if(mstimer2>0) mstimer2--;
asm("sei"); //中断允许
}
void disp_face(void)
{
byte i;
cls();
strcpy(disp_buffer,"靶靶靶靶靶靶靶靶靶靶靶靶");
str_hz(0,0,disp_buffer);
strcpy(disp_buffer,"啊啊啊阿阿阿埃123456");
str_hz(16,0,disp_buffer);
strcpy(disp_buffer,"靶把耙班搬办绊绑棒磅");
str_hz(32,0,disp_buffer);
strcpy(disp_buffer,"欢迎使用电流继电器电");
str_hz(48,0,disp_buffer);
}
//毫秒级延时函数
void dlyms(word ms)
{
mstimer1=ms;
while(mstimer1){
asm("wdr"); //软看门狗复位
// PORTB^=WDG; //硬看门狗复位
}
}
//延时函数
void delly(word ns)
{
byte i;
for(i=0;i<ns;i++){
asm("wdr"); //软看门狗复位
// PORTB^=WDG; //硬看门狗复位
}
}
//液晶忙等待
void wait_disp(void)
{
byte flag;
PORTD|=LCD_ID; //CD=1
PORTD|=LCD_ID; //CD=1
PORTD&=~LCD_CS; //CE=0
PORTD&=~LCD_CS; //CE=0
PORTD&=~LCD_CS; //CE=0
for(;;)
{
asm("nop");
asm("nop");
asm("nop");
flag=*(byte*)0x8000;
if((flag & LCD_BUSY_S0) && (flag & LCD_BUSY_S1)) //判断液晶忙否?
{
PORTD|=LCD_CS|LCD_ID; //CE=1,ID=1
PORTD|=LCD_CS|LCD_ID; //CE=1,ID=1
return;
}
asm("nop");
asm("nop");
asm("nop");
}
}
//对液晶发送命令码
void write_order(byte order)//对液晶发送命令码
{
byte *pt;
wait_disp();
PORTD|=LCD_ID; //CD=1
PORTD|=LCD_ID; //CD=1
PORTD|=LCD_ID; //CD=1
PORTD&=~LCD_CS; //CS=0
PORTD&=~LCD_CS; //CS=0
PORTD&=~LCD_CS; //CS=0
*(byte*)0x8000=order; //命令码
PORTD|=LCD_CS; //CS=1
PORTD|=LCD_CS; //CS=1
PORTD|=LCD_CS; //CS=1
PORTD&=~LCD_ID; //CD=0
PORTD&=~LCD_ID; //CD=0
PORTD&=~LCD_ID; //CD=0
}
void write_data(byte data)
{
byte *pt;
wait_disp();
PORTD&=~LCD_ID; //CD=0
PORTD&=~LCD_ID; //CD=0
PORTD&=~LCD_ID; //CD=0
PORTD&=~LCD_CS; //CS=0
PORTD&=~LCD_CS; //CS=0
PORTD&=~LCD_CS; //CS=0
*(byte*)0x8000=data; //命令码
PORTD|=LCD_CS; //CS=1
PORTD|=LCD_CS; //CS=1
PORTD|=LCD_CS; //CS=1
}
//清屏
void cls(void)
{
int i;
write_data(00); //设置显示储存器首地址
write_data(00);
write_order(0x24);
write_order(0xb0); //设置自动写方式
wait_disp();
for(i=0;i<8000;i++) //8k显示存储器填00
{
write_data_auto(0x00);
}
write_order(0xb2);
}
void write_data_auto(byte data)
{
wait_disp_auto();
write_data(data);
}
//数据自动写状态忙等待
void wait_disp_auto(void)
{
byte flag;
PORTA=0xff;
DDRA=0; //A口为输入
PORTD|=LCD_ID; //CD=1
PORTD|=LCD_ID; //CD=1
PORTD&=~LCD_CS; //CE=0
PORTD&=~LCD_CS; //CE=0
PORTD&=~LCD_CS; //CE=0
for(;;)
{
flag=*(byte*)0x8000;
if(flag & LCD_BUSY_S3){ //判断液晶忙否?
PORTD|=LCD_CS|LCD_ID; //CE=1,ID=1
PORTD|=LCD_CS|LCD_ID; //CE=1,ID=1
return;
}
}
}
//对液晶初始化,清屏
void init_disp(void)
{
PORTD&=~LCD_RST; //LCD_RST=0
PORTD&=~LCD_RST; //LCD_RST=0
dlyms(2);
PORTD|=LCD_RST; //LCD_RST=1
PORTD|=LCD_RST; //LCD_RST=1
dlyms(3);
write_data(0x00); //设置图形显示首地址00H
write_data(0x00);
write_order(0x42);
dlyms(2);
write_data(DIS_LEN); //设置图形显示区域宽度
write_data(00); //即一行显示所占字节数
write_order(0x43);
dlyms(2);
write_order(0xa7); //光标形状设置
write_order(0x80); //显示方式设置逻辑"或"合成
write_order(0x98); //显示开关设置,开图形和文本显示
}
//显示汉字串及大ASCII串
void str_hz(byte row,byte col,byte *str)
{
byte q,w,i,dis_code;
int address1,lrow,lcol;
byte *pt;
unsigned int aa;
long zk;
lrow=(row)%80; //设置行
lcol=(col*8)%160; //列
for(;*str;)
{ //如果*str=0,则退出循环
if(*str<160) //如果是ASC码字符,<A0H
{
q=(*str++);
if(q==13) //处理回车符
{
lrow+=16; //换两行
lcol=0; //列的开始
continue;
}
if(q<0x20) continue; //为不可见字符,继续循环
zk=q*16l+0x100l+0x800l;
lib_addr.l=zk<<2;
PORTF=lib_addr.bytes.a2 & 0x0f;
aa=zk;
aa=(aa & 0x3fff)|0xc000;
pt=(byte *)aa;
address1=lrow;
address1=DIS_LEN*address1+lcol/8;
address1=address1+START_ADDRESS; //+图形地址偏移量
for(i=0;i<16;i++){
q=address1/0x100; //地址高位
w=address1%0x100; //地址低位
write_data(w); //送低地址
write_data(q); //送高地址
write_order(0x24); //设置显示RAM地址
write_data(*pt);
write_order(0x0c0); //设置一次写数据指令代码
pt++;
address1=address1+DIS_LEN; //地址调整到下一行
}
lcol=lcol+8; //
if(lcol>=160)
{
lrow+=16;
lcol=0;
}
continue;
}
q=(*str++)-160;
if(*str==0) break;
w=(*str++)-161;
if(q<=3) q--;
else if(q==6) q-=3;
else q-=12;
// zk=q;
zk=(q*94l+w)*32l+0x100l+0x800l+0x1000l;
lib_addr.l=zk<<2;
PORTF=lib_addr.bytes.a2 & 0x0f;
aa=(zk & 0x3fff) | 0xc000;
pt=(byte *)aa;
//汉字定位,行
address1=lrow;
address1=DIS_LEN*address1+lcol/8;
if(lcol<145)
{
for(i=0;i<16;i++)
{
q=address1/0x100; //地址高位
w=address1%0x100; //地址低位
write_data(w); //送低地址
write_data(q); //送高地址
write_order(0x24); //设置显示RAM地址
dis_code=*pt;
write_data(dis_code);
pt++;
write_order(0x0c0); //设置一次写数据指令代码
write_data(*pt);
pt++;
write_order(0x0c4); //设置一次写数据指令代码
address1=address1+DIS_LEN; //地址调整到下一行
}
}
else
{ //如果本行只剩下半个字的位置,则将这个位置填空格
for(i=0;i<16;i++)
{
q=address1/0x100; //地址高位
w=address1%0x100; //地址低位
write_data(w); //送低地址
write_data(q); //送高地址
write_order(0x24); //设置显示RAM地址
write_data(00); //填空格
write_order(0xc0); //设置一次写数据指令代码
write_data(00); //填空格
write_order(0xc0); //设置一次写数据指令代码
address1=address1+DIS_LEN; //地址调整到下一行
}
*str--;
*str--;
}
lcol=lcol+16; //列数+8
if(lcol>=160)
{
lrow+=16;
lcol=0;
}
}
}
//显示小ASCII串
//row--行
//col--列
//str--字符串指针
void str_sasc(byte row,byte col,byte *str)
{
byte q,w,dis_code,i;
int address1,lrow,lcol;
byte *pt;
unsigned int aa;
long zk;
lrow=row%80; //设置行
lcol=(col*8)%160; //列
for(;*str;)
{
q=(*str++);
if(q==13) //处理回车符
{
lrow+=2; //换两行
lcol=0; //列的开始
continue;
}
if(q<0x20) continue; //为不可见字符,继续循环
zk=q*8l+0x100l;
lib_addr.l=zk<<2;
aa=lib_addr.bytes.a2 & 0x0f;
PORTF=aa;
aa=(zk & 0x3fff) | 0xc000;
pt=(byte *)aa;
address1=lrow;
address1=DIS_LEN*address1+lcol/8;
address1=address1+START_ADDRESS; //+图形地址偏移量
for(i=0;i<8;i++){
q=address1/0x100; //地址高位
w=address1%0x100; //地址低位
write_data(w); //送低地址
write_data(q); //送高地址
write_order(0x24); //设置显示RAM地址
write_data(*pt);
pt++;
write_order(0x0c0); //设置一次写数据指令代码
address1=address1+DIS_LEN; //地址调整到下一行
}
lcol=lcol+8;
if(lcol>=160)
{
lrow+=16;
lcol=0;
}
}
}
//居中显示汉字串
void mediacy_hz(byte row,byte* str)
{
byte i;
i=strlen(str);
if(i>=20)
str_hz(row,0,str);
else
str_hz(row,10-i/2,str);
}
//居右显示汉字串
void dexter_hz(byte row,byte* str)
{
byte i;
i=strlen(str);
if(i>=20)
str_hz(row,0,str);
else
str_hz(row,20-i,str);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -