没用过DS1302,对这个芯片不是很了解。哪位高手替我看看是怎么回事?
程序如下;
#INCLUDE P16F877A.INC
#DEFINE D0 PORTD,7
#DEFINE D1 PORTD,6
#DEFINE D2 PORTD,5
#DEFINE D3 PORTD,4
#DEFINE D4 PORTD,3
#DEFINE D5 PORTD,2
;==================================================;
LED0W EQU 20H
LED1W EQU 21H
LED2W EQU 22H
LED3W EQU 23H
LED4W EQU 24H
LED5W EQU 25H
LEDSM_FLAG EQU 26H
#DEFINE SM0W LEDSM_FLAG,0
#DEFINE SM1W LEDSM_FLAG,1
#DEFINE SM2W LEDSM_FLAG,2
#DEFINE SM3W LEDSM_FLAG,3
#DEFINE SM4W LEDSM_FLAG,4
#DEFINE SM5W LEDSM_FLAG,5
;=================================================;
W_TEMP EQU 27H
STATUS_TEMP EQU 28H
PCLATH_TEMP EQU 29H
TIME_FLAG EQU 2AH
#DEFINE SJINT TIME_FLAG,0
#DEFINE LED_SMSJ TIME_FLAG,1
;==================DS1302总线定义==================;
#DEFINE SDAT PORTA,0
#DEFINE SCK PORTA,1
#DEFINE RST PORTA,2
#DEFINE TRISA_SDAT TRISA,0
#DEFINE TRISA_SCK TRISA,1
#DEFINE TRISA_RST TRISA,2
CNT EQU 2BH
RXBUF EQU 2CH
TXBUF EQU 2DH
;==================================================;
SECONDH EQU 31H
SECONDL EQU 32H
MINUTEH EQU 33H
MINUTEL EQU 34H
HOURH EQU 35H
HOURL EQU 36H
;=================================================;
ORG 0000H
GOTO START
ORG 0004H
GOTO INT_SEVER
ORG 0005H
INT_SEVER: MOVWF W_TEMP
SWAPF STATUS,W
MOVWF STATUS_TEMP
MOVF PCLATH,W
MOVWF PCLATH_TEMP
BTFSC INTCON,TMR0IF
GOTO T0INT
GOTO INT_SEVER_OK
T0INT: BCF INTCON,TMR0IF
MOVLW .200
MOVWF TMR0
BSF SJINT
GOTO INT_SEVER_OK
INT_SEVER_OK: MOVF PCLATH_TEMP,W
MOVWF PCLATH
SWAPF STATUS_TEMP,W
MOVWF STATUS
MOVF W_TEMP,W
RETFIE
;=========================================================;
START:
BANKSEL TRISB
CLRF TRISB
CLRF TRISD
CLRF TRISA
MOVLW .6
MOVWF ADCON1
MOVLW .2
MOVWF OPTION_REG
BANKSEL 20H
CLRF PORTB
CLRF PORTD
CLRF PORTA
MOVLW .200
MOVWF TMR0
BSF INTCON,GIE
BSF INTCON,PEIE
BSF INTCON,TMR0IE
CALL DS1302_INT
MAIN:
CALL READ1302
CALL LED_SM
GOTO MAIN
;=======================================================
READ1302:
CLRWDT
BCF RST
BCF SCK
BSF RST
MOVLW 0X81
MOVWF TXBUF
CALL Ds1302IutputByte
CALL DS1302OutputByte
MOVLW 0X0F
ANDWF RXBUF,W
MOVWF SECONDL
MOVLW 0X70
ANDWF RXBUF,W
MOVWF SECONDH
RRF SECONDH,F
RRF SECONDH,F
RRF SECONDH,F
RRF SECONDH,F
MOVLW 0X83
MOVWF TXBUF
CALL Ds1302IutputByte
CALL DS1302OutputByte
MOVLW 0X0F
ANDWF RXBUF,W
MOVWF MINUTEL
MOVLW 0X70
ANDWF RXBUF,W
MOVWF MINUTEH
RRF MINUTEH,F
RRF MINUTEH,F
RRF MINUTEH,F
RRF MINUTEH,F
MOVLW 0X85
MOVWF TXBUF
CALL Ds1302IutputByte
CALL DS1302OutputByte
MOVLW 0X0F
ANDWF RXBUF,W
MOVWF HOURL
MOVLW 0X70
ANDWF RXBUF,W
MOVWF HOURH
RRF HOURH,F
RRF HOURH,F
RRF HOURH,F
RRF HOURH,F
READ1302_OK: RETURN
;=======================================================;
Ds1302IutputByte:
CLRWDT
BANKSEL TRISA
BCF TRISA_SDAT ;设置为输出
BANKSEL 20H
BCF RST
BCF SCK
BSF RST
MOVLW .8
MOVWF CNT
SENT_LOOP:
BCF SCK
BCF SDAT
BTFSC TXBUF,0
BSF SDAT
RRF TXBUF,F
BCF TXBUF,7
BSF SCK
DECFSZ CNT,F
GOTO SENT_LOOP
BCF RST
BCF SCK
BCF SDAT
GOTO Ds1302IutputByte_OK
Ds1302IutputByte_OK: RETURN
;========================================================;
DS1302OutputByte:
CLRWDT
BANKSEL TRISA
BSF TRISA_SDAT ;设置为输入
BANKSEL 20H
BCF RST
BCF SCK
BSF RST
MOVLW .8
MOVWF CNT
RECIVE_LOOP:
BCF SCK
RRF RXBUF,F
BCF RXBUF,7
BTFSC SDAT
BSF RXBUF,7
BSF SCK
DECFSZ CNT,F
GOTO RECIVE_LOOP
BCF RST
BCF SCK
GOTO DS1302OutputByte_OK
DS1302OutputByte_OK:RETURN
;======================================================;
DS1302_INT:
BCF RST
BCF SCK
BSF RST
BANKSEL TRISA
BCF TRISA_SDAT
BANKSEL 20H
MOVLW 0X80 ;发送写秒命令
MOVWF TXBUF
CALL Ds1302IutputByte
MOVLW 0X00 ;清除CE,开始工作
MOVWF TXBUF
CALL Ds1302IutputByte
RETURN
;=======================================================;
LED_SM:
CLRWDT
BTFSS SJINT
GOTO LED_SM_OK
BCF SJINT
GOTO SM_CLOCK
SM_CLOCK: MOVF SECONDL,W
MOVWF LED5W
MOVF SECONDH,W
MOVWF LED4W
MOVF MINUTEL,W
MOVWF LED3W
MOVF MINUTEH,W
MOVWF LED2W
MOVF HOURL,W
MOVWF LED1W
MOVF HOURH,W
MOVWF LED0W
GOTO SMSMSM
SMSMSM:
BTFSS SM0W
GOTO LED0W_SM
BTFSS SM1W
GOTO LED1W_SM
BTFSS SM2W
GOTO LED2W_SM
BTFSS SM3W
GOTO LED3W_SM
BTFSS SM4W
GOTO LED4W_SM
GOTO LED5W_SM
GOTO LED_SM_OK
LED0W_SM:
BSF SM0W
BCF D0
MOVF LED0W,W
CALL TABLE
MOVWF PORTB
BSF D5
GOTO LED_SM_OK
LED1W_SM:
BSF SM1W
BCF D5
MOVF LED1W,W
CALL TABLE
MOVWF PORTB
BSF D4
GOTO LED_SM_OK
LED2W_SM:
BSF SM2W
BCF D4
MOVF LED2W,W
CALL TABLE
MOVWF PORTB
BSF D3
GOTO LED_SM_OK
LED3W_SM:
BSF SM3W
BCF D3
MOVF LED3W,W
CALL TABLE
MOVWF PORTB
BSF D2
GOTO LED_SM_OK
LED4W_SM:
BSF SM4W
BCF D2
MOVF LED4W,W
CALL TABLE
MOVWF PORTB
BSF D1
GOTO LED_SM_OK
LED5W_SM:
MOVLW B'00000000'
MOVWF LEDSM_FLAG
BCF D1
MOVF LED5W,W
CALL TABLE
MOVWF PORTB
BSF D0
GOTO LED_SM_OK
LED_SM_OK: RETURN
TABLE: ADDWF PCL,F
; RETLW ABCDEFGH
RETLW B'00000011'
RETLW B'10011111'
RETLW B'00100101'
RETLW B'00001101'
RETLW B'10011001'
RETLW B'01001001'
RETLW B'01000001'
RETLW B'00011111'
RETLW B'00000001'
RETLW B'00001001'
END
#include "pic.h"
#include"math.h"
#define IO RC4 //定义DS1302的数据口
#define CLK RC3 //定义DS1302的时钟口
#define RST RC2 //定义DS1302的复位口
#define uchar unsigned char //宏定义uchar为无符号字符型
#define uint unsigned int //宏定义uint为无符号整型
const uchar *table2[]={0x22,0x22,0x10,0x11,0x00,0x11,0x00}; //初值显示
uchar table1[7]; //总缓存数组
uchar set_tab[7]; //调整时间后的缓存数组
const char *table[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char TABLE_BIT_SELECT[]={0x01,0x02,0x04,0x20,0x10,0x08};
//unsigned char TABLE_NUMBER[]={ZERO,ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE};
unsigned char TABLE_NUMBER[]={0x00,0x08,0x01,0x09,0x02,0x0a,0x03,0x0b,0x04,0x0c};
char sec,min,hou,day,month,week,year,weekadd,week1;//秒,分,时,日,月,星期,年,星期时间选择参数
uchar count,i; //用于计数button2的次数;用于延时计数
uchar a,b; //用于十六进制码转换成BCD码的寄存变量
uchar *pda; //用于设置时间的指针变量
void delay(uchar dly); //延时函数n毫秒
/*******************************************/
// ds1302模块
/*******************************************/
/****************八位数据写入函数*********************/
void inputbyte(uchar cdata)
{
uchar i;
TRISC=0;
for(i=8;i>0;i--)
{
CLK=0;
IO=(cdata&0x01);
//delay(50);
CLK=1;
//delay(50);
cdata=cdata>>1; //在时钟上升沿写入一位数据
}
CLK=0;
}
/***************八位数据读出函数*********************/
uchar outputbyte(void)
{
uchar i;
uchar cdata=0;
TRISC=0x10;
for(i=8;i>0;i--)
{
cdata =cdata >> 1;
CLK = 1;
//delay(50);
CLK = 0;
//delay(50);
if(IO==1) cdata =(cdata|0x80);
}
return(cdata);
TRISC=0;
}
/*************************************************************/
//名称:re_1302
//功能:读出对应寄存器的内容
//调用:inputbyte(uchar cdata)、outputbyte(void)
/***************************************************************/
uchar re_1302(uchar add)
{
uchar cdata;
RST=0;
CLK=0;
RST=1;
inputbyte(add);
cdata = outputbyte();
CLK=0;
RST=0;
delay(40);
return(cdata);
}
/*********************************************************/
//名称:wr_1302
//功能:将指令或数据写入对应寄存器
//调用:inputbyte(uchar cdata)
/******************************************************************/
void wr_1302(uchar add,uchar cdata)
{
RST=0;
CLK=0;
RST=1;
inputbyte(add);
inputbyte(cdata);
CLK=0;
RST=0;
delay(40);
}
/**************************************************************/
//名称:set_1302
//功能:设置时间初值
//调用:wr_1302(uchar add,uchar cdata)
/***************************************************************/
void set_1302(uchar *pda)
{
uchar i;
uchar add=0x80;
wr_1302(0x8e,0x00); //将控制寄存器值设为零,最高位WP=0允许写
for(i=7;i>0;i--) //将七个时间初值写入对应寄存器
{
wr_1302(add,*pda++); //写对应时钟寄存器的值
add+=2;
}
//wr_1302(0x8e,0x80); //写保护,防止干扰影响时间值??????????
}
/*******************************************************************/
//名称:get_1302
//功能:读取当前时间值
//调用函数:re_1302() 、 BCD_transform()
/*******************************************************************/
void get_1302()
{
uchar i;
uchar add=0x81;
for(i=0;i<7;i++)
{
table1=re_1302(add); //读对应时钟寄存器的值
add+=2;
}
}
/****************************************************************************
* 名 称:display()
* 功 能:数码管显示
* 入口参数:
* 出口参数:
* 说 明:
****************************************************************************/
void display()
{
int i, temp, temp1; //定义查表变量
i = table1[0] & 0x0f; //求秒的个位
PORTD = TABLE_NUMBER; //点亮秒的个位
//PORTD=i;
PORTA = TABLE_BIT_SELECT[0];
delay(10); //延长一段时间,保证亮度
i = table1[0] & 0xf0; //求秒的十位
i = i >> 4; //右移4位
PORTD =TABLE_NUMBER; //送D口显示
//PORTD=i;
PORTA = TABLE_BIT_SELECT[1]; //点亮秒的十位
delay(10); //延长一段时间,保证亮度
i = table1[1] & 0x0f; //求分的个位
PORTD =TABLE_NUMBER ; //送D口显示,并显示小数点
//PORTD=i;
PORTA = TABLE_BIT_SELECT[2]; //点亮分的个位
delay(10); //延时一定时间,保证亮度
i = table1[1] & 0xf0; //求分的十位
i = i >> 4;
PORTD = TABLE_NUMBER; //送D口显示
//PORTD=i;
PORTA = TABLE_BIT_SELECT[3]; //点亮分的十位
delay(10); //延长一段时间,保证亮度
i = table1[2] & 0x0f; //求时的个位
PORTD = TABLE_NUMBER ; //送D口显示,并加上小数点
//PORTD=i;
PORTA = TABLE_BIT_SELECT[4]; //点亮时的个位
delay(10); //延时一定时间,保证亮度
i = table1[2] & 0xf0; //求时的十位
i = i >> 4;
PORTD =TABLE_NUMBER;
//送D口显示
//PORTD=i;
PORTA = TABLE_BIT_SELECT[5]; //点亮时的十位
delay(10); //延长一段时间,保证亮度
}
/****************************************************************************
* 名 称:ds1302_init()
* 功 能:DS1302初始化
* 入口参数:
* 出口参数:
* 说 明:
****************************************************************************/
void ds1302_init()
{
CLK=0; //拉低时钟信号
RST=0; //复位DS1302
RST=1; //使能DS1302
inputbyte(0x8e); //发控制命令
inputbyte(0); //允许写DS1302
RST=0; //复位
}
/****************************************************************************
* 名 称:port_init()
* 功 能:引脚初始化
* 入口参数:
* 出口参数:
* 说 明:
****************************************************************************/
void port_init()
{
ADCON1 = 0X07; //设置A口为普通I/O口
//TRISB = 0X0F; //设置B口低4位为输入//高四位为输出
SSPCON=0;
TRISD = 0; //portd 输出
TRISA = 0; //porta 输出
PORTA = 0x3f; //先关闭所有显示
PORTD = 0x08;
TRISC = 0X00; //rc输出
}
/****************************************************************************
* 名 称:delay()
* 功 能:延时
* 入口参数:
* 出口参数:
* 说 明:
****************************************************************************/
void delay(uchar dly) //延时程序
{ //定义整形变量
for (;dly>0;dly--); //延时
}
/***********************************************************/
//功能:主函数
//调用:set_1302()、get_1302()、display()
/************************************************************/
void main()
{
port_init(); //调用引脚初始化函数
ds1302_init(); //调用DS1302初始化函数
set_1302(table); //调用设置时间函数
while (1)
{ get_1302();
//调用取时间函数
display(); //调用显示函数
}
}
一周热门 更多>