CO2Modbus.c


1
/*
2
 * CO2Modbus.c
3
 *
4
 * Created: 19.03.2015 17:19:59
5
 *  Author: Johannes1
6
 */ 
7
8
9
#include <avr/io.h>
10
#include "uart0.h"
11
#include "uart1.h"
12
#include "util/delay.h"
13
14
uint16_t ModRTU_CRC(uint8_t buf[], int len);
15
int main(void)
16
{  
17
  uint8_t buffer[8],crc_low,crc_high,i;
18
  uint8_t receive_buffer[14];
19
  uint16_t crc;
20
  uart0_init(9600,1,1);
21
  uart1_init_x(9600,1,1,8,0,0,0,2);
22
  //Baudrate=9600; send..enabled; receive..enabled;8 Databits; send and receive with interrupt disabled
23
  //2 Stopbits
24
25
  
26
  DDRH |=(1<<PH0);
27
  //DDRH &=~(1<<PH0);
28
  //Meiner Meinung nach sollte das so stimmen, aber so wird der Converter nach dem Sendevorgang immer orange
29
  //Als Rückmeldung kommen lauter 0C0C0C0C und beim Simulator sind zwischendurch 0er
30
  //Verwende ich das Auskommentierte bleibt er zwar grün, sendet jedoch zwischendurch immer 0er
31
  
32
  //HIGH....Transmit
33
  //LOW.....Receive
34
  
35
  PORTH|=(1<<PH0);  //switch so send-Mode
36
37
  //Command to read Inputregister
38
  buffer[0]=0x01;
39
  buffer[1]=0x04;
40
  buffer[2]=0x00;
41
  buffer[3]=0x0C;
42
  buffer[4]=0x00;
43
  buffer[5]=0x01;
44
  buffer[6]=0x00;
45
  buffer[7]=0x00;
46
  
47
  //Generate CRC
48
  crc=ModRTU_CRC(buffer,6);
49
  crc_high=crc>>8;
50
  crc_low=crc&0xFF;
51
  
52
  //Transmit crc to TeraTerm --> check
53
    uart0_putCharAsHex(crc_low);
54
  uart0_putCharAsHex(crc_high);
55
  
56
  //write crc to command
57
  buffer[6]= crc_low;
58
  buffer[7]= crc_high;
59
  
60
  //send command via Rs485
61
  for(i=0;i<8;i++)
62
  {
63
    uart1_putc(buffer[i]);
64
  }
65
  
66
  while ( (UCSR1A & (1<<TXC1)) == 0);
67
  
68
  //switch to receive Mode
69
  PORTH&=~(1<<PH0);
70
  
71
  
72
  //read response from the RS485 interface
73
  for(i=0;i<7;i++)
74
  {
75
    receive_buffer[i]=uart1_getc();  
76
  }
77
  
78
  //transmit response to TeraTerm
79
  for(i=0;i<9;i++)
80
    uart0_putCharAsHex(receive_buffer[0]);
81
  
82
    while(1)
83
    {
84
85
    }
86
}
87
88
// Compute the MODBUS RTU CRC
89
uint16_t ModRTU_CRC(uint8_t buf[], int len)
90
{
91
  uint16_t crc = 0xFFFF;
92
  
93
  for (int pos = 0; pos < len; pos++) {
94
    crc ^= (uint16_t)buf[pos];          // XOR byte into least sig. byte of crc
95
    
96
    for (int i = 8; i != 0; i--) {    // Loop over each bit
97
    if ((crc & 0x0001) != 0) {      // If the LSB is set
98
    crc >>= 1;                    // Shift right and XOR 0xA001
99
    crc ^= 0xA001;
100
  }
101
  else                            // Else LSB is not set
102
  crc >>= 1;                    // Just shift right
103
}
104
  }
105
  // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
106
  return crc;  
107
}