DS18B20 Ansteuerung über Interrupt

Bitte nutzt dieses Forum um eure eigenen Projekte vorzustellen oder um selbst entwickelten Code zur Verfügung zu stellen.

DS18B20 Ansteuerung über Interrupt

#1

Ungelesener Beitrag pic18 » 10. Dez 2018, 12:05

Der Temperaturfühler DS18B20 wurde hier schon öfters erwähnt. Nun habe ich mir überlegt, wie ich in einem komplexeren Programm diesen nachträglich einbauen kann. (Ich habe benötige ca. 20 Stück davon.)
Ich habe dazu einen Timer programmiert der einen alle 10ms einen Interrupt auslöst. Hier lasse ich einen Zähler von x bis Null zurückzählen.
Im Hauptprogramm (main) frage ich den Zählwert ab und springe in das Unterprogramm, welches so aussieht.
In main habe ich also nur eingefügt:
if (ti18b20==0) ds18b20int();

Code: Alles auswählen

#include "configuration.h"	//muß vor #include lcd.h stehen wegen LCD_SUPPORT = 1
#include "sw18b20.h"
#include "ds18b20_2.h"
#include "ds18b20_search2.h"
#include "inttypes.h"
#include "typedefs.h"
#include "lcd\lcd.h"
#include "hardware.h"
#include "main.h"

extern void ausg16b(word);
extern void ausg12b(word);
extern void ausg8b(uint8_t byte);	
extern BYTE mr_byte;

uint8_t fu;
extern uint8_t ti18b20;
extern uint8_t ds18b20_LCD;	//in Main definiert

uint8_t i0;	
uint8_t id[8];
uint8_t diff;
uint8_t sn_anz;
uint8_t x10,y10;
char sr_1[10];

char sn_liste[sn_max][8];
char sn_alm_liste[sn_max][8];
char get0[10]="123456789";
char alw[sn_max][3];
char temp[sn_max];
char temp_int[sn_max];

unsigned char search;

/*
typedef enum {
	ds18b20Conv =0,
	ds18b20Tread,
	ds18b20ToutInit_LCD,
	ds18b20Tout_LCD,  
//	ds18b20EEoutInit,
//	ds18b20EEout
}ds18b20CMD_t;
*/

ds18b20CMD_t ds18b20CMD = ds18b20Conv;


void ds18b20int (void)
{
//		if (ti18b20==0) switch(ds18b20CMD) //abfrage in main.c
		switch(ds18b20CMD)
		{	
			case ds18b20Conv:	//Temperatur einlesen vorbereiten
					ow_sn(0); //0 nicht sn, damit skipt (alle convertiert werden)
					write_byte(Convert_T);
					fu=0;	//bei Fühler 0 anfangen
					ti18b20 =75;	//750ms warten bis Convert fertig
					if (ds18b20_LCD) ds18b20CMD = ds18b20ToutInit_LCD;
					else ds18b20CMD = ds18b20Tread;
				break;
			
			case ds18b20Tread:
					ow_sn(sn_liste[fu]);
					get0[0] = get0[1] = 0xff;	//-1C löschen zum Testen falls Read_ScratchPad nicht ausgeführt wird (keine korekte SN)
					Read_ScratchPad(get0);
					temp[fu] = ((get0[0] & 0xf0)>>4) | ((get0[1] & 0x0f)<<4);	//aktuelle Temperatur (ganzzahl) sichern

					/********** 16 Bit Zahl merken *************/
					temp_int[fu] = get0[0];      			// low byte
      				        temp_int[fu] |= (unsigned int)get0[1] << 8;    // high byte
					/*******************************************/
					fu++;
					if (fu<sn_anz) 	ti18b20 = 20; //Zeit setzen und hier bleiben
					else{
						ti18b20 = 250;
						ds18b20CMD = ds18b20Conv;	//next bzw neu anfangen
					}
				break;

			case ds18b20ToutInit_LCD:	//Tout init
					LCD_Control_noBF(1);	//ClrHome ohne Wartezeit
					x10=0; y10=0; 

					ti18b20 =2;		//10ms warten wegen ClrHome
					ds18b20CMD = ds18b20Tout_LCD;
				break;
	
			case ds18b20Tout_LCD: //alle Temperaturwerte ausgeben, convert war vorher  //fu = fühler (j0)

					if ((x10==0)&(y10>3)) {y10=3; LCD_scr_up();}	//hier erst Scrollen, damit noch Zeit zum Lesen x10 wurde unten auf 0 gesetzt
					ow_sn(sn_liste[fu]);
					get0[0] = get0[1] = 0xff;	//-1C löschen zum Testen falls Read_ScratchPad nicht ausgeführt wird (keine korekte SN)
					Read_ScratchPad(get0);
					temp[fu] = ((get0[0] & 0xf0)>>4) | ((get0[1] & 0x0f)<<4);	//aktuelle Temperatur (ganzzahl) sichern

					/********** 16 Bit Zahl merken *************/
					temp_int[fu] = get0[0];      			// low byte
      				        temp_int[fu] |= (unsigned int)get0[1] << 8;    // high byte
					/*******************************************/
					float4li(get0,sr_1); //*sr_1
					LCD_gotoxy(x10,y10);	//evtl weg, siehe unten

					ausg8b(get0[2]);		//Th (SN_F) Register ausgeben 
					LCD_Out(' ');

					sr_1[6]=0;		//Byte 6=0 Endemarkierung Text (6 Zeichen)
					LCD_string(sr_1);
					fu++;	//hier

					if (fu<sn_anz) 
					{
						if(x10==10)
						{
							x10=0;y10++;	
							if (y10>3) 
							{
								ti18b20 = 100;		//bei mehr als 4 Zeilen 1sec warten
							}
						}
						else 
						{
							x10=10;
							ti18b20 = 20;
						}	
						//ds18b20CMD = ds18b20Tout_LCD;		//hier bleiben
					}
					else 
					{
						//fu=0;	//nicht umbed. nötig, in Temp_einlesen vorbereiten
						ti18b20 = 250;
						ds18b20CMD = ds18b20Conv;	//next bzw neu anfangen
					}
				break;

		}	
}
void Init_18b20(void)
{
	ds18b20_suchen ();
//	if (!PORTEbits.RE3) WR_alle_Scratchpad(); //gibt jeden Fühler eine Nummer und speichert diese im EEProm des Fühlers
	RD_alle_Scratchpad(); //liest von jeden Fühler das EEProm und speichert die Werte in alw[][]

	ds18b20CMD = ds18b20Conv; //bei Convert anfangen
	ti18b20=200;	//2 sec warten
}	

void ds18b20_suchen(void)
{
//	writeLCDRomString("Suchen Anf");
	fu = 0;
	for(diff = 0xff; diff !=0;fu++ ) //=OW_SEARCH_FIRST	!=OW_LAST_DEVICE)
	{
		diff = ow_rom_search_ff(diff,&id[0],Search_Rom); //bool

		for (i0=0;i0<8;i0++)
			sn_liste[fu][i0] = id[i0];
	}
	sn_anz= fu;
	ausg8b(sn_anz); LCD_Out(' '); writeLCDRomString("Fuehler gefunden");

}

void WR_alle_Scratchpad(void)	//gibt jeden Fühler eine Nummer und speichert diese im EEProm des Fühlers
{
	writeLCDRomString("Fuehler init");
	for (fu=0;fu<sn_anz;fu++)
	{
		ow_sn(sn_liste[fu]);	
		write_byte(Write_Scratchpad);
		write_byte(fu);			//byte 0	th 	durchgehende Nummer
		write_byte(0xff);		//byte 1	tl	Reserve
		write_byte(0x3f);		//byte 2	config (nur bit 5-6 beschreibar) 0x3f ist 10 Bit Auflösung
		//delay wird  in write_bit erledigt?
		ow_sn(sn_liste[fu]);	
		write_byte(Copy_Scratchpad); //Kopiert Werte ins EEProm
		//evtl bit speichern um zu zählen
	}
	ti18b20 = 255;		//2,55s warten damit lesbar 
//	SleepMs(255);
}

void RD_alle_Scratchpad(void)	//liest von jeden Fühler das EEProm und speichert die Werte in alw[][]
{
//	writeLCDRomString("RD_alle_Spd.");
	for (fu=0;fu<sn_anz;fu++)
	{
		ow_sn(sn_liste[fu]);	
		write_byte(Recall_EE);

		wait_10us(12);	//tmr3Us(120);
		ow_sn(sn_liste[fu]);

		Read_ScratchPad(get0);
		for (i0=0;i0<3;i0++)
			alw[fu][i0] = get0[i0+2];	//Byte 2 bis 4 sichern
	}
}
 


Re: DS18B20 Ansteuerung über Interrupt

#3

Ungelesener Beitrag pic18 » 10. Dez 2018, 18:26

keine, wollte nur den Code zeigen. Wie ich die Wartezeit von 750ms umgehe.

Antworten