Por favor ayúdenme a escribir un programa fuente para un reloj electrónico.
#pragma ot(6,SIZE)
#include
#include
#define ErrorCount 10
//nombre del bus IIC
sbit SDA=P3^1;
sbit SCL=P3^0;
//Definir una enumeración
enum EepromType {M2401,M2402,M2404,M2408,M2416,M2432,M2464,M24128,M24256};
enum EepromType EEPROM_Type;
//Capacidad del chip correspondiente
unsigned int M24_N[]={0x7F,0xFF,0x1FF,0x3FF,0x7FF,0xFFF,0x1FFF,0x3FFF,0x7FFF} //M24_N[EEPROM_Type] p >
////////////////////Se inicia la función de operación del bus IIC/////////////////////// / ///
/******************Arranque el autobús****************** ******* **/
void I2CStart(void){
SCL=0; //Bloquear el bus
SDA=1; SCL=1; //Preparar
_nop_();_nop_();_nop_();
SDA=0; //Iniciar
_nop_() ;_nop_();_nop_( );_nop_();
SCL=0; //Listo para enviar
SDA=1;
} p>
/** ****************Detener bus I2C****************/
void I2CStop(void){ p>
SCL=0; //Preparación
SDA=0;
SCL=1;
_nop_ ();_nop_ ();_nop_ ();
SDA=1; //Para el autobús
_nop_();_nop_();_nop_();
SCL=0; // Bloquear el bus
}
/***************Compruebe el bit de reconocimiento**** ********** *****/
bit I2CRecAck(void){
SCL=0;
SDA=1 ;
SCL= 1;
_nop_();_nop_();_nop_();_nop_();
CY=SDA; el valor de retorno siempre se coloca en CY p>
SCL=0;
return(CY);
}
/**** ************** **Respuesta al bus I2C************************/
void I2CAck(void){
SDA=0 ;
SCL=1;
_nop_();_nop_();_nop_(); _nop_();<
/p>
SCL=0;
_nop_();
SDA=1;
}
/** ***************No hay respuesta al bus I2C***************/
void I2CNoAck(void){
SDA=1;
SCL=1;
_nop_();_nop_();_nop_();_nop_();
SCL=0;
}
/**********************Escribir datos en el bus I2C* **** ****************/
void I2CSendByte(unsigned char sendbyte){
datos de caracteres sin firmar j=8;
for(;j>0;j--){
SCL=0;
sendbyte<<=1 // No importa cómo se implemente C51; esta operación, siempre hará Make CY=sendbyte^7;
SDA=CY;
SCL=1;
}
SCL=0;
p>}
/******************Leer subrutina de datos del bus I2C*** ******* ****/
carácter sin firmar I2CReceiveByte(void){
registro de recepción,i=8;
SCL=0 ;
while(i--){
SCL=1;
recibirbyte=(receivebyte<<1)|SDA;
SCL=0; p>
}
return(recibirbyte);
}
/********* ***Un programa de retraso simple ****************/
void Delay_E(unsigned int DelayCount){
while(DelayCount- -);
}
/***************24XX función principal de lectura y escritura*********** ************ **********************
DataBuff es la primera dirección de la lectura y escribir el búfer de entrada/salida de datos
ByteQuantity es el número de bytes de datos que se leerán y escribirán
La dirección es la dirección en el chip de EEPROM
ControlByte es el byte de control de EEPROM, la forma específica es (1)(0)(1)(0)(A2)(A1)(A0)(R/W), donde R/W=1,
significa operación de lectura, R/W=0 significa operación de escritura, A2, A1, A0 Es la dirección de selección de página o de selección de chip de EEPROM;
EEPROM_Type es una variable de enumeración, que debe ser uno de M2401 a M24256, correspondiente a 24C01 a 24C256 respectivamente;
Valor de retorno de la función: variable de bit, 1=operación fallida, 0=operación exitosa;
ErrorCount es el número máximo de operaciones permitidas Si las operaciones ErrorCount fallan, la función aborta la operación y devuelve 1
SDA y SCL están definidos por el usuario, aquí se definen temporalmente como P0^0 y P0^1;
El resto se utilizan
No tienes que preocuparte por eso, simplemente coloca la subrutina en tu programa y llámala;
************************ ************************************************** * ********/
bit RW24XX(carácter unsigned *DataBuff, char unsigned ByteQuantity, dirección int unsigned, char unsigned ControlByte, enumeración EepromType EEPROM_Type)
{< / p>
datos de caracteres sin firmar j,i=ErrorCount;
bit errorflag=1;
while(i--){
I2CStart( ) ;
I2CSendByte(ControlByte&0xfe);
if(I2CRecAck()) continuar;
if(EEPROM_Type>M2416){
I2CSendByte ((carácter sin firmar)(Dirección>>8));
if(I2CRecAck()) continuar;
}
I2CSendByte((carácter sin firmar) Dirección );
if(I2CRecAck()) continuar;
if(!(ControlByte&0x01)){
j=ByteQuantity;
errorflag=0; //********clr errorflag
while(j--){
I2CSendByte(*DataBuff++);
if(!I2CRecAck()) continuar;
errorflag=1;
romper;
}
if(errorflag== 1 ) continuar;
romper;
}else{
I2CStart();
I2CSendByte(ControlByte);
if(I2CRecAck()) continuar;
while(--ByteQuantity){
*DataBuff++=I2CReceiveByte();
I2CAck();
}
*DataBuff=I2CReceiveByte(); //leer los datos del último byte
I2CNoAck();
errorflag=0;
descanso;
}
}
I2CStop();
if(!(ControlByte&0x01)) {
Retraso_E(1000);
}
return(errorflag);
}
Lo anterior es un reloj electrónico con alarma
/*********** ***** *************************/
/* */
/ *Programa de prueba DS1302* /
/*Dispositivo de destino: AT89S51 */
/*Oscilador de cristal: 11,0592 MHZ */
/*Entorno de compilación: Keil 7.50A */
/************************************/
/************************************Contiene archivos de encabezado**** ************** *******************/
#include "reg51.h" p>
#include /****************************** ****Definición de puerto********* *************************/ sbit DS1302_CLK = P1^0; bit DS1302_IO = P1^1; sbit DS1302_RST = P1^2; /********* *************** **********Tabla de códigos de segmentos LED********************* *********/ pestaña de código de caracteres sin firmar[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; /********* **********************Definir variables globales************* ***************** *******/ carácter sin firmar segundo,minuto,hora,semana,día,mes,año //; segundo, minuto, hora, semana, día, mes, año unsigned char time[]={0x06,0x03,0x14,0x03,0x12,0x30,0x00} //Matriz de tiempo inicial /************ ********************************** ******************* ******************* Función: Subrutina de retardo de escaneo de tubo digital Parámetros de entrada: Parámetros de salida: ************************ ******************* ******************************* *****/ retraso nulo1(nulo) { int k; for(k=0;k <400;k++); } /****************************** ************************************************* Función: Subrutina de visualización de tubo digital Parámetros de entrada: k Parámetros de exportación: ************ ******************* ********************************** ****************/ visualización nula(nulo ) { P2=0xfe P0=tab[hora/16]; retraso1(); P2=0xfd; P0=tab[hora%16]; retraso1(); P2=0xfb; P0=0xbf; //Mostrar "-" retardo1(); P2=0xf7; P0=tab[minuto/16] ; retraso1(); P2=0xef; P0=tab[minuto%16]; retraso1(); P2=0xdf; P0=0xbf; //Mostrar "-" retardo1(); P2=0xbf; P0=tab[segundo/16]; retardo1(); P2=0x7f; P0=tab[segundo %16]; retraso1(); } /********************* *** ************************************************* **** ******** Función: Subrutina para enviar un byte de datos al DS1302 Parámetros de entrada: Parámetros de salida: ********************************************* *** *******************************/ void InputByte(byte1 de caracteres sin firmar) { char i; for(i=8;i>0;i--) { DS1302_IO=(bit)(byte1&0x01); DS1302_CLK=1; _nop_(); DS1302_CLK=0; byte1 >>=1; } retorno; } /********* *** ************************************************* **** *************** Función: Leer subrutina de un byte DS1302 Parámetros de entrada: Parámetros de salida: ****************************************** ******** *************************************/ byte de salida de carácter sin firmar (vacío) { carácter sin signo i; ucdat sin signo=0; for(i= 8;i>0;i- -) { DS1302_IO=1; ucdat>>=1; si (DS1302_IO)ucdat|=0x80; DS1302_CLK=1; _nop_(); DS1302_CLK=0; } retorno(ucdat); } /*************************************** ******************************************* Función función: a la subrutina DS1302 para escribir un byte de datos en una dirección determinada Parámetros de entrada: addr, TDat Parámetros de salida: **** ******** ******************************************* ********* *******************/ void write_ds1302(dirección de caracteres sin firmar, TDat de caracteres sin firmar) { DS1302_RST=0; _nop_(); DS1302_CLK=0; _nop_(); DS1302_RST=1; InputByte(addr); _nop_(); InputByte(TDat); DS1302_CLK=1; _nop_(); DS1302_RST=0; } /****** ******************* ********************************** ******************* ********** Función: Leer subrutina de dirección DS1302 Entrada parámetro: agregar Salir del parámetro: timedata ***************************** ******************* *******************************/ carácter sin firmar read_ds1302(dirección de caracteres sin firmar) { datos de tiempo de caracteres sin firmar; DS1302_RST=0; _nop_(); DS1302_CLK=0; _nop_(); DS1302_RST=1; InputByte(dirección); timedata=OutputByte(); DS1302_CLK=1; _nop_(); DS1302_RST=0; retorno(datos de tiempo); } /*************************** ******************* ********************************** * Función: Inicializar subrutina DS1302 Parámetro de entrada: tiempo[] (variable global) Parámetro de salida: * ******************* ********************************** ****************** *********/ void inicial_ds1302() { write_ds1302(0x8e,0x00); //Registro de protección de escritura, en WP debe ser 0 antes de escribir en el reloj o en la RAM write_ds1302(0x8c,time[0]); p> write_ds1302(0x88,hora[1]); Mes write_ds1302(0x86,time[2]); //Día write_ds1302(0x8A,time[3]); //Día de la semana write_ds1302( 0x84,tiempo[4]); //Tiempo write_ds1302(0x82,tiempo[5]); //Minutos write_ds1302(0x80,tiempo[6]); Segundos write_ds1302(0x8e,0x80); //Registro de protección contra escritura } /************** ************************************************** * ************* Función: Leer subrutina de tiempo DS1302 Parámetros de entrada: Parámetros de salida: variables globales ( segundo,minuto,hora,semana,día,mes,año) **************************** * *************************************************/ void read_time() { second=read_ds1302(0x81); //segundo registro minuto=read_ds1302(0x83); //minutos hora=read_ds1302(0x85); //horas semana=read_ds1302(0x8B); //semana día=read_ds1302(0x87 ) ; //Día mes=read_ds1302(0x89); //Mes año=read_ds1302(0x8d); //Año } /************************************************ ** ********************************** Función: Programa principal Parámetros de entrada: Parámetros de salida: *************************** ********** **************************************** ********/ void main(void) { inicial_ds1302() //Inicializar DS1302 while(1) { read_time(); //Leer hora display() //Mostrar hora } } #include sbit DQ = P3^3; //Definir el puerto DS18B20 sbit BEEP=P3^7; presencia de caracteres sin firmar; código de caracteres sin firmar LEDData[ ] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8 , 0x80,0x90 ,0xff}; datos de caracteres sin firmar temp_d ata[2] = {0x00,0x00}; visualización de datos de caracteres sin firmar[5] = {0x00,0x00,0x00,0x00,0x00}; ditab de código de caracteres sin firmar[ 16] = {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04, 0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; void beep(); sbit DIN = P0^7; //punto decimal bit flash=0; //mostrar marca de interruptor /* * ************************************************* ** ******/ void Delay(unsigned int num)//Función de retraso { while( --num ); } /************************************ * ************************/ Init_DS18B20(void)//Inicializar ds1820 { DQ = 1; //Reinicio de DQ Delay(8); //Retraso leve DQ = 0; //MCU baja el DQ Delay(90); //El retraso exacto es mayor que 480us DQ = 1; //Tira del autobús alto Delay(8); presencia = DQ; //Si =0, la inicialización es exitosa =1, entonces la inicialización falla Retraso(100); DQ = 1; return( presencia); //Señal de retorno, 0=presencia,1= sin presencia } /************* ***** *******************************************/ p> ReadOneChar( void)//Leer un byte { unsigned char i = 0; unsigned char dat = 0; p> for (i = 8; i > 0; i--) { DQ = 0; // Da señal de pulso dat >>= 1; DQ = 1; //Da señal de pulso if(DQ) dat |= 0x80; Retraso(4) ; } retorno (dat); } /******* ********* ******************************************* ****/ WriteOneChar(unsigned char dat)//Escribe un byte { unsigned char i = 0; f o (i = 8; i > 0; i--) { DQ = 0; DQ = dat&0x01; Retraso(5); DQ = 1; dat>>=1; } } /************************************************ ***********/ Read_Temperature(void)//Leer temperatura { Init_DS18B20(); p > if(presence==1) { beep();flash=1;} //DS18B20 es anormal, el timbre suena else { flash=0; WriteOneChar(0xCC); // Omitir la operación de lectura del número de serie WriteOneChar(0x44); / Iniciar conversión de temperatura Init_DS18B20(); WriteOneChar(0xCC); //Omitir la operación de lectura del número de serie WriteOneChar(0xBE); /Leer registro de temperatura temp_data[0] = ReadOneChar(); //La temperatura es 8 bits menor temp_data[1] = ReadOneChar(); //La temperatura es 8 bits altos } } /************************ ****** ****************************/ Disp_Temperature()//Mostrar temperatura { carácter sin firmar n=0; mostrar[4]=temp_data[0]&0x0f; mostrar[0]= ditab[display[ 4]]; //Busca la tabla para obtener el valor decimal display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1] ]&0x0f)<<4) ; mostrar[3]=mostrar[4]/100; mostrar[1]=mostrar[4]%100; mostrar[2] =mostrar[1]/10; mostrar[1]=mostrar[1]%10; if(!display[3]) / /El bit alto es 0, no se muestra { display[3]=0 if(!display[2]) //El segundo el bit más alto es 0, no se muestra display[2]=0; } P0 = 0xc6 //Mostrar C P2 = 0x7f; Retraso(300); P0 = 0x9c; //Mostrar ° P2 = 0xbf; Retraso(300) ; P0 =LEDData[display[0]] ; //Mostrar decimales P2 = 0xdf; Retraso(300); P0 =LEDData[display[1]]; //Mostrar los dígitos DIN = 0; P2 = 0xef; Retraso(300 ); P0 =LEDData[display[2]]; //Mostrar dígitos de decenas P2 = 0xf7; Retraso(300); P0 =LEDData[display[3]]; //Mostrar dígitos de decenas P2 = 0xfb; Retraso(300); P2 = 0xff; //Cerrar visualización } /*************************** * ******************************/ Anular pitido() { carácter sin firmar i; para (i=0;i<100;i++) { Retraso(60) ; BEEP=!BEEP; //Invertir BEEP } BEEP=1 //Apagar el timbre } /****************************************** ***************/ void main(void) { while(1) { Read_Temperature(); if(flash==0) {Disp_Temperature();} else P2 = 0xff; //DS18B20 es anormal, apague la pantalla } } /*********** ******* ******************************************* **/ Cambie los tres usted mismo, simplemente llame a la función C y agregue los botones usted mismo