¿Puede la función SPI del microcontrolador STC controlar el chip de reloj DS1302?
El siguiente es un artículo sobre el uso de DS1302 para mostrar un reloj digital en una pantalla LCD 1602, espero que le sea útil.
/****************************************** ******************************
* Nombre del archivo: Reloj DS1302LCD.c
** ********************** ************************* ****** *******************/
#includelt;reg52.hgt;
#includelt; intrins.hgt;
p>
#define uchar unsigned char
#define uint unsigned int
sbit ACC0 = ACC^0;
bit ACC7 = ACC^7;
bit P3_2 = P3^2;
bit P3_5 = P3^ 4
bit T_CLK = P1; ^6; /*Pin de línea de reloj de tiempo real */
sbit T_IO = P3^5 /*Pin de línea de datos de reloj de tiempo real*/
sbit T_RST = P1 ^7; /*Pin de línea de reinicio del reloj en tiempo real*/
//Referencia de estos tres pines
sbit E=P2^7; //1602 pin de habilitación
sbit RW=P2^6 ; //1602 pin de lectura/escritura
sbit RS=P2^5; //1602 pin de selección de datos/comandos
/** ********** **************************** ************* ********** ********
* Nombre: retraso()
* Función: retraso, el tiempo de retraso es de aproximadamente 140US.
* Entrada: Ninguna
* Salida: Ninguna
********************* *** ************************************************* *** /
retraso nulo()
{
int i, j
for(i=0; ilt; =10; i )
para(j= 0; jlt;=2; j )
}
/********* *** ************************************************* **** ******
* Nombre: enable(uchar del)
* Función: función de comando 1602
* Entrada: Entrada: Ingrese el valor del comando
* Salida: Ninguna
********************************* ********* *************************************/
void enable(uchar del) p>
{
P0 = del;
RS = 0
RW = 0;
E = 0;
retraso();
E = 1
retraso(); >}
/* **************************************** ************ *******************
* Nombre: escribir(uchar del)
* Función: 1602 función de escritura de datos
* Entrada a escribir en 1602
* Salida: Ninguna
******* ************ **************************************** ************* */
void write(uchar del)
{
P0 = del
RS = 1;
RW = 0;
E = 0;
retraso(); 1;
retraso();
}
/****************** *** ************ *************************************
* Nombre: L1602_init()
* Función: inicialización 1602, consulte la información 1602
* Entrada: Ninguna
* Salida : Ninguno
******* ********************************** ***************** *******************/
void L1602_init(void) p>
{
habilitar(0x01);
habilitar(0x38);
habilitar(0x0c); (0x06);
habilitar(0xd0);
}
;/*********************************************** **********************
* Nombre: L1602_char (uchar colgar, uchar mentir, signo de carbón)
* Función: cambia el valor de un determinado bit en la pantalla LCD. Si desea que el quinto carácter de la primera línea muestre "b", llame a esta función. Como se muestra a continuación
L1602_char(1, 5, 'b')
* Entrada: filas, columnas, se deben ingresar 1602 datos
* Salida: Ninguno
****************************************** ****** ************* **************/
void L1602_char(uchar colgar,uchar mentir, signo de carácter)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang = = 2) a = 0xc0 ;
a = una mentira - 1;
enable(a);
escribir(firmar); p>}
/*************************************** ********* ********* ****************
* Nombre: L1602_string(uchar colgar, uchar mentir, uchar *p)
* Función: cambia el valor de un determinado bit en la pantalla LCD. Si desea que el quinto carácter de la primera línea comience a mostrar "ab cd ef", llame a esta función de la siguiente manera. /p>
L1602_string(1, 5, " ab cd ef;")
* Entrada: filas, columnas, 1602 datos requeridos
* Salida: Ninguna
******** **************************************** ************ *************/
void L1602_string(uchar colgar, uchar mentir, uchar *p)
{
uchar a;
if(hang == 1) a = 0x80
if(hang == 2) a = 0xc0; ;
a = una mentira - 1
enable(a
while(1)
{
if(*p == '\0' ) romper
escribir(*p>
p
}
}
/***** ************************************* ************** *************
* Nombre: v_RTInputByte()
* Función: Escriba 1 byte en DS1302.
Datos
* Entrada: Datos escritos por ucDa
* Salida: Ninguna
****************** * ************************************************** ******/
void v_ RTInputByte(uchar ucDa)
{
uchar i;
ACC = ucDa;
T_RST = 1;
for(i=8; igt; 0; i--)
{
T_IO = ACC0 ;
T_CLK = 1
T_CLK = 0;
ACC = ACC gt; >
}
/*************************************** ******************* *************
* Nombre: uc_RTOutputByte()
* Función: Leer datos de 1 byte de DS1302
* Entrada: Ninguna
* Valor de retorno: ACC
******** ** ******************* ******************************* *************/
uchar uc_RTOutputByte(void)
{
uchar i;
T_RST = 1;
for(i=8; i gt; 0; i--)
{
ACC = ACC gt; ;
T_IO=1;
ACC7 = T_IO;
T_CLK = 1
T_CLK = 0; p> }
retorno(ACC);
}
/*************** *** ************************************************* **** ***
* Nombre: v_W1302(uchar ucAddr, uchar ucDa)
* Función: Escribir datos en DS1302
* Entrada: ucAddr : Dirección DS1302, ucDa: Datos a escribir
* Valor de retorno: Ninguno
********************* ******* ********************************** ********** *********/
void v_W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0
T_CLK = 0;
T_RST = 1;
v_RTInputByte( ucAddr); ;
v_RTInputByte(ucDa ); // Escribe 1Byte de datos
T_CLK = 1
T_RST =
0;
}
/**** **************************** ** ************************************
* Nombre: uc_R1302( uchar ucAddr )
* Función: Leer datos de una dirección de DS1302
* Entrada: ucAddr: dirección DS1302
* Valor de retorno: ucDa: Leer datos
********************************************* **********************************/
uchar uc_R1302(uchar ucAddr) p>
{
uchar ucDa
T_RST = 0;
T_CLK = 0
T_RST = 1; /p>
v_RTInputByte(ucAddr);
_nop_();
_nop_()
ucDa = uc_RTOutputByte(); de datos
T_CLK = 1
T_RST = 0
retorno(ucDa
}
/**** ********************************************** ******* *******************
* Nombre: v_BurstW1302T
* Función: Escribir datos de reloj en DS1302 (multibyte ***** *************************************/
void v_BurstW1302T(uchar *pSecDa)
{
uchar i;
v_W1302(0x8e, 0x00); //Comando de control WP=0); , operación de escritura
T_RST = 0
T_CLK = 0;
T_RST = 1
v_RTInputByte(0xbe); 0xbe: Comando de escritura multibyte de reloj
for (i=8; igt; 0; i--) //8Byte = 7Bytes de datos de reloj 1Byte de control
{
v_RTInputByte(*pSecDa); //escribe datos de 1Byte p>
pSecDa
}
T_CLK = 1
T_RST = 0;
}
/********************************* ************** **********************
* Nombre: v_BurstR1302T(uchar *pSecDa )
* Función: Leer datos del reloj DS1302
* Entrada: pSecDa: Formato de dirección de datos del reloj: leer datos
********* *********** *****
*** *******************************************/
void v_BurstR1302T(uchar *pSecDa)
{
uchar i;
T_RST = 0;
T_ CLK = 0;
T_RST = 1;
v_RTInputByte(0xbf); //0xbf: comando de lectura multibyte de reloj
for(i=8; igt; 0; i--)
{
*pSecDa = uc_RTOutputByte(); //Leer datos de 1Byte
pSecDa ;
}
T_CLK = 1;
T_RST = 0
}
/******** ****; *********************************** ********** **** *****
* Nombre: v_BurstW1302R(uchar *pReDa)
* Función: Escribir datos en el registro DS1302 (modo multibyte)
* Entrada: pReDa: dirección de datos del registro
* Valor de retorno: Ninguno
******************/
T_CLK = 0;
T_RST = 0
}
/****************** * ***** p>****************************************** **********************************/
void v_BurstW1302R(uchar *pReDa)
{
uchar i;
v_W1302(0x8e, 0x00); //Comando de control, WP=0, operación de escritura
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_RTInputByte(0xfe); //0xbe: comando de escritura multibyte de reloj
for (i=31; igt; 0; i--) //datos de registro de 31 bytes
{
v_RTInputByte(*pReDa); -byte de datos
pReDa;
}
T_CLK = 1; //Solo 0xbe: comando de escritura de varios bytes del reloj.
T_RST = 0
}
/************************ ***** **********************************************
* Nombre: v_BurstR1302R(uchar * pReDa)
* Función: Leer datos de registro DS1302
* Entrada: pReDa: dirección de datos de registro
* Valor de retorno: Ninguno
************************************ ****** **************** ****************/
void v_BurstR1302R(uchar * pReDa)
{
uchar i;
T_RST = 0;
T_CLK = 0; = 1;
v_ RTInputByte(0xff); //0xbf: comando de lectura multibyte del reloj
for(i=31; igt; 0; i--) //31Byte registrar datos
{
*pReDa = uc_RTOutputByte(); //Leer datos de 1Byte
pReDa;
}
T_CLK = 1;
T_RST = 0
}
/************** ************************************************* p>
* Nombre: v_Set1302(uchar *pSecDa)
* Función: Establecer hora inicial
* Entrada: pSecDa: dirección de hora inicial. **********/
void v_Set1302(uchar *pSecDa)
{
uchar i;
uchar ucAddr = 0x80;
v_W1302(0x8e, 0x00); //Comando de control, WP=0, operación de escritura
for(i=7; igt; 0; i-- )
{
v_W1302(ucAddr, *pSecDa); // Segundos Minutos Hora Días Meses Semanas Años
pSecDa
ucAddr; = 2;
}
v_ W1302(0x8e, 0x80); //comando de control, WP=1, protección contra escritura
}
/************************************************ *********************
* Nombre: v_ Get1302(uchar ucCurtime[])
* Función: Leer Obtener la hora actual de DS1302
* Entrada: ucCurtime: guarda la dirección de hora actual.
**********/
void v_Get1302(uchar ucCurtime[])
{
uchar i;
uchar ucAddr = 0x81;
for(i=0; ilt; 7; i )
{<
ucCurtime[i] = uc_R1302(ucAddr) ; //formato: segundos, minutos, horas, días y meses, aniversario
ucAddr = 2
}
}
/**** ********************************** *********** *** ****************
* Nombre: dectobcd(uchar dec)
* Función: Convertir código DEC a código BCD
* Entrada: código dec
* Salida: código bcd
****************** *** ********** **************************************** *********/ p>
uchar dectobcd(uchar dec)
{
uchar bcd
bcd = 0;
while(dec gt; = 10)
{
diciembre -=
bcd ;
}
bcd lt; = 4;
bcd |= dec;
retorno bcd; /p>
/***** **************************************** ************ *************
* Nombre: bcdtodec(uchar bcd)
* Función : Convertir código BCD a código DEC
* Entrada: código bcd
* Salida: código dec
************ ******************* ********************************** ****************/
uchar bcdtodec(uchar bcd)
{
uchar data1; p>
data1 = bcd amp; 0x0f; //Obtiene los 4 bits inferiores de BCD
bcd = bcd amp; //Obtiene los 4 bits más altos y más bajos.
data1 = bcd gt; gt;
data1 = bcd gt; //Reemplazar multiplicación con desplazamiento
return data1; p> p>
}
/****************************** **** ** ************************************
* Nombre: Write_DS1302Init( )
* Función: Escribir datos en DS1302 Configure aquí los datos que se muestran al principio.
* Entrada: Ninguna
* Salida: Ninguna
********************* *** ************************************************* **** /
void Write_DS1302Init (void)
{
v_W1302(0x8e, 0);
v_W1302(0x80, 0x50);/ /Escribe segundos
v_W1302(0x8e, 0);
v_W1302(0x82, 0x59); //Escribe minutos
v _W1302(0x8e) , 0 );
v_W1302(0x84, 0x07); // Hora de escritura
v_W1302(0x8e, 0);
v_W1302(0x86, 0x08);
v_W1302(0x8e, 0);
v_W1302(0x8e, 0);
v_W1302(0x88, 0x08); //escribir mes
v_W1302(0x8e, 0);
v_W1302(0x8a, 0x05); //escribir semana
v_W1302(0x8e, 0); ( 0x8c, 0x08); //Escribe el año
v_W1302(0x8c, 0x08); //Escribe el año
}
/**** * ************************************************* ** ************
* Nombre: Run_DS1302(void)
* Función: Leer DS1302 y mostrarlo en LCD 1602 p >
* Entrada: Ninguna
* Salida: Ninguna
************************ ****** ********************************************** ****/
void Run_DS1302(void)
{
uchar seg, min, hora, día, mes, año;
while(1)
{
v_W1302(0x8f, 0);
sec = bcdtodec(uc_R1302(0x81)); en DS1302
v_W1302(0x8f, 0);
min = bcdtodec(uc_R1302(0x83) // Lee el número de minutos en DS1302
v_W1302 (0x8f, 0);
hora = bcdtodec(uc_R1302(0x85)); // Leer la hora en DS1302
v_W1302(0x8f, 0); > día = bcdtodec (uc_R1302(0x87)); // Lee la fecha en DS1302
v_W1302(0x8f, 0);
mes = bcdtodec(uc_R1302(0x89));
// Leer el mes en DS1302
v_W1302(0x8f, 0);
año = bcdtodec(uc_R1302(0x8d)).// Leer el año en DS1302
L1602_char(2, 6, hora / 10 10 48);
L1602_char(2, 7, hora 10 48);
L1602_char(2, 8, ': ') ;
L1602_char(2, 9, min / 10 10 48);
L1602_char(2, 10, min 10 48);
L1602_char( 2, 11, ':');
L1602_char(2, 12, seg / 10 10 48);
L1602_ char(2, 13, seg 10 48);
p>L1602_char(1, 8, año / 10 10 48);
L1602_char(1, 9, año 10 48);
L1602_char(1, 10, ' -');
L1602_char(1, 11, mes / 10 10 48);
L1602_char(1, 12, mes 10 48);
L1602_char (1, 13, '-');
L1602_char(1, 14, día / 10 10 48);
L1602_char(1, 15, día 10 48); p> p>
}
}
/************************** ** ****************************************
* Nombre: Principal(void)
* Función: Función principal
* Entrada: Ninguna
* Salida: Ninguna
*** ** ************************************************* *** ********* *******/
void Main(void)
{
L1602_init() ;
p>L1602_string(1, 1, "DÍAS 20");
L1602_string (2, 1, "TIEMPO"); ;
Ejecutar_DS1302();
}