This works for me:-)
For reading out ISKRA Smart meter
Maybe it helps some other beginner
program Sun2000_Master;
{ Declarations section }
// LCD module connections
var LCD_RS : sbit at PORTC0_bit;
var LCD_EN : sbit at PORTC2_bit;
var LCD_D4 : sbit at PORTC4_bit;
var LCD_D5 : sbit at PORTC5_bit;
var LCD_D6 : sbit at PORTC6_bit;
var LCD_D7 : sbit at PORTC7_bit;
var LCD_RS_Direction : sbit at DDC0_bit;
var LCD_EN_Direction : sbit at DDC2_bit;
var LCD_D4_Direction : sbit at DDC4_bit;
var LCD_D5_Direction : sbit at DDC5_bit;
var LCD_D6_Direction : sbit at DDC6_bit;
var LCD_D7_Direction : sbit at DDC7_bit;
// connect R/W to ground
// End LCD module connections
var LCD_Backlight : sbit at PortD7_bit; // Display Power ON
var Beeper : sbit at PORTD4_bit;
var ADC_Value : word;
counter_str, counter_str1, ADC_STR : STRING[32];
hex0, hex1, hex2, hex3, hex4, hex5, hex6 : STRING[3];
Wirkleistung_str : STRING[5];
VAR str_length, empfang : WORD;
laenge : WORD;
Einheit : STRING[2];
//Output_str : String[255];
Output_Str, Output1_str : array [0..255] of char;
lt, timer, counter, counter1, n, read_byte : BYTE;
delim: array [0..3] of char;
output_byte : array[0..255] OF short;
wirkleistung : INTEGER;
procedure Timer1Overflow_ISR(); org IVT_ADDR_TIMER1_COMPA;
begin
inc(timer);
end;
procedure Read(); iv IVT_ADDR_USART0_RX; ics ICS_AUTO;
Begin
if (UART1_Data_Ready() = 1) then
Begin
output_byte[lt] := Uart1_Read();
inc(lt);
timer:=0;
end;
end;
//******************************************
function Adc_Read_1(channel : byte) : word;
begin
ADMUX.0 := 0;
ADMUX.1 := 0;
ADMUX.2 := 0;
ADMUX.3 := 0;
ADMUX.4 := 0;
ADMUX.5 := 0;
ADMUX.6 := 1;
ADMUX.7 := 0;
ADCSRA := %11000111;
delay_ms(1);
ADCSRA := 128; //199
while ADCSRA.6 = 1 do nop;
Lo(result) := ADCL;
Hi(result) := ADCH;
end;
//******************************************
begin
{ Main program }
ADC_Init();
UART1_Init(9600);
//UART2_Init(9600);
DDRA := 0x00;
PortA := 0x00;
DDRC := 0xFF;
PortC := 0x00;
DDRD.7 := 1;
LCD_Backlight:= 1;
Lcd_Init();
delay_ms(100);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_out(1,1,'Initialize LCD');
delay_ms(1000);
Lcd_Cmd(_LCD_CLEAR);
ADC_STR:='';
{ SREG_I_bit := 1;
TCCR1A := 0x80;
TCCR1B := 0x0B;
OCR1AH := 0x59;
OCR1AL := 0xFF;
OCIE1A_bit := 1; }
// for n:=0 to 10 DO UART1_Read();
// RXCIE0_bit := 1;
For lt := 0 TO 255 DO
Output_byte[lt]:=0;
lt:=0;
TCCR1A := 0x80;
TCCR1B := 0x0B;
OCR1AH := 0x70;
OCR1AL := 0x7F;
OCIE1A_bit := 1;
SREG_I_bit := 1; // Interrupt enable
RXCIE0_bit := 0; //UART1 Interrupt ennable
delay_ms(200);
While TRUE Do
Begin
If TIMER >= 4 THEN // count= X * 100ms
Begin
lt := 0;
RXCIE0_bit := 1;
end;
bytetostr(lt,counter_str);
bytetostr(timer,counter_str1);
ByteToHEX(output_byte[193], HEX0);
ByteToHEX(output_byte[194], HEX1); //Wirkleistung gesammt Einheit(1B=W)
ByteToHEX(output_byte[195], HEX2);
ByteToHEX(output_byte[196], HEX3);
ByteToHEX(output_byte[197], HEX4); // Länge (52, 53 etc)
If Output_byte[194] = 0x1B THEN Einheit := 'W' ELSE Einheit := '?';
IF output_byte[197] = 0x53 THEN
Begin
Hi(wirkleistung) := output_byte[198];
Lo(wirkleistung) := output_byte[199];
end
ELSE
wirkleistung := output_byte[198];
IntToStr(Wirkleistung,Wirkleistung_Str);
ltrim(Wirkleistung_Str);
LCD_CMD(_LCD_CLEAR);
LCD_OUT(1,14, counter_str);
LCD_OUT(2,14, counter_str1);
LCD_Out(1,1, Wirkleistung_Str);
LCD_Out(1,5, Einheit);
delay_ms(10);
// Output_Str:='';
end;
end.