專注差異化嵌入式產(chǎn)品解決方案 給智能產(chǎn)品定制注入靈魂給予生命
提供開發(fā)工具、應(yīng)用測(cè)試 完善的開發(fā)代碼案例庫(kù)分享
從全面的產(chǎn)品導(dǎo)入到強(qiáng)大技術(shù)支援服務(wù) 全程貼心伴隨服務(wù),創(chuàng)造無限潛能!
深圳市英銳恩科技有限公司:臺(tái)灣麥肯單片機(jī)(Micon MDT單片機(jī))亞太地區(qū)A級(jí)代理商
QLdsPIC3] PS2協(xié)議 {C30+dsPIC30F6014A]
//實(shí)驗(yàn)?zāi)康模菏煜CU與PS2設(shè)備通信
//軟件規(guī)劃:
// 1,采用查詢的方法檢測(cè)PS2設(shè)備發(fā)送過來的時(shí)鐘和數(shù)據(jù)
// 2,軟件只檢測(cè)字母(小寫)數(shù)字(左邊鍵盤)和數(shù)字鍵的通碼,暫時(shí)不能檢測(cè)斷碼。
// 3,不檢測(cè)組合鍵盤
// 4,掃描按鍵結(jié)果送LCD1602顯示
//硬件要求:
// 1,撥碼開關(guān)S4全部置ON端
// 2,連接好鍵盤
// 3,跳線J18全部接通
#include //dsPIC30F6014標(biāo)準(zhǔn)頭文件
_FOSC(0x0ffe5); //XT振蕩,4倍頻晶振.
_FWDT(WDT_OFF); //關(guān)閉看門狗定時(shí)器
_FBORPOR(PBOR_OFF & MCLR_EN); //掉電復(fù)位禁止,MCLR復(fù)位使能。
_FGS(CODE_PROT_OFF); //代碼保護(hù)禁止
unsigned char __attribute__((address(0x900))) recdata1; //按鍵結(jié)果緩存單元1
unsigned char __attribute__((address(0x902))) recdata2; //按鍵結(jié)果緩存單元2
unsigned char __attribute__((address(0x904))) result; //按鍵的ASCII碼保存單元
unsigned char __attribute__((address(0x906))) result1;
unsigned char __attribute__((address(0x908))) count; //循環(huán)次數(shù)
unsigned int __attribute__((address(0x90a))) temp; //臨時(shí)單元
unsigned char __attribute__((address(0x9a0))) loop; //LCD顯示次數(shù)計(jì)數(shù)器
#define rs LATBbits.LATB4 //定義LCD控制位(注意這里只能用LATB寄存器,不能直接用PORTB寄存器)
#define rw LATBbits.LATB5 //定義LCD的RW控制信號(hào)
#define e LATBbits.LATB6 //定義LCD的使能信號(hào)E
unsigned char const noshift[80][2]= //shift鍵不按下時(shí)按鍵的鍵碼與ASCII對(duì)應(yīng)表
{
//鍵盤碼 ASCII碼
22 ,49, // { 1 }
30 ,50, // { 2 }
38 ,51, // { 3 }
37 ,52, // { 4 }
46 ,53, // { 5 }
54 ,54, // { 6 }
61 ,55, // { 7 }
62 ,56, // { 8 }
70 ,57, // { 9 }
69 ,48, // { 0 }
28 ,97, // { a }
50 ,98, // { b }
33 ,99, // { c }
35 ,100, // { d }
36 ,101, // { e }
43 ,102, // { f }
52 ,103, // { g }
51 ,104, // { h }
67 ,105, // { i }
59 ,106, // { j }
66 ,107, // { k }
75 ,108, // { l }
58 ,109, // { m }
49 ,110, // { n }
68 ,111, // { o }
77 ,112, // { p }
21 ,113, // { q }
45 ,114, // { r }
27 ,115, // { s }
44 ,116, // { t }
60 ,117, // { u }
42 ,118, // { v }
29 ,119, // { w }
34 ,120, // { x }
53 ,121, // { y }
26 ,122, // { z }
84 ,91, // { [ }
91 ,93, // { ] }
76 ,59, // { ; }
82 ,39, // { ' }
65 ,44, // { , }
73 ,46, // { . }
74 ,47, // { / }
78 ,45, // { - }
85 ,61, // { = }
93 ,92, // { \ }
14 ,96, // { ` }
90 ,32, // { enter }
5 ,0, // { f1 }
6 ,1, // { f2 }
4 ,2, // { f3 }
12 ,3, // { f4 }
3 ,4, // { f5 }
11 ,5, // { f6 }
131 ,6, // { f7 }
10 ,7, // { f8 }
1 ,8, // { f9 }
9 ,9, // { f10 }
120 ,10, // { f11 }
7 ,11, // { f12 }
102 ,12, // { back }
224 ,13, // { home }
105 ,14, // { end }
125 ,15, // { pageup }
122 ,16, // { pagedown }
117 ,17, // { up }
114 ,18, // { down }
107 ,19, // { left }
116 ,20, // { right }
113 ,21, // { del }
112 ,22, // { insert }
225 ,23, // { pause }
118 ,24, // { esc }
13 ,25, // { tab }
88 ,26, // { caps }
20 ,27, // { ctrl }
17 ,28, // { alt }
41 ,29, // { space }
31 ,30, // { win }
47 ,31, // { winright
};
unsigned char const addshift[47][2]= //shift鍵按下時(shí)按鍵的鍵碼與ASCII對(duì)應(yīng)表
{
14 ,126, // { ~ }
22 , 33, // { ! }
30 , 64, // { @ }
38 , 35, // { # }
37 , 36, // { $ }
46 , 37, // { % }
54 , 94, // { ^ }
61 , 38, // { & }
62 , 42, // { * }
70 , 40, // { ( }
69 , 41, // { ) }
78 , 95, // { _ }
85 , 43, // { + }
93 ,124, // { | }
84 ,123, // { { }
91 ,125, // { } }
76 , 58, // { : }
82 , 34, // { " }
65 , 60, // { < }
73 , 62, // { > }
74 , 63, // { ? }
28 ,65, // { a }
50 ,66, // { b }
33 ,67, // { c }
35 ,68, // { d }
36 ,69, // { e }
43 ,70, // { f }
52 ,71, // { g }
51 ,72, // { h }
67 ,73, // { i }
59 ,74, // { j }
66 ,75, // { k }
75 ,76, // { l }
58 ,77, // { m }
49 ,78, // { n }
68 ,79, // { o }
77 ,80, // { p }
21 ,81, // { q }
45 ,82, // { r }
27 ,83, // { s }
44 ,84, // { t }
60 ,85, // { u }
42 ,86, // { v }
29 ,87, // { w }
34 ,88, // { x }
53 ,89, // { y }
26 ,90, // { z }
};
void init(); //I/O口初始化函數(shù)
void getkey(); //讀取按鍵鍵碼函數(shù)
void judge(); //鍵碼轉(zhuǎn)換成ASCII碼
void lcd_display(unsigned char res); //LCD顯示函數(shù)
void lcd_init(); //申明LCD初始化函數(shù)
void write_web(); //申明顯示公司web地址函數(shù)
void write(unsigned int x); //申明顯示1字節(jié)數(shù)據(jù)函數(shù)
void lcd_enable(); //申明LCD顯示設(shè)置函數(shù)
void delay(); //申明延時(shí)函數(shù)
//************************初始化函數(shù)**************************
void init()
{
TRISC=0X0018;
TRISB=0X0000; //設(shè)置B口為輸出
TRISD=0X0000; //設(shè)置D口為輸出
result=0;
result1=0;
}
//********************讀取按鍵鍵碼函數(shù)*************************
void getkey()
{
unsigned char i;
temp=0;
for(count=1;count<21;count++) //循環(huán)20次(第1字節(jié)的1bit起始位,8bit數(shù)據(jù),1bit校驗(yàn)位,1bit停止位,第2字節(jié)的1bit起始位和8bit數(shù)據(jù),忽略校驗(yàn)位和停止位)
{
while(PORTCbits.RC4); //等待低電平
while(!PORTCbits.RC4) //低電平
{
for(i=0;i<15;i++); //延時(shí)一定時(shí)間,保證下降沿足夠時(shí)間
if(count<10|count>12) //只讀取數(shù)據(jù)位,忽略起始位和校驗(yàn)位,停止位
{
temp=temp>>1; //讀取的數(shù)據(jù)右移1位(傳輸時(shí)低位在前)
if(PORTCbits.RC3) temp=temp|0x8000; //若為高,最高位加1
else temp=temp&0x7fff; //若為低,最高位清0
}
while(!PORTCbits.RC4); //等待恢復(fù)為高電平(下降沿讀取數(shù)據(jù))
}
}
recdata1=0;
recdata2=0;
recdata1=(unsigned char)temp&0x00ff; //按鍵碼低8位
recdata2=(unsigned char)((temp>>8)&0x00ff); //按鍵碼高8位
}
//*********************按鍵碼轉(zhuǎn)ASCII碼**************************
void judge()
{
unsigned char i;
if(!(recdata1==0xf0)) //若按鍵碼低8位為0XF0,則是按鍵的斷碼
{
if(recdata1==0x12) //shift有按下
{
if(recdata2=0xf0) return; //若只有shift按下,則返回
for(i=0;i<47;i++) //查找shift按下時(shí)按鍵的ASCII碼
{
if(addshift[i][0]==recdata2)
{
result=addshift[i][1]; //返回讀取的ASCII碼
break;
}
}
}
else //shift鍵沒有按下
{
for(i=0;i<80;i++)
{
if(noshift[i][0]==recdata1)
{
result=noshift[i][1];
break;
}
}
}
}
}
//*******************LCD初始化函數(shù)*******************************
void lcd_init()
{
PORTD=0X1; //清除顯示
lcd_enable();
PORTD=0X38; //8位2行5*7點(diǎn)陣
lcd_enable();
PORTD=0X0e; //顯示開,光標(biāo)開,閃爍
lcd_enable();
PORTD=0X06; //文字不動(dòng),光標(biāo)右移
lcd_enable();
PORTD=0X80; //產(chǎn)品名字顯示地址
lcd_enable();
}
//*********************LCD顯示函數(shù)*******************************
void lcd_display(unsigned char res)
{
unsigned char j;
if(loop<16) //一行只顯示16字符
{
write(res); //寫一個(gè)字節(jié)數(shù)據(jù)函數(shù)送LCD顯示
loop++;
for(j=0;j<5;j++) //延時(shí)一段時(shí)間(主要是為了控制顯示的速度)
{
delay();
}
}
else
{
loop=0;
PORTD=0X80; //重頭開始顯示
lcd_enable();
write(res); //寫一個(gè)字節(jié)數(shù)據(jù)函數(shù)送LCD顯示
}
}
//*****************寫一個(gè)字節(jié)數(shù)據(jù)函數(shù)***************************
//在電平發(fā)生改變后需要插入一段延時(shí)時(shí)間,否則LCD反應(yīng)不過來。
void write(unsigned int x)
{
PORTD=x; //待顯示數(shù)據(jù)送PORTD口
delay();
rs=1; //該字節(jié)數(shù)據(jù)為數(shù)據(jù),而不是命令
delay();
rw=0; //此次操作為寫,而不是讀
delay();
e=0; //拉低使能信號(hào)
delay(); //保持使能信號(hào)為低一段時(shí)間
e=1; //拉高使能信號(hào),建立LCD操作所需要的上升沿
delay();
}
//******************LCD顯示設(shè)置函數(shù)*****************************
//在電平發(fā)生改變后需要插入一段延時(shí)時(shí)間,否則LCD反應(yīng)不過來。
void lcd_enable()
{
delay();
rs=0; //該字節(jié)數(shù)據(jù)為命令,而不是數(shù)據(jù)
delay();
rw=0; //此次操作為寫,而不是讀
delay();
e=0; //拉低使能信號(hào)
delay(); //保持使能信號(hào)為低一段時(shí)間
e=1; //拉高使能信號(hào),建立LCD操作所需要的上升沿
delay();
}
//**********************延時(shí)函數(shù)*********************************
void delay()
{
unsigned int i;
for(i=0;i<100;i++);
}
//**********************主函數(shù)***********************************
int main(void)
{
unsigned char m, k=0;
delay();
delay();
delay();
delay();
delay(); //延時(shí)一段時(shí)間,保證鍵盤,LCD等工作穩(wěn)定
init(); //調(diào)用I/O口初始化函數(shù)
lcd_init(); //調(diào)用LCD初始化函數(shù)
while(1)
{
getkey(); //調(diào)用讀取按鍵碼函數(shù)
judge(); //調(diào)用按鍵碼轉(zhuǎn)ASCII碼函數(shù)
if(recdata1!=0x12) lcd_display(result); //如按下鍵不為shift則送LCD顯示
for(m=0;m<100;m++) //延長(zhǎng)一段時(shí)間
{
delay();
delay();
}
}
}