#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
}
}
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
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- MSP430F5529 ADC analog-to-digital conversion source program
- Thank you for having you + you who helped me and myself who struggled
- The Dragon Boat Festival Chip Coin Exchange Event has begun! Zongzi, multimeter, Huawei router... are waiting for you!
- @PCB Engineer, here are some practical tips for Allegro drawing board
- TMS320F28335 generates SPWM
- What happens if the installation directory of keil5 is different from the installation directory of pack?
- I don't understand this speed, is it normal? The environment is esp8266
- [Old Post] Richengfeng's Eighteen Dragon Subduing Palms in C Language
- Introduction to DSP GPIO
- Examples of embedded system security issues