?? ds12997.c
字號(hào):
/******************************************************/
//Title:ATMAGE16 & DS12887加上串口通信顯示時(shí)鐘程序-查詢(xún)方式
//ICC-AVR : 2009-3-4 17:04:40
// Target : M16
// Crystal: 1.0000Mhz ~8.0000Mhz都好使
//Author :borlittle
//Function:usart+DS12887 RTC test
//備注 :本程序經(jīng)調(diào)試好使,如果程序不好使,請(qǐng)注意檢查硬件連線,內(nèi)部時(shí)鐘
//記得要校驗(yàn)準(zhǔn),串口才能發(fā)送正確,
// AVR 執(zhí)行時(shí)間:8MHZ ->0.125us 4MHZ->0.25us //有串口,模擬總線最簡(jiǎn)版
// 2MHZ->0.5us *1MHZ->1us ,每句后延時(shí)2句
// at89s52 執(zhí)行時(shí)間:11.0592MHZ->2.17us
//
//
/****************************************************/
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char //定義無(wú)符號(hào)字符為 uchar
#define uint unsigned int //定義無(wú)符號(hào)整型
#define Crystal 8000000 //晶振8MHZ
#define Baud 9600 //波特率
uchar y1,y2,y3,y4,y5,y6; //用于調(diào)試用,在JTAG仿真器與AVR Studio 中查看是否讀取正確
uchar y[19]={0,0,'.',0,0,'.',0,0,' ',0,0,':',0,0,':',0,0,' ',' '}; //09.3.4 17:06:50
//上位機(jī)接收到得時(shí)間數(shù)據(jù)格式
/**********************接口定義*********************************/
//GND <-- MOT VCC -->VCC
// . SQW
// . .
//PA_0<-- AD0 .
//PA_1<-- AD1 .
//PA_2<-- AD2 IRQ -->PB_0
//PA_3<-- AD3 REET -->VCC
//PA_4<-- AD4 DS -->PB_1
//PA_5<-- AD5 .
//PA_6<-- AD6 R/W -->PB_2
//PA_7<-- AD7 AS -->PB_3
// GND CS -->GND--可以用端口控制以省電降功耗
/*********************引腳說(shuō)明***********************************/
//DS12887 16 器件
//數(shù)據(jù)線 PA口 數(shù)據(jù)地址公用總線
//DS_IRQ PB0 時(shí)間中斷
//DS_DS PB1 數(shù)據(jù)選通
//DS_RW PB2 讀寫(xiě)控制
//DS_AS PB3 地址選通
//DS_CS PB4 芯片片選
//DS_MOT GND 模式選擇
/*******************數(shù)據(jù)地址定義*************************************/
#define DS12887_Second 0x00 //秒
#define DS12887_Minute 0x02 //分
#define DS12887_Hour 0x04 //時(shí)
#define DS12887_Week 0x06 //星期
#define DS12887_Day 0x07 //日
#define DS12887_Month 0x08 //月
#define DS12887_Year 0x09 //年
//引腳電平定義
#define P_DS_1 PORTB|=BIT(PB1) //DS_DS為1
#define P_DS_0 PORTB&=~BIT(PB1) //DS_DS為0
#define D_DS_1 DDRB |=BIT(PB1) //設(shè)為輸出
#define P_RW_1 PORTB|=BIT(PB2) //DS_RW為1
#define P_RW_0 PORTB&=~BIT(PB2) //DS_RW為0
#define D_RW_1 DDRB |=BIT(PB2) //設(shè)為輸出
#define P_AS_1 PORTB|=BIT(PB3) //DS_AS為1
#define P_AS_0 PORTB&=~BIT(PB3) //DS_AS為0
#define D_AS_1 DDRB |=BIT(PB3) //設(shè)為輸出
#define P_CS_1 PORTB|=BIT(PB4) //DS_CS為1
#define P_CS_0 PORTB&=~BIT(PB4) //DS_CS為0
#define D_CS_1 DDRB |=BIT(PB4) //設(shè)為輸出
//數(shù)據(jù)端口定義
#define AD_DDR DDRA //AD(地址/數(shù)據(jù)服用線)的輸入/輸出控制
#define AD_PORT PORTA //AD(地址/數(shù)據(jù)服用線)的輸出電平控制
#define AD_PIN PINA //AD(地址/數(shù)據(jù)服用線)的輸入電平控制
//定義時(shí)間類(lèi)型,結(jié)構(gòu)體數(shù)據(jù)類(lèi)型
typedef struct _SYSTEMTIME_
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Week;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char DateString[9];
unsigned char TimeString[9];
}SYSTEMTIME;
/***********************函數(shù)聲明*****************************/
void DS12887_Init(void); //DS12887初始化
void DS12887_Write( uchar Address, uchar Value); //DS12887指定地址寫(xiě)入數(shù)據(jù)
uchar DS12887_Read(uchar Address); //DS12887指定地址中讀出數(shù)據(jù)
void DS12887_SetTime( uchar Address, uchar Value); //設(shè)置時(shí)間函數(shù)
void DS12887_GetTime(SYSTEMTIME *Time); //讀出時(shí)間
void port_init(void);
void init_devices(void);
void usart_char_send(uchar i);
void usart_str_send(char *s);
uchar usart_char_receive(void);
/*****************串口初始化*********************************/
void usart_init(void)
{
UCSRB = 0x00; //禁止發(fā)送和接收
UCSRA = 0x02; //倍速異步模式USX=1
UCSRC = 0x06; //0000 0110,UCSZ1=1,UCSZ0=1;8位字符,1位停止位
UBRRL=(Crystal/8/(Baud+1))%256; //若為正常異步模式USX0=0則位(Crystal/16/(Baud+1))%256
UBRRH=(Crystal/8/(Baud+1))/256; //參見(jiàn)ATMAGE16使用手冊(cè)
UCSRB = 0x18; //允許發(fā)送和接收
}
/******************端口初始化*******************************/
void port_init(void)
{
DDRB = 0xFF;
PORTB = 0xFF; //設(shè)為輸出高電平
DDRA = 0x00;
PORTA = 0x00; //設(shè)為高阻態(tài)
PORTD = 0xFF; //設(shè)置RXD0和TXD0
DDRD = 0x02;
}
//****************發(fā)送一個(gè)字符******************************
void usart_char_send(uchar i)
{
while(!(UCSRA&(1<<UDRE)));
UDR=i;
}
/******************發(fā)送一個(gè)字符串*************************/
void usart_str_send(char *s)
{
while(*s)
{
usart_char_send(*s);
s++;
}
}
/*****************發(fā)送數(shù)組數(shù)據(jù)**************************************/
void usart_send_arry(void)
{
uchar i;
for(i=0;i<19;i++)
usart_char_send(y[i]);
}
/*****************接收一個(gè)字符****************************/
uchar usart_char_receive(void)
{
while(!(UCSRA&(1<<RXC)));
return UDR;
}
/*******DS12887指定地址寫(xiě)入數(shù)據(jù) ,嚴(yán)格按照INTERL的時(shí)序,程序**********/
void DS12887_Write( uchar Address, uchar Value)
{
P_AS_0;
_NOP();
_NOP();
P_DS_1;
_NOP();
_NOP();
P_RW_1; //給出讀信號(hào)
_NOP();
_NOP();
P_AS_1; //鎖存信號(hào)高電平
_NOP();
_NOP();
AD_DDR = 0xFF; //數(shù)據(jù)口設(shè)置為輸出
_NOP();
_NOP();
_NOP();
_NOP();
AD_PORT = Address; //給出地址
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP(); //
P_AS_0; //鎖存信號(hào)低電平
_NOP();
_NOP();
P_RW_0; //給出寫(xiě)信號(hào)
_NOP();
_NOP();
_NOP();
AD_PORT = Value; //寫(xiě)出數(shù)據(jù)
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
P_RW_1; //給出讀信號(hào)
_NOP();
_NOP();
_NOP();
P_AS_1; //片選信號(hào)高電平
_NOP();
_NOP();
}
/*********DS12887指定地址中讀出數(shù)據(jù),嚴(yán)格按照INTERL的時(shí)序!!!!!********/
uchar DS12887_Read( uchar Address)
{
unsigned char temp = 0;
P_AS_0; //鎖存信號(hào)高電平
_NOP();
_NOP();
P_DS_1;
_NOP();
_NOP();
P_RW_1; //給出讀信號(hào)
_NOP();
_NOP();
P_AS_1; //鎖存信號(hào)高電平
_NOP();
_NOP();
AD_DDR = 0xFF; //數(shù)據(jù)口設(shè)置為輸出
_NOP();
_NOP();
_NOP();
_NOP();
AD_PORT = Address; //給出地址
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
P_AS_0; //鎖存信號(hào)低電平
_NOP();
_NOP();
P_DS_0; //給出寫(xiě)信號(hào)
_NOP();
_NOP();
AD_DDR = 0X00; //端口方向設(shè)置為輸入
_NOP();
_NOP();
_NOP();
_NOP();
temp = AD_PIN; //讀入數(shù)據(jù)
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
P_DS_1; //
_NOP();
_NOP();
P_AS_1; //
_NOP();
_NOP();
return temp;
}
//DS12887初始化
void DS12887_Init(void)
{
DS12887_Write(0x0a, 0x20); //打開(kāi)振蕩器,啟動(dòng)DS12887
DS12887_Write(0x0b, 0x86); //禁止更新,接下來(lái)初始化數(shù)據(jù),即寫(xiě)入時(shí)間,日期等
DS12887_Write(0x0b, 0x06); //正常更新,二進(jìn)制格式,24進(jìn)制小時(shí)
}
//設(shè)置時(shí)間函數(shù)
void DS12887_SetTime( uchar Address, uchar Value)
{
DS12887_Write(0x0b, 0x86); //禁止更新,接下來(lái)初始化數(shù)據(jù),即寫(xiě)入時(shí)間,日期等
DS12887_Write(Address,Value);
DS12887_Write(0x0b, 0x06); //正常更新,二進(jìn)制格式,24進(jìn)制小時(shí)
}
//讀出時(shí)間
void DS12887_GetTime(SYSTEMTIME *Time)
{ uchar temp;
Time->Second = DS12887_Read(DS12887_Second);
Time->Minute = DS12887_Read(DS12887_Minute);
Time->Hour = DS12887_Read(DS12887_Hour );
Time->Day = DS12887_Read(DS12887_Day );
//Time->Week = DS12887_Read(DS12887_Week );
Time->Month = DS12887_Read(DS12887_Month );
Time->Year = DS12887_Read(DS12887_Year );
y1=DS12887_Read(DS12887_Second);
y2=DS12887_Read(DS12887_Minute);
y3=DS12887_Read(DS12887_Hour );
y4=DS12887_Read(DS12887_Day );
y5=DS12887_Read(DS12887_Month );
y6=DS12887_Read(DS12887_Year );
}
/*********************日期轉(zhuǎn)化成字符 09-02-19************/
void DateToStr(SYSTEMTIME *Time)
{
Time->DateString[0] = Time->Year/10 + '0';
Time->DateString[1] = Time->Year%10 + '0';
Time->DateString[2] = '-';
Time->DateString[3] = Time->Month/10 + '0';
Time->DateString[4] = Time->Month%10 + '0';
Time->DateString[5] = '-';
Time->DateString[6] = Time->Day/10 + '0';
Time->DateString[7] = Time->Day%10 + '0';
Time->DateString[8] = '\0';
y[0]=Time->DateString[0];
y[1]=Time->DateString[1]; //年
y[3]=Time->DateString[3];
y[4]=Time->DateString[4]; //月
y[6]=Time->DateString[6];
y[7]=Time->DateString[7]; //日
}
/*********************時(shí)間轉(zhuǎn)化成字符***********************************/
void TimeToStr(SYSTEMTIME *Time)
{
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 + '0';
Time->TimeString[2] = ':';
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
Time->TimeString[5] = ':';
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second%10 + '0';
Time->TimeString[8] = '\0';
y[9]=Time->TimeString[0];
y[10]=Time->TimeString[1]; //時(shí)
y[12]=Time->TimeString[3];
y[13]=Time->TimeString[4]; //分
y[15]=Time->TimeString[6];
y[16]=Time->TimeString[7]; //秒
}
/********************初始化器件************************************/
void init_devices(void)
{
port_init();
usart_init();
}
/***************主函數(shù)*****************************/
void main(void)
{
SYSTEMTIME CurrentTime;
uchar temp;
init_devices();
DS12887_Init(); //只讀時(shí)間的時(shí)候可以屏蔽該句
DS12887_GetTime(&CurrentTime);
/*************時(shí)間初始化設(shè)置 ,2009-3-4 16:57:00************/
//時(shí)鐘調(diào)準(zhǔn)后屏蔽該段程序
//*
DS12887_SetTime(DS12887_Second, 0); //設(shè)置秒
DS12887_SetTime(DS12887_Minute, 57); //設(shè)置分
DS12887_SetTime(DS12887_Hour,16); //設(shè)置時(shí)
DS12887_SetTime(DS12887_Day, 4); //設(shè)置天
DS12887_SetTime(DS12887_Month, 3); //設(shè)置月
DS12887_SetTime(DS12887_Year, 9); //設(shè)置年
//*/
usart_str_send("DS12887工作中.......");
while(1)
{
DS12887_GetTime(&CurrentTime);
DateToStr(&CurrentTime);
TimeToStr(&CurrentTime);
temp=usart_char_receive();
if(temp=='0') //字符0----數(shù)據(jù)傳送啟動(dòng)指令
usart_str_send("現(xiàn)在時(shí)間是:");
usart_send_arry();//傳送時(shí)間數(shù)據(jù)
usart_str_send(" ");
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -