#include
#include
#define uchar unsigned char
#define uint unsigned int
#include "DS1302_drive.h"
uchar K1_FLAG=0; //Define the key flag. When the K1 key is pressed, this position is 1. When the K1 key is not pressed, this position is 0.
uchar const bit_tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //Bit selection table, used to select which digital tube to display
uchar const seg_data[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xbf};
//0~F, extinguisher and character "-" display code (font code) //0~F, extinguisher and character "-" display code (font code)
#define beep_0 (PORTD=PORTD&0x7f) //The buzzer on PD7 sounds
#define beep_1 (PORTD=PORTD|0x80) //The buzzer on PD7 does not sound
uchar disp_buf[8] ={0x00}; //Define display buffer
uchar time_buf[7] ={0,0,0x12,0,0,0,0}; //DS1302 time buffer, storing seconds, minutes, hours, days, months, weeks, years
uchar temp [2]={0}; //Used to store the intermediate values of hours and minutes when set
/********Function: Delay function********/
void Delay_ms(uint xms)
{
int i,j;
for(i=0;i
{ for(j=0;j<1140;j++); }
}
/*********The following is a function to make the buzzer sound********/
void beep()
{
beep_0; //The buzzer sounds
Delay_ms(100);
beep_1; //Turn off the buzzer
Delay_ms(100);
}
/********Port setting function********/
void port_init(void)
{
PORTA = 0xFF; //Output high level
DDRA = 0xFF; //Set to output
PORTC = 0xff; //Output high level
DDRC = 0xFF; //Set to output
DDRD =(0<
PORTD = 0xFF; //PD7 outputs high level, others are inputs with pull-up
}
/********The following is the time conversion function, which is responsible for converting the time data into data suitable for digital tube display********/
void conv(uchar in1,uchar in2,uchar in3) //Formal parameters in1, in2, in3 receive the hour/minute/second data from actual parameters time_buf[2], time_buf[1], time_buf[0]
{
disp_buf[0] =in1/10; // Hour tens digit
disp_buf[1] = in1%10; // Hour units digit
disp_buf[3] = in2/10; // Minute tens digit
disp_buf[4] = in2%10; // Minute units digit
disp_buf[6] = in3/10; // Seconds tens digit
disp_buf[7] = in3%10; // Seconds units digit
disp_buf[2] = 17; // The 3rd digital tube displays "-" (the 17th bit in the seg_data table)
disp_buf[5] = 17; // The 6th digital tube displays "-"
}
/********The following is the display function********/
void Display()
{
uchar tmp; //Define display temporary storage
static uchar disp_sel=0; //Display bit selection counter, through which the display program knows which digital tube is currently displayed, the initial value is 0
tmp=bit_tab[disp_sel]; //Determine which digital tube to display based on the current bit select count value
PORTC=tmp; //Send to P2 to control the selected digital tube to light up
tmp=disp_buf[disp_sel]; //Look up the display code of the number based on the current bit select count value
tmp=seg_data[tmp]; //Get the display code
PORTA=tmp; //Send to P0 port to display the corresponding number
disp_sel++; //Add 1 to the bit select count value and point to the next digital tube
if(disp_sel==8)
disp_sel=0; //If 8 digital tubes are displayed once, return them to 0 and scan again
}
/********The following is the timer T0 interrupt function,Used for dynamic scanning of digital tubes********/
#pragma interrupt_handler timer0_ovf:10
void timer0_ovf(void)
{
TIFR=0x01; //Write 1 to clear the timer T0 flag
TCNT0=240; //Set the initial count value and set the timing time to 2ms
Display(); //Call the display function
}
/********The following is the key processing function********/
void KeyProcess()
{
uchar min16,hour16; //Define hexadecimal minute and hour variables
write_ds1302(0x8e,0x00); //DS1302 write protection control word, allow writing
write_ds1302(0x80,0x80); //Clock stops running
if((PIND&0x3C)!=0x3C) //If one of the K1~K4 keys is pressed
Delay_ms(10); //Delay 10ms
if((PIND&0x3C)!=0x3C) //If it is still pressed, it means that it is not caused by jitter
{
if((PIND&0x08)==0) //The K2 key is used to adjust the hour by adding 1
{
while(!(PIND&0x08)); //Wait for the K2 key to be released
beep();
time_buf[2]=time_buf[2]+1; //Increase the hour by 1
if(time_buf[2]==24) time_buf[2]=0; //When it becomes 24, it is initialized to 0
hour16=time_buf[2]/10*16+time_buf[2]%10; //Convert the obtained hour data into hexadecimal data
write_ds1302(0x84,hour16); //Write the adjusted hour data into DS1302
}
if((PIND&0x10)==0) //The K3 key is used to adjust the minute by adding 1
{
while(!(PIND&0x10)); //Wait for the K3 key to be released
beep();
time_buf[1]=time_buf[1]+1; //Increase the minute by 1
if(time_buf[1]==60) time_buf[1]=0; //When the minute is added to 60, it is initialized to 0
min16=time_buf[1]/10*16+time_buf[1]%10; //Convert the obtained minute data into hexadecimal data
write_ds1302(0x82,min16); //Write the adjusted minute data to DS1302
}
if((PIND&0x20)==0) //K4 key is the confirmation key
{
while(!(PIND&0x20)); //Wait for K4 key to be released
beep();
write_ds1302(0x80,0x00); //After adjustment, start the clock
write_ds1302(0x8e,0x80); //Write protection control word, prohibit writing
K1_FLAG=0; //Clear the K1 key pressed flag
}
}
}
/********The following is the time reading function, which is responsible for reading the current time and converting the read time into a decimal number********/
void get_time()
{
uchar sec,min,hour; //Define the variables of seconds, minutes and hours
write_ds1302(0x8e,0x00); //Control command, WP=0, write operation is allowed
write_ds1302(0x90,0xab); //Trickle charge control
sec=read_ds1302(0x81); //Read seconds
min=read_ds1302(0x83); //Read minutes
hour=read_ds1302(0x85); //Read time
time_buf[0]=sec/16*10+sec%16; //Convert the read hexadecimal number into decimal
time_buf[1]=min/16*10+min%16; //Convert the read hexadecimal number to decimal
time_buf[2]=hour/16*10+hour%16; //Convert the read hexadecimal number to decimal
}
/********Timer 0 initialization********/
void timer0_init()
{
SREG = 0x80; //Enable global interrupt
TIMSK|=(1<
TCCR0|=(1<
TCNT0 = 240; //Set the initial value of the timing, the timing time is 2ms
}
/********The following is the main function********/
void main(void)
{
port_init();
timer0_init(); //Call the timer T0, T1 initialization function
init_ds1302(); //DS1302 initialization
while(1)
{
get_time(); //Read the current time
if((PIND&0x04)==0) //If the K1 key is pressed
{
Delay_ms(10); //Delay 10ms to debounce
if((PIND&0x04)==0)
{
while(!(PIND&0x04)); //Wait for the K1 key to be released
beep(); //The buzzer sounds once
K1_FLAG=1; //The K1 key flag position is 1 for clock adjustment
}
}
if(K1_FLAG==1)KeyProcess(); //If K1_FLAG is 1, adjust the time
conv(time_buf[2],time_buf[1],time_buf[0]); //Transfer the hours/minutes/seconds of DS1302 to the conversion function
}
}
Reference address:C language programming of DS1302 digital tube time display based on AVR microcontroller
#include
#define uchar unsigned char
#define uint unsigned int
#include "DS1302_drive.h"
uchar K1_FLAG=0; //Define the key flag. When the K1 key is pressed, this position is 1. When the K1 key is not pressed, this position is 0.
uchar const bit_tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //Bit selection table, used to select which digital tube to display
uchar const seg_data[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xbf};
//0~F, extinguisher and character "-" display code (font code) //0~F, extinguisher and character "-" display code (font code)
#define beep_0 (PORTD=PORTD&0x7f) //The buzzer on PD7 sounds
#define beep_1 (PORTD=PORTD|0x80) //The buzzer on PD7 does not sound
uchar disp_buf[8] ={0x00}; //Define display buffer
uchar time_buf[7] ={0,0,0x12,0,0,0,0}; //DS1302 time buffer, storing seconds, minutes, hours, days, months, weeks, years
uchar temp [2]={0}; //Used to store the intermediate values of hours and minutes when set
/********Function: Delay function********/
void Delay_ms(uint xms)
{
int i,j;
for(i=0;i
}
/*********The following is a function to make the buzzer sound********/
void beep()
{
beep_0; //The buzzer sounds
Delay_ms(100);
beep_1; //Turn off the buzzer
Delay_ms(100);
}
/********Port setting function********/
void port_init(void)
{
PORTA = 0xFF; //Output high level
DDRA = 0xFF; //Set to output
PORTC = 0xff; //Output high level
DDRC = 0xFF; //Set to output
DDRD =(0<
}
/********The following is the time conversion function, which is responsible for converting the time data into data suitable for digital tube display********/
void conv(uchar in1,uchar in2,uchar in3) //Formal parameters in1, in2, in3 receive the hour/minute/second data from actual parameters time_buf[2], time_buf[1], time_buf[0]
{
disp_buf[0] =in1/10; // Hour tens digit
disp_buf[1] = in1%10; // Hour units digit
disp_buf[3] = in2/10; // Minute tens digit
disp_buf[4] = in2%10; // Minute units digit
disp_buf[6] = in3/10; // Seconds tens digit
disp_buf[7] = in3%10; // Seconds units digit
disp_buf[2] = 17; // The 3rd digital tube displays "-" (the 17th bit in the seg_data table)
disp_buf[5] = 17; // The 6th digital tube displays "-"
}
/********The following is the display function********/
void Display()
{
uchar tmp; //Define display temporary storage
static uchar disp_sel=0; //Display bit selection counter, through which the display program knows which digital tube is currently displayed, the initial value is 0
tmp=bit_tab[disp_sel]; //Determine which digital tube to display based on the current bit select count value
PORTC=tmp; //Send to P2 to control the selected digital tube to light up
tmp=disp_buf[disp_sel]; //Look up the display code of the number based on the current bit select count value
tmp=seg_data[tmp]; //Get the display code
PORTA=tmp; //Send to P0 port to display the corresponding number
disp_sel++; //Add 1 to the bit select count value and point to the next digital tube
if(disp_sel==8)
disp_sel=0; //If 8 digital tubes are displayed once, return them to 0 and scan again
}
/********The following is the timer T0 interrupt function,Used for dynamic scanning of digital tubes********/
#pragma interrupt_handler timer0_ovf:10
void timer0_ovf(void)
{
TIFR=0x01; //Write 1 to clear the timer T0 flag
TCNT0=240; //Set the initial count value and set the timing time to 2ms
Display(); //Call the display function
}
/********The following is the key processing function********/
void KeyProcess()
{
uchar min16,hour16; //Define hexadecimal minute and hour variables
write_ds1302(0x8e,0x00); //DS1302 write protection control word, allow writing
write_ds1302(0x80,0x80); //Clock stops running
if((PIND&0x3C)!=0x3C) //If one of the K1~K4 keys is pressed
Delay_ms(10); //Delay 10ms
if((PIND&0x3C)!=0x3C) //If it is still pressed, it means that it is not caused by jitter
{
if((PIND&0x08)==0) //The K2 key is used to adjust the hour by adding 1
{
while(!(PIND&0x08)); //Wait for the K2 key to be released
beep();
time_buf[2]=time_buf[2]+1; //Increase the hour by 1
if(time_buf[2]==24) time_buf[2]=0; //When it becomes 24, it is initialized to 0
hour16=time_buf[2]/10*16+time_buf[2]%10; //Convert the obtained hour data into hexadecimal data
write_ds1302(0x84,hour16); //Write the adjusted hour data into DS1302
}
if((PIND&0x10)==0) //The K3 key is used to adjust the minute by adding 1
{
while(!(PIND&0x10)); //Wait for the K3 key to be released
beep();
time_buf[1]=time_buf[1]+1; //Increase the minute by 1
if(time_buf[1]==60) time_buf[1]=0; //When the minute is added to 60, it is initialized to 0
min16=time_buf[1]/10*16+time_buf[1]%10; //Convert the obtained minute data into hexadecimal data
write_ds1302(0x82,min16); //Write the adjusted minute data to DS1302
}
if((PIND&0x20)==0) //K4 key is the confirmation key
{
while(!(PIND&0x20)); //Wait for K4 key to be released
beep();
write_ds1302(0x80,0x00); //After adjustment, start the clock
write_ds1302(0x8e,0x80); //Write protection control word, prohibit writing
K1_FLAG=0; //Clear the K1 key pressed flag
}
}
}
/********The following is the time reading function, which is responsible for reading the current time and converting the read time into a decimal number********/
void get_time()
{
uchar sec,min,hour; //Define the variables of seconds, minutes and hours
write_ds1302(0x8e,0x00); //Control command, WP=0, write operation is allowed
write_ds1302(0x90,0xab); //Trickle charge control
sec=read_ds1302(0x81); //Read seconds
min=read_ds1302(0x83); //Read minutes
hour=read_ds1302(0x85); //Read time
time_buf[0]=sec/16*10+sec%16; //Convert the read hexadecimal number into decimal
time_buf[1]=min/16*10+min%16; //Convert the read hexadecimal number to decimal
time_buf[2]=hour/16*10+hour%16; //Convert the read hexadecimal number to decimal
}
/********Timer 0 initialization********/
void timer0_init()
{
SREG = 0x80; //Enable global interrupt
TIMSK|=(1<
}
/********The following is the main function********/
void main(void)
{
port_init();
timer0_init(); //Call the timer T0, T1 initialization function
init_ds1302(); //DS1302 initialization
while(1)
{
get_time(); //Read the current time
if((PIND&0x04)==0) //If the K1 key is pressed
{
Delay_ms(10); //Delay 10ms to debounce
if((PIND&0x04)==0)
{
while(!(PIND&0x04)); //Wait for the K1 key to be released
beep(); //The buzzer sounds once
K1_FLAG=1; //The K1 key flag position is 1 for clock adjustment
}
}
if(K1_FLAG==1)KeyProcess(); //If K1_FLAG is 1, adjust the time
conv(time_buf[2],time_buf[1],time_buf[0]); //Transfer the hours/minutes/seconds of DS1302 to the conversion function
}
}
Previous article:C language programming of 24C08 data operation based on AVR microcontroller
Next article:IC card program based on sle4442 (avr)
- Popular Resources
- Popular amplifiers
Recommended Content
Latest Microcontroller Articles
- 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)
He Limin Column
Microcontroller and Embedded Systems Bible
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
MoreSelected Circuit Diagrams
MorePopular Articles
- 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
MoreDaily News
- 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
Guess you like
- Learning Linux kernel semaphores on SinlinxA33 development board
- STM32 encoder signal interference.
- [GD32L233C-START Evaluation] +ADC collects PT1000 to obtain temperature
- Three traditional methods of wireless video transmission
- Displaying the SARS-CoV-2 virus with flashing LEDs
- How to improve simulation? Learn to generate LTspice models yourself
- Essential for EMC Electronic Engineers
- Can you help me take a look at this FPGA development board?
- FLUKE is hiring!
- Help, about converting hexadecimal to numeric value (LIS25BA)