Diseño de termómetro digital basado en microcontrolador y programa de escritura en lenguaje C
//----------------------------------------- --------------------------
//Pantalla de salida del sensor de temperatura DS18B20, al ejecutar este ejemplo, la temperatura exterior se mostrará en 1602LCD
//------------------------------------- ----- --------------------------
#include lt;reg52.hgt;
# include lt;intrins.hgt;
#define uchar unsigned char
#define uint unsigned int
#define delayNOP() {_nop_( ); _nop_( );_nop_();_nop_();}
sbit DQ=P2^2;
sbit dula=P2^6 //Definir el extremo del pestillo
p>sbit wela=P2^7;
sbit rs=P3^5 //Definición del terminal RS LCD 1602
sbit lcden=P3^ 4; //Definición 1602 terminal LCD LCDEN
sbit s1=P3^0; //Definir teclas--Teclas de función
sbit s2=P3^1; -Agregar clave
p>sbit s3=P3^2; //Definir claves--disminuir clave
sbit s4=P3^6; //Tecla de vista de despertador
sbit rd= P3^7;
sbit beep=P2^3; //Definir el final del timbre
código uchar Temp_Disp_Title[]={" Temp actual: " };
uchar Current_Temp_Display_Buffer[]={" TEMP: "};
uchar code Alarm_Temp[]={"ALARM TEMP Hi Lo"};
uchar Alarm_HI_LO_STR[]={ "Hola: Lo: "};
uchar temp_data[2]={0x00, 0x00};
uchar temp_alarm[2]={0x00, 0x00 };
pantalla uchar[5]={0x00, 0x00, 0x00, 0x00, 0x00};
pantalla uchar1[3]={0x00, 0x00, 0x00}; p>
usar código df_Table[]={0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9};
uchar CurrentT=0 ; //La parte entera de la temperatura leída actualmente
uchar Temp_Value[]={0x00, 0x00} //El valor de temperatura leído de DS18B20
uchar Display_Digit[]={ 0, 0, 0, 0}; //Los dígitos de temperatura que se mostrarán
bit DS18B20_IS_OK=1 //Indicador normal del sensor
//- ------ ------
--------------------------
//Retraso 1
//---- - --------------------------------
retraso nulo1(uint x)
{
uchar i;
while(x--) for(i=0;ilt;200;i);
} p >
//-------------------------------
//Retraso 2
//------------------------------ -
Retraso nulo(uint x)
{
while(x--);
}
//------------------------------------
//Comprobación de ocupado
//------------------------------------
void write_com(uchar com)//Función de comando de escritura LCD
{
rs=0
lcden=0; > P0=com;
retraso1(5);
lcden=1;
retraso1(5);
}
void Write_LCD_Data(uchar date)//Función de escritura de datos LCD
{
rs=1;
lcden=0;
P0=fecha;
retraso1(5);
lcden=1; (5);
lden=0;
}
//------------------ -----------
//Establece la posición de la pantalla LCD
//---------------- - ----------------
void Set_Disp_Pos(uchar Pos)
{
write_com(Pos|0x80 ) ;
}
//------------------------------- -
//Inicialización de LCD
//----------------------- ----
void Initialize_LCD()
{
uchar num;
rd=0 //El software establece uno; final de la cuarta columna del botón de matriz Ajuste bajo para descomponer botones independientes
dula=0; //Cierre los terminales de los dos pestillos para evitar que el tubo digital produzca caracteres confusos al operar la pantalla LCD
wela=0;
lcden=0;
write_com(0x38); //Inicializar 1602 LCD
write_com(0x0c);
write_com(0x06 );
write_com(0x01);
write_com(0x80); //Establece las coordenadas iniciales para mostrar
para(núm=0; númlt; 14; n
um )//Mostrar año, mes, día y semana
{
Write_LCD_Data(Temp_Disp_Title[num]);
delay1(5);
}
}
//---------------------- ------ ------
//Función: Inicializar DS18B20
//Parámetros de salida: estado---Bandera que indica si DS18B20 se ha restablecido correctamente
/ /-------------------------------------
uchar Init_DS18B20()
{
uchar status; //Almacena el indicador de si DS18B20 existe, estado = 0, significa que existe estado = 1, significa que no; exist
DQ=1 ; Delay(8); // Primero tira la línea de datos hacia arriba // Retrasa ligeramente durante unos 6 microsegundos
DQ=0; / Luego, tire de la línea de datos de mayor a menor. Se requiere mantener 480~960us
//Retrase ligeramente unos 600 microsegundos para enviar un pulso de reinicio de bajo nivel al DS18B20 que dure 480~960us
DQ=1; Delay(8 ); //Libera la línea de datos (tira la línea de datos hacia arriba) //El retraso es de aproximadamente 30 us (debes esperar de 15 a 60 us después de liberar el bus para que la salida DS18B20 tiene pulsos)
status=DQ; Delay(100) ; //Deja que el microcontrolador detecte si se emite un pulso de presencia (DQ=0 indica presencia) //Retraso suficiente para esperar la salida del pulso de presencia para completar
DQ=1 //Sube la línea de datos
return status; //Devuelve el indicador de éxito de detección
}
//------------------ ------------------
//Función: leer un byte
//Parámetro de exportación: dat-- -Leer datos
//-------------------- ---------------------- -
uchar ReadOneByte()
{ p>
uchar i, dat=0;
DQ=1; _nop_() // Primero tire de la línea de datos hacia arriba // Espere un ciclo de la máquina
(i=0; ilt; 8; i)
{
DQ=0 ; //Cuando el microcontrolador lee datos de DS18B20, tire de la línea de datos de mayor a menor para comenzar la secuencia de lectura
datgt;gt;=1;
_nop_(); //Espera un ciclo de la máquina
DQ=1; línea de datos "artificialmente" alta para preparar que el microcontrolador detecte el nivel de salida de DS18B20
_nop_(); _nop_() // El retraso es de aproximadamente 6us, lo que permite que el host muestree dentro de 15us p>
if (DQ) dat|=0x80; //Si los datos leídos son 1, almacena 1 en dat, si es 0, conserva el valor original. El valor permanece sin cambios
Delay(30 ); // El retraso es de 3 us y debe haber un período de recuperación superior a 1 us entre las dos secuencias de lectura
DQ=1 // Cambie la línea de datos Tire hacia arriba para prepararse para leer el siguiente bit. de datos
}
devolver dat;
}
//------------------------------ --- -------
//Función: escribir un byte
//Parámetro de entrada: dat---datos a escribir
//-------------------------------
void WriteOneByte( uchar dat)
{
uchar i;
for (i=0; ilt; 8; i)
{ p> p>
DQ=0; //La secuencia de escritura se inicia cuando la línea de datos se pasa de mayor a menor
DQ=dat amp; //Utilice la operación AND para tomar; escribe un cierto bit de datos binarios,
//Y envíalo a la línea de datos para esperar el muestreo DS18B20
Delay(5); 30us, DS18B20 tiene entre 15 y 60us después de bajarlo. Durante este período, muestree la línea de datos
DQ=1; //Libere la línea de datos
datgt;gt;= 1; //Desplaza cada dato de bit binario en dat a la derecha 1 bit
}
}
//---------- -------------- ------------
//Función: Leer valor de temperatura
//Entrada y parámetros de salida: Ninguno
// ------------------------------ -
void Read_Temperature() p>
{
if(Init_DS18B20() == 1) //fallo de DS18B20
DS18B20_IS_OK=0 ;
else
{
WriteOneByte(0xCC); // Salta la lectura del número de serie y el número de columna
WriteOneByte(0x44) ; // Iniciar conversión de temperatura
Init_DS18B20 (); //Inicializar DS18B20
WriteOneByte(0xCC); //Omitir la operación de lectura del número de serie y del número de columna
WriteOneByte(0xBE); //Lee el registro de temperatura, antes Los dos son los bits bajo y alto de la temperatura
Temp_Value[0]=ReadOneByte(); lower
Temp_Value[1]=ReadOneByte(); //Temperatura alta 8 bits
DS18B20_IS_OK=1;
}
}
//----------- --------------------------
//Función: Muestra la temperatura actual en la pantalla LCD
//Parámetros de entrada:
//--------------- ------------------- --
void Display_Temperature()
{
uchar i;
//Valor de retraso e identificador de número negativo
uchar t=150, ng=0
//Los 5 bits altos son todos 1 (
0xF8) es un número negativo. Si es un número negativo, agregue 1 y establezca el indicador de número negativo
if ((Temp_Value[1] amp; 0xF8)==0xF8)
p>
Valor_Temp[1]=~Valor_Temp[1]
Valor_Temp[0]=~Valor_Temp[0] 1; > if(Temp_Value[0]== 0x00) Temp_Value[1]; //Después de agregar 1, si el byte bajo es 00, significa que hay un acarreo y el bit de acarreo se agrega al byte alto
ng=1; //El indicador de número negativo se establece en 1 p>
}
Display_Digit[0]=df_Table[Temp_Value[0] amp; Busque la tabla para obtener la parte decimal de la temperatura
//Obtenga la parte entera de la temperatura (los 3 bits inferiores del byte alto y los 4 bits superiores del byte bajo, sin signo)
CurrentT=((Temp_Value[0] amp; 0xF0)gt;gt;4)|((Temp_Value [1] amp; 0x07)lt; lt; 4); /Descomponga la parte entera en 3 dígitos para mostrar
Display_Digit[3]=CurrentT/100; / /Cientos de dígitos[CurrentT/100];
Display_Digit[2]=CurrentT100; /10; //Dígito de las decenas
Display_Digit[1]=CurrentT10; //Dígito de las unidades p>
//Actualiza el búfer de la pantalla LCD
Current_Temp_Display_Buffer[11] =Display_Digit[0] '0'; //Primero convierte '0' en un número entero 48, y luego agrégalo al número anterior, obtiene el carácter ASCII del número correspondiente
Current_Temp_Display_Buffer[10]= '.';
Current_Temp_Display_Buffer[9]=Display_Digit[1] '0'; //Dígito de las unidades
Current_Temp_Display_Buffer[8]=Display_Digit[2] '0'; Dígito de decenas
Current_Temp_Display_Buffer[7]=Display_Digit[3] '0'; //Dígito de centenas
//No se muestra cuando el bit alto es 0
if(Display_Digit[3]==0) Current_Temp_Display_Buffer[7]=' ';
//El bit alto es 0 y el segundo bit más alto es Cuando 0, el segundo bit más alto no se muestra
if(Display_Digit[2]==0 amp; amp; Display_Digit[3]==0)
Current_Temp_Display_Buffer[8]=' '; /El símbolo del número negativo se muestra en la posición apropiada
if(ng)
{
if (Current_Temp_Display_Buffer[8]==' ') p>
Current_Temp_Display_Buffer[8]='-';
si no (Current_Temp_D
isplay_Buffer[7]==' ')
Current_Temp_Display_Buffer[7]='-';
else
Current_Temp_Display_Buffer[6]='-';
}
//Mostrar título en la primera línea
Set_Disp_Pos(0x00);
for(i=0; ilt; 16); ; i )
{
Write_LCD_Data(Temp_Disp_Title[i]);
}
Set_Disp_Pos(0x40); Dos líneas muestran la temperatura actual
for(i=0; ilt; 16; i )
{
Write_LCD_Data(Current_Temp_Display_Buffer[i]); p >
}
//Mostrar símbolo de temperatura
// Set_Disp_Pos(0x4D); Write_LCD_Data(0x00); ( 0xdf);
Set_Disp_Pos(0x4E Write_LCD_Data('C');
}
//----------); --------------------------
//Función función: función principal
//Entrada Parámetros:
//--------------------------------- - p>
void main()
{
Initialize_LCD();
Read_Temperature();
Retraso; (50000) ;
Retraso(50000);
mientras (1)
{
Read_Temperature();
if (DS18B20_IS_OK) Display_Temperature();
retraso1(100);