51单片机实验15:DS1302时钟模块应用

开发板DS1302模块电路图如下:

 

目的:单片机查询DS1302时钟模块时间,并将其显示在数码管上。

DS1302的初始化时间为2019年1月1日12:00(星期二)

#include<reg52.h>
#include<dse1302.h>

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

uc code x[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uc tim[9];

void delay(uc x)
{
	uc i,j;
	for(i=1;i<=x;i++)
		for(j=1;j<=110;j++);
}

void digdisplay()
{
	uc i;
	for(i=1;i<=8;i++)
	{
		switch(i)
		{
			case (1):
			LSA=0;LSB=0;LSC=0;break;
			case (2):
			LSA=1;LSB=0;LSC=0;break;
			case (3):
			LSA=0;LSB=1;LSC=0;break;
			case (4):
			LSA=1;LSB=1;LSC=0;break;
			case (5):
			LSA=0;LSB=0;LSC=1;break;
			case (6):
			LSA=1;LSB=0;LSC=1;break;
			case (7):
			LSA=0;LSB=1;LSC=1;break;
			case (8):
			LSA=1;LSB=1;LSC=1;break;
		}
		P0=tim[i];
		delay(1);
		P0=0x00;
	}
}

void datapros()//数据处理函数,将存储在ti数组中的时间,转化为可以在数码管上显示的时间。
{
	ds1302readtime();
	tim[8]=x[ti[2]/16];//数据以BCD码的形式存储在ti数组中(十六进制),在获取时间时注意处理方法。

	tim[7]=x[ti[2]%16];
	tim[6]=0x40;
	tim[5]=x[ti[1]/16];
	tim[4]=x[ti[1]%16];
	tim[3]=0x40;
	tim[2]=x[ti[0]/16];
	tim[1]=x[ti[0]%16];
}

void main()
{
	ds1302init();
	while(1)
	{
		datapros();
		digdisplay();
	}
}
#include<ds1302.h>

uc code read_addr[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};//读地址,读为1 
uc code write_addr[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};//写地址,写为0
uc ti[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x19};//初始化时间

void ds1302write(uc addr,uc dat)
{
	uc i;
	sclk=0;
	rst=0;
	rst=1;
	for(i=1;i<=8;i++)
	{
		dsio=addr&0x01;
		addr>>=1;
        sclk=1;
		sclk=0;
	}
	for(i=1;i<=8;i++)
	{
		dsio=dat&0x01;
		dat>>=1;
		sclk=1;
		_nop_();
		sclk=0;
		_nop_();
	}
	rst=0;
}

uc ds1302read(uc addr)
{
	uc i,dat,dat1;
	sclk=0;
	rst=0;
	rst=1;
	for(i=1;i<=8;i++)
	{
		dsio=addr&0x01;
		addr>>=1;
		sclk=1;
		sclk=0;
	}
	for(i=1;i<=8;i++)
	{
		dat1=dsio&0x01;
		dat=(dat>>1)|(dat1<<7);
		sclk=1;
		sclk=0;
	}
	rst=0;
	dsio=0;//ds1302芯片复位稳定时间,必须有这句。
	return dat;
}

void ds1302init()
{
	uc i;
	ds1302write(0x8e,0x00);
	for(i=0;i<7;i++)
	{
		ds1302write(write_addr[i],ti[i]);
	}
	ds1302write(0x8e,0x80);
}

void ds1302readtime()
{
	uc i;
	for(i=0;i<7;i++)
	{
		ti[i]=ds1302read(read_addr[i]);
	}
}
#ifndef _DS1302_H_
#define _DS1302_H_

#include<reg52.h>
#include<intrins.h>

#ifndef uc
#define uc unsigned char
#endif
#ifndef ui
#define ui unsigned int
#endif

sbit sclk=P3^6;
sbit dsio=P3^4;
sbit rst=P3^5;

void ds1302readtime();
void ds1302init();

extern uc ti[7];

#endif

 

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是普中51-实验板制作的简易作业代码: ```c #include <reg52.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int sbit beep = P1^5; // 蜂鸣器 sbit DIO = P2^0; // 点阵屏数据线 sbit CLK = P2^1; // 点阵屏时钟线 sbit SDA = P2^2; // 温度传感器数据线 sbit SCL = P2^3; // 温度传感器时钟线 sbit LATCH = P2^4; // 74HC595锁存器控制线 uchar code DIG_CODE[] = { // 共阴数码管显示代码表 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F }; uchar code LED_CODE[] = { // LED灯显示代码表 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F }; uchar code KEY_CODE[] = { // 矩阵键盘按键代码表 0xEE, 0xDE, 0xBE, 0x7E }; uchar code DIS_CODE[] = { // 显示屏显示代码表 0x38, 0x0C, 0x01, 0x06, 0x1F }; uchar code TEXT[] = "Hello, World!"; // 显示屏显示文本 void delay(uint t) // 延时函数 { while (t--); } void writeByte(uchar dat) // 点阵屏写入一个字节 { uchar i; for (i = 0; i < 8; i++) { DIO = dat & 0x80; dat <<= 1; CLK = 0; _nop_(); CLK = 1; } } void writeCmd(uchar cmd) // 点阵屏写入命令 { LATCH = 0; writeByte(0xC0); writeByte(cmd); LATCH = 1; } void writeData(uchar dat) // 点阵屏写入数据 { LATCH = 0; writeByte(0xC1); writeByte(dat); LATCH = 1; } void initDS18B20() // 初始化温度传感器 { SDA = 1; SCL = 1; delay(2); SDA = 0; delay(80); SDA = 1; delay(2); } void writeDS18B20(uchar dat) // 写入温度传感器一个字节 { uchar i; for (i = 0; i < 8; i++) { SDA = dat & 0x01; dat >>= 1; SCL = 0; delay(2); SCL = 1; delay(2); } } uchar readDS18B20() // 读取温度传感器一个字节 { uchar i, dat = 0; for (i = 0; i < 8; i++) { SCL = 0; delay(2); SCL = 1; delay(2); dat >>= 1; if (SDA) dat |= 0x80; } return dat; } void displayDS18B20() // 显示温度传感器温度 { uchar temp[2]; float t; initDS18B20(); writeDS18B20(0xCC); writeDS18B20(0x44); delay(1000); initDS18B20(); writeDS18B20(0xCC); writeDS18B20(0xBE); temp[0] = readDS18B20(); temp[1] = readDS18B20(); t = (temp[1] << 8) | temp[0]; t /= 16; writeCmd(0x80); writeData(DIG_CODE[(int)(t / 10)]); writeData(DIG_CODE[(int)(t % 10)] | 0x80); writeData(0x39); writeData(DIG_CODE[(int)((t - (int)t) * 10)]); } void main() { uchar i, j, k, key, led, dis; TMOD = 0x01; // 定时器0工作在模式1 TH0 = 0xFC; // 定时器0计数初值 TL0 = 0x66; ET0 = 1; // 开启定时器0中断 EA = 1; // 开启总中断 TR0 = 1; // 开始计数 while (1) { key = 0; P2 = 0xFE; if (P0 != 0xFF) { for (i = 0; i < 4; i++) { P2 = 0xFE >> i; if (P0 != 0xFF) { for (j = 0; j < 4; j++) { if (P0 == KEY_CODE[j]) { key = i * 4 + j + 1; break; } } break; } } } if (key > 0) { led = LED_CODE[key - 1]; dis = DIS_CODE[key - 1]; } else { led = 0xFF; dis = 0xFF; } P1 = led; writeCmd(0x40); for (k = 0; k < 8; k++) { writeData(TEXT[k]); } displayDS18B20(); delay(1000); writeCmd(0x80); writeData(dis); delay(500); beep = 1; delay(50); beep = 0; delay(450); } } void timer0() interrupt 1 // 定时器0中断服务函数 { TH0 = 0xFC; TL0 = 0x66; P0 = DIG_CODE[k]; if (++k >= 8) k = 0; } ``` 其中,点阵屏使用74HC595移位寄存器控制,共阴数码管、LED灯、矩阵键盘、显示屏、蜂鸣器都是直接接口控制,温度传感器使用DS18B20芯片,通过单总线协议控制读取温度数据。代码实现了按键控制LED灯、显示屏显示文本和数码管显示温度,每隔1秒钟更新一次温度数据,并且每隔500毫秒闪烁一次显示屏的显示代码,同时蜂鸣器发出滴声。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值