采用DS1302完成实时时钟的设计数码管显示时间按键调整时间请在以下代码的基础上修改#include avrioh#include utildelayh#include NBCAVRH#include avrinterrupthunsigned char smg=0xD70x140xCD0x5D0x1E0x5B0xDB0x150xDF0x5F;unsigned int sceminhourmina
在代码中添加DS1302的相关函数来实现实时时钟的功能。首先,需要添加DS1302的读写函数,用于与DS1302进行通信。然后,在主函数中初始化DS1302,并在循环中读取DS1302的时间数据,并将其显示在数码管上。同时,通过按键来调整时间,按下不同的按键可以增加分钟和小时。以下是修改后的代码:
#include <avr/io.h>
#include <util/delay.h>
#include "NBCAVR.H"
#include <avr/interrupt.h>
// DS1302相关定义
#define DS1302_CLK_PIN PD0
#define DS1302_DAT_PIN PD1
#define DS1302_RST_PIN PD2
unsigned char smg[]={0xD7,0x14,0xCD,0x5D,0x1E,0x5B,0xDB,0x15,0xDF,0x5F};
unsigned int sce,min,hour,mina,minb,hourc,hourd;
unsigned int temp;
// DS1302读写函数
void DS1302_WriteByte(unsigned char dat)
{
unsigned char i;
for(i=0; i<8; i++)
{
if(dat & 0x01)
PORTD |= (1 << DS1302_DAT_PIN);
else
PORTD &= ~(1 << DS1302_DAT_PIN);
PORTD |= (1 << DS1302_CLK_PIN);
_delay_us(1);
PORTD &= ~(1 << DS1302_CLK_PIN);
_delay_us(1);
dat >>= 1;
}
}
unsigned char DS1302_ReadByte()
{
unsigned char i, dat = 0;
for(i=0; i<8; i++)
{
dat >>= 1;
if(PIND & (1 << DS1302_DAT_PIN))
dat |= 0x80;
PORTD |= (1 << DS1302_CLK_PIN);
_delay_us(1);
PORTD &= ~(1 << DS1302_CLK_PIN);
_delay_us(1);
}
return dat;
}
void DS1302_Write(unsigned char reg, unsigned char dat)
{
PORTD &= ~(1 << DS1302_RST_PIN); // 拉低RST引脚
_delay_us(1);
PORTD &= ~(1 << DS1302_CLK_PIN); // 拉低CLK引脚
_delay_us(1);
DS1302_WriteByte(reg); // 写入寄存器地址
DS1302_WriteByte(dat); // 写入数据
PORTD |= (1 << DS1302_RST_PIN); // 拉高RST引脚
_delay_us(1);
}
unsigned char DS1302_Read(unsigned char reg)
{
unsigned char dat;
PORTD &= ~(1 << DS1302_RST_PIN); // 拉低RST引脚
_delay_us(1);
PORTD &= ~(1 << DS1302_CLK_PIN); // 拉低CLK引脚
_delay_us(1);
DS1302_WriteByte(reg | 0x01); // 写入寄存器地址,最低位为1表示读取
dat = DS1302_ReadByte(); // 读取数据
PORTD |= (1 << DS1302_RST_PIN); // 拉高RST引脚
_delay_us(1);
return dat;
}
void SMG(){
hourd=hour/10;
hourc=hour%10;
minb=min/10;
mina=min%10;
PIOA7=1;
PORTC=smg[hourd];
_delay_ms(2);
PIOA7=0;
PIOA6=1;
PORTC=smg[hourc];
_delay_ms(2);
PIOA6=0;
PIOA5=1;
PORTC=smg[minb];
_delay_ms(2);
PIOA5=0;
PIOA4=1;
PORTC=smg[mina];
_delay_ms(2);
PIOA4=0;
}
void key(){
if((PIND&0x70)!=0x70){
_delay_ms(20);
if((PIND&0x70)!=0x70){
if((PIND&0x70)==0x60){
_delay_ms(100);
min++;
}
if((PIND&0x70)==0x30){
_delay_ms(100);
hour++;
}
if((PIND&0x70)==0x50){
}
}
}
}
void TIME0_INIT(){
TCCR0=0X00;
TCNT0=131;
TIMSK=0X01;
SREG=0X80;
TCCR0=0X02;
}
ISR(TIMER0_OVF_vect){
temp++;
if(temp>999){
temp = 0;
PIOA0=~PIOA0;
PIOA1=~PIOA1;
PIOA2=~PIOA2;
PIOA3=~PIOA3;
sce++;
}
if (sce>=60)
{
min++;
sce=0;
}
if (min>=60)
{
hour++;
min=0;
}
if (hour>=24)
{
hour=0;
}
}
int main(void)
{
DDRA=0XFF;
DDRC=0XFF;
PORTA=0X0F;
DDRD=0xFF;
PORTD=0x70;
// 初始化DS1302
DS1302_Write(0x8E, 0x00); // 关闭写保护
DS1302_Write(0x80, 0x00); // 秒设为00
DS1302_Write(0x82, 0x00); // 分设为00
DS1302_Write(0x84, 0x00); // 时设为00
TIME0_INIT();
/* Replace with your application code */
while (1)
{
// 读取DS1302的时间数据
hour = DS1302_Read(0x85);
min = DS1302_Read(0x83);
sce = DS1302_Read(0x81);
key();
SMG();
// 更新DS1302的时间数据
DS1302_Write(0x80, 0x00); // 秒设为00
DS1302_Write(0x82, min); // 分设为当前分钟
DS1302_Write(0x84, hour); // 时设为当前小时
}
}
请注意,以上代码仅为示例,具体的DS1302读写函数可能需要根据DS1302的规格书进行修改,以确保正确的通信和操作。
原文地址: https://www.cveoy.top/t/topic/hRSu 著作权归作者所有。请勿转载和采集!