📄 keylcd.c
字号:
/*
硬件连接
PS/2 1-----INT1 数据
PS/2 5-----INT0 时钟
PS/2 3-----GND
PS/2 4-----VCC
4 。
2。 6 。
口
1。 5 。
3。
*/
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
//#include "t1.h"
#include "keycode.h" //PS/2键盘译码表
#include "ASC.h"
#include "GB16.h"
#include "GB24.h"
#include "scancodes.h"
#define PIN_DIR DDRD
#define PIN_KB PIND
#define PORT_KB PORTD
#define CLOCK 2
#define DATAPIN 3
#define LOBYTE(a) ((BYTE)(a))
#define HIBYTE(a) ((BYTE)((a)>>8))
typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD;
//#define SEI() asm volatile("sei"::)
//#define XTAL 6
volatile BYTE count=0,num=9,shu=0;
volatile BYTE Int_Number; //中断计数器;
volatile BYTE Key_Value,Key_Value1; //键盘编码值;
volatile BYTE Key_Up; //键盘被释放标志;
volatile BYTE Byte_Flag=0; //键盘编码接收完成标志;
volatile BYTE tmp[2];
volatile unsigned char shift=0,up=0,shiftup,E0=0;
volatile char cur_x=20,cur_y=15;
void delay_us(int time)//微秒级延时程序
{
do
{
time--;
}
while (time>1);
}
void delay_ms(unsigned int time)//毫秒级延时程序
{
while(time!=0)
{
delay_us(1000);
time--;
}
}
//***************************外部中断1初试化***************//
void INT_Init(void)
{
MCUCR=MCUCR&0xfc; //INT0低电平中断
GICR=GICR|0x40; //INT0中断使能
SREG=SREG|0x40; //全局中断使能
}
/*
void WC(BYTE comm) //write command
{
PORTB|=(1<<PB7); //A0
PORTB|=(1<<PB5); //RD
PORTA=comm;
PORTB&=~(1<<PB4); //WD
PORTB|=(1<<PB4); //WD
}
*/
void W_comm(BYTE COMMAND)
{
PORTB|=(1<<PB5); //RD
PORTA=COMMAND;
PORTB|=(1<<PB7); //A0
PORTB&=~(1<<PB4);//WD
asm volatile("nop"::);
PORTB|=(1<<PB4); //WD
PORTB&=~(1<<PB7); //A0
}
/*
void WD_WC(BYTE code) //write data and command paramete
{
PORTB&=~(1<<PB7); //A0
PORTB|=(1<<PB5); //RD
PORTA=code;
PORTB&=~(1<<PB4); //WD
PORTB|=(1<<PB4); //WD
}
*/
void W_code(BYTE code)
{
PORTA=code;
PORTB&=~(1<<PB7); //A0
PORTB|=(1<<PB5); //RD
PORTB&=~(1<<PB4); //WD
asm volatile("nop"::);
PORTB|=(1<<PB4); //WD
}
void init_devices(void)
{
PORTB = 0x00;
DDRB = 0xFF;
PORTA = 0xFF;//FB
DDRA = 0xFF;
DDRD=0x00;
PORTD=0xFF;
}
void initLCD(void)
{
init_devices();
PORTB&=~(1<<6); // /cs -> 0
W_comm(0x40);//SYSTEM SET
W_code(0x30);//P1
W_code(0x87);//P2
W_code(0x07);//P3
W_code(0x27);//p4
W_code(0x49);//p5
W_code(0xf0);//P6
W_code(0x28);//p7
W_code(0x00);//p8
W_comm(0x44);//SCROLL
W_code(0x00);//P1
W_code(0x00);//P2
W_code(0xf1);//P3
W_code(0xB0);//P4
W_code(0x04);//P5
W_code(0xf1);//P6
W_code(0x00);//P7
W_code(0x00);//P8
//W_code(0x00);//P9
//W_code(0x00);//P10
W_comm(0x5d);//CSR FORM
W_code(0x07);
W_code(0x07);
W_comm(0x5a);//HDOT SCR
W_code(0x00);
W_comm(0x5b);//OVLAY
W_code(0x00);
//W_code(0x18);
W_comm(0x59);//DISP ON
//W_code(0x54);//无光标
W_code(0x56); //有光标
}
void clear1(void)
{
unsigned int i;
i=0x4b0;
W_comm(0x4c);
W_comm(0x46);
W_code(0x00);
W_code(0x00);
W_comm(0x42);
do{
W_code(0xa0);
i--;
}
while(i>0);
}
void clear2(void)
{
unsigned int j;
j=0x2580;
W_comm(0x4c);
W_comm(0x46);
W_code(0xB0);
W_code(0x04);
W_comm(0x42);
do{
W_code(0x00);
j--;
}
while(j>0);
}/*
void clear3(void)
{
unsigned int j;
j=0x2580;
W_comm(0x4c);
W_comm(0x46);
W_code(0x30);
W_code(0x2a);
W_comm(0x42);
do{
W_code(0x00);
j--;
}
while(j>0);
}*/
void W_data(BYTE z)
{
W_comm(0X42);
W_code(z);
}
BYTE r_data(void)
{
BYTE a;
W_comm(0X43);
DDRA=0x00;
PORTB|=(1<<PB7); //A0
PORTA=0xff;
PORTB|=(1<<PB4); //WD
PORTA=0xff;
PORTB&=~(1<<PB5); //RD
asm volatile("nop"::);
a=PINA;
PORTB|=(1<<PB5); //RD
PORTA=0x00;
DDRA=0xff;
return(a);
}
void set_csr(void)//(char x,char y)
{
WORD addr;
if(cur_x<0 ||cur_x>41)
{
cur_x=39;
cur_y-=1;
}
if(cur_y<0)
{
cur_y=0;
}
if(cur_x>=40)
{
cur_x-=40;
cur_y+=1;
}
if(cur_y>=30)
{
//cur_y-=30;
cur_y=0;
}
addr=cur_x+cur_y*40;//+0x4b0
W_comm(0x4c);
W_comm(0x46);
W_code(LOBYTE(addr));
W_code(HIBYTE(addr));
}
void set_pos(BYTE pos_x,BYTE pos_y)
{
WORD addr;
addr=pos_x+pos_y*40+0x4b0;
W_comm(0x4c);
W_comm(0x46);
W_code(LOBYTE(addr));
W_code(HIBYTE(addr));
}
WORD r_pos(void)
{
BYTE tp=0;
WORD ad=0;
W_comm(0x4c);
W_comm(0x47);
DDRA=0x00;
PORTB|=(1<<PB7); //A0
PORTA=0xff;
PORTB|=(1<<PB4); //WD
PORTA=0xff;
PORTB&=~(1<<PB5); //RD
asm volatile("nop"::);
tp=PINA;
PORTB|=(1<<PB5); //RD
PORTB&=~(1<<PB5); //RD
asm volatile("nop"::);
ad = (WORD)(PINA);
ad<<=8;
ad|=tp;
PORTB|=(1<<PB5); //RD
PORTA=0x00;
DDRA=0xff;
return(ad);
}
unsigned char printf_16(unsigned char x,unsigned char y, char *ptr)
{
unsigned char c1,c2,i=0,j,k,uLen=0;
while (ptr[uLen]!=0) //探测字串长度
{
uLen++;
}
while(i<uLen)
{
set_pos(x++,y);
if(x>39) {x=0;y+=16;set_pos(x,y);}
c1 = ptr[i];
c2 = ptr[i+1];
//ascii字符与汉字内码的区别在于128做分界,大于界线的为汉字码
if(c1 <=128) // ASCII
{
for(j=0;j<16;j++) //写16行
{
W_comm(0X42); // 写数据(命令)
if (c1 >= 0x20)
{
W_code(pgm_read_byte(ASC+(c1-0x20)*16+j));
}
else
{
W_code(0);
}
set_pos(x,y+1+j);
}
}
else // 中文
{
for(j=0;j<sizeof(GB16_Index)/sizeof(GB16_Index[0]);j++) // 查找定位
{
if(c1 ==pgm_read_byte(GB16_Index+j*2) && c2 == pgm_read_byte(GB16_Index+j*2+1))
{
break;
}
}
for(k=0;k<16;k++)
{
set_pos(x,y+k);
if(x>38) {x=0;y+=16;set_pos(x,y);}
W_comm(0X42); // 写数据
if(j < sizeof(GB16_Index)/sizeof(GB16_Index[0]))
{
W_code(pgm_read_byte(GB16_Msk+j*32+k*2));
W_code(pgm_read_byte(GB16_Msk+j*32+k*2+1));
}
else // 未找到该字
{
if(k < 8)
{
W_code(0x00);
W_code(0x00);
}
else
{
W_code(0xff);
W_code(0xff);
}
}
}
x++;
i++;
};
i++;
}
return uLen; //返回字串长度,汉字按2字节计算
}
unsigned char printf_24(unsigned char x,unsigned char y, char *ptr)
{
unsigned char c1,c2,i=0,j,k,uLen=0;
while (ptr[uLen]!=0) //探测字串长度
{
uLen++;
}
while(i<uLen)
{
set_pos(x++,y);
if(x>39) {x=0;y+=16;set_pos(x,y);}
c1 = ptr[i];
c2 = ptr[i+1];
//ascii字符与汉字内码的区别在于128做分界,大于界线的为汉字码
if(c1 <=128) // ASCII
{
for(j=0;j<24;j++) //写16行
{
W_comm(0X42); // 写数据(命令)
if (c1 >= 0x20)
{
W_code(pgm_read_byte(ASC+(c1-0x20)*16+j));
}
else
{
W_code(0);
}
set_pos(x,y+1+j);
}
}
else // 中文
{
for(j=0;j<sizeof(GB24_Index)/sizeof(GB24_Index[0]);j++) // 查找定位
{
if(c1 ==pgm_read_byte(GB24_Index+j*2) && c2 == pgm_read_byte(GB24_Index+j*2+1))
{
break;
}
}
for(k=0;k<24;k++)
{
set_pos(x,y+k);
if(x>37) {x=0;y+=24;set_pos(x,y);}
W_comm(0X42); // 写数据
if(j < sizeof(GB24_Index)/sizeof(GB24_Index[0]))
{
W_code(pgm_read_byte(GB24_Msk+j*72+k*3));
W_code(pgm_read_byte(GB24_Msk+j*72+k*3+1));
W_code(pgm_read_byte(GB24_Msk+j*72+k*3+2));
}
else // 未找到该字
{
if(k < 8)
{
W_code(0x00);
W_code(0x00);
}
else
{
W_code(0xff);
W_code(0xff);
}
}
}
x++;
x++;
i++;
};
i++;
}
return uLen; //返回字串长度,汉字按2字节计算
}
//再指定坐标(x,y)画点
void point(WORD px,WORD py,BYTE dshow)
{
BYTE px1;
volatile BYTE temp,temp1;
px1=px/8;
px=px & 0x0007;
temp =(BYTE)(7-px);
temp = 1<<temp;
set_pos(px1,py);
temp1=r_data();
if(dshow)
temp|=temp1;
else
temp=(~temp)&temp1;
set_pos(px1,py);
W_comm(0X42);
W_code(temp); //在屏上写一点
}
void Line(int x1, int y1, int x2, int y2, BYTE show)
{
int dy = y2 - y1;
int dx = x2 - x1;
int stepx, stepy, fraction;
if (dy < 0)
{
dy = -dy;
stepy = -1;
}
else
{
stepy = 1;
}
if (dx < 0)
{
dx = -dx;
stepx = -1;
}
else
{
stepx = 1;
}
dy <<= 1;
dx <<= 1;
point(x1,y1,show);
if (dx > dy)
{
fraction = dy - (dx >> 1);
while (x1 != x2)
{
if (fraction >= 0)
{
y1 += stepy;
fraction -= dx;
}
x1 += stepx;
fraction += dy;
point(x1,y1,show);
}
}
else
{
fraction = dx - (dy >> 1);
while (y1 != y2)
{
if (fraction >= 0)
{
x1 += stepx;
fraction -= dy;
}
y1 += stepy;
fraction += dx;
point(x1,y1,show);
}
}
}
void Circle(int x, int y, int radius, BYTE show)
{
int xc = 0;
int yc = radius;
int p = 3 - (radius<<1);
while (xc <= yc)
{
point(x + xc, y + yc, show);
point(x + xc, y - yc, show);
point(x - xc, y + yc, show);
point(x - xc, y - yc, show);
point(x + yc, y + xc, show);
point(x + yc, y - xc, show);
point(x - yc, y + xc, show);
point(x - yc, y - xc, show);
if (p < 0)
p += (xc++ << 2) + 6;
else
p += ((xc++ - yc--)<<2) + 10;
}
}
//***************************PS/2键盘译码******************//
void decode(unsigned char sc)
{
unsigned char i;
if (sc==0xf0)
{
up=1;
E0=0;
return;
}
if (up==1)
{
up=0;
if ((sc==0x12)|(sc==0x59)) shift=0;
return;
} /**/
if(sc==0xe1)
{
printf_16(17,160,"PAUSE");
}
if(sc==0xe0)
{
E0=1;
return;
}
if(E0==1)
{
E0=0;
switch (sc)
{
case 0x4A:
{
Key_Value1='/';
break;
}
case 0x5a://KPEN
{
Key_Value1=13;
break;
}
case 0x75:
{
cur_y-=1;
set_csr();//(cur_x,cur_y)
return;
}
case 0x7a:
{
cur_y+=10;
set_csr();//(cur_x,cur_y)
return;
}
default:
return;
}
Byte_Flag=1;
return;
}
switch (sc)
{
case 0x12:
{
shift=1;
//shiftup=1;
}
case 0x59:
{
shift=1;
//shiftup=1;
}
default:
{
if (shift==0)
{
for(i = 0;pgm_read_byte(unshifted+i*2)!=sc && pgm_read_byte(unshifted+i*2); i++);
if (pgm_read_byte(unshifted+i*2) == sc)
{
Key_Value1=pgm_read_byte(unshifted+i*2+1);
Byte_Flag=1;
}
}
else
{
for(i = 0;pgm_read_byte(shifted+i*2)!=sc && pgm_read_byte(shifted+i*2); i++);
if (pgm_read_byte(shifted+i*2) == sc)
{
Key_Value1=pgm_read_byte(shifted+i*2+1);
Byte_Flag=1;
}
}
}
}
}
//*****************************中断服务程序****************//
/*#pragma interrupt_handler INT0_Handler:2
void INT0_Handler(void)*/
SIGNAL(SIG_INTERRUPT0)
{
if (Int_Number==0)
{
if (PIND&0x08)
{
Int_Number= 0;
while (!(PIND&0x04)); //等待PS/2CLK拉高
return;
}
}
if ((Int_Number > 0) && (Int_Number < 9)) //接受只有一字节通码字符
{
Key_Value = Key_Value >> 1; //因键盘数据是低>>高,结合上一句所以右移一位
if (PIND&0x08) Key_Value = Key_Value|0x80;
} //当键盘数据线为1时为1到最高位
if(Int_Number==10)//收到第10个脉冲表示一字节传送完成
{
if (!(PIND&0x08))
{
Int_Number= 0;
while (!(PIND&0x04)); //等待PS/2CLK拉高
return;
}
else
{
Int_Number=0;
decode(Key_Value);
return;
}
}
while (!(PIND&0x04)); //等待PS/2CLK拉高
Int_Number++;
}
int main(void)
{
volatile WORD ii=0;
BYTE tmp=10;
initLCD();
clear1();
clear2();
//clear3();
INT_Init(); //中断初始化
sei();/*
set_csr();//(0,0)
W_data('3');
W_data('5');
W_data('6');
W_data('7');
printf_16(36,8,"ok中文yes测试");
printf_16(1,1,"武 中");
printf_16(36,24,"E_mail:qianwei_518@163.com");*/
point(30,100,1);
point(31,101,1);
point(31,100,1);
point(32,100,1);
point(31,100,0);
set_pos(10,5);
printf_24(10,32,"电压");
set_pos(10,8);
W_comm(0x42);
W_code(0x22);
set_pos(10,8);
ii=r_data();
ii=r_data();
cur_x=10;
cur_y=10;
set_csr();//(cur_x,cur_y)
ii=r_pos();
ii=r_pos();
Line(10,10,50,80,1);
Line(10,10,10,80,1);
Line(10,10,50,10,1);
Line(10,10,50,210,1);
Line(10,20,10,30,0);
//Circle(160, 120, 40,1);
W_comm(0x4c);
W_comm(0x46);
W_code(0xff);
W_code(0x2f);
W_data(0xff);
while(1)
{
set_csr();
if(Byte_Flag) //检测到键盘输入
{
//set_csr();
Byte_Flag=0; //清除检测标志
if(Key_Value1==8)
{
cur_x--;
set_csr();//(--cur_x,cur_y);
W_data(' ');
}
else if(Key_Value1==13)
{
cur_y+=1;
}
else
{
W_data(Key_Value1);
cur_x++;
}
}
if(tmp==50)
{
tmp=10;
Circle(160, 120, 49,0);
}
else
{
Circle(160, 120, tmp-1,0);
Circle(160, 120, tmp,1);
tmp++;
}
delay_ms(100);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -