Advertisement
Guest User

Modbus 8 bit cpu

a guest
Nov 21st, 2019
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.04 KB | None | 0 0
  1. #include <SI_EFM8UB2_Register_Enums.h>
  2.  
  3. //-----------------------------------------------------------------------------
  4. // Global Variables
  5. //-----------------------------------------------------------------------------
  6.  
  7. #define UART_BUFFERSIZE 64
  8. uint8_t UART_Buffer[UART_BUFFERSIZE];
  9. extern uint8_t UART_Buffer_Size;
  10. uint8_t UART_Input_First;
  11. uint8_t UART_Output_First;
  12. extern uint8_t TX_Ready;
  13. extern char Byte;
  14.  
  15.  
  16. /* Supported function codes */
  17. #define _READ_HOLDING_REGISTERS 0x03
  18. #define _WRITE_MULTIPLE_REGISTERS 0x10
  19.  
  20. char Chip_Address;
  21.  
  22. SI_SBIT(IN1, SFR_P0, 1);
  23. SI_SBIT(IN2, SFR_P0, 2);
  24. SI_SBIT(IN3, SFR_P0, 3);
  25. SI_SBIT(IN4, SFR_P0, 4);
  26. SI_SBIT(IN5, SFR_P0, 5);
  27. SI_SBIT(IN6, SFR_P0, 6);
  28. SI_SBIT(IN7, SFR_P0, 7);
  29.  
  30. SI_SBIT(OUT1, SFR_P2, 1);                 // OUT='0' means ON
  31. SI_SBIT(OUT2, SFR_P2, 2);                 // OUT='1' means OFF
  32. SI_SBIT(OUT3, SFR_P2, 3);
  33. SI_SBIT(OUT4, SFR_P2, 4);
  34. SI_SBIT(OUT5, SFR_P2, 5);
  35. SI_SBIT(OUT6, SFR_P2, 6);
  36. SI_SBIT(OUT7, SFR_P2, 7);
  37.  
  38. static int Check_Chip_Address(uint8_t Msg_Address){         // ADRESS BASED ON THE P0.1-P0.4 GPIOS
  39.     char Address1, Address2, Address3, Address4;
  40.     Address1 = IN1;
  41.     Address2 = IN2;
  42.     Address3 = IN3;
  43.     Address4 = IN4;
  44.     Chip_Address = Address1;
  45.     Chip_Address += Address2;
  46.     Chip_Address += Address3;
  47.     Chip_Address += Address4;
  48.     if(Chip_Address == Msg_Address){
  49.         return 1;
  50.     }else{
  51.         return -1;
  52.     }
  53. }
  54.  
  55. static uint16_t Crc_Check(uint8_t *req, uint8_t req_length)
  56. {
  57.     uint8_t j;
  58.     uint16_t crc;
  59.     crc = 0xFFFF;
  60.     while (req_length--) {
  61.         crc = crc ^ *req++;
  62.         for (j = 0; j < 8; j++) {
  63.             if (crc & 0x0001)
  64.                 crc = (crc >> 1) ^ 0xA001;
  65.             else
  66.                 crc = crc >> 1;
  67.         }
  68.     }
  69.     return (crc << 8 | crc >> 8);
  70. }
  71.  
  72. static int check_integrity(uint8_t *msg, uint8_t msg_length)
  73. {
  74.     uint16_t crc_calculated;
  75.     uint16_t crc_received;
  76.     if (msg_length < 2)
  77.         return -1;
  78.     crc_calculated = Crc_Check(msg, msg_length - 2);
  79.     crc_received = (msg[msg_length - 2] << 8) | msg[msg_length - 1];
  80.  
  81.     /* Check CRC of msg */
  82.     if (crc_calculated == crc_received) {
  83.         return msg_length;
  84.     } else {
  85.         return -1;
  86.     }
  87. }
  88.  
  89. static void Check_Message(){
  90.     uint8_t Address,Code;
  91.     uint8_t Data[2];
  92.     uint8_t Crc[2];
  93.     int k = 0;
  94.     int i = 0;
  95.     for(i = 0; i < UART_Input_First;i++){
  96.         if (i <= 2){
  97.             Address = UART_Buffer[i];
  98.         }
  99.         else if (i <= 4){
  100.             Code = UART_Buffer[i];
  101.         }
  102.         else if (i <= 8){
  103.             if(i <= 6){
  104.                 Data[0] = UART_Buffer[i];
  105.             }else{
  106.                 Data[1] = UART_Buffer[i];
  107.             }
  108.         }else{
  109.             Crc[k] = UART_Buffer[i];
  110.             k++;
  111.         }
  112.     }
  113.     if(Check_Chip_Address(Address) != -1){                  // Check if Message is ours.
  114.         if(check_integrity(Crc,UART_Buffer_Size) != -1){    // Check if no errors on crc
  115.             if(Code == _READ_HOLDING_REGISTERS){
  116.                 /** MASTER WANTS TO READ THE GPIOS **/
  117.             }if(Code == _WRITE_MULTIPLE_REGISTERS){
  118.                 /** MASTER WANTS TO TOGGLE THE GPIOS **/
  119.             }
  120.         }
  121.     }
  122. }
  123.  
  124. //-----------------------------------------------------------------------------
  125. // UART0_ISR
  126. //-----------------------------------------------------------------------------
  127. //
  128. // UART0 ISR Content goes here. Remember to clear flag bits:
  129. // SCON0::RI (Receive Interrupt Flag)
  130. // SCON0::TI (Transmit Interrupt Flag)
  131. //
  132. //-----------------------------------------------------------------------------
  133. SI_INTERRUPT(UART0_ISR, UART0_IRQn)
  134. {
  135.     if (SCON0_RI == 1)
  136.        {
  137.           if( UART_Buffer_Size == 0)  {         // If new word is entered
  138.              UART_Input_First = 0;
  139.           }
  140.           SCON0_RI = 0;                         // Clear interrupt flag
  141.           Byte = SBUF0;                         // Read a character from UART
  142.           if (UART_Buffer_Size < UART_BUFFERSIZE)
  143.           {
  144.              UART_Buffer[UART_Input_First] = Byte; // Store in array
  145.  
  146.              UART_Buffer_Size++;                // Update array's size
  147.  
  148.              UART_Input_First++;                // Update counter
  149.           }else{
  150.               Check_Message();                  // Get the whole message and brake it into pieces
  151.           }
  152.        }
  153.  
  154.  
  155.  /** ECHO BACK THE MESSAGES **/
  156.  
  157. if (SCON0_TI == 1)                              // Check if transmit flag is set
  158.    {
  159.       SCON0_TI = 0;                             // Clear interrupt flag
  160.       if (UART_Buffer_Size != 1)                // If buffer not empty
  161.       {
  162.          // If a new word is being output
  163.          if ( UART_Buffer_Size == UART_Input_First ) {
  164.               UART_Output_First = 0;
  165.          }
  166.          // Store a character in the variable byte
  167.          Byte = UART_Buffer[UART_Output_First];
  168.          if ((Byte >= 0x61) && (Byte <= 0x7A)) { // If upper case letter
  169.             Byte -= 32;
  170.          }
  171.          SBUF0 = Byte;                          // Transmit to Hyperterminal
  172.          UART_Output_First++;                   // Update counter
  173.          UART_Buffer_Size--;                    // Decrease array size
  174.       }
  175.       else
  176.       {
  177.          UART_Buffer_Size = 0;                  // Set the array size to 0
  178.          TX_Ready = 1;                          // Indicate transmission complete
  179.       }
  180.    }
  181. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement