From ea666e44b97e32fc245c07b44e10461b4dc60533 Mon Sep 17 00:00:00 2001 From: Jan Michel Date: Tue, 18 Aug 2015 11:33:29 +0200 Subject: [PATCH] PT100: readout working, display working --- pt100/Makefile | 2 +- pt100/ads_adc.h | 4 +- pt100/lcdlib/font.c | 19 +++-- pt100/lcdlib/font.h | 10 +-- pt100/lcdlib/lcd-color-graphic.h | 9 ++- pt100/main.c | 128 +++++++++++++++++++++---------- pt100/main.h | 6 +- pt100/tempmeas.c | 85 +++++++++++++------- pt100/uart.c | 19 +++-- 9 files changed, 185 insertions(+), 97 deletions(-) diff --git a/pt100/Makefile b/pt100/Makefile index 0df2e23..b246656 100644 --- a/pt100/Makefile +++ b/pt100/Makefile @@ -5,7 +5,7 @@ # (GNU make, BSD make, SysV make) -MCU = atmega324p +MCU = atmega324pa FORMAT = ihex TARGET = main SRC = $(TARGET).c lcdlib/lcd-color-graphic.c lcdlib/font.c \ diff --git a/pt100/ads_adc.h b/pt100/ads_adc.h index 9e53877..71a2732 100644 --- a/pt100/ads_adc.h +++ b/pt100/ads_adc.h @@ -14,8 +14,8 @@ // MODE "device operating mode" #define ADS_MODE_S (1 << 8) // DR "Data rate" -#define ADS_1600SPS (0b100 << 5) -#define ADS_128SPS (0b000 << 5) +#define ADS_860SPS (0b111 << 5) +#define ADS_128SPS (0b100 << 5) // PULL_UP_EN "Pull-up enable" #define ADS_PULLUP_DRDY (1 << 3) // NOP "No operation" diff --git a/pt100/lcdlib/font.c b/pt100/lcdlib/font.c index a5d5169..78f6f72 100644 --- a/pt100/lcdlib/font.c +++ b/pt100/lcdlib/font.c @@ -207,18 +207,20 @@ uint8_t lcd_put_char(FONT_P font, uint8_t style, char character) { } //write character + uint8_t cont = 0; do { for(i=(row>>hc); i>1; } for(uint8_t x = free_space<0;x--) { - LCD_WRITE(c); + LCD_WRITE(c,cont); } } LCD_MOVE(1,-char_final_width); + cont = 0; } while (++row < char_final_height); //move cursor to upper right corner of character @@ -283,7 +286,7 @@ uint16_t lcd_put_string_length(FONT_P font, uint8_t style, char* str, uint8_t le * the string from program memory. The position of the string on the display * is selected by page / col. */ -uint16_t lcd_put_string_xy_P(FONT_P font, uint8_t style, PGM_P str,uint8_t page, uint8_t col) { +uint16_t lcd_put_string_xy_P(FONT_P font, uint8_t style, PGM_P str,uint16_t page, uint16_t col) { LCD_MOVE_TO(page,col); return lcd_put_string_P(font,style,str); } @@ -294,7 +297,7 @@ uint16_t lcd_put_string_xy_P(FONT_P font, uint8_t style, PGM_P str,uint8_t page, * the string from main memory. The position of the string on the display * is selected by page / col. */ -uint8_t lcd_put_char_xy(FONT_P font, uint8_t style, char character, uint8_t page, uint8_t col) { +uint8_t lcd_put_char_xy(FONT_P font, uint8_t style, char character, uint16_t page, uint16_t col) { LCD_MOVE_TO(page,col); return lcd_put_char(font,style,character); } @@ -310,7 +313,7 @@ uint8_t lcd_putc(char c) { /****************************************************************************** * Outputs a character on the display, using the global font and style */ -uint8_t lcd_putc_xy(char c, uint8_t page, uint8_t col) { +uint8_t lcd_putc_xy(char c, uint16_t page, uint16_t col) { return lcd_put_char_xy(global_font_select, global_font_style, c, page, col); } @@ -337,7 +340,7 @@ uint16_t lcd_putstr_P(PGM_P str) { * Outputs a string on the display, using the global font and style at the * given position */ -uint16_t lcd_putstr_xy_P(PGM_P str, uint8_t page, uint8_t col) { +uint16_t lcd_putstr_xy_P(PGM_P str, uint16_t page, uint16_t col) { return lcd_put_string_xy_P(global_font_select, global_font_style, str, page, col); } diff --git a/pt100/lcdlib/font.h b/pt100/lcdlib/font.h index d3bf3ff..5142007 100644 --- a/pt100/lcdlib/font.h +++ b/pt100/lcdlib/font.h @@ -83,7 +83,7 @@ typedef const struct font_info * FONT_P; #define LCD_MOVE(x,y) lcd_move_xy((x),(y)) //relative cursor movement #define LCD_MOVE_TO(x,y) lcd_moveto_xy((x),(y)) //absolute cursor movement -#define LCD_WRITE(x) lcd_data((x)) //write data to display +#define LCD_WRITE(x,c) lcd_write_font_byte(x,c) //write data to display //Functions to read the current position as provided by the LCD library #define LCD_CURRENT_COL() lcd_get_position_column() @@ -122,15 +122,15 @@ uint16_t lcd_put_string (FONT_P font, uint8_t style, char* str); uint16_t lcd_put_string_length(FONT_P font, uint8_t style, char* str, uint8_t length); uint16_t lcd_put_string_P (FONT_P font, uint8_t style, PGM_P str); uint8_t lcd_put_char (FONT_P font, uint8_t style, char c); -uint16_t lcd_put_string_xy_P (FONT_P font, uint8_t style, PGM_P str, uint8_t page, uint8_t col); -uint8_t lcd_put_char_xy (FONT_P font, uint8_t style, char character, uint8_t page, uint8_t col); +uint16_t lcd_put_string_xy_P (FONT_P font, uint8_t style, PGM_P str, uint16_t page, uint16_t col); +uint8_t lcd_put_char_xy (FONT_P font, uint8_t style, char character, uint16_t page, uint16_t col); void lcd_set_font (FONT_P font, uint8_t style); uint8_t lcd_putc (char c); -uint8_t lcd_putc_xy (char c, uint8_t page, uint8_t col); +uint8_t lcd_putc_xy (char c, uint16_t page, uint16_t col); uint16_t lcd_putstr (char* str); uint16_t lcd_putstr_P (PGM_P str); -uint16_t lcd_putstr_xy_P (PGM_P str, uint8_t page, uint8_t col); +uint16_t lcd_putstr_xy_P (PGM_P str, uint16_t page, uint16_t col); #if INCLUDE_INTEGER_OUTPUT == 1 uint16_t lcd_put_long (int32_t integer); diff --git a/pt100/lcdlib/lcd-color-graphic.h b/pt100/lcdlib/lcd-color-graphic.h index b60093c..bc928e0 100644 --- a/pt100/lcdlib/lcd-color-graphic.h +++ b/pt100/lcdlib/lcd-color-graphic.h @@ -8,6 +8,7 @@ #include #include + /***************************************************************************** * BEGIN CONFIG BLOCK *****************************************************************************/ @@ -40,7 +41,7 @@ extern void init_spi_lcd(void); #define LCD_INIT_SPI() init_spi_lcd() //Define a function that waits until SPI interface is idle -#define spi_wait_for_idle() while(! (UCSR1A & _BV(UDRE1))); +#define spi_wait_for_idle() while(!(UCSR1A & _BV(TXC1)));UCSR1A |= _BV(TXC1) //Define how to write to SPI data register #define spi_write(i) UDR1 = i @@ -162,7 +163,7 @@ typedef struct { //Control A0 input of LCD #define LCD_DATA() PORT_DC |= _BV(PIN_DC) -#define LCD_CMD() PORT_DC &= ~_BV(PIN_DC) +#define LCD_CMD() PORT_DC &= ~_BV(PIN_DC); #define LCD_SET_OUTPUT_DC() DDR_DC |= _BV(PIN_DC) //Control reset input of LCD @@ -175,10 +176,10 @@ typedef struct { #if LCD_USE_CHIPSELECT == 1 #define LCD_SET_OUTPUT_CS() DDR_CS |= _BV(PIN_CS) #define LCD_SELECT() PORT_CS &= ~_BV(PIN_CS) - #define LCD_UNSELECT() spi_wait_for_idle(); PORT_CS |= _BV(PIN_CS) + #define LCD_UNSELECT() spi_wait_for_idle(); PORT_CS |= _BV(PIN_CS); spi_write(LCD_NOP) #else #define LCD_SET_OUTPUT_CS() - #define LCD_SELECT() spi_wait_for_idle(); + #define LCD_SELECT() spi_wait_for_idle(); spi_write(LCD_NOP) #define LCD_UNSELECT() #endif diff --git a/pt100/main.c b/pt100/main.c index c2b4f07..523cd23 100644 --- a/pt100/main.c +++ b/pt100/main.c @@ -6,12 +6,16 @@ volatile uint16_t control_reg; volatile uint16_t time; volatile uint8_t keys_pressed = 0b00000000; volatile uint8_t next_step = 0; +volatile uint8_t next_second = 0; volatile uint8_t measurement_active = 0; +uint32_t temperature[9]; + color_t col_background; color_t col_font; color_t col_title; +color_t col_neg; struct calib_t calib_settings; @@ -19,10 +23,11 @@ struct calib_t calib_settings; * Init USART for LCD *****************/ void init_spi_lcd(void) { - UCSR1B = (1 << TXEN1); - UCSR1C = (1 << UMSEL10) | (0 << UDORD1) | (0 << UCPHA1) | (0 << UCPOL1); + UCSR1B = (1 << TXEN1); + UCSR1C = (3 << UMSEL10) | (0 << UDORD1) | (0 << UCPHA1) | (0 << UCPOL1); UBRR1L = 0; UBRR1H = 0; //full speed + UDR1 = LCD_NOP; } /****************** @@ -34,22 +39,24 @@ void read_calib() { } calib_settings.nominal_offset = eeprom_read(8); calib_settings.gain_current = eeprom_read(9); + calib_settings.period = eeprom_read(10); } /****************** * Some stuff on the LCD *****************/ void lcd_design(void) { - lcd_set_color(&col_background,0x03,0x04,0x05); - lcd_set_color(&col_title, 0x1f,0x3f,0x08); - lcd_set_color(&col_font, 0x1f,0x3f,0x08); + lcd_set_color(&col_font,0x1f,0x3f,0x1f); + lcd_set_color(&col_title, 0x1f,0x1f,0x05); + lcd_set_color(&col_background, 0x00,0x00,0x00); + lcd_set_color(&col_neg, 0x1f,0x00,0x00); lcd_use_background(col_background); lcd_use_foreground(col_title); lcd_set_area_xy(0, 0x13F, 0, 0xEF); - lcd_set_font(FONT_PROP_16,DOUBLE_SIZE|SPACING); - lcd_putstr_xy_P(PSTR("PT100 Reader"),0,0); + lcd_set_font(FONT_PROP_16,DOUBLE_SIZE); + lcd_putstr_xy_P(PSTR("PT100 Reader"),0,10); } @@ -57,6 +64,35 @@ void lcd_design(void) { * All my measurements... *****************/ void lcd_update(void) { + LED2_ON(); + lcd_set_font(FONT_DIGITS_24,SPACING); + lcd_use_background(col_background); + lcd_use_foreground(col_font); + +// send_answer_hex('I','I',DDRB); + + for(uint8_t i = 0; i<8; i++){ + int32_t x = temperature[i]; + if (x < 0) {lcd_use_foreground(col_neg); x = -x;} + else {lcd_use_foreground(col_font);} + + uint16_t posx = (i&1)?170:10; + uint16_t posy = i/2*40+60; + lcd_moveto_xy(posy,posx); + + uint8_t deg = x / 1000; + uint8_t mil = (x % 1000) / 10; + if(deg<10) { + lcd_set_area_xy(posx,posx+16,posy,posy+32); + lcd_move_xy(0,16); + } + lcd_put_short(deg); + lcd_putc('.'); + if(mil<10) lcd_putc('0'); + lcd_put_short(mil); + } + LED2_OFF(); + } @@ -65,11 +101,25 @@ void lcd_update(void) { *****************/ void init(void) { //CPU Regs +// CLKPR = 0x80;CLKPR = 0x01; //clkosc/2 + +//GPIO + PORTD = (0xc8); //pull-up for switches + PORTA = (0x77); //spare I/O have pull-up + + DDRA = (0x70); //select outputs + DDRB = (0xbb); //LED are output + DDRC = (0xc0); //outputs for Inhibit signals + DDRD = (0x3c); //LCD data lines + + MUX_C_ON(); + MUX_T_ON(); //Init ADC SPI - SPCR = (0 << SPIE) | (1 << SPE ) | (0 << DORD) | (1 << MSTR) | (0 << CPOL) | (1 << CPHA) | (0 << SPR0); - SPSR = (1 << SPI2X); //fcpu/2 - DDRB |= (1 << PB7) | (1 << PB5) | (1 << PB4); //ADC has three control lines +// DDRB |= (1 << PB7) | (1 << PB5) | (1 << PB4); //ADC has three control lines + SPCR0 = (0 << SPIE0) | (1 << SPE0 ) | (0 << DORD0) | (1 << MSTR0) | (0 << CPOL0) | (1 << CPHA0) | (0 << SPR00); + SPSR0 = (0 << SPI2X0); //fcpu/2 + //Init ADC for presence measurement ADMUX = (3 << REFS0) | (1 << ADLAR) | (3 << MUX0); // internal2.56V ADC3 @@ -79,14 +129,7 @@ void init(void) { //Init UART UCSR0B = (1 << RXCIE0) | (0 << TXCIE0) | (0 << UDRIE0) | (1 << RXEN0) | ( 1 << TXEN0); //udrie enabled on request UBRR0 = 12; //38400baud - -//GPIO - PORTD |= (0xc0); //pull-up for switches - PORTA |= (0x07); //spare I/O have pull-up - - DDRB |= (0x03); //LED are output - DDRA |= (0x70); //select outputs - DDRC |= (0xc0); //outputs for Inhibit signals + //Timer0: 2ms interrupts TCCR0A = (2 << WGM00); //CTC @@ -94,20 +137,24 @@ void init(void) { OCR0A = 249; TIMSK0 = (1 << OCF0A); //Interrupt on compare match -//Timer1: 1s ticks to start measurement +//Timer1: 1s ticks to make LCD output TCCR1A = 0; TCCR1B = (1 << WGM12) | ( 4 << CS10); //CTC, fcpu/256 TIMSK1 = (1 << OCIE1A); OCR1A = 31250; + + LED1_ON(); lcd_init(); + LED1_OFF(); + LED2_ON(); lcd_command_1(LCD_MIRROR, LCD_BGR | LCD_FLIP_XY); lcd_command(LCD_ON); - + + LED2_OFF(); read_calib(); - lcd_design(); sei(); -} + } @@ -115,10 +162,10 @@ void init(void) { * 500 Hz ticks *********************/ ISR(TIMER0_COMPA_vect) { - if(++time == 500) { + if(++time == calib_settings.period) { time = 0; send_information(); - measurement_active = 1; + measurement_active = 1; } next_step = 1; } @@ -128,22 +175,25 @@ ISR(TIMER0_COMPA_vect) { * Second ticks *********************/ ISR(TIMER1_COMPA_vect) { - + next_second = 1; } int main(void) { - - init(); - - while(1) { - while(next_step==0); - next_step = 0; - if (measurement_active) {do_measurement_step();} - if (time == 40) {lcd_update();} - if(key_was_pressed(1<>8); low = SPI_transceive(data&0xFF); + ADC_UNSELECT(); return (high << 8) | low; } @@ -95,48 +108,62 @@ uint16_t SPI_transceive_16bit(uint16_t data){ //34 read ADC temperature as 9th channel //35 send ADC temperature + // should be + // (5 - 2.2E3 * 410E-6) / 2 = 2.049 V if on + // (5 - 2.2E3 * 10E-6) / 2 = 2.489 V if off + // -> compare to 2.27 V or (2.27/2.56)*2^16 = 58112 + void do_measurement_step(void) { - if(measurement_step < (CONNECTED_SENSORS*4) && (measurement_step & 0x3) == 0x0) { - LED1_ON(); + static uint16_t con; + static int32_t adc_result = 0; + uint16_t conf_register; + if( (measurement_step < (CONNECTED_SENSORS*4)) && ((measurement_step & 0x3) == 0x0) ) { select_channel(); + adc_result = 0; } else if(measurement_step < (CONNECTED_SENSORS*4) && (measurement_step & 0x3) == 0x1) { + ADCSRA |= (1< compare to 2.27 V or (2.27/2.56)*2^16 = 58112 - if (x < 58112) { + con = ADCL; + con += (ADCH<<8); + + if (con < connect_threshold) { + adc_result = SPI_transceive_16bit(conf_register); + } + } + else if(measurement_step < (CONNECTED_SENSORS*4) && (measurement_step & 0x3) == 0x3) { + set_inhibit_signals(1); + if (con < connect_threshold) { // read value - x = SPI_transceive_16bit(0x0000); - x = res_to_temp(adc_to_res(x, current_channel)); - send_answer_hex(0, 0, x); + adc_result += SPI_transceive_16bit(0x0000); + adc_result /= 2; +// send_answer_hex('C', current_channel+'0', adc_result & 0xffff); + int32_t y = res_to_temp(adc_to_res((uint16_t)adc_result, current_channel)); + temperature[current_channel] = y; + send_answer_hex('T', current_channel+'0', y & 0xfffff); } else { num_connected_sensors = 8; uint32_t nc_msg = 0x100000; - send_answer_hex(0, 0, nc_msg); + temperature[current_channel] = 0; + send_answer_hex('T', current_channel+'0', nc_msg); } - } - else if(measurement_step < (CONNECTED_SENSORS*4) && (measurement_step & 0x3) == 0x3) { current_channel += 1; } measurement_step += 1; - if(measurement_step == 36) + if(measurement_step == 36) { measurement_step = 0; current_channel = 0; - LED1_OFF(); measurement_active = 0; + } } diff --git a/pt100/uart.c b/pt100/uart.c index 77a6e99..81aa14e 100644 --- a/pt100/uart.c +++ b/pt100/uart.c @@ -20,7 +20,7 @@ #define TX_BUSY() (txcnt != 0) #define STARTTX(i) txcnt = (i);UCSR0B |= (1<< UDRIE0) -#define ISMYADDR() (rxbuf[1] == '0') +#define ISMYADDR() (rxbuf[2] == '0') uint8_t rxcnt = 0, txpoint = 0; volatile uint8_t txcnt = 0; @@ -47,8 +47,8 @@ uint8_t hex_to_byte(uint8_t* h) { void forward_msg(uint8_t i) { - if(rxbuf[0] == 'A') rxbuf[1]++; - else rxbuf[1]--; + if(rxbuf[0] == 'A') rxbuf[2]++; + else rxbuf[2]--; memcpy ((uint8_t*)txbuf,(uint8_t*)rxbuf,i); STARTTX(i); } @@ -103,17 +103,19 @@ void send_information(void) { * UART received a byte *********************/ ISR(USART0_RX_vect) { - uint8_t buf = UDR1; + uint8_t buf = UDR0; if (rxcnt != 0 || (buf == 'W' || buf == 'A')) { rxbuf[rxcnt++] = buf; } if (buf == '\n' || buf == '\r') { if(rxcnt == 11) { - if(rxbuf[0] == 'A') {forward_msg(rxcnt);} + if(rxbuf[0] == 'A' || rxbuf[2] != '0') { + forward_msg(rxcnt); + } else if(rxbuf[0] == 'W') { if(rxbuf[1] == 'E') { uint8_t addr = hex_to_byte(rxbuf+4); - eeprom_write(addr, (hex_to_byte(rxbuf+6)<<8) | hex_to_byte(rxbuf+8)); + eeprom_write(addr, (((uint16_t)hex_to_byte(rxbuf+6))<<8) | hex_to_byte(rxbuf+8)); } else if(rxbuf[1] == 'C') { control_reg = (hex_to_byte(rxbuf+6)<<8) | hex_to_byte(rxbuf+8); @@ -122,6 +124,7 @@ ISR(USART0_RX_vect) { read_calib(); } } + rxcnt = 0; } else { rxcnt = 0; @@ -136,12 +139,12 @@ ISR(USART0_RX_vect) { * UART able to send a byte *********************/ ISR(USART0_UDRE_vect) { - LED2_ON(); + UDR0 = txbuf[txpoint++]; if(--txcnt == 0 || txpoint > 12) { txpoint = 0; txcnt = 0; UCSR0B &= ~(1<< UDRIE0); - LED2_OFF(); + } } \ No newline at end of file -- 2.43.0