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,c,recchar;
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
27
  //PB7 --> Send /Receive
28
  DDRB|=(1<<DDB7);
29
  PORTB|=(1<<PB7);
30
  //HIGH....Transmit
31
  //LOW.....Receive
32
33
  //Command to read Inputregister
34
  buffer[0]=0x01;
35
  buffer[1]=0x04;
36
  buffer[2]=0x00;
37
  buffer[3]=0x0C;
38
  buffer[4]=0x00;
39
  buffer[5]=0x01;
40
  buffer[6]=0x00;
41
  buffer[7]=0x00;
42
  
43
  //Generate CRC
44
  crc=ModRTU_CRC(buffer,6);
45
  crc_high=crc>>8;
46
  crc_low=crc&0xFF;
47
  
48
  //Transmit crc to TeraTerm --> check
49
    uart0_putCharAsHex(crc_low);
50
  uart0_putCharAsHex(crc_high);
51
  
52
  //write crc to command
53
  buffer[6]= crc_low;
54
  buffer[7]= crc_high;
55
  
56
  //send command via Rs485
57
  PORTB|=(1<<PB7);
58
  
59
  for(i=0;i<8;i++)
60
  {
61
    uart1_putc(buffer[i]);
62
    
63
  }
64
  
65
  while ( (UCSR1A & (1<<TXC1)) == 0);
66
  
67
  //switch to receive Mode
68
  PORTB&=~(1<<PB7);
69
  
70
  
71
  //read response from the RS485 interface
72
  for(i=0;i<7;i++)
73
  {
74
    receive_buffer[i]=uart1_getc();  
75
  }
76
  
77
  //transmit response to TeraTerm
78
  for(i=0;i<7;i++)
79
  {
80
    uart0_putCharAsHex(receive_buffer[i]);
81
    uart0_newline();
82
  }
83
  
84
    while(1)
85
    {
86
87
    }
88
}
89
90
// Compute the MODBUS RTU CRC
91
uint16_t ModRTU_CRC(uint8_t buf[], int len)
92
{
93
  uint16_t crc = 0xFFFF;
94
  
95
  for (int pos = 0; pos < len; pos++) {
96
    crc ^= (uint16_t)buf[pos];          // XOR byte into least sig. byte of crc
97
    
98
    for (int i = 8; i != 0; i--) {    // Loop over each bit
99
    if ((crc & 0x0001) != 0) {      // If the LSB is set
100
    crc >>= 1;                    // Shift right and XOR 0xA001
101
    crc ^= 0xA001;
102
  }
103
  else                            // Else LSB is not set
104
  crc >>= 1;                    // Just shift right
105
}
106
  }
107
  // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
108
  return crc;  
109
}