Diagrama esquemático y programa del termómetro LCD basado en el microcontrolador 51 (usando 18b20, ¡gracias por las altas calificaciones!
//Detección de temperatura DS18B20 y su pantalla de cristal líquido
#include
#include
código de caracteres unsigned digit[10]={"0123456789"} //Definir la matriz de caracteres para mostrar los números
unsigned char code Str[]={"Prueba por DS18B20"}; //Indica que se muestra la temperatura
unsigned char code Error[]={"¡Error!Check!"} //Indica que no se detecta DS18B20
código de carácter unsigned Temp[]={"Temp:"} //Indica que se muestra la temperatura
código de carácter unsigned Cent[]={"Cent "}; / /Unidad de temperatura
/************************************ ******* *******************************************
Los siguientes son los procedimientos operativos del módulo LCD
****************************** ************* ************************************* ******/
sbit RS=P2^7; //Registra el bit de selección, define el bit RS como el pin P2.0
sbit RW=P2^6 ; //Lee y escribe el bit de selección, define el bit RW como P2 1 pin
sbit E=P2^5; //Habilita el bit de señal, define el bit E como P2.2 pin
sbit BF=P0^7; // Bit de indicador de ocupado, define el bit BF como el pin P0.7
/**************** ************** *******************************
Función: retardo 1ms
(3j+2 )*i=(3×33+2)×10=1010 (microsegundo), que puede considerarse como 1 milisegundo
* ******************* ********************************** /
void delay1ms()
{
unsigned char i,j
for(i=0;i<4; i++)
for(j=0;j< 33;j++)
}
/*****; ******************* ******************************* p>
Función: retardo de un número de milisegundos
Parámetros de entrada: n
********************* *********************** *******************/
nulo delaynms(unsigned char n)
{
unsigned char i;
p> for(i=0;i retraso1ms(); } /************************************ ** ******************* Función: Determinar el estado de ocupado del módulo LCD Valor de retorno: resultado. resultado=1, ocupado; resultado=0, no ocupado ******************************* *** *************************/ bit BusyTest(void) { p> resultado del bit; RS=0; //Según las regulaciones, cuando RS es de nivel bajo y RW es de nivel alto, se puede leer el estado RW= 1; E=1; //E=1, se permite lectura y escritura _nop_(); //Sin operación _nop_(); _nop_() ; _nop_(); //Cuatro ciclos de máquina sin operación para dar el tiempo de reacción del hardware result=BF; Asigne el nivel de indicador de ocupado al resultado E=0; //Restaurar E al nivel bajo devolver resultado; } /******** ******************************************* **** Función: escribir el comando de configuración del modo o mostrar la dirección en el módulo LCD Parámetro de entrada: dictar ******* ******************* ********************************** */ void WriteInstruction (dictado de caracteres sin firmar) { while(BusyTest()==1 //Espera si está ocupado RS=0; //Según las regulaciones, RS y R/ Cuando W es bajo al mismo tiempo, se pueden escribir instrucciones RW=0 E= 0; //E se establece en bajo (según la Tabla 8-6, al escribir instrucciones, E es un pulso alto, // Esto es para hacer que E haga una transición positiva de 0 a 1, por lo que primero se debe establecer "0" _nop_(); _nop_(); //Dos ciclos de máquina de operación en vacío para darle tiempo de reacción al hardware P0=dictar; //Enviar datos al puerto P0, es decir, escribir instrucciones o direcciones _nop_(); _nop_(); _nop_(); _nop_(); //Sin operación durante cuatro ciclos de la máquina, lo que le da al hardware Tiempo de reacción E=1 //E está configurado en nivel alto _nop_(); p> _nop_(); _nop_(); _nop_ (); _nop_(); //Cuatro ciclos de máquina sin operación para dar el tiempo de reacción del hardware E=0 //Cuando E salta del nivel alto al nivel bajo, el módulo LCD comienza a ejecutar el comando } /****************************** ******************* ******** Función: Especificar la dirección real de visualización de caracteres Parámetros de entrada: x ******** ********************************** ********** **/ void WriteAddress(unsigned char x) { WriteInstruction(x|0x80); //Se especifica el método para determinar la posición de visualización. como "80H+ Código de dirección x" } /*************************** *** ************************* Función: escribir datos (código de caracteres ASCII estándar) en el módulo LCD Parámetro de entrada: y (constante de carácter) ****************************** ****** **********************/ void WriteData(carácter sin firmar) { while(BusyTest()==1); RS=1; //Cuando RS es de nivel alto y RW es de nivel bajo, se pueden escribir datos RW=0; E=0; //Establece E en nivel bajo (según la Tabla 8-6, al escribir instrucciones, E es un pulso alto, // Es decir, deje que E pase de 0 a 1. Se produce una transición positiva, por lo que primero se debe establecer "0" P0=y //Envía los datos al puerto P0, es decir, escribe los datos; al módulo LCD _nop_(); _nop_(); _nop_(); _nop_(); No se realiza ninguna operación durante cuatro ciclos de la máquina para dar tiempo de reacción al hardware E=1; //E está configurado en nivel alto _nop_(); _nop_ (); _nop_(); _nop_(); //Cuatro ciclos de máquina sin operación para dar tiempo de respuesta al hardware E=0 ; //Cuando E salta del nivel alto al nivel bajo, el módulo de cristal líquido comienza a ejecutar el Comando } /************** ********************** ************************* Función: Inicializar el modo de visualización LCD ***** **************************** ********************/ void LcdInitiate(void) { delaynms( 15); //Retraso de 15 ms, se debe dar a la pantalla LCD un tiempo de respuesta más largo al escribir el comando por primera vez WriteInstruction(0x38); //Configuración del modo de visualización: pantalla de 16 × 2, Matriz de puntos de 5 × 7, interfaz de datos de 8 bits delaynms(5); //Retraso de 5 ms, da un poco de tiempo de reacción al hardware WriteInstruction(0x38); p> delaynms(5); //Retraso de 5 ms, dale al hardware un poco de tiempo de reacción WriteInstruction(0x38) //Tres veces consecutivas para garantizar una inicialización exitosa delaynms(5); //Retraso de 5 ms, dale al hardware algo de tiempo de reacción WriteInstruction(0x0c); //Configuración del modo de visualización: Mostrar encendido , sin cursor, el cursor no parpadea delaynms(5); //Retraso de 5 ms, dale al hardware algo de tiempo de reacción WriteInstruction(0x06); cursor hacia la derecha Mover, los caracteres no se moverán delaynms(5); //Retraso de 5 ms, dale al hardware algo de tiempo de reacción WriteInstruction(0x01); la pantalla anterior Contenido claro delaynms(5); //Retraso 5 ms, dale al hardware algo de tiempo de reacción } /****** ** ************************************************* *** ************* El siguiente es el procedimiento operativo del DS18B20 *********** ***** ********************************************** ****** *****/ sbit DQ=P3^3; unsigned char time; //Establece variables globales específicamente para un retraso estricto /************************************************ ** **** Función: Inicializa el sensor DS18B20 y lee la señal de respuesta Exportar parámetro: flag ******** *******************************************/ bit Init_DS18B20(void) { bit flag; //Almacena el indicador de si DS18B20 existe, flag=0, significa que existe flag=1, significa que existe; not exist DQ = 1; //Primero tire de la línea de datos hacia arriba for(time=0;time<2;time++) //Un ligero retraso de aproximadamente 6 microsegundos p> ; DQ = 0; // Tire de la línea de datos de mayor a menor nuevamente, lo que requiere 480 ~ 960us for(time=0;time<200; time++) //Retraso leve de unos 600 microsegundos ; //Para enviar un pulso de reinicio de bajo nivel que dure 480 ~ 960us a DS18B20 DQ = 1; (reemplace la línea de datos hacia arriba) for(time=0;time<10;time++) // El retraso es de aproximadamente 30 us (después de soltar el autobús, debe esperar de 15 a 60 us para que exista un pulso en la salida DS18B20) flag=DQ //Deje que el microcontrolador detecte si hay una salida de pulso (DQ=0 significa que hay un pulso) for(time=0;time<200;time++) //Retraso suficiente para esperar a que se complete la salida del pulso de existencia ; return (flag); //Devolver indicador de éxito de detección } /****************************** ****************** ******* Función: Leer un byte de datos del DS18B20 Exportar parámetro : dat ************ *** *******************************************/ unsigned char ReadOneChar(void) { unsigned char i=0; unsigned char dat //Almacenamiento de un byte de datos leídos for (i=0;i<8;i++) { DQ =1; // Tira la línea de datos hacia arriba primero _nop_(); //Espera un ciclo de la máquina DQ = 0; //Cuando el microcontrolador lee datos de DS18B20, tira de la línea de datos de mayor a menor para iniciar la secuencia de lectura dat> >=1; _nop_(); //Espera un ciclo de la máquina DQ = 1; //Pulsa la línea de datos "artificialmente" para detectar el voltaje de salida de DS18B20 para el microcontrolador Prepárese para tiempos de paz for(time=0;time<2;time++) //El retraso es de aproximadamente 6us, para que el host pueda muestra dentro de 15us if (DQ==1) dat|=0x80 //Si los datos leídos son 1, almacena 1 en dat else; dat |=0x00;//Si los datos leídos son 0, almacene 0 en dat //Almacene la señal de nivel DQ detectada por el microcontrolador en r[i] p> for(time=0;time<8;time++) ; //Retraso 3us, debe haber un período de recuperación mayor a 1us entre las dos secuencias de lectura } p> return(dat); //Devuelve los datos decimales leídos } /************* *** ************************************* Función: escribir a DS18B20 Introduzca un byte de datos Parámetro de entrada: dat *************************** ***** **********************/ WriteOneChar(dat de carácter sin firmar) { carácter sin firmar i=0; for (i=0; i<8; i++) { DQ =1; // primero coloca la línea de datos hacia arriba _nop_(); //Espera un ciclo de la máquina DQ=0 //Inicia la secuencia de escritura cuando la línea de datos baja desde alto DQ=dat&0x01; //Utilice la operación AND para extraer ciertos datos binarios para escribir, //Y envíelos a la línea de datos para esperar el muestreo DS18B20. for (time=0;time<10;time++) ;//El retraso es de aproximadamente 30us, el DS18B20 toma muestras de la línea de datos durante aproximadamente 15~60us después de bajar p> DQ=1; //Libera la línea de datos for(time=0;time<1;time++) ;//Retraso 3us, se requiere al menos 1us de período de recuperación entre dos secuencias de escritura dat>>=1; //Desplaza cada dato de bit binario en dat a la derecha 1 bit } for(time=0;time<4; time++) ; //Retraso un poco para darle al hardware algo de tiempo de reacción } /************ ************************************************* ***** ******************* Las siguientes son las configuraciones de pantalla relacionadas con la temperatura *** ********** **************************************** *********** *******************/ /*********** *********** ******************************* Función: Pantalla que DS18B20 no se detecta *************************************** ************** **/ void display_error(void) { char i sin firmar; p> WriteAddress(0x00); //Escribir visualización La dirección se mostrará a partir de la fila 1 y la columna 1 i = 0 //Se mostrará a partir del primer carácter
{
WriteData(Error[i] ); //Escribe constantes de caracteres en la pantalla LCD
i++; //Apunta al siguiente carácter
delaynms(100); //Retrasa 100 ms durante un período de tiempo más largo para ver el instrucciones en pantalla claramente
}
while(1) //Entra en un bucle infinito, esperando descubrir la causa
;
}
/************ **************************** *******************
Función: Mostrar información de descripción
************* *********************** ***************/
void display_explain(void )
{
unsigned char i;
WriteAddress(0x00); //Escribe la dirección de visualización y se mostrará comenzando desde la fila 1 y la columna 1.
i = 0; //Se muestra comenzando desde el primer carácter
while(Str[i] != '\0') //Siempre que no esté escrita la marca de final , continúa escribiendo
{
WriteData(Str[i] //Escribe constantes de caracteres en LCD
i++; //Señala el siguiente carácter
delaynms(100); //Retrasa 100 ms durante un período de tiempo más largo para ver las instrucciones en la pantalla con claridad
}
}
/*************************************** ***** *************
Función: Mostrar símbolo de temperatura
************* ********* *************************************/
void display_symbol(void)
{
unsigned char i;
WriteAddress(0x40); //Escribe la dirección de visualización y se mostrará comenzando desde la fila 2 y la columna 1
i = 0 //Comenzar a mostrar desde el primer carácter
while(Temp[i] != '\0') //Continuar escribiendo siempre que no se alcance la marca final
{
WriteData(Temp[i] //Escribe constantes de caracteres en LCD
i++; Señale el siguiente carácter
delaynms (50); //Retraso 1 ms para darle al hardware algo de tiempo de respuesta
}
}
/************ ************************************* *******
Función Función: Muestra el punto decimal de la temperatura
********************* *********************** *************/
void display_dot(void)
{
WriteAddress(0x49); //Visualización de escritura La dirección se mostrará a partir de la décima columna de la segunda fila
WriteData('.') ; //Escribe la constante del carácter de punto decimal en la pantalla LCD
delaynms(50); // Retrasa 1 ms para darle al hardware algo de tiempo de respuesta
}
/*************************** ************************* ****
Función: Muestra la unidad de temperatura (Cent)
************************ ****************************** **/
void display_cent(void)
{
unsigned char i;
WriteAddress(0x4c); //Escribir visualización La dirección se mostrará a partir de la línea 2 y la columna 13
i = 0; //Comienza desde el primer carácter que se mostrará
while(Cent[i] != '\0 ') //Mientras no esté escrita la marca de final, continúa escribiendo
{
WriteData(Cent[i]); //Escribe constantes de caracteres en LCD
i++;
Señale el siguiente carácter
delaynms(50); //Retraso de 1 ms para darle al hardware algo de tiempo de reacción
}
}
/ ************************************************ *** ***
Función de función: muestra la parte entera de la temperatura
Parámetro de entrada: x
********* ***** *************************************/
void display_temp1(unsigned char x)
{
unsigned char j,k,l; //j,k,l almacena los dígitos de centenas, decenas y unidades de la temperatura respectivamente
j=x/100; //Toma el lugar de las centenas
k=(x%100)/10; //Toma el lugar de las decenas
l= x%10; //Toma el dígito
WriteAddress(0x46); //Escribe la dirección de visualización, que se mostrará a partir de la fila 2 y la columna 7
WriteData(digit[ j]); //Escribe las centenas Escribe constantes de caracteres digitales en LCD
WriteData(digit[k]); //Escribe constantes de caracteres de diez dígitos en LCD
WriteData( digit[l]); / /Escribe constantes de caracteres de un solo dígito en la pantalla LCD
delaynms(50); //Retrasa 1 ms para darle al hardware algo de tiempo de reacción
}
/* ********************************************** ******* **
Función función: muestra la parte decimal de la temperatura
Parámetro de entrada: x
****** ******** *************************************/
void display_temp2(unsigned char x)
{
WriteAddress(0x4a); //Escribe la dirección de visualización, que se mostrará a partir de la fila 2 y la columna 11 p>
WriteData(digit[x ]); //Escribe la constante del primer dígito de la parte decimal en la pantalla LCD
delaynms(50); //Retrasa 1ms para que el hardware reaccione. hora
} p>
/********************************* *************** *********
Función: Prepárate para leer la temperatura
**** ************** **********************************/ p>
void ReadyReadTemp(void)
{
Init_DS18B20(); //Inicializar DS18B20
WriteOneChar(0xCC); de leer el número de serie
WriteOneChar (0x44); // Iniciar conversión de temperatura
for(time=0;time<100;time++)
; /La conversión de temperatura lleva algún tiempo
Init_DS18B20() //Inicializar DS18B20
<p> WriteOneChar(0xCC); //Omita la operación de leer el número de serie y el número de columna
WriteOneChar(0xBE); //Lea el registro de temperatura, los dos primeros son los bits bajo y alto del temperatura
}
/********************************* ********* ****************
Función función: función principal
******* ********* *************************************/
void main(void) p>
{
unsigned char TL; //Almacena los bits de baja temperatura del registro temporal
unsigned char TH; //Almacena los bits de alta temperatura del registro temporal
unsigned char TN; //Almacena la parte entera de la temperatura
unsigned char TD //Almacena la parte decimal de temperatura
LcdInitiate(); //Inicializa el cristal líquido p>
delaynms(5); //Retrasa 5 ms para darle al hardware algo de tiempo de reacción
if( Init_DS18B20()==1)
display_error();
display_explain();
display_symbol(); //Mostrar descripción de temperatura
display_dot(); //Muestra el punto decimal de la temperatura
display_cent( ); //Muestra la unidad de temperatura
while(1) //Detecta y muestra continuamente la temperatura
{
ReadyReadTemp(); //Leer la preparación de temperatura
TL=ReadOneChar() //El bit bajo del valor de temperatura se lee primero
TH=ReadOneChar(); //El bit alto del valor de temperatura se lee a continuación
TN=TH*16+TL/16 //El valor de temperatura real=(TH) *256+TL)/16, es decir: TH*16+TL/16
//El resultado es La parte entera de la temperatura, la parte decimal se descarta
TD =(TL%16)*10/16; //Calcula la parte decimal de la temperatura, multiplica el resto por 10 y divide por 16 para redondear,
//Lo que obtienes es el primer dígito. de la parte decimal de la temperatura (conservando 1 decimal)
display_temp1(TN); //Muestra la parte entera de la temperatura
display_temp2(TD); parte decimal de la temperatura
delaynms(10);
}
}
/ /Descargar por