简单练习(自己看)

 

main.c

#include "reg52.h"
#include "ds1302.h"
#define ur unsigned char//
#define ut unsigned int	

sfr AUXR=0x8e;//sfr特殊功能寄存器RAM(运行中保持不变再次烧写时改变)
sbit P30=P3^0;//ROM(在程序运行中随时改变)
sbit P31=P3^1;
sbit P32=P3^2;
sbit P33=P3^3;

bit modes;/*bit就是位,也叫比特位,是计算机表示数据最小的单位,例如 1b ,2b,3b.....
说白了就是0或者1*/
ur posd = 0;
ut timed = 0;
ur h,m,s,set = 1;
ur timer[3] = {0x50,0x59,0x23};
ur code ds1302_write[]={0x80,0x82,0x84};
ur code ds1302_read[]={0x81,0x83,0x85};
ur  SMGNoDot_ca[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
/*
code的作用是告诉单片机,我定义的数据要存储在ROM(程序存储区)里面,
写入后就不能再更改,其实是相当与汇编里面的寻址MOVC(好像是),
因为C语言中没办法详细描述存入的是ROM还是RAM(存储器),
所以在软件中添加了这一个语句起到代替汇编指令的作用,对应的还有data是存入RAM(存储器)的意思。
*/

void Config_DS1302 ();
void Initsystem();
void SMGdispaly(posd);
void HC138(ur channel,ur dat);
void Timer0Init(void);
void key_scan();
void LEDshow();
void Read_DS1302 ();
//==============主函数=====================
void main()
{	
    Config_DS1302 ();
	Initsystem();
	Timer0Init();	
	while(1)
	{
		if(timed%40==1)key_scan();	
		if(timed%100==11)LEDshow();
		if(timed%400==21)Read_DS1302(); 
	}
}
//=============================基础======================================================

void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时		
	ET0 = 1;        //时钟使能开关打开
	EA = 1;          //总使能开关打开
	
}
void Timer0()interrupt 1
{
	
	posd == 7?posd = 0:posd++;      //数码管位控制变量
	timed == 1000?timed = 0:timed++;//周期计时变量
	SMGdispaly(posd);               //数码管显示
}


void Initsystem()                   //初始化LED,蜂鸣器,继电器
{
	HC138(4,0xff);
	HC138(5,0x00);
}

void HC138(ur channel,ur dat)      //控制74HC138选择74Hc573锁存器
{
	switch(channel)
	{
		case 4:P2=(P2&0x1f)|0x80;P0=dat;break;
		case 5:P2=(P2&0x1f)|0xa0;P0=dat;;break;
		case 6:P2=(P2&0x1f)|0xc0;P0=dat;break;
		case 7:P2=(P2&0x1f)|0xe0;P0=dat;break;
	}
	P2&=0x1f;
}

//============================ds1302======================================================
void Config_DS1302 ()            //初始化DS1302(写入)
{
	ur i;
	Write_Ds1302_Byte(0x8e,0x00);
	for (i = 0;i<3;i++)
	{
	Write_Ds1302_Byte(ds1302_write[i],timer[i]);
	}
	Write_Ds1302_Byte(0x8e,0x80);
}
void Read_DS1302 ()              //读DS1302时钟
{
	ur i;
	EA=0;                       //使能总中断关闭
	for (i = 0;i<3;i++)
	{
		timer[i] = Read_Ds1302_Byte(ds1302_read[i]);
	}
    EA=1;	                      //使能总中断打开
}
//=================================数码管========================================================
void SMGbit(ur pos,ur dat)
{
	HC138(7,0xff);       //消隐(值)
	HC138(6,0x01<<pos);  //打开位
	HC138(7,dat);       //赋值
}


//显示界面
void SMGdispaly1(posd)
{	
	switch(posd)
	{
		case 0:SMGbit(posd,SMGNoDot_ca[timer[2]/16]);break;
		case 1:SMGbit(posd,SMGNoDot_ca[timer[2]%16]);break;
		case 2:SMGbit(posd,0xbf);break;
		case 3:SMGbit(posd,SMGNoDot_ca[timer[1]/16]);break;
		case 4:SMGbit(posd,SMGNoDot_ca[timer[1]%16]);break;
		case 5:SMGbit(posd,0xbf);break;
		case 6:SMGbit(posd,SMGNoDot_ca[timer[0]/16]);break;
		case 7:SMGbit(posd,SMGNoDot_ca[timer[0]%16]);break;
	}	
}
//参数界面
void SMGdispaly2(posd)
{
	ur c_t = 0,set_m = 0x89;
	//设置显示值
	switch(set)
	{
			case 1: set_m = 0x89;          c_t = h;break;//set为1,模式为小时参数设置
			case 2: set_m = 0xc8;          c_t = m;break;
			case 3: set_m = SMGNoDot_ca[5];c_t = s;break;			
	}
	switch(posd)
	{
		case 0:SMGbit(posd,0xc6);break;
		case 1:SMGbit(posd,set_m);break;
		case 2:SMGbit(posd,0xff);break;
		case 3:SMGbit(posd,0xff);break;
		case 4:SMGbit(posd,0xff);break;
		case 5:SMGbit(posd,0xbf);break;
		case 6:SMGbit(posd,SMGNoDot_ca[c_t/10]);break;
		case 7:SMGbit(posd,SMGNoDot_ca[c_t%10]);break;	
	}	
}
//数码管显示(选择)
void SMGdispaly(posd)
{
	if(!modes)SMGdispaly1(posd);
	else SMGdispaly2(posd);
}

//=======================LED==========================================================
//参数1控制选择哪一位led灯,参数二控制亮灭。0为亮,1为灭
void led_show(ur pos,bit i)
{
	static ur dat = 0xff;
	if(i) dat |= 0x01<<pos;
	else dat &= ~(0x01<<pos);
	HC138(4,dat);
}
//led显示
void LEDshow()
{
	static bit shan = 0;
	EA = 0;                     //总使能开关关闭
	if(modes)
	{                          //参数界面
		led_show(0,1);       //L1灭
		led_show(1,0);       //L2亮
		switch(set)
		{
			case 1:             //set为1,当前为小时参数设置
				led_show(2,0);  //L3亮
				led_show(3,1);  //L4灭
				led_show(4,1);  //L5灭
				break;
			
			case 2:	            //set为2,当前为分参数设置
				led_show(2,1);
				led_show(3,0);
			    led_show(4,1);
				break;
			
			case 3:             //set为3,当前为秒参数设置
				led_show(2,1);
				led_show(3,1);
				led_show(4,0);
				break;			
		}
	}
	else//显示界面
	{
		//L1灭,L2,L3,L4,L5灭
			led_show(0,0);
			led_show(1,1);
			led_show(2,1);
			led_show(3,1);
			led_show(4,1);			
	}
	if(timer[2] == h*16 && timer[1] == m*16 && timer[0] == s*16) //当参数值等于实际值		
		shan = 1;
	
	if(shan) 	
	{	

		if(timed<500) 
			led_show(5,0);
		else 
			led_show(5,1);
		if(timer[0] >= s+5) 
		{
			shan = 0;
			led_show(5,0);//L6熄灭
		}
	}
		EA = 1;
}
//=========================按键=================================================================
void key_scan()
{
	static bit s4,s5,s6,s7;  //1表示未按下(高电平)
	//按键S7
	if(P30) s7 = 1;    //s7未按下  modes=0;
	else if(s7)        //s7按下   modes=1
	{
		modes ^= 1;//显示界面和参数界面切换
		s7 = 0;
	}
	//按键S6	
	if(P31) s6 = 1;
	else if(s6) 
	{
		if(modes) 	
		set == 3?set = 1:set++;//参数界面,时分秒界面切换-只有1和2两只状态
		s6 = 0;
	}
		//按键S5
	if(P32) s5 = 1;
	else if(s5) 
	{
		if(modes)//当处于参数界面
	  {
		switch(set)
		{
			case 1: if(h!=23)  h++;break;//时+1
			case 2:	if(m!= 59) m++;break;
			case 3:	if(s!=59)  s++;break;			
		}
	  }
		else led_show(5,1);//处于显示界面,L6熄灭
		s5 = 0;
	}
		//按键S4
	if(P33) s4 = 1;
	else if(s4) 
	{	
		if(modes)//当处于参数界面
		switch(set)
		{        //是h为1否则为0
			case 1: if(h) h--;break;      //时-1
			case 2: if(m) m--;break;
			case 3: if(s) s--;break;			
		}
		s4 = 0;
	}
}

ds1302.h

/*
  程序说明: DS1302驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台 8051,12MHz
  日    期: 2011-8-9
*/

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

sbit SCK=P1^7;		
sbit SDA=P2^3;		
sbit RST = P1^3;   // DS1302复位												

void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK=0;
		SDA=temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1; 	_nop_();  
 	Write_Ds1302(address);	
 	Write_Ds1302(dat);		
 	RST=0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1;	_nop_();
 	Write_Ds1302(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	SDA=0;	_nop_();
	SDA=1;	_nop_();
	return (temp);			
}

ds1302.h

#ifndef __DS1302_H
#define __DS1302_H

void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
#endif

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值