stm32做接收PS/2键盘实验的时候,只有MCU复位后第一次接收的数据正确,比如MCU复位后按A键,第一次接收的数据时1C F0 第二次就成38 E0了,如果复位之后一直按着A 倒是能一直正常接收1C
代码在此,设置为下降沿触发中断
[mw_shl_code=c,true]
[mw_shl_code=c,true]void EXTI15_10_IRQHandler(void)
{
static u8 tempdata=0;
static u16 parity=0; //奇偶校验
if(EXTI_GetITStatus(EXTI_Line15) != RESET) //检查指定的EXTI15线路触发请求发生与否
{
PA12=0;
EXTI_ClearITPendingBit(EXTI_Line15); //清除EXTI15线路挂起位
if(BIT_Count==0) //如果位计数器等于0
{
parity=0; //奇偶校验
tempdata=0;
}
BIT_Count++;
if(BIT_Count>1&&BIT_Count<10)//这里获得数据
{
tempdata>>=1;//左移1位
if(PS2_SDA) //如果PA13为高电平
{
tempdata+=0x80; //最高位置一
parity++;//记录1的个数 用来奇偶校验
}
}
else if(BIT_Count==10)//得到校验位
{
if(PS2_SDA)parity|=0x80;//校验位为1
}
if(BIT_Count==11)//接收到1个字节的数据了
{
BIT_Count=parity&0x7f;//取得1的个数
if(((BIT_Count%2==0)&&(parity&0x80))||((BIT_Count%2==1)&&(parity&0x80)==0))//奇偶校验OK
{
PS2_DATA_BUF[PS2_Status]=(unsigned char)tempdata;//保存数据
PS2_Status++; //数据长度加1
printf("成功按键数据=%x PS2_Status=%x,1有%d个,校验位为%d\n",tempdata,PS2_Status,BIT_Count,(parity&0x80)>>7);
}
else
{
printf("失败按键数据=%x,\t1有%d个,校验位为%d\n",tempdata,BIT_Count,(parity&0x80)>>7);
}
BIT_Count=0;
}
PA12=1;
}
}[/mw_shl_code]
[/mw_shl_code]
成功按键数据=1c PS2_Status=1,1有3个,校验位为0
成功按键数据=1c PS2_Status=2,1有3个,校验位为0
成功按键数据=1c PS2_Status=3,1有3个,校验位为0
成功按键数据=1c PS2_Status=4,1有3个,校验位为0
成功按键数据=1c PS2_Status=4,1有3个,校验位为0
成功按键数据=1c PS2_Status=5,1有3个,校验位为0
成功按键数据=1c PS2_Status=6,1有3个,校验位为0
成功按键数据=1c PS2_Status=7,1有3个,校验位为0
成功按键数据=1c PS2_Status=8,1有3个,校验位为0
成功按键数据=1c PS2_Status=9,1有3个,校验位为0
成功按键数据=1c PS2_Status=a,1有3个,校验位为0
成功按键数据=1c PS2_Status=b,1有3个,校验位为0
成功按键数据=1c PS2_Status=c,1有3个,校验位为0
成功按键数据=1c PS2_Status=d,1有3个,校验位为0
成功按键数据=f0 PS2_Status=e,1有4个,校验位为1
成功按键数据=38 PS2_Status=c,1有3个,校验位为0
成功按键数据=38 PS2_Status=d,1有3个,校验位为0
成功按键数据=38 PS2_Status=e,1有3个,校验位为0
失败按键数据=e0, 1有3个,校验位为1
成功按键数据=38 PS2_Status=1,1有3个,校验位为0
失败按键数据=e0, 1有3个,校验位为1
成功按键数据=38 PS2_Status=1,1有3个,校验位为0
失败按键数据=e0, 1有3个,校验位为1
成功按键数据=38 PS2_Status=1,1有3个,校验位为0
失败按键数据=e0, 1有3个,校验位为1
成功按键数据=38 PS2_Status=1,1有3个,校验位为0
失败按键数据=e0, 1有3个,校验位为1
成功按键数据=38 PS2_Status=1,1有3个,校验位为0
失败按键数据=e0, 1有3个,校验位为1
|