/******************************************************************
* Custom Macro
*******************************************************************/
//All encodings are reverse encoding
#define CLEAR 0x7f //define the inverse code of clear
#define LED_BEGIN 0x01 // Define the display of the digital tube at the beginning
#define LED_FOUL 0x38 // Display the letter "F" after a foul, digital tube code
#define LED_C 0x31 // Code for the letter "C"
#define LED_L 0x71 // The code for the letter "L". Two are used to display "CL" after the host cancels the function.
#define GET 1 // This is used as a function parameter, which means successful answer
#define FOUL 0 // Mixed with the above parameters, foul---the usage of these two will be reflected later
#define READY 0x7e
/******************************************************************
* Custom data types
*******************************************************************/
typedef unsigned char Byte; // one byte
typedef unsigned int Word; // one word, two bytes
typedef bit Bool; // imitate Boolean variable
//typedef sbit Port; // I wanted to define a variable of type port, which is more convenient, but I don't know why this sentence cannot be compiled.
/******************************************************************
* Define MAX7219 registers
*******************************************************************/
#define REG_NO_OP 0x00 // Define no operation register
#define DIG_1 0x01 // Define digital tube 1 register
#define DIG_2 0x02 // Define digital tube 2 register
#define DIG_3 0x03 // Define digital tube 3 register
#define DIG_4 0x04 // Define digital tube 4 register
#define DIG_5 0x05 // Define digital tube 5 register
#define DIG_6 0x06 // Define digital tube 6 register
#define DIG_7 0x07 // Define digital tube 7 register
#define DIG_8 0x08 // Define digital tube 8 register
#define REG_DECODE 0x09 // Define the decoding control register
#define REG_INTENSITY 0x0a // Define display brightness register
#define REG_SCAN_LIMIT 0x0b // Define scan limit register
#define REG_SHUTDOWN 0x0c // define "shutdown" mode register
#define REG_DISPLAY_TEST 0x0f // define "display test" mode register
#define INTENSITY_MIN 0x00 // Define the minimum display brightness
#define INTENSITY_MAX 0x0f // Define the maximum display brightness
/*********************************************************************
* Define hardware pin connections
**********************************************************************/
sbit DA
sbit LOAD=P2^1; // MAX7219 latch port
sbit CLK=P2^2; // MAX7219 clock port
//sbit HOST_SWITCH=P0^0; // Host switch interface
sbit HOST_START=P0^0; //Host button, used to restart start
sbit HOST_CANCEL=P0^1; //Key used by the host to cancel the answer clear
sbit SWITCH1_3=P1^4; // DIP switch for adjusting countdown time. The number before the underscore represents the switch number, and the number after the underscore represents the value of the switch.
sbit SWITCH2_2=P1^5; // Same as above
sbit SWITCH3_2=P1^6; // Same as above
sbit SWITCH4_1=P1^7; // Same as above
sbit BEEP=P0^7; //define buzzer port
sbit LS138_C=P2^4; //define decoder input terminal
sbit LS138_B=P2^5; //same as above
sbit LS138_A=P2^6; //same as above
sbit LS138_E1=P2^7; //define decoder enable terminal
/*********************************************************************
* Define global variables
**********************************************************************/
Byte
Byte data
Byte
Byte
Bool
Bool data
Bool
Byte
co
/***********************************************************************
* Common cathode seven-segment digital tube display corresponding segment query table (digits 0-9 correspond to code_table
***********************************************************************/
Byte co
{0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b};
Byte co
{0x01,0x4f,0x12,0x06,0x4c,0x24,0x20,0x0f,0x00,0x04};
/***********************************************************************
* Function declaration
***********************************************************************/
void MAX7219_SendByte (Byte dataout);
void MAX7219_Write (Byte reg_number, Byte dataout);
void MAX7219_DisplayChar(Byte digit, Byte character);
void MAX7219_Clear (void);
void MAX7219_SetBrightness (Byte brightness);
void MAX7219_DisplayTestStart (void);
void MAX7219_DisplayTestStop (void);
void MAX7219_ShutdownStart (void);
void MAX7219_ShutdownStop (void);
void MAX7219_Init (void);
void Delay10ms(void);
Bool GetHostStartKey (void);
Bool GetHostCancelKey (void);
void GetCounter(void);
Byte GetPressed(Byte KeyState);
void IT0_Init(void);
void Timer0_Overflow();
void PressedHandle(Byte keyPressed);
void GetOrFoulHandle(Bool state);
void CancelHandle();
void SPEAKER_count (void); //Declare countdown sound function
void SPEAKER_start(void); //Declare the function to start answering voice
void SPEAKER_get(void); //Declare the function to grab the sound
void SPEAKER_foul(void); // declare foul sound function
/***********************************************************************
* MAX7219_SendByte()
*
* Description: Send one byte of data to MAX7219
* Arguments : dataout = da
* Returns : none
*************************************************************************/
void MAX7219_SendByte (Byte dataout)
{
Byte i;
for (i=8;i>0;i--)
{
Byte mask=1<<(i-1); //mask is a mask, use the bit
CLK=0; //The bit input of MAX7219 is before the rising edge of the clock, so it must become a low level before each bit is sent
if (dataout&mask)
DA
else
DA
CLK=1; //After all eight bits are transmitted, it becomes high level and latches
}
}
/***********************************************************************
* MAX7219_Write()
*
* Description: Write commands to MAX7219
* Arguments : reg_number = register to write to
* dataout = da
* Returns : none
Incomplete~
***************************************************************************/
void MAX7219_Write (Byte reg_number, Byte dataout)
{
LOAD=0; //It is also before the latch rising edge, and it must become a low level before sending these two bytes.
MAX7219_SendByte(reg_number); //Send register address
MAX7219_SendByte(dataout); //Send data
LOAD=1; //Change to high level, latch
}
/**************************************************************************
* MAX7219_DisplayChar()
*
* Description: Make a certain position display a number
* Arguments : digit = digit number (0-7)
* character = character to display (0-9, A-Z)
* Returns : none
**************************************************************************/
void MAX7219_DisplayChar(Byte digit, Byte character)
{
MAX7219_Write(digit, character);
}
/**************************************************************************
* MAX7219_Clear()
*
* Description: Clear all bits of display
* Arguments : none
* Returns : none
***************************************************************************/
void MAX7219_Clear (void)
{
Byte i;
for (i=1; i<=2; i++)
MAX7219_Write(i, CLEAR); // Clear all eight digital tubes, the writing is reversed^_^
}
/**************************************************************************
* MAX7219_SetBrightness()
*
* Description: Set the digital tube display brightness
* Arguments : brightness (0-15)
* Returns : none
***************************************************************************/
void MAX7219_SetBrightness (Byte brightness)
{
brightness &= 0x0f;
MAX7219_Write(REG_INTENSITY, brightness);
}
/**************************************************************************
* MAX7219_DisplayTestStart()
*
* Description: Enter test mode
* Arguments : none
* Returns : none
***************************************************************************/
void MAX7219_DisplayTestStart (void)
{
MAX7219_Write(REG_DISPLAY_TEST, 1);
}
/**************************************************************************
* MAX7219_DisplayTestStop()
*
* Description: Exit test mode
* Arguments : none
* Returns : none
***************************************************************************/
void MAX7219_DisplayTestStop (void)
{
MAX7219_Write(REG_DISPLAY_TEST, 0);
}
/**************************************************************************
* MAX7219_ShutdownStart()
*
* Description: Enter shutdown mode
* Arguments : none
* Returns : none
***************************************************************************/
void MAX7219_ShutdownStart (void)
{
MAX7219_Write(REG_SHUTDOWN, 0);
}
/**************************************************************************
* MAX7219_ShutdownStop()
*
* Description: Exit shutdown mode
* Arguments : none
* Returns : none
***************************************************************************/
void MAX7219_ShutdownStop (void)
{
MAX7219_Write(REG_SHUTDOWN, 1);
}
/**************************************************************************
* MAX7219_Init()
*
* Description: MAX7219 initialization module; should be called before other MAX7219 functions
* Arguments : none
* Returns : none
***************************************************************************/
void MAX7219_Init (void)
{
DA
CLK=1;
LOAD=1;
MAX7219_Write(REG_SCAN_LIMIT,1); //The setting here is to scan two digital tubes
MAX7219_Write(REG_DECODE, 0x00);
MAX7219_SetBrightness(INTENSITY_MAX); //Set the maximum brightness display
MAX7219_DisplayTestStart();
MAX7219_DisplayTestStop();
MAX7219_ShutdownStop();
MAX7219_Clear();
}
/**************************************************************************
* Delay_100us()
*
* Description: Delay 100us, mainly used to eliminate switch jitter
* Arguments : none
* Returns : none
***************************************************************************/
void Delay10ms(void)
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
/**************************************************************************
* GetHostStartKey()
*
* Description: Get the key value of the host's start button
* Arguments : none
* Returns: 1-->host presses the button; 0-->host does not press the button
***************************************************************************/
Bool GetHostStartKey (void)
{
if (HOST_START ==1)
return 0;
else
Delay10ms (); //If the host presses the button to connect, delay 100us to prevent jitter
if (HOST_START==1)
return 0;
else
return 1; //If the key is still connected during the delay, it is judged that the key is pressed
}
/**************************************************************************
* GetHostCancelKey()
*
* Description: Get the host's cancel button key value
* Arguments : none
* Returns: 1-->host presses the button; 0-->host does not press the button
***************************************************************************/
Bool GetHostCancelKey (void)
{
if (HOST_CANCEL ==1)
return 0;
else
Delay10ms (); //If the host presses the button to connect, delay 100us to prevent jitter
if (HOST_CANCEL ==1)
return 0;
else
return 1; //If the key is still connected during the delay, it is judged that the key is pressed
}
/**************************************************************************
* GetCounter
*
* Description: Get the preset countdown time
* Arguments : none
* Returns : none
***************************************************************************/
void GetCounter(void)
{
beginNum=1; //When all switches are not turned, the countdown is 1 second, which is better than setting it to 0 seconds
intrCounter=20; //The number of interrupts per second is 20
if (SWITCH1_3==1)
{
beginNum+=3;
}
if (SWITCH2_2==1)
{
beginNum+=2;
}
if (SWITCH3_2==1)
{
beginNum+=2;
}
if (SWITCH4_1==1)
{
beginNum+=1;
}//The above judgment statement is to judge the state of the dip switch
intrCounter=20*beginNum; //Calculate the total number of scans
}
/**************************************************************************
* GetPressed
*
* Description: Connect the four digits of the answer terminal from the P1 port to judge the answer situation
* Arguments : Byte KeyState-->P1 state
* Returns: The number of the answering terminal; 0--> No one answers
***************************************************************************/
Byte GetPressed(Byte KeyState)
{
Byte key; //Record the number of the answering terminal
KeyState&=0x0f; //Get the lower four bits of P1 port
switch (KeyState)
{
case 0x0f: key=0;break;//full height, no one answers
case 0x0e: key=1;break;//Only P1.1, key1 answers
case 0x0d: key=2;break;//Only P1.2, key2 answers
case 0x0b: key=3;break;//Only P1.3, key3 answers
case 0x07: key=4;break;//Only P1.4, key4 answers
}
/*
switch (KeyState)
{
case 0x00: key=0;break;//full height, no one answers
case 0x01: key=1;break;//Only P1.0, key1 answers
case 0x02: key=2;break;//Only P1.1, key2 answer
case 0x04: key=3;break;//Only P1.2, key3 answer
case 0x08: key=4;break;//Only P1.3, key4 answer
}
*/
//The above is the program for using high level to judge the answering status. It is proved to be invalid for some reason.
return key;
}
/**************************************************************************
* IT0_Heat
*
* Description: Initialize the state of timer T0
* Arguments : none
* Returns : none
***************************************************************************/
void IT0_Init(void)
{
TMOD=0x01; //Set T0 to work in mode 1
TH0=0x3C;
TL0=0xAF; //These two registers store the starting value of the counter. It is found that the two values are accumulated to overflow, which is exactly 50ms.
ET0=1; // Enable T0 interrupt to overflow
EA=1; // Enable general interrupt
TF0=0; // Overflow bit cleared
TR0=1; //Turn on T0
}
/**************************************************************************
* Timer0_Overflow() interrupt 1
*
* Description: Interrupt overflow service routine, using interrupt mode 1, it is best not to add "using" to select the register group to avoid conflicts with the registers used by the system in the main program
* Arguments : none
* Returns : none
***************************************************************************/
void Timer0_Overflow() interrupt 1
{
static Byte second=20; //Use 20 interrupts to determine 1 second
TH0=0x3C;
TL0=0xAF;
second--;
intrCounter--;
/*
if (second==0) //Operation every one second
{
MAX7219_DisplayChar(DIG_2,
second=20; //Reassign the counter per second
if (intrCounter==0)
{
TR0=0; //Close T0 counter
isStart=1; //Timeout ends, enter normal answering
//SPEAKER_start(); //Start answering the question
}
//After "0" is displayed, start answering
else
{
//SPEAKER_count(); //Countdown sound
}
}
*/
if (second==0) //Operation every one second
{
//if (showNum!=1) SPEAKER_count(); //Countdown sound
//else SPEAKER_start();//Start answering the question
MAX7219_DisplayChar(DIG_2,
second=20; //Reassign the counter per second
}//After "0" is displayed, start answering
if (intrCounter==0)
{
TR0=0; //Close T0 counter
isStart=1; //Timeout ends, enter normal answering
}
}
/**************************************************************************
* PressedHandle
*
* Description: Key processing
* Arguments : Byte keyPressed-->The key pressed
* Returns : none
***************************************************************************/
void PressedHandle(Byte keyPressed)
{
MAX7219_Clear();//LED clear
MAX7219_DisplayChar(DIG_2,
}
/**************************************************************************
* GetOrFoulHandle(Bool state)
*
* Description: Normal answer or foul treatment
* Arguments: Bool state-->One of the two macros GET and FOUL
* Returns : none
***************************************************************************/
void GetOrFoulHandle(Bool state)
{
if (!state)
{
MAX7219_DisplayChar(DIG_1,LED_FOUL); //If it is a foul, the left LED should display "F", foul
}
}
/**************************************************************************
* CancelHandle()
*
* Description: Process the host to cancel the countdown
* Arguments : none
* Returns : none
***************************************************************************/
void CancelHandle()
{
MAX7219_DisplayChar(DIG_1,LED_C);
MAX7219_DisplayChar(DIG_2,LED_L); //After the host cancels the countdown, the two digital tubes display "CL" --> cancel
}
/**************************************************************************
* delayus()
*
* Description: Delay program
* Arguments : t-->us
* Returns : time delayed
***************************************************************************/
void delayus(unsigned char t )
{
unsigned char j;
for(;t>0;t--)
for(j=19;j>0;j--);
}
/**************************************************************************
* SPEAKER_count/start/foul/get()
*
* Description: Speaker sound program-> count/start/foul/answer four sounds
* Arguments : none
* Returns : none
***************************************************************************/
void SPEAKER_count(void)
{
unsigned char i;
for (i=0;i<10;i++)
{
BEEP =1; //light up
delayus(20);
BEEP =0; // off
delayus(20);
}
}
void SPEAKER_start(void)
{
unsigned char i;
for(i=0;i<200;i++)
{
BEEP =1; //light up
delayus(10);
BEEP =0; // off
delayus(10);
}
}
void SPEAKER_foul(void)
{
unsigned char i;
for(i=0;i<250;i++)
{
BEEP =1; //light up
delayus(15);
BEEP =0; // off
delayus(17);
}
}
void SPEAKER_get(void)
{
unsigned char i;
for(i=0;i<250;i++)
{
BEEP =1; //light up
delayus(10);
BEEP =0; // off
delayus(10);
}
for(i=0;i<250;i++)
{
BEEP =1; //light up
delayus(20);
BEEP =0; // off
delayus(20);
}
}
/**************************************************************************
* Main program
***************************************************************************/
void main()
{
Byte keyPressed,i; //Player key number, if not, it is 0
Bool hostPressed; //Used to record the host's key press cancellation, 0 means no action, 1 means cancel
number_temp=P1&0xf0; //The last status of P1 port, used when adjusting the countdown time
LS138_E1=1; //Decoder initialization
MAX7219_Init(); // Initialize the digital tube
GetCounter(); //Get the countdown time set at the beginning
MAX7219_DisplayChar(DIG_1,
MAX7219_DisplayChar(DIG_2,READY); //Display of the right position when adjusting the time
//while(1);
while(GetHostStartKey()==0) //Enter the loop when the host does not press a key
{
if (number_temp!=(P1&0xf0)) //If the countdown time is adjusted, the status of P1 port will change and it needs to be reset and displayed again
{
GetCounter(); //Get the countdown time after adjustment
MAX7219_DisplayChar(DIG_1,
number_temp=P1&0xf0; //Record the current status of P1 port for later comparison
}
} //When the host presses the button, the adjustment ends and the countdown to answering the question begins
MAX7219_DisplayChar(DIG_1,READY);
while(GetHostCancelKey()==0);
MAX7219_DisplayChar(DIG_1,READY); //Clear the right digital tube
MAX7219_DisplayChar(DIG_2,co
for (i=100;i--;i>0)
Delay10ms(); //Prevent continuous reading later..
//After adjusting the countdown time, press start to display "--", then press cancel to display the countdown time, and you can start the countdown.
counterBack=intrCounter;
// The original code here is while(1), but it doesn't work after I write it. I don't know why..
while(1) // Here you need to use your own loop to constrain the program to run here
{
showNum=beginNum; //Set the time to be displayed, of course, starting from the countdown time
intrCounter=counterBack; //Set the total number of interrupts
TR0=0; //Disable timer 0
isPressed=0; //Record whether someone presses a button
isStart=0;//No answer has started
while(GetHostStartKey()==0);
IT0_Init(); //Initialize timer 0, enable.
MAX7219_DisplayChar(DIG_1,CLEAR); //Clear the left digital tube
MAX7219_DisplayChar(DIG_2,co
while(!isPressed) //If no key is recorded, enter
{
keyPressed=GetPressed(P1); //Query the status of port P1, i.e. the key status
hostPressed=GetHostCancelKey();
if (!keyPressed&&!hostPressed) //If no one presses a key, enter the next loop
continue;
else
{
TR0=0; //turn off the timer
isPressed=1; //Records when someone presses a button, providing conditions to exit the loop
}
}
if (keyPressed!=0)
{
if (isStart) // If the answer has started
{
PressedHandle(keyPressed); //Handle the key, that is, display the contestant's number
GetOrFoulHandle(GET); //Handle the answer
LS138_E1=0; //Decoder preparation
switch (keyPressed)
{
case 1: LS138_A=0;LS138_B=0;LS138_C=0;break; //No. 1 success light is on
case 2: LS138_A=0;LS138_B=1;LS138_C=0;break; //No. 2 success light is on
case 3: LS138_A=1;LS138_B=0;LS138_C=0;break; //No. 3 success light is on
case 4: LS138_A=1;LS138_B=1;LS138_C=0;break; //No. 4 success light is on
default : break;
}
//SPEAKER_get(); //Handle the answer
}
else//Otherwise, no answer is started
{
PressedHandle(keyPressed); //Handle the key, that is, display the contestant's number
GetOrFoulHandle(FOUL); //Handle foul, must be placed at the end, because there is a clear in the displayed number
LS138_E1=0; //Decoder preparation
switch (keyPressed)
{
case 1: LS138_A=0;LS138_B=0;LS138_C=1;break; //No. 1 foul light is on
case 2: LS138_A=0;LS138_B=1;LS138_C=1;break; //No. 2 foul light is on
case 3: LS138_A=1;LS138_B=0;LS138_C=1;break; //No. 3 foul light is on
case 4: LS138_A=1;LS138_B=1;LS138_C=1;break; //No. 4 foul light is on
default : break;
}
//SPEAKER_foul(); //Foul sound
}
}
if (hostPressed==1)
{
CancelHandle();
for (i=100;i--;i>0)
Delay10ms(); //Prevent continuous reading later..
}
while(GetHostCancelKey()==0); //If the host does not press the key to start again, it will stop at the next infinite loop
LS138_E1=1; //Turn off the decoder
MAX7219_DisplayChar(DIG_1,READY); //Clear the right digital tube
MAX7219_DisplayChar(DIG_2,
//One cycle ends here
}
}
Previous article:How to Write a Music Program for 51 Single Chip Microcomputer
Next article:Railway crossing alarm based on single chip microcomputer control
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- Design considerations for automotive battery wiring harness
- Do you know all the various motors commonly used in automotive electronics?
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- HGI HC32A460 series function comparison chart
- PCB drawing process shortcut keys
- How to start power supply design
- EEWORLD University ---- Machine Learning
- Has anyone tried the baud rate adaptation of LIN communication?
- Analog Electronics Design
- Will adding a nonlinear link to the RC bridge sine wave oscillation circuit cause waveform distortion?
- Introduction to TI_DSP link command file (*.cmd)
- [N32L43x Review] 2. Turn on the lights, blink, blink, blink...
- EEWORLD University Hall - Talking about the development creativity of electronic products and using network resources to help development