[C51 Single Chip Microcomputer] Single Chip Microcomputer Controlled by PC (Simulation)

1. Functional description

1. SCM and PC are connected by RS232, and an asynchronous serial port communication program is written to realize the communication between SCM and PC's serial port assistant. Specific functions are as follows:

(1) PC sends orders to MCU to turn on or off designated LED lights

(2) PC sends orders to MCU to start or stop buzzer playing music

(3) The PC sends characters to the MCU and displays them on the 1602 LCD. It can also issue commands to delete characters, change lines and clear the display.

At the end of the single chip computer, click on the matrix key and send the serial number of the key to the PC.

2. Circuit diagrams designed in PROTEUS

3. Source code

 

#include<reg52.h>
#include<intrins.h>
#include <stdio.h>
sbit LCDEN=P3^4;
sbit RS=P3^5;
sbit RW=P3^6;
sbit BF=P1^7;
sbit FM=P3^2;

unsigned char code SONG_TONE[]={212,212,190,212,159,169,212,212,190,212,142,159,
						212,212,106,126,159,169,190,119,119,126,159,142,159,0};
//Happy birthday, the beat meter, the beat determines the length of each note.
unsigned char code SONG_LONG[]=
{9,3,12,12,12,24,9,3,12,12,12,24,9,3,12,12,12,12,12,9,3,12,12,12,24,0};

unsigned char code keyval[]="0123456789ABCDEF"; //Key corresponding symbols
unsigned char code keycode[]={
0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};	 //Keystroke key coding

void delay(unsigned int t)	  //Delay t milliseconds
{int i,j;
 for(i=0;i<=t;i++)
	 for(j=0;j<=110;j++);
}


void  send(unsigned char s)	 //Sender function, the state of eight lights (0/1), in the form of a string sent to the upper computer, the first highest bit
{
      unsigned char i,t;
	  for(i=0;i<8;i++)
	  {	
	    s<<=1;
		t=CY;
		SBUF='0'+ t;	//Send lamp status to PC
    	while(!TI);//Waiting to be sent
    	TI=0;//Clear Send End Flag	
	  }			
}


unsigned char DectectBusyBit(void)//State Judgment Function (Busy/idle?)
{   
	bit result;
	P1 = 0xff;	//Pre-reading high level to prevent misjudgment
	RS = 0;
	delay(5);
    RW = 1;
	LCDEN = 1;
	delay(5);
	result=BF; //If LCM is busy, test again and again, step in place; when LCM is idle, continue.
	LCDEN = 0;
	return result;		      
}

void WrComLCD(unsigned char ComVal)//Write command functions
{
	while(DectectBusyBit()==1);         //First check if LCM is idle
	RS = 0;
	delay(1);
    RW = 0;
	LCDEN = 1;
	P1 = ComVal;
	delay(1);
	LCDEN = 0;	
}

void WrDatLCD(unsigned char DatVal)//Write data functions
{
while(DectectBusyBit()==1); 
	RS = 1;
	delay(1);
    RW = 0;
	LCDEN = 1;
	P1 = DatVal;
	delay(1);
	LCDEN = 0;	
}

void LCD_Init(void)//1602 Initialization Function
{ 
	WrComLCD(0x38);     // Functional settings: 16*2 rows, 5*7 bits, 8 bits data interface
	WrComLCD(0x38);
	WrComLCD(0x38);    
//Repeat setting function instructions many times, because LCD does not know whether to use 4-bit data interface or 8-bit data interface after starting, so it always defaults to 4-bit at the beginning.
	WrComLCD(0x01);    // Clean screen 
	WrComLCD(0x06);    // Cursor self-increasing, screen immovable  
	delay(1);	      // Delay, wait for the above instructions to take effect, and then show below to prevent scrambling.
	WrComLCD(0x0e);    // On display, on cursor, flashing
}



unsigned char keypad4_4()//Key Scanning Function: To de-jitter, if a key is pressed, the corresponding key value (0-15) is returned, and no key is pressed, 16 is returned.
{
unsigned char i,row,temp;
unsigned char key=16;//Key number, initial value set to 16, the purpose is: no key press when returning 16;
          //If no initial value is set (default value is 0), when no key is pressed, 0 will be returned, and 0 will be mistaken for being pressed.  
row=0xef; //Start with the first column      
for(i=0;i<4;i++)
{
	P2=0xff;  
	P2=row;	//Signals in column i, corresponding to low, all others high
	row=_crol_(row,1); 	  //Generate the next sequence of signals
	temp=P2; //Read-in Scanning Signal
	temp=temp&0x0f; //Shield high 4-bit signal, only low 4-bit row signal 
	if(temp!=0x0f)//If a key is pressed, one of the lower four bits is lower because a key is pressed in a row in column i.  
 	{  
		delay(10);  //Delay shaking
		temp=P2;  
		temp=temp&0x0f;  
		if(temp!=0x0f)   //Make sure the key is pressed again
  		{  
        	switch(temp)  //Decide which button is pressed according to the low 4-bit line signal
            {  
            	case 0x0e:key=0+i;break; //Column i, row 1, button pressed 
                case 0x0d:key=4+i;break; //The key in line 2 of column i is pressed  
                case 0x0b:key=8+i;break; //The key in line 3 of column i is pressed
				case 0x07:key=12+i;      //The key in line 4 of column i is pressed 
            }
			
			do
			{
				temp=P2;  	    //Scan the button again
  				temp=temp&0x0f;  
  			}while(temp!=0x0f); //Waiting for key release   
  		}  
     }
}  
return(key);//Finish the scan and return the key value
}

void matrix(){
	unsigned char y,i=0;
	//while(1){
	y=keypad4_4();
	if(y<16){
		SBUF=keyval[y];	//Send lamp status to PC
    	while(!TI);//Waiting to be sent
    	TI=0;//Clear Send End Flag
	//	i++;		
	}
//	if(i==10) break;
//	} 		
}


//Playback function
void PlayMusic()
{
	unsigned int i=0,j,k;
	while(SONG_LONG[i]!=0||SONG_TONE[i]!=0)
	{	//Play each note, SONG_LONG for beat length
		for(j=0;j<SONG_LONG[i]*20;j++)
		{
			FM=~FM;
			//The SONG_TONE delay vote determines the frequency of each note.
			for(k=0;k<SONG_TONE[i]/3;k++);
		}
		delay(50);
		i++;		
	}
}




void main (void)
{ unsigned char t,led=0xff;		//The initial state of the lamp is completely extinguished
  unsigned int a=1;
  FM=0;
  SCON=0x50;//Serial Port Mode 1
  PCON=0x00;//T1 initialization,
  TMOD=0x20;//T1 is set as mode 2
  TH1=0xFD;//Choose 9600, fosc=11.0592MHz
  TR1=1;//Start T1

  P0=led;
  send(led); //Send the initial state to the host computer 
  LCD_Init();    //Initialization 1602
  WrComLCD(0x80); //Location is the first in the first line.
  while(1)
  {
  	matrix();
  
    if(RI)//Receiving Upper Computer Data
    {	RI=0;//Clear Receiving Mark
        t=SBUF;	//Receiving data from host computer
		if(t!='d' && t!='l' && t!='c')  WrDatLCD(t);

		if(t=='s') 	 //'s'is the synchronization requester of the host computer.
		    send(led);//Direct sending display status to host computer
		if(t=='d'){    //'d'deletes a character for the 1602 display
			WrComLCD(0x10); WrDatLCD(' '); delay(5);  WrComLCD(0x10);
		}
		if(t=='l'){	   //'l'is a line change for 1602 display
			if(a==1){
				WrComLCD(0xC0); a=0;}
			else {WrComLCD(0x80);a=1;}
		}
		if(t=='c'){    // 'c'clears the screen for 1602 display screen
			WrComLCD(0x01);	   //Clean screen
			WrComLCD(0x80);
		}
		if(t=='f'){
			PlayMusic();
		}
		if(t>='0' && t<='7'){		 //Receiving the Upper Computer Key
			t=t-'0';// Get the key code of the host computer
			led=led^(1<<t);//Keyboard counterposition
			P0=led;	//Updating SCM Display
			send(led); //Send Display Status to PC
		}	
    }
  }  
}

4. Experimental results

Because I can't upload videos, so I upload effect videos to Youku, please click and watch - --->. Effect Video Display

Added by sajidfiaz on Tue, 08 Oct 2019 07:38:18 +0300