PS\2 keyboard communication program based on stc51 microcontroller

Publisher:脑电狂徒Latest update time:2015-05-15 Source: 51heiKeywords:stc51 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
PS2 keyboard communication (only the receiving part is written because there are too many key codes and the decoding can be selectively translated as needed)

#include //STC12C5AxxS2 series MCU header file
#include //Header file including _nop_delay function
#define uchar unsigned char //Macro definition
#define uint unsigned int //Macro definition
//-------------------------------------------------------------------------------------
//Global declaration part
sbit CLK=P3^2; //Clock line
sbit DATA=P1^0; //Data line
sbit LED_zs=P0^0; //Run indication LED
char DATA_Z[6]; //Key code buffer
int D_Z=0; //Key code buffer tail pointer
char DATA_K[6]; //Keyboard control instruction buffer
int D_K=0; //Control instruction buffer tail pointer


//-------------------------------------------------------------------------------------

void DELAY_MS (unsigned int a){
unsigned int i;
while( --a != 0){
for(i = 0; i < 500; i++);
}
}
/********************************************************************************************/
Function name: UART serial port initialization function
void UART_init (void){
EA = 1; //Allow total interrupt (if not using interrupt, can be used //shielded)
//ES = 1; //Allow UART serial port interrupt

TMOD = 0x20; //Timer T/C1 working mode 2
SCON = 0x50; //Serial port working mode 1, serial port reception is allowed (serial port reception is prohibited when SCON = 0x40)
TH1 = 0xF3; //Timer initial value high 8 bits set
TL1 = 0xF3; //Timer initial value low 8 bits set
PCON = 0x80; //Baud rate multiplication (shield the baud rate of this sentence is 2400)
TR1 = 1; //Timer start
}
/*************************************************************************************************/
Function name: UART serial port receive interrupt processing function
void UART_R (void) interrupt 4 using 1{ //Switch register group to 1
unsigned char UART_data; //Define serial port receive data variable
RI = 0; //Set the receive interrupt flag to 0 (software clear)
UART_data = SBUF; //Send the received data to the variable UART_data

//User function content (users can use UART_data for data processing)
//SBUF = UART_data; //Send the received data back (delete // to take effect)
//while(TI == 0); //Check the send interrupt flag
//TI = 0; //Set the send interrupt flag to 0 (software clear)
}
/*********************************************************************************************/
Function name: UART serial port sending function
void UART_T (unsigned char UART_data){ //Define serial port send data variable
SBUF = UART_data; //Send the received data backwhile
(TI == 0); //Check the send interrupt flag
TI = 0; //Set the send interrupt flag to 0 (software clear)
}
/*********************************************************************************************/
Function name: external interrupt INT initialization function
void INT_init (void){
EA = 1; //Interrupt master switch
EX1 = 1; //Enable external interrupt 1
EX0 = 1; //Enable external interrupt 0
IT1 = 1; //1: falling edge trigger 0: low level trigger
IT0 = 1; //1: falling edge trigger 0: low level trigger
}

/********************************************************************************************/
Function name: External interrupt INT1 interrupt handler
void INT_1 (void) interrupt 2 using 2{ //Switch register bank to 2

//User function content

}[page]

/********************************************************************************************/
Function name: External interrupt INT0 interrupt handler
void INT_0 (void) interrupt 0 using 2{ //Switch register bank to 2

//The interrupt preparation must be completed before the keyboard is powered on. The keyboard will be powered on after the interrupt is started. If the keyboard is powered off after powering on,
the main program must also be restarted, otherwise the clock may be synchronized with the data part. This may be the reason why the PS/2 keyboard does not support hot plugging
unsigned char dat ; //Used to store a complete key code received
unsigned int i; //Used for loop marking
//Start receiving a frame of 11-bit standard frame
EX0=0; //Turn off interrupts when processing a byte to avoid repeated interrupts
while(CLK==0);
while(CLK==1); //Because the first bit is the start code and has no meaning, it is discarded
for(i=0;i<8;i++) //Get the eight-bit key code
{
while(CLK==0); //Wait for the next bit of data to arrive
while(CLK==1); //Wait for the falling edge of the clock line
_nop_(); //Delay for two weeks and wait for the data to stabilize before starting to get a bit of data
_nop_();
dat=dat>>1; //Because the key code data is little-headed data, the data bit is stored after right shift
if(DATA==1)
{
dat=dat|0x80;
}else
{
dat=dat&0x7f;
}
}
while(CLK==0); //Discard the parity bit (because it is not very important data, no parity check is performed)
while(CLK==1);
while(CLK==0); //Discard the stop bit and wait for the keyboard to release the clock line

if(D_Z<6)//If the buffer queue is not full, add the key code data to the queue, otherwise discard the key press
{
DATA_Z[D_Z]=dat;
D_Z++; //Move to the end of the queue
}

LED_zs=!LED_zs; //The indicator light flashes if there is a key code

DELAY_MS(3); //!!!!!!!!!!!!!!!!!! The delay length is very important, because the key release code and special key code are multi-frame delays. If the delay is too long, frames will be lost, and if it is too short, it will fall into an infinite loop! ! ! ! !

CLK=0; //Suppress keyboard transmission and wait for the host to process data
}
/**************************************************************************************************/

//--------------------------------------------------------------------------------------


//--------------------------------------------------------------------------------------
//Main entry point function
void main()
{
uint i,j,z; //Used for loop mark
INT_init(); //External interrupt initialization
UART_init(); //Serial port initialization

for(i=0;i<6;i++)
{
DATA_Z[i]=0;
}

while(1)
{

for(z=0;z<6;z++) //Send all cached key codes in the buffer
{
if(DATA_Z[0]!=0) //If there is data in the key code buffer, send the data at the front of the queue, and then dequeue the sent data
{
UART_T(DATA_Z[0]);
for(i=0,j=1;j<6;i++,j++) //Move the queue forward
{
DATA_Z[i]=DATA_Z[j];
}
DATA_Z[5]=0;
D_Z--; //Move the tail pointer forward
}
}

EX0=1; //Wait for the keyboard to send a frame and release the clock line before opening the interrupt. Opening the interrupt too early will cause data errors and an endless loop
CLK=1; //Cancel the inhibition of the keyboard
}


Keywords:stc51 Reference address:PS\2 keyboard communication program based on stc51 microcontroller

Previous article:Using 89C51 to drive nRf905 transceiver C source code
Next article:Microcontroller Course Design-ATMEL51 Series Microcontroller Programmer

Recommended ReadingLatest update time:2024-11-16 14:28

STC51 from entry to mastery (assembly) ~~~ Lecture 8: Serial communication technology
8.1 Characteristics of 80C51 MCU serial communication technology The 80C51 microcontroller has a full-duplex serial communication interface, which means it can perform serial transmission and reception simultaneously. Can be used as UART (Universal Asynchronous Receiver and Transmitter) Can be used as a synchronous sh
[Microcontroller]
STC51 from entry to mastery (assembly) ~~~ Lecture 8: Serial communication technology
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号