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单片机与DS1320动态数码管时钟 -> 正文阅读

[嵌入式]51单片机与DS1320动态数码管时钟

?

#include<reg52.h>
#include<intrins.h>
sbit IO = P3^4;					//数据输入和输出引脚
sbit CE = P3^5;         //复位引脚,高电平启用数据传输
sbit Clock = P3^6;			//时钟输入引脚
/*38译码器的输入端定义*/
sbit AA = P2^0;
sbit BB = P2^1;
sbit CC = P2^2;
sbit K1 = P2^3;
sbit K2 = P2^4;
sbit K3 = P2^5;
sbit K4 = P2^6;
void delay(int a,int b)
{
	int i,j;
	for(i = 0;i <= a;i ++)
	{
		for(j = 0;j <= b;j ++)
		{}
	}
}
/*DS1302中的数据以BCD码存储,每4位2进制表示一位十进制
下面Time数组中的第一个0x00就表示0十秒0秒;0x15表示24小时
形式的下午15点*/
unsigned char Time[] = {0x25,0x31,0x11,0x03,0x05,0x01,0x22};//初始化时间秒,分,时,日,月,周,年
char Read_Cmd[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; 
char Write_Cmd[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
/*数码管0-F段码值*/
unsigned char Seg_Code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
/*向DS1320发送命令,告知对其进行的操作是读还是写,和读写的是时分秒等的哪一位*/
void Ds1302_Cmd(char Cmd)
{
	char n;
	CE = 0;_nop_();
	Clock = 0;_nop_();
	CE = 1;_nop_();
	for(n = 0;n <= 7;n ++)//发送八位命令代码,已保存在上面的数组中
	{
		IO = Cmd & 0x01;
		Cmd = Cmd >> 1;
		Clock = 1;          //上升沿读取数据
		_nop_();
		Clock = 0;          
		_nop_();
	}
}
/*向DS1320中写入8位数据*/
void WriteDatToDs1320(char Dat)
{
	char n;
	for(n = 0;n <= 7;n ++)
	{
		IO = Dat & 0x01;
		Dat = Dat >> 1;
		Clock = 1;          //上升沿读取数据
		_nop_();
		Clock = 0;          //时钟重置为0
		_nop_();
	}
	CE = 0;               //传输数据结束
	_nop_();
}
/*从DS1320接收8位数据*/
char ReadDatFromDs1320()		//数据是从最低位开始接收,因此要进行下列移位操作
{
	char n;
  unsigned char Data_Temp,Data; /*这里注意使用无符号字符类型,否则移位会发生错误!!!
	具体原因可能是C51的编译器关于移位是逻辑右移还是算术右移的问题,我也搞不懂*/
	for(n = 0;n <= 7;n ++)
	{
		Data_Temp = IO;
		Data = ((Data >> 1) | (Data_Temp << 7));
		/*Data右移1位,空出最高位(为0);Data_Temp为接收到的一
		位数据将其左移7位,这样就与Data最高位对齐,在进行“或”运
		算,将数据传给Data,再进行下一次循环,这样先接收的数据就
		逐渐移到了低位,最后接收的数据就到了高位。*/
		Clock= 1;_nop_();
		Clock= 0;					//下降沿放置数据.
		_nop_();
	}
	/*DS1320复位稳定时间*/
	CE = 0;								//关闭数据传输
	_nop_();
	Clock = 1;	
	_nop_();
  IO = 0;	
	_nop_();
	IO = 1;
	_nop_();
	return Data;
}
/*从DS1320中读取全部时间,要进行7次读数据操作,每次读取一个参数*/
void ReadTimeFromDs1320()
{
	unsigned char n;
	for(n = 0;n <= 6;n ++)
	{
		Ds1302_Cmd(Read_Cmd[n]);      //先发送读的命令
		Time[n] = ReadDatFromDs1320();//读取8位数据
	}
}
/*初始化DS1320中的时间为Time数组中的时间,将预先设定的全部时间
写到DS1320中,由于有7个参数,因此要循环7次*/
void Ds1320_Init()
{
	int n;
	Ds1302_Cmd(0x8e);
	WriteDatToDs1320(0x00);//这两句话是关闭写保护
	/*像DS1320中写入:秒,分,时,日,月,周,年七组8位数据*/
	for(n = 0;n <= 6;n ++)
	{
		Ds1302_Cmd(Write_Cmd[n]);WriteDatToDs1320(Time[n]);
		/*例如:当n = 1时,先发送写秒的命令,再发送秒的数据
		命令和数据都提前保存在了数组中,具体命令代码查阅数
		据手册,如下图*/
	}
	Ds1302_Cmd(0x8e);WriteDatToDs1320(0x80);//打开写保护.
}
//扫描数码管显示程序
void Display(int Hour1,int Hour2,int Min1,int Min2,int Sec1,int Sec2)
{
	int i,j;
	for(i=0;i<8;i++)
	{
		switch(i)	 //位选,选择点亮的数码管,
		{
			case(0):AA=0;BB=0;CC=0;P0 = Seg_Code[Hour1];break;//显示第0位			
			case(1):AA=1;BB=0;CC=0;P0 = Seg_Code[Hour2];break;//显示第1位
			case(2):AA=0;BB=1;CC=0;P0 = 0X40;break;//显示第2位
			case(3):AA=1;BB=1;CC=0;P0 = Seg_Code[Min1];break;//显示第3位
			case(4):AA=0;BB=0;CC=1;P0 = Seg_Code[Min2];break;//显示第4位
			case(5):AA=1;BB=0;CC=1;P0 = 0X40;break;//显示第5位
			case(6):AA=0;BB=1;CC=1;P0 = Seg_Code[Sec1];break;//显示第6位
			case(7):AA=1;BB=1;CC=1;P0 = Seg_Code[Sec2];break;//显示第7位	
		}
		j = 50; 
		while(j--);
		P0 = 0X00;
	}
}
/*主程序*/
void main()
{
	int Hour1,Hour2,Min1,Min2,Sec1,Sec2;
	unsigned char temp1,temp2;
	Ds1320_Init();
	K1 = 1;K2 = 1;K3 = 1;K4 = 1;
	while(1)
	{
		ReadTimeFromDs1320();//读取时间并存储到Time数组中
		Hour1 = Time[2]/16;  //小时的十位,Time[2]对16取余,因为是16进制
		Hour2 = Time[2]&0x0f;//保留低四位的小时个位数
		Min1 = Time[1]/16;
		Min2 = Time[1]&0x0f;
		Sec1 = Time[0]/16;
		Sec2 = Time[0]&0x0f;
		/*按键调时间程序,K1调整小时的个位,K2调整小时的10位。以此类推/
		if(K1 == 0)
		{
			delay(300,10);
			if(K1 == 0)
			{
				Time[2] ++;
				if((Time[2]&0x0f)==10)
				{
					Time[2] = (Time[2]&0xf0);
				}
				Ds1320_Init();
			}
			delay(30,10);
		}
		if(K2 == 0)
		{
			temp1 = Time[2];
			delay(300,10);
			if(K2 == 0)
			{
				Time[2] = Time[2] >> 4;
				Time[2] ++;
				if(Time[2] == 3)
				{
					Time[2] = 0x0f&temp1;
					Ds1320_Init();
				}
				else
				{
					Time[2] = Time[2] << 4;
					temp1 = temp1&0x0f;
					Time[2] = (Time[2]|temp1);
					Ds1320_Init();
				}
			}
			delay(30,10);
		}		
		
		if(K3 == 0)
		{
			delay(300,10);
			if(K3 == 0)
			{
				Time[1] ++;
				if((Time[1]&0x0f)==10)
				{
					Time[1] = (Time[1]&0xf0);
				}
				Ds1320_Init();
			}
			delay(30,10);
		}
		if(K4 == 0)
		{
			temp1 = Time[1];
			delay(300,10);   
			if(K4 == 0)
			{
				Time[1] = Time[1] >> 4;
				Time[1] ++;
				if(Time[1] == 6)
				{
					Time[1] = 0x0f&temp1;
					Ds1320_Init();
				}
				else
				{
					Time[1] = Time[1] << 4;
					temp1 = temp1&0x0f;
					Time[1] = (Time[1]|temp1);
					Ds1320_Init();
				}
			}
			delay(30,10);
		}
		Display(Hour1,Hour2,Min1,Min2,Sec1,Sec2);		
	}
}

?

1、DS1320操作顺序:先给芯片一个命令,读或者写。然后再进行操作,读命令就从芯片读取数据;写命令就把数据写到芯片。

2、注意事项:最好使用无符号字符型,因为涉及到数据移位操作,带符号数容易出问题!!

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-01-03 16:16:35  更:2022-01-03 16:17:07 
 
开发: 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 12:17:26-

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