1-Wire tester, shows ROM code and temperature on an LCD screen
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
1wire-tester/main.c

164 rader
4.1 KiB

#include <avr/io.h> // register definitions
#include <avr/pgmspace.h> // storing data in program memory
#include <avr/interrupt.h> // interrupt vectors
#include <util/delay.h> // delay functions
#include <stdint.h> // C header for int types like uint8_t
#include <stdbool.h> // C header for the bool type
#include <stdlib.h>
#include <stdio.h>
// Include stuff from the library
#include "lib/iopins.h"
#include "lib/usart.h"
#include "lcd.h"
#include "onewire.h"
// Pins
#define LED 13
#define OW_PIN D9
void _lcd_wait_bf();
void _lcd_write_byte(uint8_t bb);
#if 0
// UART receive handler
ISR(USART_RX_vect)
{
// "ECHO" function:
uint8_t b = usart_rx();
usart_tx(b); // send back
}
#endif
void main()
{
#if 0
usart_init(BAUD_115200);
usart_isr_rx_enable(true); // enable RX interrupt handler
#endif
// configure pins
as_output(LED);
lcd_init();
lcd_clear();
lcd_puts("");
// globally enable interrupts (for the USART_RX handler)
sei();
uint8_t addr[8];
char charbuf[21];
int dots = 0;
bool signal = false, last_signal;
while (1) {
last_signal = signal;
signal = ow_reset(OW_PIN);
if (signal) {
ow_write(OW_PIN, 0x33);
ow_read_arr(OW_PIN, addr, 8);
// check if valid
if (addr[0] == 0x00 || (crc8(addr, 7) != addr[7])) {
signal = false;
}
}
if (!signal) {
if (last_signal) {
lcd_clear();
}
lcd_puts_xy(0,0,"No 1-Wire detected..");
dots = 0;
} else {
if (!last_signal) {
lcd_clear();
}
// Show chip type
switch (addr[0]) {
case 0x10:
sprintf(charbuf, "18S20 ");
break;
case 0x28:
sprintf(charbuf, "18B20 ");
break;
case 0x01:
sprintf(charbuf, "iButton");
break;
default:
sprintf(charbuf, "UNKNOWN");
break;
}
lcd_puts_xy(12, 0, charbuf);
// Show address
char *p = charbuf;
for(uint8_t i = 0; i < 4; i++) {
p += sprintf(p, "%02X", addr[i]);
if (i < 3) *p++ = ':';
}
lcd_puts_xy(0, 0, charbuf);
p = charbuf;
for(uint8_t i = 0; i < 4; i++) {
p += sprintf(p, "%02X", addr[4+i]);
if (i < 3) *p++ = ':';
}
lcd_puts_xy(0, 1, charbuf);
// Measure temperature
int16_t cels;
if (addr[0] == 0x10 || addr[0] == 0x28) {
ds18x20_single_measure(OW_PIN);
if (addr[0] == 0x10) {
// 18S20
cels = ds18s20_read_temp_c(OW_PIN);
} else {
// 18B20
cels = ds18b20_read_temp_c(OW_PIN);
}
if (cels == TEMP_ERROR || cels == 850) {
lcd_xy(12, 1);
for (uint8_t i = 0; i <= dots; i++) {
lcd_putc('.');
}
dots = (dots + 1) % 3;
}
else {
p = charbuf;
if (cels < 0) {
*p++ = '-';
cels = -cels;
}
p += sprintf(p, "%d", cels / 10);
*p++ = '.';
p += sprintf(p, "%d", cels % 10);
*p++ = 0xDF; // ring symbol
*p++ = 'C';
*p++ = ' '; // padding to prevent artifacts if the number shrinks (we're not clearing screen when 1w is connected)
*p++ = ' ';
*p++ = ' ';
*p = 0;
lcd_puts_xy(12, 1, charbuf);
}
}
}
pin_toggle(13); // blink the LED
_delay_ms(100);
}
}