From: Jan Michel Date: Mon, 5 Jan 2015 11:31:30 +0000 (+0100) Subject: added old 1wire project X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=7168f804b312204406aba78f24e982f575244394;p=avr.git added old 1wire project --- diff --git a/1wire/1wire.c b/1wire/1wire.c new file mode 100644 index 0000000..29892b3 --- /dev/null +++ b/1wire/1wire.c @@ -0,0 +1,128 @@ +/************************************************************************/ +/* */ +/* Access Dallas 1-Wire Devices */ +/* */ +/* Author: Peter Dannegger */ +/* danni@specs.de */ +/* */ +/************************************************************************/ +#include "main.h" + + +#ifndef W1_PIN +#define W1_PIN PD6 +#define W1_IN PIND +#define W1_OUT PORTD +#define W1_DDR DDRD +#endif + + +bit w1_reset(void) +{ + bit err; + + W1_OUT &= ~(1<>= 1; + if( j ) + b |= 0x80; + }while( --i ); + return b; +} + + +uint w1_byte_rd( void ) +{ + return w1_byte_wr( 0xFF ); +} + + +uchar w1_rom_search( char diff, char idata *id ) +{ + char i, j, next_diff; + bit b; + + if( w1_reset() ) + return PRESENCE_ERR; // error, no device found + w1_byte_wr( SEARCH_ROM ); // ROM search command + next_diff = LAST_DEVICE; // unchanged on last device + i = 8 * 8; // 8 bytes + do{ + j = 8; // 8 bits + do{ + b = w1_bit_io( 1 ); // read bit + if( w1_bit_io( 1 ) ){ // read complement bit + if( b ) // 11 + return DATA_ERR; // data error + }else{ + if( !b ){ // 00 = 2 devices + if( diff > i || + ((*id & 1) && diff != i) ){ + b = 1; // now 1 + next_diff = i; // next pass 0 + } + } + } + w1_bit_io( b ); // write bit + *id >>= 1; + if( b ) // store bit + *id |= 0x80; + i--; + }while( --j ); + id++; // next byte + }while( i ); + return next_diff; // to continue search +} + + +void w1_command( char command, char idata *id ) +{ + char i; + w1_reset(); + if( id ){ + w1_byte_wr( MATCH_ROM ); // to a single device + i = 8; + do{ + w1_byte_wr( *id ); + id++; + }while( --i ); + }else{ + w1_byte_wr( SKIP_ROM ); // to all devices + } + w1_byte_wr( command ); +} diff --git a/1wire/1wire.h b/1wire/1wire.h new file mode 100644 index 0000000..53d4e5c --- /dev/null +++ b/1wire/1wire.h @@ -0,0 +1,27 @@ +#ifndef _1wire_h_ +#define _1wire_h_ +#define MATCH_ROM 0x55 +#define SKIP_ROM 0xCC +#define SEARCH_ROM 0xF0 + +#define CONVERT_T 0x44 // DS1820 commands +#define READ 0xBE +#define WRITE 0x4E +#define EE_WRITE 0x48 +#define EE_RECALL 0xB8 + +#define SEARCH_FIRST 0xFF // start new search +#define PRESENCE_ERR 0xFF +#define DATA_ERR 0xFE +#define LAST_DEVICE 0x00 // last device found +// 0x01 ... 0x40: continue searching + +bit w1_reset(void); + +uint w1_byte_wr( char b ); +uint w1_byte_rd( void ); + +uchar w1_rom_search( char diff, char idata *id ); + +void w1_command( char command, char idata *id ); +#endif diff --git a/1wire/Makefile b/1wire/Makefile new file mode 100644 index 0000000..f9ce0cd --- /dev/null +++ b/1wire/Makefile @@ -0,0 +1,93 @@ +############################################################################### +# Makefile for the project ds1820 +############################################################################### + +## General Flags +PROJECT = ds1820 +MCU = atmega8 +TARGET = ds1820.elf +CC = avr-gcc + +## Options common to compile, link and assembly rules +COMMON = -mmcu=$(MCU) + +## Compile options common for all C compilation units. +CFLAGS = $(COMMON) +CFLAGS += -Wall -gdwarf-2 -DF_CPU=3686400UL -O1 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d + +## Assembly specific flags +ASMFLAGS = $(COMMON) +ASMFLAGS += $(CFLAGS) +ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 + +## Linker flags +LDFLAGS = $(COMMON) +LDFLAGS += -Wl,-Map=ds1820.map + + +## Intel Hex file production flags +HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature + +HEX_EEPROM_FLAGS = -j .eeprom +HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" +HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings + + +## Objects that must be built in order to link +OBJECTS = delay.o main.o tempmeas.o timebase.o uart.o 1wire.o adc.o + +## Objects explicitly added by the user +LINKONLYOBJECTS = + +## Build +all: $(TARGET) ds1820.hex ds1820.eep ds1820.lss size + +## Compile +DELAY.o: ../DELAY.C + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +MAIN.o: ../MAIN.C + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +TEMPMEAS.o: ../TEMPMEAS.C + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +TIMEBASE.o: ../TIMEBASE.C + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +UART.o: ../UART.C + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +1WIRE.o: ../1WIRE.C + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +ADC.o: ../ADC.C + $(CC) $(INCLUDES) $(CFLAGS) -c $< + +##Link +$(TARGET): $(OBJECTS) + $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET) + +%.hex: $(TARGET) + avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ + +%.eep: $(TARGET) + -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 + +%.lss: $(TARGET) + avr-objdump -h -S $< > $@ + +size: ${TARGET} + @echo + @avr-size -C --mcu=${MCU} ${TARGET} + +## Clean target +.PHONY: clean +clean: + -rm -rf $(OBJECTS) ds1820.elf dep/* ds1820.hex ds1820.eep ds1820.lss ds1820.map + + +## Other dependencies +-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) + diff --git a/1wire/adc.c b/1wire/adc.c new file mode 100644 index 0000000..6357cd7 --- /dev/null +++ b/1wire/adc.c @@ -0,0 +1,13 @@ +#include "adc.h" + + + +void init_adc() { + //external AREF, right align, channel 0 + ADMUX = (0 << REFS1) | (0 << REFS0) | (0 << ADLAR) | 0; + + //enable ADC, start conversion, free running, no interrupt, 2^-5 prescaler + ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADFR) | (1 << ADIE) | (5 << ADPS0); + +return; +} diff --git a/1wire/adc.h b/1wire/adc.h new file mode 100644 index 0000000..ea42840 --- /dev/null +++ b/1wire/adc.h @@ -0,0 +1,13 @@ +#ifndef _adc_h_ +#define _adc_h_ + +#include "main.h" + +#define set_adc_port(x) ADMUX = (ADMUX & 0xF0) | (x & 0x0F) + + +void init_adc(); + + + +#endif diff --git a/1wire/delay.c b/1wire/delay.c new file mode 100644 index 0000000..b5967e9 --- /dev/null +++ b/1wire/delay.c @@ -0,0 +1,14 @@ +#include "main.h" + + +// Attention !!! +// take care, that during delay no interrupt access a timer register +// or restore TCNT1H + + +void delay( int d ) // d = 0 ... 32000 +{ + d += TCNT1; // not atomic ! + + while( (TCNT1 - d) & 0x8000 ); // not atomic ! +} diff --git a/1wire/delay.h b/1wire/delay.h new file mode 100644 index 0000000..071427c --- /dev/null +++ b/1wire/delay.h @@ -0,0 +1,11 @@ +#ifndef _delay_h_ +#define _delay_h_ + + +#define DELAY_US(x) ((uint)( (x) * 1e-6 * XTAL )) +#define DELAY(x) delay(x) + +void delay( int d ); + + +#endif diff --git a/1wire/ds1820.aps b/1wire/ds1820.aps new file mode 100644 index 0000000..5198cd9 --- /dev/null +++ b/1wire/ds1820.aps @@ -0,0 +1 @@ +ds182021-Jul-2008 15:53:1116-Mai-2014 14:28:31241021-Jul-2008 15:53:1144, 14, 0, 589AVR GCCdefault\ds1820.elfD:\ds1820\AVR SimulatorATmega8.xmlfalseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31Auto000DELAY.CMAIN.CTEMPMEAS.CTIMEBASE.CUART.C1WIRE.CADC.CDELAY.HMAIN.HTEMPMEAS.HTIMEBASE.HUART.H1WIRE.HADC.Hdefault\ds1820.lssdefault\ds1820.mapdefaultNOatmega8111ds1820.elfdefault\0-Wall -gdwarf-2 -DF_CPU=4000000UL -O1 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enumsdefault1C:\Programme\WinAVR-20081205\bin\avr-gcc.exeC:\Programme\WinAVR-20081205\utils\bin\make.exeD:\ds1820\DELAY.HD:\ds1820\MAIN.HD:\ds1820\TEMPMEAS.HD:\ds1820\TIMEBASE.HD:\ds1820\UART.HD:\ds1820\1WIRE.HD:\ds1820\ADC.HD:\ds1820\DELAY.CD:\ds1820\MAIN.CD:\ds1820\TEMPMEAS.CD:\ds1820\TIMEBASE.CD:\ds1820\UART.CD:\ds1820\1WIRE.CD:\ds1820\ADC.C00000main.c1000011wire.c100002tempmeas.c100003uart.c100004main.h100005TIMEBASE.C100006adc.c100007delay.c1 diff --git a/1wire/ds1820.aws b/1wire/ds1820.aws new file mode 100644 index 0000000..73153a6 --- /dev/null +++ b/1wire/ds1820.aws @@ -0,0 +1 @@ + diff --git a/1wire/main.c b/1wire/main.c new file mode 100644 index 0000000..783cf0a --- /dev/null +++ b/1wire/main.c @@ -0,0 +1,76 @@ +#include "main.h" + +uint16_t adc_values[6]; +uint32_t temp_values[6]; +uint8_t led; +uint8_t count_convs = 0; + +ISR(ADC_vect) { + uint8_t tmp = ADMUX & 0x07; + if (count_convs == 1){ + //if(tmp >= 1) + adc_values[(tmp)] = ADC; + //else + // adc_values[(NUM_ADC_CHANNELS-1)] = ADC; + tmp = (tmp + 1) %NUM_ADC_CHANNELS; + set_adc_port(tmp); + } + count_convs = 1-count_convs; + } + + +int main( void ) +{ + uint8_t i; + + DDRB = 0xF; + char s[30]; + init_timer(); + uinit(); + init_adc(); + sei(); + uputsnl( "1-Wire-Reader:" ); + second = 0; + + for(;;){ // main loop + if(uart_rx_flag) { + switch(uart_rx_buffer[0]) { + case 'y': led ^= 2; uart_rx_counter = 0; break; + case 'r': led ^= 1; uart_rx_counter = 0; break; + case 'g': led ^= 4; uart_rx_counter = 0; break; + case 'd': + if(uart_rx_counter == 4) { + OCR2 = ((uart_rx_buffer[1]-'0')*100+(uart_rx_buffer[2]-'0')*10+(uart_rx_buffer[3]-'0')); + uart_rx_counter = 0; + } + break; + } + + PORTB = (PORTB & ~0x7) | (led & 0x7); + uart_rx_flag = 0; + } + + if( second %3 == 0 ){ + start_meas(); + second++; + } + if( second %3 == 2 ){ + read_meas(); + uputs("ADC: "); + for(i=0;i +#include +//#include +#include +#include + +//#define XTAL 11059200L +#define XTAL F_CPU + +#define BAUD 19200 +#define bauddivider (uint)(1.0 * XTAL / BAUD / 16 - 0.5) + +#define NUM_ADC_CHANNELS 6 + +#define uchar unsigned char +#define uint unsigned int +#define bit uchar +#define idata +#define code + + +#define W1_PIN PD5 +#define W1_IN PIND +#define W1_OUT PORTD +#define W1_DDR DDRD + +#include "1wire.h" +#include "delay.h" +#include "tempmeas.h" +#include "timebase.h" +#include "uart.h" +#include "adc.h" + +#endif diff --git a/1wire/tempmeas.c b/1wire/tempmeas.c new file mode 100644 index 0000000..5c126e1 --- /dev/null +++ b/1wire/tempmeas.c @@ -0,0 +1,113 @@ +#include "main.h" + + +void start_meas( void ){ + if( W1_IN & 1<< W1_PIN ){ + w1_command( CONVERT_T, NULL ); + W1_OUT |= 1<< W1_PIN; + W1_DDR |= 1<< W1_PIN; // parasite power on + + }else{ + //uputsnl( "Short Circuit !" ); + } +} + + +void read_meas( void ) +{ + char id[8], diff; + char s[30]; + uchar i; + uint temp; + + for( diff = SEARCH_FIRST; diff != LAST_DEVICE; ){ + diff = w1_rom_search( diff, id ); + + if( diff == PRESENCE_ERR ){ + uputsnl( "No 1-wire Sensor found" ); + break; + } + if( diff == DATA_ERR ){ + uputsnl( "1-wire Bus Error" ); + break; + } + if( id[0] == 0x28 || id[0] == 0x10 ){ // temperature sensor + uputs( "ID: " ); + for( i = 0; i < 8; i++ ){ + sprintf( s, "%02X ", id[i] ); + uputs( s ); + } + w1_byte_wr( READ ); // read command + temp = w1_byte_rd(); // low byte + temp |= (uint)w1_byte_rd() << 8; // high byte + if( id[0] == 0x10 ) // 9 -> 12 bit + temp <<= 3; + sprintf( s, " T: %04X", temp ); // hex value + uputs( s ); + if ((int)temp >= 0) { + sprintf( s, " = %4d.%01d �C", ((int)temp) / 16, (temp * 4096) / 6553 ); // 0.1�C + } + else { + temp = - temp; + sprintf( s, " = -%d.%01d �C", ((int)temp) / 16, (temp * 4096) / 6553 ); // 0.1�C + } + + uputsnl( s ); + } + } + //uputsnl( "" ); +} + +//Coefficients for each amplifier for R *1000*512 = a * ADC + b +const uint32_t a_coeff[6] = {65997L,65997L,65997L,65997L,65997L,65997L}; +const uint32_t b_coeff[6] = {7772160L,7772160L,7772160L,7772160L,7772160L,7772160L}; +const uint32_t pt100_coeff = 5447L; // (1/385)*2^21 +const uint32_t pt100_neg_coeff[4] = {242L, 73L, 1677L, 299L}; +const uint8_t pt100_neg_shifts[4] = {0,10,20,19}; //absolute shift +const uint8_t pt100_neg_shift_adjust[4] = {0,10,10,12}; //shift before multiplying + + +const int8_t pt100_offset[4] = {0,-4,3,0}; +const uint8_t pt100_gain = 32; + +unsigned long int get_pt100_resistance_simple(uint16_t adc, uint8_t channel) { + uint32_t temp; + temp = (uint32_t)(adc+pt100_offset[channel])*5200 / pt100_gain; + return temp; + } + + +unsigned long int make_temp_pt100(uint16_t adc, uint8_t channel){ + uint32_t temp; + uint32_t m,n,o; + uint32_t erg; + //resistance is for each channel + //temp = (uint32_t)adc * a_coeff[channel] + b_coeff[channel]; + temp = get_pt100_resistance_simple(adc,channel); + //temp >>= 9; + //this is the resistance in Milliohm, now get temperature in dezikelvin + if(temp >= 100000L) { //linear case above 0�C + temp = (temp-100000L)* pt100_coeff * 10L; + temp >>= 21L; + } + else { + temp >>= 5; + erg = (0-pt100_neg_coeff[0])*10; //absolute term + m = pt100_neg_coeff[1] * temp*10; //linear term + n = pt100_neg_coeff[2] * temp; //quadratic term + o = pt100_neg_coeff[3] * temp; //cubic term + m >>= pt100_neg_shift_adjust[1]; + n >>= pt100_neg_shift_adjust[2]; + o >>= pt100_neg_shift_adjust[3];//adjust size by /1024 + n = n*n*10; o=o*o*o*10; //square and cube terms + n >>= (pt100_neg_shifts[2]-pt100_neg_shift_adjust[2])*2; //do last shifts + o >>= (pt100_neg_shifts[3]-pt100_neg_shift_adjust[3])*3; + erg = erg + m + n - o; //add everything + temp = erg; + } + temp += 2732; //change to kelvin + return temp; + } + + + diff --git a/1wire/tempmeas.h b/1wire/tempmeas.h new file mode 100644 index 0000000..8fff15f --- /dev/null +++ b/1wire/tempmeas.h @@ -0,0 +1,5 @@ +void start_meas( void ); +void read_meas( void ); + + +unsigned long int make_temp_pt100(uint16_t adc, uint8_t channel); \ No newline at end of file diff --git a/1wire/timebase.c b/1wire/timebase.c new file mode 100644 index 0000000..4ecb593 --- /dev/null +++ b/1wire/timebase.c @@ -0,0 +1,50 @@ + +/************************************************************************/ +/* */ +/* Precise 1 Second Timebase */ +/* */ +/* Author: Peter Dannegger */ +/* danni@specs.de */ +/* */ +/************************************************************************/ +#include "main.h" + + +#define DEBOUNCE 256L // debounce clock (256Hz = 4msec) + + +uchar prescaler; +uchar volatile second; // count seconds + + +SIGNAL (SIG_OUTPUT_COMPARE1A) +{ + uchar tcnt1h = TCNT1H; + + OCR1A += XTAL / DEBOUNCE; // new compare value + + if( ++prescaler == (uchar)DEBOUNCE ){ + prescaler = 0; + second++; // exact one second over +#if XTAL % DEBOUNCE // handle remainder + OCR1A += XTAL % DEBOUNCE; // compare once per second +#endif + } + TCNT1H = tcnt1h; // restore for delay() ! +} + + +void init_timer( void ) +{ + TCCR1B = (1<> 8; + UCSRA = 0; //no U2X, MPCM + UCSRC = 1<