/*********************************************************************
目 的: 建立操作PC键盘的示例程序(硬件中断读取PS/2接收到的数据)
目标系统: 基于AVR单片机
应用软件: ICCAVR
版 本: Version 1.0
*********************************************************************/
/*01010101010101010101010101010101010101010101010101010101010101010101
----------------------------------------------------------------------
版本更新记录:
----------------------------------------------------------------------
实验内容:
按PC键盘,观察单片机读到的数据,使用PA/PB口的LED做指示。
----------------------------------------------------------------------
硬件连接:
将PA/PB口的LED指示灯使能开关切换到"ON"状态
将PC键盘插入PS2接口,将PD3与PS2.SDA连接,将PD4与PS2.SCK连接
----------------------------------------------------------------------
注意事项:
(1)若有加载库函数,请将光盘根目录下的“库函数”下的“ICC_H”文件夹拷到D盘
(2)请详细阅读“使用必读”及相关资料。
----------------------------------------------------------------------
10101010101010101010101010101010101010101010101010101010101010101010*/
#include
#include "D:ICC_HCmmICC.H"
#include "D:ICC_HPS2.H"
#define PRESS_DATA_DDR DDRA
#define PRESS_DATA_PORT PORTA
#define SHIFT_DATA_DDR DDRB
#define SHIFT_DATA_PORT PORTB
#define SET_SDA sbi(PORTD,4)
#define CLR_SDA cbi(PORTD,4)
#define GET_SDA gbi(PIND,4)
#define OUT_SDA sbi(DDRD,4)
#define IN_SDA cbi(DDRD,4)
#define SET_SCK sbi(PORTD,3)
#define CLR_SCK cbi(PORTD,3)
#define GET_SCK gbi(PIND,3)
#define OUT_SCK sbi(DDRD,3)
#define IN_SCK cbi(DDRD,3)
bool rcvF = 0; //是否收到字符标志
uint8 keyVal; //键值
/*--------------------------------------------------------------------
函数名称:PS/2
函数功能:
注意事项:
提示说明:
输 入:
返 回:
--------------------------------------------------------------------*/
#pragma interrupt_handler int1_isr:3
void int1_isr(void)
{
static uint8 rcvBits = 0; //接收次数,中断次数
if((rcvBits>0) && (rcvBits<9))
{
keyVal=keyVal>>1; //数据是LSB格式
//IN_SDA; //当有对键盘有属性设置时,注意输入输出切换
//DELAY();
if(GET_SDA)
keyVal=keyVal|0x80;
}
rcvBits++;
while(!GET_SCK); //等待PS/2CLK拉高
if(rcvBits>10)
{
rcvBits=0; //接收11次表示接收完一帧数据
rcvF=1; //标识有字符已经输入
}
}
/*--------------------------------------------------------------------
函数名称:PS/2
函数功能:
注意事项:
提示说明:
输 入:
返 回:
--------------------------------------------------------------------*/
void keyHandle(uint8 val)
{
uint8 i;
static bool isUp=0; //按键释放动作标志
static bool shift=0; //shift键按下标志
rcvF = 0;
PRESS_DATA_PORT = val; //状态指示
if(!isUp)
{
switch(val)
{
case 0xF0 : // a relase action
isUp = 1;
break;
case 0x12 : // Left shift
shift = 1;
break;
case 0x59 : // Right shift
shift = 1;
break;
default:
if(!shift) // If shift not pressed
{
/*
for(i=0; unshifted[i][0]!=val && unshifted[i][0]; i++)
;
上述写法较为灵活,但KEIL非UNIXC标准,不能采用该写法
*/
for(i=0; unshifted[i][0]!=val && i<59; i++)
;
if(unshifted[i][0] == val)
; //状态指示
}
else // If shift pressed
{
/*
for(i=0; unshifted[i][0]!=val && unshifted[i][0]; i++)
;
上述写法较为灵活,但KEIL非UNIXC标准,不能采用该写法
*/
for(i=0; shifted[i][0]!=val && i<59; i++)
;
if(shifted[i][0] == val)
SHIFT_DATA_PORT = val;//状态指示
}
}
}
else
{
isUp=0;
switch(val)
{
case 0x12 : // Left SHIFT
shift = 0;
break;
case 0x59 : // Right SHIFT
shift = 0;
break;
}
}
}
/*--------------------------------------------------------------------
函数名称:PS/2
函数功能:
注意事项:
提示说明:
输 入:
返 回:
--------------------------------------------------------------------*/
void int1_init()
{
IN_SCK; // set SCK_DDR (PD3/INT1) as input
SET_SCK; // set SCK_PORT as high level,avoid triggering
MCUCR |= 0b11110011; // set PD3/INT1 as low level active
GICR |= 0b10000000; // enable global interrupt
SEI(); // enable external interrupt
}
/*--------------------------------------------------------------------
函数名称:PS/2
函数功能:
注意事项:
提示说明:
输 入:
返 回:
--------------------------------------------------------------------*/
void main(void)
{
PRESS_DATA_DDR = 0XFF;
SHIFT_DATA_DDR = 0XFF;
IN_SDA;
int1_init();
while(1)
{
if(rcvF)
keyHandle(keyVal);
}
}
上一篇:LCD12864子程序
下一篇:AVR PS/2 软件查询控制程序
设计资源 培训 开发板 精华推荐
- 用于精密电流源的 ADR366A、3.3V 低功耗、低噪声电压基准的典型应用
- ADP2503-5.0-EVALZ,用于 ADP2503ACPZ-5.0-R7、0.6 A、5V 降压升压转换器的评估板
- ADP2118、2.5V、3A、1.2MHz降压稳压器的典型应用,启用PFM模式
- LTC3406ES5-1.8 单节锂离子 1.2V/600mA 稳压器的典型应用电路,用于实现高效率和小尺寸
- 【训练营】机械狗子
- LT3990EDD 12V 降压转换器的典型应用
- 具有固定输出电压的典型应用,ADP7118 为 5V 20V、200mA 低噪声 CMOS LDO
- 2020_06_09_mini8266
- 具有模拟电流控制和 2A 输入电流限制的 LTM8054IY 12Vout 风扇电源(从 3Vin 到 36Vin)的典型应用电路
- 使用符合 EN55022 B 类(24Vin 和 48Vin,单输出)具有 EMC 滤波的 RP40-483.3SFR DC/DC 转换器的典型应用