当前位置:首页 > 单片机 > 单片机
[导读]#include #include #include "delay.h"#include "lcd.h"#define uchar unsigned char#define uint unsigned int#define DS1302_RST_SET PORTA |= ( 1 > 4; DS1302TIMEDISP[t + 1] = DS1302TIME[i] & 0x0f;}}//将时间

#include
#include
#include "delay.h"
#include "lcd.h"

#define uchar unsigned char
#define uint unsigned int

#define DS1302_RST_SET PORTA |= ( 1 << 0 )
#define DS1302_RST_CLR PORTA &=~ ( 1 << 0 )
#define DS1302_SCLK_SET PORTA |= ( 1 << 1 )
#define DS1302_SCLK_CLR PORTA &=~ ( 1 << 1 )
#define DS1302_DATA_SET PORTA |= ( 1 << 2 )
#define DS1302_DATA_CLR PORTA &=~ ( 1 << 2 )
#define DS1302_DTTA_CHECK PINA & ( 1 << 2 )

#define DS1302_CONTROL_DDR_OUT { DDRA |= ( 1 << 0 ) | ( 1 << 1 ); } //时钟口,以及启动口定义为输出, 注意这里的写法, 不影响其它位
#define DS1302_DATA_DDR_OUT DDRA |= ( 1 << 2 ) //数据口为输出
#define DS1302_DATA_DDR_IN { DDRA &=~ ( 1 << 2 ); PORTD |= ( 1 << 2 ); } //输入为高阻态


//-------------------------DS1302部分------------------------------------
//设置时间 年 月 日 周 时 分 秒
uchar DS1302TIME[8] = { 0x20, 0x08, 0x10, 0x17, 0x04, 0x21, 0x39, 0x56 };
uchar DS1302TIMEDISP[18];

//定义标志位, 初始化为0
uchar model = 0; //模式变化值
uchar t = 0;
uchar count = 0;
uchar count1sok = 0;

//DS1302初始化
//初始化要求/RST为低电平,SCLK为低电平
void DS1302_init( void )
{
DS1302_CONTROL_DDR_OUT; //控制口为输出
DS1302_DATA_DDR_IN; //数据口为输出, 高阻态
DS1302_RST_CLR; //启动为低电平
DS1302_SCLK_CLR; //时钟为低电平
}

//向地址写数据
//RST被设置为高就启动了一个数据传送的过程
void DS1302_write_bytetoaddr( uchar addr, uchar byte )
{
uchar addr_t = addr; //转移数据
uchar byte_t = byte;
uchar i = 0;

DS1302_DATA_DDR_OUT; //输出
DS1302_RST_CLR;
DS1302_SCLK_CLR; //时钟为低电平
DS1302_RST_SET; //启动数据传输

for( i = 0; i < 8; i++ )
{
if( addr_t & 0x01 )
DS1302_DATA_SET; //输出1
else
DS1302_DATA_CLR; //输出0

DS1302_SCLK_SET; //上升沿
DS1302_SCLK_CLR;

addr_t = addr_t >> 1;
}

for( i = 0; i < 8; i++ )
{
if( byte_t & 0x01 )
DS1302_DATA_SET;
else
DS1302_DATA_CLR;

DS1302_SCLK_SET;
DS1302_SCLK_CLR;

byte_t = byte_t >> 1;
}

DS1302_RST_CLR;
}

//从地址读数据
//RST被设置为高就启动了一个数据传送的过程
uchar DS1302_read_bytefromaddr( uchar addr )
{
uchar addr_t = addr; //转移数据
uchar byte_t;
uchar i = 0;

DS1302_DATA_DDR_OUT; //输出
DS1302_RST_CLR;
DS1302_SCLK_CLR; //时钟为低电平
DS1302_RST_SET; //启动数据传输

for( i = 0; i < 8; i++ )
{
if( addr_t & 0x01 )
DS1302_DATA_SET; //输出1
else
DS1302_DATA_CLR; //输出0

DS1302_SCLK_SET; //上升沿
DS1302_SCLK_CLR;

addr_t = addr_t >> 1;
}

DS1302_DATA_DDR_IN; //数据为输入高阻态
byte_t = 0;

for( i = 0; i < 8; i++ )
{
byte_t = byte_t >> 1; //先移位

if( DS1302_DTTA_CHECK ) //读数据输出口
byte_t |= 0x80;

else
byte_t &= 0x7f;

DS1302_SCLK_SET;
DS1302_SCLK_CLR;
}

DS1302_RST_CLR;
return byte_t;
}

//将十六进制码变为十进制码
//如: 0x45 -- > 45d
uchar hex2dec( uchar hex_data )
{
//十位 //个位
return ( ( ( hex_data >> 4 ) * 10 ) + ( hex_data & 0b00001111 ) );
}

//写时间年月日
//08-10-15 14:36:56
void DS1302_write_time( void )
{
DS1302_write_bytetoaddr( 0X8E, 0X00 ); //写控制寄存器 WP000 0000 <===> WP = 0, 数据可以写入
DS1302_write_bytetoaddr( 0X80, 0X80 ); //写秒寄存器, 停止时钟

DS1302_write_bytetoaddr( 0X8C, DS1302TIME[1] ); //年
DS1302_write_bytetoaddr( 0X88, DS1302TIME[2] ); //月
DS1302_write_bytetoaddr( 0X86, DS1302TIME[3] ); //日
DS1302_write_bytetoaddr( 0X8A, DS1302TIME[4] ); //周日
DS1302_write_bytetoaddr( 0X84, DS1302TIME[5] ); //小时
DS1302_write_bytetoaddr( 0X82, DS1302TIME[6] ); //分
DS1302_write_bytetoaddr( 0X80, DS1302TIME[7] ); //秒, 开户时钟脉冲

DS1302_write_bytetoaddr( 0X8E, 0X80 ); //写控制寄存器, 保护数据
}

//读时间年月日
void DS1302_read_time( void )
{
DS1302_write_bytetoaddr( 0X8E, 0X00 ); //写控制寄存器 WP000 0000 <===> WP = 0, 数据可以写入

DS1302TIME[1] = DS1302_read_bytefromaddr( 0X8D ); //年
DS1302TIME[2] = DS1302_read_bytefromaddr( 0X89 ); //月
DS1302TIME[3] = DS1302_read_bytefromaddr( 0X87 ); //日
DS1302TIME[4] = DS1302_read_bytefromaddr( 0X8B ); //周日
DS1302TIME[5] = DS1302_read_bytefromaddr( 0X85 ); //小时
DS1302TIME[6] = DS1302_read_bytefromaddr( 0X83 ); //分
DS1302TIME[7] = DS1302_read_bytefromaddr( 0X81 ); //秒, 开户时钟脉冲

DS1302_write_bytetoaddr( 0X8E, 0X80 ); //写控制寄存器, 保护数据
}

//将时间分解
void TimeSpare( void )
{
uchar t = 0;
uchar i = 0;
uchar j = 0;

for( i = 0; i < 8; i++ )
{
t = i * 2;
DS1302TIMEDISP[t] = DS1302TIME[i] >> 4;
DS1302TIMEDISP[t + 1] = DS1302TIME[i] & 0x0f;
}
}

//将时间合成
void TimeMix( void )
{
uchar t = 0;
uchar i = 0;
uchar j = 0;

for( i = 0; i < 8; i++ )
{
t = i * 2;
DS1302TIME[i] = ( ( DS1302TIMEDISP[t] << 4 ) | DS1302TIMEDISP[t + 1] );
}
}

//显示时间
void disptime( void )
{
TimeSpare(); //将每一个时间分隔为两部分,十位部分,个位部分。

LCD_write_char( 1, 8, DS1302TIMEDISP[2] + 0X30 );
LCD_write_char( 1, 9, DS1302TIMEDISP[3] + 0X30 );
LCD_write_char( 1, 10, '/' );
LCD_write_char( 1, 11, DS1302TIMEDISP[4] + 0X30 );
LCD_write_char( 1, 12, DS1302TIMEDISP[5] + 0X30 );
LCD_write_char( 1, 13, '/' );
LCD_write_char( 1, 14, DS1302TIMEDISP[6] + 0X30 );
LCD_write_char( 1, 15, DS1302TIMEDISP[7] + 0X30 );

LCD_write_char( 2, 8, DS1302TIMEDISP[10] + 0X30 );
LCD_write_char( 2, 9, DS1302TIMEDISP[11] + 0X30 );
LCD_write_char( 2, 10, ':' );
LCD_write_char( 2, 11, DS1302TIMEDISP[12] + 0X30 );
LCD_write_char( 2, 12, DS1302TIMEDISP[13] + 0X30 );
LCD_write_char( 2, 13, ':' );
LCD_write_char( 2, 14, DS1302TIMEDISP[14] + 0X30 );
LCD_write_char( 2, 15, DS1302TIMEDISP[15] + 0X30 );
}

//**********************************************************************************

//-----------------------T0计数部分主要对模式选择时闪动要更改的数据-----------------
//---------------------------------------按键部分------------------------------------
#define on 1
#define off 0

uchar model_year = 0; //年
uchar model_month = 0; //月
uchar model_date = 0; //日
uchar model_hour = 0; //时
uchar model_min = 0; //分
uchar model_sec = 0; //秒

//测度灯
void led_on( uchar onoff )
{
DDRB |= ( 1 << PB0 );
if( onoff == 1 )
PORTB &=~ ( 1 << PB0 );
if( onoff == 0 )
PORTB |= ( 1 << PB0 );
}
//按键引脚端口初始化
void key_port_init( void )
{
DDRD &=~ ( 1 << PD2 ) | ( 1 << PD4 ) | ( 1 << PD5 ) | ( 1 << PD6 ) | ( 1 << PD7 ); //定义上拉电阻
PORTD |= ( 1 << PD2 ) | ( 1 << PD4 ) | ( 1 << PD5 ) | ( 1 << PD6 ) | ( 1 << PD7 ); //不影响其它位
}

//T0寄存器初始化
//TIMER0 initialize - prescale:1024
// WGM: CTC
// desired value: 20mSec
// actual value: 20.096mSec (-0.5%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x64; //set count
OCR0 = 0x9C; //set compare
TCCR0 = 0x0D; //start timer
}


void flash_bit( void )
{
//判断model值, 闪动该位
switch( model )
{
//年十位
case 1:
{
if( t == 1 ) t = 0;
else if( t == 0 ) { LCD_write_char( 1, 8, ' ' ); delay_nms( 100 ); t = 1; }
}; break;

//年个位
case 2:
{
if( t == 1 ) t = 0;
else if( t == 0 ) { LCD_write_char( 1, 9, ' ' ); delay_nms( 100 ); t = 1; }
}; break;

//月十位
case 3:
{
if( t == 1 ) t = 0;
else if( t == 0 ) { LCD_write_char( 1, 11, ' ' ); delay_nms( 100 ); t = 1; }
}; break;

//月个位
case 4:
{
if( t == 1 ) t = 0;
else if( t == 0 ) { LCD_write_char( 1, 12, ' ' ); delay_nms( 100 ); t = 1; }
}; break;

//日十位
case 5:
{
if( t == 1 ) t = 0;
else if( t == 0 ) { LCD_write_char( 1, 14, ' ' ); delay_nms( 100 ); t = 1; }
}; break;

//日个位
case 6:
{
if( t == 1 ) t = 0;
else if( t == 0 ) { LCD_write_char( 1, 15, ' ' ); delay_nms( 100 ); t = 1; }
}; break;

//时十位
case 7:
{
if( t == 1 ) t = 0;
else if( t == 0 ) { LCD_write_char( 2, 8, ' ' ); delay_nms( 100 ); t = 1; }
}; break;

//时个位
case 8:
{
if( t == 1 ) t = 0;
else if( t == 0 ) { LCD_write_char( 2, 9, ' ' ); delay_nms( 100 ); t = 1; }
}; break;

//分十位
case 9:
{
if( t == 1 ) t = 0;
else if( t == 0 ) { LCD_write_char( 2, 11, ' ' ); delay_nms( 100 ); t = 1; }
}; break;

//分个位
case 10:
{
if( t == 1 ) t = 0;
else if( t == 0 ) { LCD_write_char( 2, 12, ' ' ); delay_nms( 100 ); t = 1; }
}; break;

//秒十位
case 11:
{
if( t == 1 ) t = 0;
else if( t == 0 ) { LCD_write_char( 2, 14, ' ' ); delay_nms( 100 ); t = 1; }
}; break;

//秒个位
case 12:
{
if( t == 1 ) t = 0;
else if( t == 0 ) { LCD_write_char( 2, 15, ' ' ); delay_nms( 100 ); t = 1; }
}; break;

default: break;
}
}


//模式闪动
void modelflash( void )
{
model++;
model %= 13;
}

//加
void add_timebybit( void )
{
switch( model )
{
case 1: DS1302TIMEDISP[2]++; if( DS1302TIMEDISP[2] == 10 ) DS1302TIMEDISP[2] = 0; break;
case 2: DS1302TIMEDISP[3]++; if( DS1302TIMEDISP[3] == 10 ) DS1302TIMEDISP[3] = 0; break;
case 3: DS1302TIMEDISP[4]++; if( DS1302TIMEDISP[4] == 2 ) DS1302TIMEDISP[4] = 0; break;
case 4: DS1302TIMEDISP[5]++; if( DS1302TIMEDISP[5] == 10 ) DS1302TIMEDISP[5] = 0; break;
case 5: DS1302TIMEDISP[6]++; if( DS1302TIMEDISP[6] == 4 ) DS1302TIMEDISP[6] = 0; break;
case 6: DS1302TIMEDISP[7]++; if( DS1302TIMEDISP[7] == 10 ) DS1302TIMEDISP[7] = 0; break;

case 7: DS1302TIMEDISP[10]++; if( DS1302TIMEDISP[10] == 3 ) DS1302TIMEDISP[10] = 0; break;
case 8: DS1302TIMEDISP[11]++; if( DS1302TIMEDISP[11] == 10 ) DS1302TIMEDISP[11] = 0; break;
case 9: DS1302TIMEDISP[12]++; if( DS1302TIMEDISP[12] == 7 ) DS1302TIMEDISP[12] = 0; break;
case 10: DS1302TIMEDISP[13]++; if( DS1302TIMEDISP[13] == 10 ) DS1302TIMEDISP[13] = 0; break;
case 11: DS1302TIMEDISP[14]++; if( DS1302TIMEDISP[14] == 7 ) DS1302TIMEDISP[14] = 0; break;
case 12: DS1302TIMEDISP[15]++; if( DS1302TIMEDISP[15] == 10 ) DS1302TIMEDISP[15] = 0; break;

default : break;
}

TimeMix();
DS1302_write_time();
}

//确定部分
void sure( void )
{
model = 0;
}


//中断服务程序
#pragma interrupt_handler int0_isr:iv_INT0
void int0_isr( void )
{
//external interupt on INT0
CLI(); //关闭全局中断
if( ( ( PIND & 0b11110100 ) != 0b11110100 ) )
{
delay_nms( 40 ); //去除抖动
if( ( ( PIND & 0B11110100 ) != 0B11110100 ) )
{
switch( PIND & 0B11110100 )
{
//模式
case 0b11100000 : modelflash(); break;
//加
case 0b11010000 : add_timebybit(); break;
//减
case 0b10110000 : break;
//确定
case 0b01110000 : sure(); break;

default : break;
}
}
}
SEI();
}


//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
key_port_init();
LCD_init();
DS1302_init();
//timer0_init();

MCUCR = 0x02;
GICR = 0x40;
TIMSK = 0x02; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
//**********************************************************************************


void main( void )
{
init_devices();

LCD_write_string( 1, 0, "DATA 20 / / " );
LCD_write_string( 2, 0, "TIME : : " );

DS1302_write_time();

while( 1 )
{
DS1302_read_time();
disptime();
delay_nms( 100 );
flash_bit();
}
}


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

特朗普集团近日取消了其新推出的T1智能手机“将在美国制造”的宣传标语,此举源于外界对这款手机能否以当前定价在美国本土生产的质疑。

关键字: 特朗普 苹果 AI

美国总统特朗普在公开场合表示,他已要求苹果公司CEO蒂姆·库克停止在印度建厂,矛头直指该公司生产多元化的计划。

关键字: 特朗普 苹果 AI

4月10日消息,据媒体报道,美国总统特朗普宣布,美国对部分贸易伙伴暂停90天执行新关税政策,同时对中国的关税提高到125%,该消息公布后苹果股价飙升了15%。这次反弹使苹果市值增加了4000多亿美元,目前苹果市值接近3万...

关键字: 特朗普 AI 人工智能 特斯拉

3月25日消息,据报道,当地时间3月20日,美国总统特朗普在社交媒体平台“真实社交”上发文写道:“那些被抓到破坏特斯拉的人,将有很大可能被判入狱长达20年,这包括资助(破坏特斯拉汽车)者,我们正在寻找你。”

关键字: 特朗普 AI 人工智能 特斯拉

1月22日消息,刚刚,新任美国总统特朗普放出重磅消息,将全力支持美国AI发展。

关键字: 特朗普 AI 人工智能

特朗普先生有两件事一定会载入史册,一个是筑墙,一个是挖坑。在美墨边境筑墙的口号确保边境安全,降低因非法移民引起的犯罪率过高问题;在中美科技产业之间挖坑的口号也是安全,美国企业不得使用对美国国家安全构成威胁的电信设备,总统...

关键字: 特朗普 孤立主义 科技产业

据路透社1月17日消息显示,知情人士透露,特朗普已通知英特尔、铠侠在内的几家华为供应商,将要撤销其对华为的出货的部分许可证,同时将拒绝其他数十个向华为供货的申请。据透露,共有4家公司的8份许可被撤销。另外,相关公司收到撤...

关键字: 华为 芯片 特朗普

曾在2018年时被美国总统特朗普称作“世界第八奇迹”的富士康集团在美国威斯康星州投资建设的LCD显示屏工厂项目,如今却因为富士康将项目大幅缩水并拒绝签订新的合同而陷入了僵局。这也导致富士康无法从当地政府那里获得约40亿美...

关键字: 特朗普 富士康

今年5月,因自己发布的推文被贴上“无确凿依据”标签而与推特发生激烈争执后,美国总统特朗普签署了一项行政令,下令要求重审《通信规范法》第230条。

关键字: 谷歌 facebook 特朗普

众所周知,寄往白宫的所有邮件在到达白宫之前都会在他地进行分类和筛选。9月19日,根据美国相关执法官员的通报,本周早些时候,执法人员截获了一个寄给特朗普总统的包裹,该包裹内包含蓖麻毒蛋白。

关键字: 美国 白宫 特朗普
关闭