Advertisement
Guest User

Modbus 8 bit cpu

a guest
Nov 21st, 2019
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.85 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. // Port0 1-7 inputs
  23. SI_SBIT(IN1, SFR_P0, 1);                // IN1 = '0' means on
  24. SI_SBIT(IN2, SFR_P0, 2);
  25. SI_SBIT(IN3, SFR_P0, 3);
  26. SI_SBIT(IN4, SFR_P0, 4);
  27. SI_SBIT(IN5, SFR_P0, 5);
  28. SI_SBIT(IN6, SFR_P0, 6);
  29. SI_SBIT(IN7, SFR_P0, 7);
  30. // Port1 1-7 inputs
  31. SI_SBIT(IN1, SFR_P1, 1);                // IN1 = '0' means on
  32. SI_SBIT(IN2, SFR_P1, 2);
  33. SI_SBIT(IN3, SFR_P1, 3);
  34. SI_SBIT(IN4, SFR_P1, 4);
  35. SI_SBIT(IN5, SFR_P1, 5);
  36. SI_SBIT(IN6, SFR_P1, 6);
  37. SI_SBIT(IN7, SFR_P1, 7);
  38. // Port2 1-7 outputs
  39. SI_SBIT(OUT1, SFR_P2, 1);
  40. SI_SBIT(OUT2, SFR_P2, 2);
  41. SI_SBIT(OUT3, SFR_P2, 3);
  42. SI_SBIT(OUT4, SFR_P2, 4);
  43. SI_SBIT(OUT5, SFR_P2, 5);
  44. SI_SBIT(OUT6, SFR_P2, 6);
  45. SI_SBIT(OUT7, SFR_P2, 7);
  46. // Port3 1-7 outputs
  47. SI_SBIT(OUT1, SFR_P3, 1);
  48. SI_SBIT(OUT2, SFR_P3, 2);
  49. SI_SBIT(OUT3, SFR_P3, 3);
  50. SI_SBIT(OUT4, SFR_P3, 4);
  51. SI_SBIT(OUT5, SFR_P3, 5);
  52. SI_SBIT(OUT6, SFR_P3, 6);
  53. SI_SBIT(OUT7, SFR_P3, 7);
  54.  
  55. static void Check_GPIO_Status(){
  56.     uint8_t GPIO_STATUS_Input_P0 = SFR_P0;  // I have to put the gpio statuses together to be able to send back to master on request.
  57.     uint8_t GPIO_STATUS_Input_P1 = SFR_P1;
  58.     uint8_t GPIO_STATUS_Output_P2 = SFR_P2;
  59.     uint8_t GPIO_STATUS_Output_P3 = SFR_P3;
  60. }
  61.  
  62. static int Check_Chip_Address(uint8_t Msg_Address){         // ADRESS BASED ON THE P0.1-P0.4 GPIOS
  63.     char Address1, Address2, Address3, Address4;            // This function is not okay.
  64.     Address1 = IN1;                                         // I have to read the input gpio statuses and match it with a 8 bit variable
  65.     Address2 = IN2;
  66.     Address3 = IN3;
  67.     Address4 = IN4;
  68.     Chip_Address = Address1;
  69.     Chip_Address += Address2;
  70.     Chip_Address += Address3;
  71.     Chip_Address += Address4;
  72.     if(Chip_Address == Msg_Address){
  73.         return 1;
  74.     }else{
  75.         return -1;
  76.     }
  77. }
  78.  
  79. static uint16_t Crc_Check(uint8_t *req, uint8_t req_length)
  80. {
  81.     uint8_t j;
  82.     uint16_t crc;
  83.     crc = 0xFFFF;
  84.     while (req_length--) {
  85.         crc = crc ^ *req++;
  86.         for (j = 0; j < 8; j++) {
  87.             if (crc & 0x0001)
  88.                 crc = (crc >> 1) ^ 0xA001;
  89.             else
  90.                 crc = crc >> 1;
  91.         }
  92.     }
  93.     return (crc << 8 | crc >> 8);
  94. }
  95.  
  96. static int check_integrity(uint8_t *msg, uint8_t msg_length)
  97. {
  98.     uint16_t crc_calculated;
  99.     uint16_t crc_received;
  100.     if (msg_length < 2)
  101.         return -1;
  102.     crc_calculated = Crc_Check(msg, msg_length - 2);
  103.     crc_received = (msg[msg_length - 2] << 8) | msg[msg_length - 1];
  104.  
  105.     /* Check CRC of msg */
  106.     if (crc_calculated == crc_received) {
  107.         return msg_length;
  108.     } else {
  109.         return -1;
  110.     }
  111. }
  112.  
  113. static void Check_Message(){
  114.     uint8_t Address,Code;
  115.     uint8_t Data[2];
  116.     uint8_t Crc[2];
  117.     int k = 0;
  118.     int i = 0;
  119.     // Get the whole message in separate variables for further analization
  120.     for(i = 0; i < UART_Input_First;i++){
  121.         if (i <= 2){
  122.             Address = UART_Buffer[i];
  123.         }
  124.         else if (i <= 4){
  125.             Code = UART_Buffer[i];
  126.         }
  127.         else if (i <= 8){
  128.             if(i <= 6){
  129.                 Data[0] = UART_Buffer[i];
  130.             }else{
  131.                 Data[1] = UART_Buffer[i];
  132.             }
  133.         }else{
  134.             Crc[k] = UART_Buffer[i];
  135.             k++;
  136.         }
  137.     }
  138.     // Checking the separated variables
  139.     if(Check_Chip_Address(Address) != -1){                  // Check if Message is ours.
  140.         if(check_integrity(Crc,UART_Buffer_Size) != -1){    // Check if no errors on crc
  141.             if(Code == _READ_HOLDING_REGISTERS){
  142.                 /** MASTER WANTS TO READ THE GPIOS **/
  143.                 Check_GPIO_Status();
  144.             }else if(Code == _WRITE_MULTIPLE_REGISTERS){
  145.                 /** MASTER WANTS TO TOGGLE THE GPIOS **/
  146.             }
  147.         }
  148.     }
  149. }
  150.  
  151. //-----------------------------------------------------------------------------
  152. // SCON0::RI (Receive Interrupt Flag)
  153. // SCON0::TI (Transmit Interrupt Flag)
  154. //-----------------------------------------------------------------------------
  155. SI_INTERRUPT(UART0_ISR, UART0_IRQn)
  156. {
  157.     if (SCON0_RI == 1)
  158.        {
  159.           if( UART_Buffer_Size == 0)  {         // If new word is entered
  160.              UART_Input_First = 0;
  161.           }
  162.           SCON0_RI = 0;                         // Clear interrupt flag
  163.           Byte = SBUF0;                         // Read a character from UART
  164.           if (UART_Buffer_Size < UART_BUFFERSIZE)
  165.           {
  166.              UART_Buffer[UART_Input_First] = Byte; // Store in array
  167.  
  168.              UART_Buffer_Size++;                // Update array's size
  169.  
  170.              UART_Input_First++;                // Update counter
  171.           }else{
  172.               Check_Message();                  // Get the whole message and brake it into pieces
  173.           }
  174.        }
  175.  
  176.  
  177.  /** ECHO BACK THE MESSAGES **/
  178.  
  179. if (SCON0_TI == 1)                              // Check if transmit flag is set
  180.    {
  181.       SCON0_TI = 0;                             // Clear interrupt flag
  182.       if (UART_Buffer_Size != 1)                // If buffer not empty
  183.       {
  184.          // If a new word is being output
  185.          if ( UART_Buffer_Size == UART_Input_First ) {
  186.               UART_Output_First = 0;
  187.          }
  188.          // Store a character in the variable byte
  189.          Byte = UART_Buffer[UART_Output_First];
  190.          if ((Byte >= 0x61) && (Byte <= 0x7A)) { // If upper case letter
  191.             Byte -= 32;
  192.          }
  193.          SBUF0 = Byte;                          // Transmit to Hyperterminal
  194.          UART_Output_First++;                   // Update counter
  195.          UART_Buffer_Size--;                    // Decrease array size
  196.       }
  197.       else
  198.       {
  199.          UART_Buffer_Size = 0;                  // Set the array size to 0
  200.          TX_Ready = 1;                          // Indicate transmission complete
  201.       }
  202.    }
  203. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement