IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 51单片机+TM1638+DS3232驱动数码管按键切换显示时间和日期 -> 正文阅读

[嵌入式]51单片机+TM1638+DS3232驱动数码管按键切换显示时间和日期

51单片机+TM1638+DS3232驱动数码管按键切换显示时间和日期


在这里插入图片描述

  • Proteus仿真
  • AT89C52、8位共阴数码管、DS3232

实例代码

#include <reg51.h>
#include <intrins.h>
#include "tm1638.h"

#define uchar unsigned char
#define uint unsigned int
sbit SDA = P3 ^ 6; //??I2C?????SDA
sbit SCL = P3 ^ 7; //??I2C?????SCL
sbit INT = P3 ^ 2;
sbit RESET = P3 ^ 3;
sbit led0 = P1 ^ 0;
sbit led1 = P1 ^ 1;
sbit led2 = P1 ^ 2;
sbit led3 = P1 ^ 3;
sbit led4 = P1 ^ 4;
sbit led5 = P1 ^ 5;
sbit led6 = P1 ^ 6;
sbit led7 = P1 ^ 7;
bit ack; //?????

#define DS3231_WriteAddress 0xD0 //?????
#define DS3231_ReadAddress 0xD1  //?????
#define DS3231_SECOND 0x00       //?
#define DS3231_MINUTE 0x01       //?
#define DS3231_HOUR 0x02         //?
#define DS3231_WEEK 0x03         //??
#define DS3231_DAY 0x04          //?
#define DS3231_MONTH 0x05        //?
#define DS3231_YEAR 0x06         //?
//??1
#define DS3231_SALARM1ECOND 0x07 //?
#define DS3231_ALARM1MINUTE 0x08 //?
#define DS3231_ALARM1HOUR 0x09   //?
#define DS3231_ALARM1WEEK 0x0A   //??/?
//??2
#define DS3231_ALARM2MINUTE 0x0b //?
#define DS3231_ALARM2HOUR 0x0c   //?
#define DS3231_ALARM2WEEK 0x0d   //??/?
#define DS3231_CONTROL 0x0e      //?????
#define DS3231_STATUS 0x0f       //?????
#define BSY 2                    //?
#define OSF 7                    //???????
#define DS3231_XTAL 0x10         //???????
#define DS3231_TEMPERATUREH 0x11 //????????(8?)
#define DS3231_TEMPERATUREL 0x12 //????????(?2?)

uchar code dis_code[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
                         0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71}; // 4,5,6,7,8,9,off
uchar data dis_buf[8];
uchar data dis_index;
uchar data dis_digit;

uchar BCD2HEX(uchar val) //BCD???Byte
{
    return (val >> 4) * 10 + (val & 0x0F);
}

uchar HEX2BCD(uchar val) //B????BCD?
{
    return ((val / 10) << 4) | (val % 10);
}

void delayus(uint us)
{
    while (us--)
        ;
}

void Start_I2C()
{
    SDA = 1; //???????????
    delayus(1);
    SCL = 1;
    delayus(5); //??????????4.7us,??

    SDA = 0;    //??????
    delayus(5); // ??????????4?s

    SCL = 0; //??I2C??,?????????
    delayus(2);
}

void Stop_I2C()
{
    SDA = 0;    //???????????
    delayus(1); //???????????
    SCL = 1;    //??????????4us
    delayus(5);

    SDA = 1; //??I2C??????
    delayus(4);
}

void SendByte(uchar c)
{
    uchar BitCnt;

    for (BitCnt = 0; BitCnt < 8; BitCnt++) //?????????8?
    {
        if ((c << BitCnt) & 0x80)
            SDA = 1; //?????
        else
            SDA = 0;
        delayus(1);
        SCL = 1;    //??????,????????????
        delayus(5); //???????????4?s
        SCL = 0;
    }

    delayus(2);
    SDA = 1; //8??????????,???????
    delayus(2);
    SCL = 1;
    delayus(3);
    if (SDA == 1)
        ack = 0;
    else
        ack = 1; //???????????
    SCL = 0;
    delayus(2);
}

uchar RcvByte()
{
    uchar retc;
    uchar BitCnt;

    retc = 0;
    SDA = 1; //?????????
    for (BitCnt = 0; BitCnt < 8; BitCnt++)
    {
        delayus(1);
        SCL = 0; //??????,???????

        delayus(5); //?????????4.7?s

        SCL = 1; //???????????????
        delayus(3);
        retc = retc << 1;
        if (SDA == 1)
            retc = retc + 1; //????,????????retc?
        delayus(2);
    }
    SCL = 0;
    delayus(2);
    return (retc);
}

void Ack_I2C(bit a)
{

    if (a == 0)
        SDA = 0; //????????????
    else
        SDA = 1;
    delayus(3);
    SCL = 1;

    delayus(5); //?????????4?s

    SCL = 0; //????,??I2C????????
    delayus(2);
}

uchar write_byte(uchar addr, uchar write_data)
{
    Start_I2C();
    SendByte(DS3231_WriteAddress);
    if (ack == 0)
        return 0;

    SendByte(addr);
    if (ack == 0)
        return 0;

    SendByte(write_data);
    if (ack == 0)
        return 0;

    Stop_I2C();
    delayus(10);
    return 1;
}

uchar read_current()
{
    uchar read_data;
    Start_I2C();
    SendByte(DS3231_ReadAddress);
    if (ack == 0)
        return (0);

    read_data = RcvByte();
    Ack_I2C(1);
    Stop_I2C();
    return read_data;
}

uchar read_random(uchar random_addr)
{
    Start_I2C();
    SendByte(DS3231_WriteAddress);
    if (ack == 0)
        return (0);

    SendByte(random_addr);
    if (ack == 0)
        return (0);

    return (read_current());
}

void ModifyTime(uchar yea, uchar mon, uchar da, uchar hou, uchar min, uchar sec)
{
    uchar temp = 0;

    temp = HEX2BCD(yea);
    write_byte(DS3231_YEAR, temp); //???

    temp = HEX2BCD(mon);
    write_byte(DS3231_MONTH, temp); //???

    temp = HEX2BCD(da);
    write_byte(DS3231_DAY, temp); //???

    temp = HEX2BCD(hou);
    write_byte(DS3231_HOUR, temp); //???

    temp = HEX2BCD(min);
    write_byte(DS3231_MINUTE, temp); //???

    temp = HEX2BCD(sec);
    write_byte(DS3231_SECOND, temp); //???
}

void TimeDisplay(uchar Dhour, uchar Dmin, uchar Dsec)
{
    dis_buf[7] = dis_code[Dhour / 10]; // ???
    dis_buf[6] = dis_code[Dhour % 10]; // ???
    dis_buf[4] = dis_code[Dmin / 10];  // ???
    dis_buf[3] = dis_code[Dmin % 10];  // ???
    dis_buf[1] = dis_code[Dsec / 10];  // ???
    dis_buf[0] = dis_code[Dsec % 10];  // ???
    dis_buf[2] = 0x40;                 // ??"-"
    dis_buf[5] = 0x40;
}

void DateDisplay(uchar Dyear, uchar Dmonth, uchar Dday)
{
    dis_buf[7] = dis_code[Dyear / 10];  // ???
    dis_buf[6] = dis_code[Dyear % 10];  // ???
    dis_buf[4] = dis_code[Dmonth / 10]; // ???
    dis_buf[3] = dis_code[Dmonth % 10]; // ???
    dis_buf[1] = dis_code[Dday / 10];   // ???
    dis_buf[0] = dis_code[Dday % 10];   // ???
    dis_buf[2] = 0x40;                  // ??"-"
    dis_buf[5] = 0x40;
}

void get_show_time(void)
{
    uchar Htemp1, Htemp2, Mtemp1, Mtemp2, Stemp1, Stemp2;

    Htemp1 = read_random(DS3231_HOUR); //? 24???
    Htemp1 &= 0x3f;
    Htemp2 = BCD2HEX(Htemp1);

    Mtemp1 = read_random(DS3231_MINUTE); //?
    Mtemp2 = BCD2HEX(Mtemp1);

    Stemp1 = read_random(DS3231_SECOND); //?
    Stemp2 = BCD2HEX(Stemp1);

    TimeDisplay(Htemp2, Mtemp2, Stemp2);
}

void get_show_date(void)
{
    uchar Ytemp1, Ytemp2, Mtemp1, Mtemp2, Dtemp1, Dtemp2;

    Ytemp1 = read_random(DS3231_YEAR); //?
    Ytemp2 = BCD2HEX(Ytemp1);

    Mtemp1 = read_random(DS3231_MONTH); //?
    Mtemp2 = BCD2HEX(Mtemp1);

    Dtemp1 = read_random(DS3231_DAY); //?
    Dtemp2 = BCD2HEX(Dtemp1);

    DateDisplay(Ytemp2, Mtemp2, Dtemp2);
}

void get_show_Temperature(void)
{
    uchar Ttemp1, Ttemp2, Ttemp3, Ttemp4;

    Ttemp1 = read_random(DS3231_TEMPERATUREH); //?? ???
    Ttemp2 = BCD2HEX(Ttemp1);

    Ttemp3 = read_random(DS3231_TEMPERATUREL); //?????
    Ttemp4 = BCD2HEX(Ttemp3);

    dis_buf[7] = 0;                            // ???
    dis_buf[6] = 0;                            // ???
    dis_buf[3] = dis_code[Ttemp2 / 10];        // ???
    dis_buf[2] = dis_code[Ttemp2 % 10] | 0x80; // ???
    dis_buf[1] = dis_code[Ttemp4 / 10];        // ???
    dis_buf[0] = dis_code[Ttemp4 % 10];        // ???
    dis_buf[5] = 0;                            // ??"-"
    dis_buf[4] = 0;
    //    DateDisplay(0,Ttemp2,Ttemp4);
}

void main()
{
    int i;
    int status;

    RESET = 0x1; //DS3231????,?????????????
    delayus(5000);

    led0 = 0;
    led1 = 0;
    led2 = 0;
    led3 = 0;
    led4 = 0;

    P0 = 0xff;
    P2 = 0xff;

    dis_digit = 0xfe;
    dis_index = 0;

    //TimeDisplay(12, 5, 18);
			DateDisplay(21,9,8);
    /*
    TMOD=0x11;          // ???0, 1????1, 16?????
    TH0=0xDC;
    TL0=0x00;
    
    TCON=0x01;
    IE=0x82;            // ??timer0,1 ??
    
    TR0=1;
    */

    if (write_byte(DS3231_CONTROL, 0x1C) == 0)
        led0 = 1;

    if (write_byte(DS3231_STATUS, 0x00) == 0)
        led1 = 1;

    ModifyTime(21,9,8,8,29,00);       //2021/9/08,08-29-00

    init_TM1638(); //初始化TM1638
    for (i = 0; i < 8; i++)
        Write_DATA(i << 1, tab[i]); //

    status = 0;

    while (1)
    {

        i = Read_key();
        if (i < 3)
        {
            while (Read_key() == i)
                ;
            status = i;
        }

        switch (status)
        {
        case 0:
            get_show_time();
            break;
        case 1:
            get_show_date();
            break;
        case 2:
            get_show_Temperature();
            break;
        }

        for (i = 0; i < 8; i++)
        {
            Write_DATA(i << 1, dis_buf[7 - i]);
        }
        delayus(10000);
    }
}
  • tm1638.h文件
#ifndef	_TM1638_H
#define	_TM1638_H

#include	<REGX51.H>

#define	DATA_COMMAND	0X40
#define	DISP_COMMAND	0x80
#define	ADDR_COMMAND	0XC0

//TM1638模块引脚定义
sbit	DIO=P2^0;
sbit	CLK=P2^1;
sbit	STB=P2^2;

//共阴数码管显示代码
unsigned char code tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
                           0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};


void TM1638_Write(unsigned char	DATA)			//写数据函数
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		CLK=0;
		if(DATA&0X01)
			DIO=1;
		else
			DIO=0;
		DATA>>=1;
		CLK=1;
	}
}
unsigned char TM1638_Read(void)					//读数据函数
{
	unsigned char i;
	unsigned char temp=0;
	DIO=1;	//设置为输入
	for(i=0;i<8;i++)
	{
		temp>>=1;
		CLK=0;
		if(DIO)
			temp|=0x80;
		CLK=1;
	}
	return temp;
}
void Write_COM(unsigned char cmd)		//发送命令字
{
	STB=0;
	TM1638_Write(cmd);
	STB=1;
}
unsigned char Read_key(void)
{
	unsigned char c[4],i,key_value=0;
	STB=0;
	TM1638_Write(0x42);		           //读键扫数据 命令
	for(i=0;i<4;i++)		
		c[i]=TM1638_Read();
	STB=1;					           //4个字节数据合成一个字节
	for(i=0;i<4;i++)
		key_value|=c[i]<<i;
	for(i=0;i<8;i++)
		if((0x01<<i)==key_value)
			break;
	return i;
}
void Write_DATA(unsigned char add,unsigned char DATA)		//指定地址写入数据
{
	Write_COM(0x44);
	STB=0;
	TM1638_Write(0xc0|add);
	TM1638_Write(DATA);
	STB=1;
}
/****************
void Write_oneLED(unsigned char num,unsigned char flag)	//单独控制一个LED函数,num为需要控制的led序号,flag为0时熄灭,不为0时点亮
{
	if(flag)
		Write_DATA(2*num+1,1);
	else
		Write_DATA(2*num+1,0);
} 
*/
void Write_allLED(unsigned char LED_flag)					//控制全部LED函数,LED_flag表示各个LED状态
{
	unsigned char i;
	for(i=0;i<8;i++)
		{
			if(LED_flag&(1<<i))
				//Write_DATA(2*i+1,3);
				Write_DATA(2*i+1,1);
			else
				Write_DATA(2*i+1,0);
		}
}

//TM1638初始化函数
void init_TM1638(void)
{
	unsigned char i;
	Write_COM(0x8b);       //亮度 (0x88-0x8f)8级亮度可调
	Write_COM(0x40);       //采用地址自动加1
	STB=0;		           //
	TM1638_Write(0xc0);    //设置起始地址

	for(i=0;i<16;i++)	   //传送16个字节的数据
		TM1638_Write(0x00);
	STB=1;
}
#endif

  • intrins.h这个头文件只需包含进去就可以了,在keil库当中,我就不贴代码了,

源程序和资料

baidu链接:https://pan.baidu.com/s/1jw2HLP9Jkx74clOnALtUXQ 
提取码:ttlk
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-09-09 11:56:09  更:2021-09-09 11:56:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 0:38:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码