From 76ced85569acd3f460559120ac9c029d90e81f1f Mon Sep 17 00:00:00 2001 From: Eggert Jung Date: Thu, 20 May 2021 20:56:22 +0200 Subject: [PATCH] rewrite with minimal hd444780/modbus example --- i2c.c | 61 +++++++++++++++++++++ i2c.h | 26 +++++++++ lcd.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lcd.h | 46 ++++++++++++++++ main.c | 149 +++++++++++--------------------------------------- makefile | 2 +- 6 files changed, 354 insertions(+), 117 deletions(-) create mode 100644 i2c.c create mode 100644 i2c.h create mode 100644 lcd.c create mode 100644 lcd.h diff --git a/i2c.c b/i2c.c new file mode 100644 index 0000000..b484b73 --- /dev/null +++ b/i2c.c @@ -0,0 +1,61 @@ +/* + * i2c.c + * + * Created: 20.01.2018 12:50:54 + * Author: Ulrich + */ + +#include "i2c.h" + +void i2c_init(void){ + I2C_PORT |= (1 << SDA_PIN | 1 << SCL_PIN); //Port Pullup + TWCR = 0; + TWSR = 0; + TWBR = ((F_CPU/SCL_CLOCK)-16)/2; + _delay_ms(50); +} + +//*************************************************************************************** +uint8_t i2c_start (uint8_t addr){ + uint16_t timeout = 0; + + TWCR = (1 << TWINT | 1 << TWSTA | 1 << TWEN); + while(!(TWCR & (1< 1000) return 1; + } + TWDR = addr; + TWCR = (1 << TWINT | 1 << TWEN); + timeout = 0; + while(!(TWCR & (1< 1000) return 1; + } + return 0; +} + +//*************************************************************************************** +uint8_t i2c_byte (uint8_t byte){ + uint16_t timeout = 0; + TWDR = byte; + TWCR = (1 << TWINT | 1 << TWEN); + while(!(TWCR & (1< 1000) return 1; + } + return 0; +} + +//*************************************************************************************** +uint8_t i2c_readNak(void) +{ + uint16_t timeout = 0; + TWCR = (1< 1000) return 0; + } + return TWDR; +} + +//*************************************************************************************** +void i2c_stop (void){ + TWCR = (1 << TWINT | 1 << TWSTO | 1 << TWEN); + TWCR = 0; +} diff --git a/i2c.h b/i2c.h new file mode 100644 index 0000000..5ee4a34 --- /dev/null +++ b/i2c.h @@ -0,0 +1,26 @@ +/* + * i2c.h + * + * Created: 20.01.2018 12:51:11 + * Author: Ulrich + */ + +#ifndef I2C_H_ + #define I2C_H_ + + #include + #include + + //I2C + #define SDA_PIN PC4 //PIN am Atmel + #define SCL_PIN PC5 //PIN am Atmel + #define I2C_PORT PORTC //PORT am Atmel + #define SCL_CLOCK 100000UL + + void i2c_init(void); + uint8_t i2c_start (uint8_t); + uint8_t i2c_byte (uint8_t); + uint8_t i2c_readNak(void); + void i2c_stop (void); + +#endif /* I2C_H_ */ \ No newline at end of file diff --git a/lcd.c b/lcd.c new file mode 100644 index 0000000..15d2f49 --- /dev/null +++ b/lcd.c @@ -0,0 +1,187 @@ +/* + * lcd.c + * + * Created: 20.01.2018 12:51:11 + * Author: Ulrich + */ + +#include "lcd.h" + +volatile unsigned char char_counter = 0; + +// output data to lcd +void lcd_out (unsigned char c) { + i2c_start(LCD_I2C_ADDR); + i2c_byte(c | LCD_BACKLIGHT); + i2c_stop(); +} + +//*************************************************************************************** +// CD = Command or Data +void lcd_nibble_out(unsigned char c, unsigned char cd) { + unsigned char out = 0; + unsigned char rs = 0; + + if(cd) rs=LCD_RS; + + //4 upper bits + if(c & (1<<4)) out |= LCD_D4; + if(c & (1<<5)) out |= LCD_D5; + if(c & (1<<6)) out |= LCD_D6; + if(c & (1<<7)) out |= LCD_D7; + lcd_out(out | rs | LCD_E); + _delay_ms(5); + lcd_out(out | rs); + + //4 lower bits + out=0; + if(c & (1<<0)) out |= LCD_D4; + if(c & (1<<1)) out |= LCD_D5; + if(c & (1<<2)) out |= LCD_D6; + if(c & (1<<3)) out |= LCD_D7; + lcd_out(out | rs | LCD_E); + _delay_ms(5); + lcd_out(out | rs ); +} + +//*************************************************************************************** +// clear LCD +void lcd_clear() { + lcd_nibble_out(0x01, 0); // clear display + lcd_nibble_out(0x80, 0); + char_counter = 0; +} + + +//*************************************************************************************** +// LCD home +void lcd_home() { + lcd_nibble_out(0x80, 0); + char_counter = 0; +} + +//*************************************************************************************** +// Init LCD +void lcd_init() { + unsigned char loop=3; + + while(loop--){ + lcd_out(LCD_D4 | LCD_D5 | LCD_E); + _delay_ms(10); + lcd_out(LCD_D4 | LCD_D5); + _delay_ms(100); + } + + // 4 bit mode + lcd_out(LCD_D5 | LCD_E); + _delay_ms(10); + lcd_out(LCD_D5); + _delay_ms(10); + + lcd_nibble_out(0x28, 0); + lcd_nibble_out(0x0C, 0); + + lcd_clear(); +} + +//*************************************************************************************** +void lcd_write_char (char c) { + if(char_counter == LCD_WIDTH) lcd_nibble_out(LCD_ADDR_LINE2,0); + if(char_counter == (LCD_WIDTH*2)){ + lcd_nibble_out(LCD_ADDR_LINE1,0); + char_counter = 0; + } + char_counter++; + lcd_nibble_out(c, 1); +} + +//*************************************************************************************** +void lcd_print_str(char *str) { + while (*str != 0){ + if(char_counter == LCD_WIDTH) lcd_nibble_out(LCD_ADDR_LINE2,0); + if(char_counter == (LCD_WIDTH*2)){ + lcd_nibble_out(LCD_ADDR_LINE1,0); + char_counter = 0; + } + char_counter++; + lcd_nibble_out(*str++, 1); + } +} + +//*************************************************************************************** +void lcd_write_P (const char *Buffer,...) +{ + va_list ap; + va_start (ap, Buffer); + + int format_flag; + char str_buffer[10]; + char str_null_buffer[10]; + char move = 0; + char Base = 0; + int tmp = 0; + char by; + char *ptr; + + //Ausgabe der Zeichen + for(;;){ + by = pgm_read_byte(Buffer++); + if(by==0) break; // end of format string + + if (by == '%'){ + by = pgm_read_byte(Buffer++); + if (isdigit(by)>0){ + str_null_buffer[0] = by; + str_null_buffer[1] = '\0'; + move = atoi(str_null_buffer); + by = pgm_read_byte(Buffer++); + } + + switch (by){ + case 's': + ptr = va_arg(ap,char *); + while(*ptr) { lcd_write_char(*ptr++); } + break; + case 'b': + Base = 2; + goto ConversionLoop; + case 'c': + //Int to char + format_flag = va_arg(ap,int); + lcd_write_char (format_flag++); + break; + case 'i': + Base = 10; + goto ConversionLoop; + case 'o': + Base = 8; + goto ConversionLoop; + case 'x': + Base = 16; + //**************************** + ConversionLoop: + //**************************** + itoa(va_arg(ap,int),str_buffer,Base); + int b=0; + while (str_buffer[b++] != 0){}; + b--; + if (b + #include + #include + #include + #include + #include + #include + #include + #include "i2c.h" + + #define LCD_I2C_ADDR 0x4E + + //Port Belegung am PCF8574 (1< -#include #include +#include +#include "lcd.h" +#include "i2c.h" #include "modbus.h" -#include "pid.h" -#include "adc.h" -#include "i2cmaster.h" - -void modbusGet(void); - -volatile uint16_t holdingRegisters[40]; - -volatile float output; -volatile struct pid controller; - -volatile float setpoint_1 = 130; -volatile float setpoint_2 = 150; -volatile float setpoint_3 = 150; - -int main(){ - DDRD |= (1 << 4); // LED - DDRD |= (1 << 3); // FU PWM - DDRD |= (1 << 2); // 485 DE - - PORTD |= 1 << 4; - - DDRB |= 0x0F; // out channels - - PORTD|=(1<<0); // RX - - // FU PWM on PD3 - TCCR2A |= (1 << COM2B1) | (1 << COM2B0); - TCCR2A |= (1 << WGM21) | (1 << WGM20); - TCCR2B |= (1 << CS21); - - modbusSetAddress(1); - modbusInit(); - - // Modbus Tick Timer - TCCR0B|=(1< 128) - output = 128; + sei(); + modbusSetAddress(1); + modbusInit(); - if(output >= 1){ - uint32_t tmp = output * 512; - if(tmp >= 0x10000) - tmp = 0xFFFE; + TCCR0B|=(1<