Witam wszystkich, w temacie mikrokontrolerów nie jestem zbyt mocny, dlatego proszę o pomoc. Postanowiłem zbudować termometr dwupunktowy na ds18b20 i wysterować multipleksując IW-18. Poniższy program działa, jego mankamentem jest losowy zanik pomiaru w jednym (IN) albo drugim (OUT) czujniku, czasem przekłamuje na sekundę pomiar, podając 80 stopni, jednak po chwili wraca do normy, obsługa multipleksu jest moja, natomiast czujników temp. wzorowana na kursie C dioda. Podejrzewam, że problem leży w programie, proszę o pomoc w lokalizacji błędu. Oto kody:
main.c:
ds18b20.c :
ds18b20.h:
[/b]
main.c:
/*
Plik "main.c"
*/
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#include "ds18b20.h"
#include <avr/interrupt.h>
#include <inttypes.h>
#define F_CPU 8000000L
void wyswietl(uint8_t cyfra) { /* instrukcja wyswietla zadane cyferki na wyswietlaczu led */
switch (cyfra){
case 0:
PORTD = 0b11000000;
break;
case 1:
PORTD = 0b11111001;
break;
case 2:
PORTD = 0b10100100;
break;
case 3:
PORTD = 0b10110000;
break;
case 4:
PORTD = 0b10011001;
break;
case 5:
PORTD = 0b10010010;
break;
case 6:
PORTD = 0b10000010;
break;
case 7:
PORTD = 0b11111000;
break;
case 8:
PORTD = 0b10000000;
break;
case 9:
PORTD = 0b10010000;
break;
case 10:
PORTD = 0b11111111; //czysty ekran
break;
case 11:
PORTD = 0b01111111;
break;
case 12: //minus
PORTD = 0b10111111;
break;
default :
PORTD = 0b11111111;
break;
}
}
void wyswietl_kropke(void){
PORTD ^= 0x80;
}
volatile uint8_t wysw=0; // zmienna oznaczająca numer aktywnego wyświetlacza
volatile uint8_t minus_in;
volatile uint8_t dziesiatki_in;
volatile uint8_t jednosci_in;
volatile uint8_t poprzecinku_in;
volatile uint8_t minus_out;
volatile uint8_t dziesiatki_out;
volatile uint8_t jednosci_out;
volatile uint8_t poprzecinku_out;
int main(void)
{
/* Wszystkie linie portu D będą wyjściami */
DDRD = 0xFF; /* 0xFF binarnie 1111 1111 */
DDRB = 0xFF;
/* Obsługa przerwań - multipleksowanie*/
TCCR1B |= (1 << WGM12); // Ustawia timer1 w tryb CTC
OCR1A = 2073; // Ustawia wartość pożądaną na 100Hz dla preskalera 64
TCCR1B |= (1 << CS11);
TIMSK |= (1 << OCIE1A); // Zezwolenie na przerwania dla CTC
sei(); // Zezwolenie globalne na przerwania
/* Zmienna przechowuje aktualną wartość temperatury */
double temp_1;
double temp_2;
/* W tablicy zapisywane będą dane odczytane z układu ds18b20 */
unsigned char ds18b20_pad_1[9]; //bylo 9
unsigned char ds18b20_pad_2[9];
while(1)
{
/* Funkcja 'ds18b20_ConvertT' wysyła do układu ds18b20
polecenie pomiaru czujnika 1*/
if(ds18b20_ConvertT_1())
{
/* 750ms - czas konwersji */
_delay_ms(750);
ds18b20_Read_1(ds18b20_pad_1);
temp_1 = ((ds18b20_pad_1[1] << 8) + ds18b20_pad_1[0]) / 16.0 ;
int liczba1=(int)(temp_1*10);
//minus_out=0;
dziesiatki_in = (uint8_t)(liczba1/100);
jednosci_in= (uint8_t)((liczba1/10)%10);
poprzecinku_in= (uint8_t)(liczba1%10);
}
//Drugi czujnik
if(ds18b20_ConvertT_2())
{
/* 750ms - czas konwersji */
_delay_ms(750);
ds18b20_Read_2(ds18b20_pad_2);
temp_2 = ((ds18b20_pad_2[1] << 8) + ds18b20_pad_2[0]) / 16.0 ;
_delay_ms(1);
int liczba2=(int)(temp_2*10);
//minus_out=0;
dziesiatki_out = (uint8_t)(liczba2/100);
jednosci_out= (uint8_t)((liczba2/10)%10);
poprzecinku_out= (uint8_t)(liczba2%10);
}
}
}
ISR(TIMER1_COMPA_vect)
{
switch (wysw)
{
case 0:
PORTB = 0b11111110;
wyswietl(poprzecinku_in);
wysw++;
break;
case 1:
PORTB= 0b11111101;
wyswietl(jednosci_in);
wyswietl_kropke();
wysw++;
break;
case 2:
PORTB= 0b11111011;
wyswietl(dziesiatki_in);
wysw++;
break;
case 3:
PORTB= 0b11110111;
wyswietl(10);
wysw++;
break;
case 4:
PORTB= 0b11101111;
wyswietl(10);
wysw++;
break;
case 5:
PORTB= 0b11011111;
wyswietl(poprzecinku_out);
wysw++;
break;
case 6:
PORTB= 0b10111111;
wyswietl(jednosci_out);
wyswietl_kropke();
wysw++;
break;
case 7:
PORTB= 0b01111111;
wyswietl(dziesiatki_out);
wysw=0;
break;
}
}
ds18b20.c :
/*
Plik ds18b20.c
(minimum kodu do odczytu temperatury z ds18b20)
xyz.isgreat.org
*/
#include <avr/io.h>
#include <util/delay.h>
#include "ds18b20.h"
/**********************************************************/
unsigned char ds18b20_ConvertT_1(void)
{
if (!OneWireReset_1()) return 0;
OneWireWriteByte_1(0xcc); // SKIP ROM
OneWireWriteByte_1(0x44); // CONVERT T
return -1;
}
unsigned char ds18b20_ConvertT_2(void)
{
if (!OneWireReset_2()) return 0;
OneWireWriteByte_2(0xcc); // SKIP ROM
OneWireWriteByte_2(0x44); // CONVERT T
return -1;
}
/***********************************************************/
int ds18b20_Read_1(unsigned char scratchpad[])
{
unsigned char i;
if (!OneWireReset_1()) return 0;
OneWireWriteByte_1(0xcc); // SKIP ROM
OneWireWriteByte_1(0xbe); // READ SCRATCHPAD
for(i=0; i<10; i++) scratchpad[i] = OneWireReadByte_1();
return 1;
}
/**********************************************************/
int ds18b20_Read_2(unsigned char scratchpad[])
{
unsigned char i;
if (!OneWireReset_2()) return 0;
OneWireWriteByte_2(0xcc); // SKIP ROM
OneWireWriteByte_2(0xbe); // READ SCRATCHPAD
for(i=0; i<10; i++) scratchpad[i] = OneWireReadByte_2(); //i<10
return 1;
}
/**********************************************************/
void OneWireStrong_1(char s)
{
if (s)
{
SET_ONEWIRE_PORT_1;
SET_OUT_ONEWIRE_DDR_1;
}
else
{
SET_IN_ONEWIRE_DDR_1;
}
}
/**********************************************************/
void OneWireStrong_2(char s)
{
if (s)
{
SET_ONEWIRE_PORT_2;
SET_OUT_ONEWIRE_DDR_2;
}
else
{
SET_IN_ONEWIRE_DDR_2;
}
}
/**********************************************************/
unsigned char OneWireReset_1()
{
CLR_ONEWIRE_PORT_1;
if (!(IS_SET_ONEWIRE_PIN_1)) return 0;
SET_OUT_ONEWIRE_DDR_1;
_delay_us(500); //bylo 500
SET_IN_ONEWIRE_DDR_1;
_delay_us(70); //bylo 70
if(!(IS_SET_ONEWIRE_PIN_1))
{
_delay_us(500); //bylo 500
return(1);
}
_delay_us(500); //bylo 500
return(0);
}
/**********************************************************/
unsigned char OneWireReset_2()
{
CLR_ONEWIRE_PORT_2;
if (!(IS_SET_ONEWIRE_PIN_2)) return 0;
SET_OUT_ONEWIRE_DDR_2;
_delay_us(500); //bylo 500
SET_IN_ONEWIRE_DDR_2;
_delay_us(70); //bylo 70
if(!(IS_SET_ONEWIRE_PIN_2))
{
_delay_us(500); //bylo 500
return(1);
}
_delay_us(500); //bylo 500
return(0);
}
/**********************************************************/
void OneWireWriteByte_1(unsigned char byte)
{
unsigned char i;
CLR_ONEWIRE_PORT_1;
for (i=0; i<8; i++)
{
SET_OUT_ONEWIRE_DDR_1;
if (byte & 0x01)
{
_delay_us(7);
SET_IN_ONEWIRE_DDR_1;
_delay_us(70);
}
else
{
_delay_us(70); //bylo 70
SET_IN_ONEWIRE_DDR_1;
_delay_us(7); //bylo 7
}
byte >>= 1;
}
}
/***********************************************************/
void OneWireWriteByte_2(unsigned char byte)
{
unsigned char i;
CLR_ONEWIRE_PORT_2;
for (i=0; i<8; i++)
{
SET_OUT_ONEWIRE_DDR_2;
if (byte & 0x01)
{
_delay_us(7);
SET_IN_ONEWIRE_DDR_2;
_delay_us(70);
}
else
{
_delay_us(70); //bylo 70
SET_IN_ONEWIRE_DDR_2;
_delay_us(7); //bylo 7
}
byte >>= 1;
}
}
unsigned char OneWireReadByte_1(void)
{
unsigned char i, byte = 0;
SET_IN_ONEWIRE_DDR_1;
for (i=0; i<8; i++)
{
SET_OUT_ONEWIRE_DDR_1;
_delay_us(7);
SET_IN_ONEWIRE_DDR_1;
_delay_us(7); //bylo 7
byte >>= 1;
if(IS_SET_ONEWIRE_PIN_1) byte |= 0x80;
_delay_us(70); //bylo 70
}
return byte;
}
unsigned char OneWireReadByte_2(void)
{
unsigned char i, byte = 0;
SET_IN_ONEWIRE_DDR_2;
for (i=0; i<8; i++)
{
SET_OUT_ONEWIRE_DDR_2;
_delay_us(7);
SET_IN_ONEWIRE_DDR_2;
_delay_us(7);
byte >>= 1;
if(IS_SET_ONEWIRE_PIN_2) byte |= 0x80;
_delay_us(70);
}
return byte;
}
ds18b20.h:
/*
Plik ds18b20.h
(xyz.isgreat.org)
*/
#ifndef DS18B20_H
#define DS18B20_H
/* DS18B20 przyłączony do portu Pc1 AVRa */
#define SET_ONEWIRE_PORT_1 PORTC |= _BV(1)
#define CLR_ONEWIRE_PORT_1 PORTC &= ~_BV(1)
#define IS_SET_ONEWIRE_PIN_1 PINC & _BV(1)
#define SET_OUT_ONEWIRE_DDR_1 DDRC |= _BV(1)
#define SET_IN_ONEWIRE_DDR_1 DDRC &= ~_BV(1)
/* DS18B20 drugi przyłączony do portu Pc2 AVRa */
#define SET_ONEWIRE_PORT_2 PORTC |= _BV(2)
#define CLR_ONEWIRE_PORT_2 PORTC &= ~_BV(2)
#define IS_SET_ONEWIRE_PIN_2 PINC & _BV(2)
#define SET_OUT_ONEWIRE_DDR_2 DDRC |= _BV(2)
#define SET_IN_ONEWIRE_DDR_2 DDRC &= ~_BV(2)
unsigned char ds18b20_ConvertT_1(void);
unsigned char ds18b20_ConvertT_2(void);
int ds18b20_Read_1(unsigned char []);
int ds18b20_Read_2(unsigned char []);
void OneWireStrong_1(char);
void OneWireStrong_2(char);
unsigned char OneWireReset_1(void);
unsigned char OneWireReset_2(void);
void OneWireWriteByte_1(unsigned char);
void OneWireWriteByte_2(unsigned char);
unsigned char OneWireReadByte_1(void);
unsigned char OneWireReadByte_2(void);
#endif