单片机中论Task的使用结合modbus(零)——源代码

好吧,暂时回归嵌入式了,最近搞了Arduino觉得还比较简单,不过这篇blog是讨论task的。因为调试QT的modbus与这个protues仿真的联调通过了。所以还是老老实实爬这个51单片机的程序。

1.main.cpp与main.h

main.cpp:

#include"include/main.h"
#include"include/uart.h"
#include"include/sch.h"
#include"include/modbus.h"

void main()
{
	SCH_Init_T0();
	uart0_init(9600);
	Write_String_To_Buffer("modbus is testing!");
	SCH_Add_Task(Uart_Update,0,2,1);
	SCH_Start();
	while(1)
	{
		SCH_Dispatch_Tasks();
	}
}

main.h

#ifndef _MAIN_H
#define _MAIN_H


//#include 
#include 

#define OSC_FREQ (11059200UL)


#define OSC_PER_INST (12)


typedef unsigned char U8;
typedef unsigned int  U16;
typedef unsigned long LONG;
typedef signed char 	S8;

#ifndef TRUE
#define FALSE 0
#define TRUE (!FALSE)
#endif

#define RETURN_NORMAL (bit) 0
#define RETURN_ERROR (bit) 1

#define INTERRUPT_Timer_0_Overflow 1
#define INTERRUPT_Timer_1_Overflow 3

//#define INTERRUPT_Timer_2_Overflow 5

#define INTERRUPT_EXTERNAL_0 0
#define INTERRUPT_EXTERNAL_1 2
#define INTERRUPT_UART_Rx_Tx 4
#define INTERRUPT_UART1_Rx_Tx 8

#define ERROR_SCH_TOO_MANY_TASKS (1)
#define ERROR_SCH_CANNOT_DELETE_TASK (2)

extern volatile bit key_update_flag ;

#endif

2.SCH.h和SCH.cpp

SCH.h:

#ifndef SCH_H
#define SCH_H

void	SCH_Init_T0(void) ;
void	SCH_Start(void) ;
void 	SCH_Report_Status(void);
void	SCH_Dispatch_Tasks(void);

U8	SCH_Add_Task(void (code *)(void), U16, U16, bit);  
bit	SCH_Delete_Task(U8);


typedef idata struct 
{

   void (code * pTask)(void);  

   U16 Delay;          
   U16 Period;   
   U8 RunMe;       
   U8 Co_op; 
       
} sTaskH; 



#define SCH_MAX_TASKS   (4)   

#endif

SCH.cpp:

#include"include/main.h"
#include"include/sch.h"

#define TIME_OUT_ERROR 0x78

sTaskH SCH_tasks_G[SCH_MAX_TASKS];

U8 Error_code_G = 0;

static void SCH_Manual_Timer0_Reload(void);

extern bit frame_ok;
extern U8 timeout;

void SCH_Init_T0(void) 
{
    U8 i;

	for (i = 0; i < SCH_MAX_TASKS; i++) 
	{
		SCH_Delete_Task(i);
	} 
   Error_code_G = 0; 
   TMOD &= 0xF0; 
   TMOD |= 0x01; 
   SCH_Manual_Timer0_Reload();
   ET0  = 1;
}


void SCH_Start(void) 
{
   EA = 1;
}


void SCH_Update(void) interrupt INTERRUPT_Timer_0_Overflow  
{
	U8 Index;
	
	SCH_Manual_Timer0_Reload();
	for (Index = 0; Index < SCH_MAX_TASKS; Index++)
	{
		if (SCH_tasks_G[Index].pTask)
		{
			if (SCH_tasks_G[Index].Delay == 0)
			{
				if (SCH_tasks_G[Index].Co_op)
				{
					SCH_tasks_G[Index].RunMe += 1;  
				}
				else
				{
					(*SCH_tasks_G[Index].pTask)();  

					SCH_tasks_G[Index].RunMe = 0;   

					if (SCH_tasks_G[Index].Period == 0)
					{
						SCH_tasks_G[Index].pTask  = 0;
					}
				}

				if (SCH_tasks_G[Index].Period)
				{
					SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;
				}
            }
			else
			{
				SCH_tasks_G[Index].Delay -= 1;
			}
		}
		
		        
	}
	if(timeout)
	{
		timeout--;
		if(timeout == 0)
		{
			frame_ok = 1;	
		}
	}
     
} 

//5ms  timebase
void SCH_Manual_Timer0_Reload()
{
   
   TR0 = 0;
//   TH0  = 0xEE;		//5ms
//   TL0  = 0x00;
   TH0  = 0xf2;	        //1ms
   TL0  = 0x6c;				  	
   TR0  = 1;
   
}

void SCH_Dispatch_Tasks(void) 
{
	U8 Index;

	for (Index = 0; Index < SCH_MAX_TASKS; Index++)
	{
	
		if ((SCH_tasks_G[Index].Co_op) && (SCH_tasks_G[Index].RunMe > 0)) 
		{
			(*SCH_tasks_G[Index].pTask)();  
			SCH_tasks_G[Index].RunMe -= 1;   

			if (SCH_tasks_G[Index].Period == 0)
			{
				SCH_tasks_G[Index].pTask = 0;
			}
		}
		
	}
	//SCH_Report_Status();  

   
	//SCH_Go_To_Sleep();          
}


U8 SCH_Add_Task(void (code* Fn_p)(), // Task function pointer
                   U16	Del,    // Num ticks 'til task first runs 
                   U16	Per,    // Num ticks between repeat runs
                   bit	Co_op)  // Co_op / pre_emp
{
   U8 Index = 0;
   
	while ((SCH_tasks_G[Index].pTask != 0) && (Index < SCH_MAX_TASKS))
	{
		Index++;
	} 
	if (Index == SCH_MAX_TASKS)
	{
      
		Error_code_G = ERROR_SCH_TOO_MANY_TASKS;
		return SCH_MAX_TASKS;  
	}

	SCH_tasks_G[Index].pTask = Fn_p;
     
	SCH_tasks_G[Index].Delay  = Del;
	SCH_tasks_G[Index].Period = Per;
	SCH_tasks_G[Index].Co_op = Co_op;

	SCH_tasks_G[Index].RunMe  = 0;

	return Index; // return position of task (to allow later deletion)
}


bit SCH_Delete_Task(U8 Task_index) 
{
	bit Return_code;

	if (SCH_tasks_G[Task_index].pTask == 0)
	{
      
		Error_code_G = ERROR_SCH_CANNOT_DELETE_TASK;

		Return_code = RETURN_ERROR;
	}
	else
	{
		Return_code = RETURN_NORMAL;
	}      
   
	SCH_tasks_G[Task_index].pTask   = 0;
	SCH_tasks_G[Task_index].Delay   = 0;
	SCH_tasks_G[Task_index].Period  = 0;
	SCH_tasks_G[Task_index].RunMe   = 0;

	return Return_code;       // return status
}


/*void SCH_Report_Status(void)
   {
#ifdef SCH_REPORT_ERRORS
   // ONLY APPLIES IF WE ARE REPORTING ERRORS
   // Check for a new error code
   if (Error_code_G != Last_error_code_G)
      {
      // Negative logic on LEDs assumed
      Error_port = 255 - Error_code_G;
      
      Last_error_code_G = Error_code_G;

      if (Error_code_G != 0)
         {
         Error_tick_count_G = 60000;
         }
      else
         {
         Error_tick_count_G = 0;
         }
      }
   else
      {
      if (Error_tick_count_G != 0)
         {
         if (--Error_tick_count_G == 0)
            {
            Error_code_G = 0; // Reset error code
            }
         }
      }
#endif
   }



/*void SCH_Go_To_Sleep()
   {
   PCON |= 0x01;    // Enter idle mode (generic 8051 version)

   // Entering idle mode requires TWO consecutive instructions 
   // on 80c515 / 80c505 - to avoid accidental triggering
   //PCON |= 0x01;    // Enter idle mode (#1)
   //PCON |= 0x20;    // Enter idle mode (#2)
   }

*/

3.Uart.cpp与Uart.h

uart.h:

#ifndef UART_H
#define UART_H

#define RECV_BUFFER_LENGTH 15


#define TRAN_BUFFER_LENGTH 20

typedef idata struct
{
	U8 Out_written_index_G;
	U8 Out_waiting_index_G;
	U8 Tran_buffer[TRAN_BUFFER_LENGTH];
 	U8 status;
	
}UART_TRAN;

typedef idata struct
{
	U8 In_read_index_G;
	U8 In_waiting_index_G;
	U8 Recv_buffer[RECV_BUFFER_LENGTH];
 	U8 status;
	
}UART_RECV;

typedef union
{
	U16  item; 
	struct
	{
		U8   high;
		U8   low;
	}convert;
	
	
}CHAR_CONVERT;

void uart0_init(U16 BAUD_RATE);
void Send_Char(U8 CHARACTER);
void Uart_Update();
void Write_Char_To_Buffer(U8 CHARACTER) ;
void Write_String_To_Buffer(U8*  STR_PTR);

#endif

uart.cpp:

#include"include/main.h"
#include"include/uart.h"
#include"include/sch.h"
#include"include/modbus.h"
#include 
#define ERROR_USART_WRITE_CHAR 0x55

volatile UART_TRAN uart_tran_data;// _at_ 0xc0;
volatile UART_RECV uart_recv_data;// _at_ 0x80;

extern U8 Error_code_G;

bit frame_ok = 0;
U8 timeout;

void uart0_init(U16 BAUD_RATE)
{
	PCON &= 0x7F;   
	SCON = 0x50;
	TMOD |= 0x20;   
	TH1 = (256 - (U8)((((LONG)OSC_FREQ / 100) * 3125) 
            / ((LONG) BAUD_RATE * OSC_PER_INST * 1000)));
	TL1 = TH1;  
	TR1 = 1;   
	ES = 1;
}

void Send_Char(U8 CHARACTER)
{

	TI=0;
	SBUF=CHARACTER;
	while(TI==0);
	TI=0;
  
}
void Uart_Update()
{
 	if(frame_ok)
	{
		frame_Parse();
		uart_recv_data.In_waiting_index_G = 0;
		frame_ok =0;
	}
	if (uart_tran_data.Out_written_index_G < uart_tran_data.Out_waiting_index_G)
    {
      	Send_Char(uart_tran_data.Tran_buffer[uart_tran_data.Out_written_index_G]);     
      	uart_tran_data.Out_written_index_G++;
    }
	else
    {
      uart_tran_data.Out_waiting_index_G = 0;
      uart_tran_data.Out_written_index_G = 0;
    }
	
	

}

void Uart0RxdInterrupt(void) interrupt INTERRUPT_UART_Rx_Tx using 2
{
	U8 temp;
	if(RI)
    {
		RI = 0;
 		temp = SBUF;
	//	Send_Char(temp);
        if(frame_ok==0)    
        {
			if(uart_recv_data.In_waiting_index_G == uart_recv_data.In_read_index_G)
			{
				uart_recv_data.In_waiting_index_G =	0;
				uart_recv_data.In_read_index_G = 0;	
			}
            if(uart_recv_data.In_waiting_index_G

4.modbus.cpp与modbus.h

modbus.cpp:

#include"include/main.h"
#include"include/uart.h"
#include"include/modbus.h"

code U8 auchCRCHi[] = { 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 
} ; 
/* CRCµÍλ×Ö½ÚÖµ±í*/ 
code U8 auchCRCLo[] = { 
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 
0x43, 0x83, 0x41, 0x81, 0x80, 0x40 
};

#define LACAL_ADRR 0x01

extern UART_TRAN uart_tran_data;
extern UART_RECV uart_recv_data;

U8 Coil_Status_TBL[5] = {0x55,0x55,0x55,0x55,0x55}; //40¸öÏßȦ £¬·ÖΪ5×é
U8 Switch_Status_TBL[5] = {0x00,0x00,0x00,0x00,0x00};//40¸öÀëÉ¢¿ª¹Ø£¬·ÖΪ5×é
U8 Coil_Output_TBL[5] = {0x00,0x00,0x00,0x00,0x00};

U16 Crc16(U8 *buf, U16 DataLen) 
{ 
	U8 uchCRCHi = 0xFF ; /* ¸ßCRC×Ö½Ú³õʼ»¯ */ 
	U8 uchCRCLo = 0xFF ; /* µÍCRC ×Ö½Ú³õʼ»¯ */ 
	U16 uIndex ; /* CRCÑ­»·ÖеÄË÷Òý */ 
	while (DataLen--) /* ´«ÊäÏûÏ¢»º³åÇø */ 
	{ 
		uIndex = uchCRCHi ^ *buf++ ; /* ¼ÆËãCRC */ 
		uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ; 
		uchCRCLo = auchCRCLo[uIndex] ; 
	} 
	return (uchCRCHi << 8 | uchCRCLo) ; 
}


bit frame_Parse()
{
	CHAR_CONVERT Crc;
	
	U8 Lacal_Adrr;
	U8 Fun_Code;
	Crc.item = Make_word(uart_recv_data.Recv_buffer[uart_recv_data.In_waiting_index_G-2],\
						 uart_recv_data.Recv_buffer[uart_recv_data.In_waiting_index_G-1]);
	
	if(Crc.item != Crc16(uart_recv_data.Recv_buffer,uart_recv_data.In_waiting_index_G-2))
	{
		return FALSE;
	}
	
	Lacal_Adrr = uart_recv_data.Recv_buffer[0];
	Fun_Code = uart_recv_data.Recv_buffer[1];
	
	if(Lacal_Adrr != LACAL_ADRR&&Lacal_Adrr!=0)
	{
		return FALSE;
	}
	if(Lacal_Adrr == LACAL_ADRR)
	{
		Write_Char_To_Buffer(LACAL_ADRR);
		switch(Fun_Code)
		{
			case 1:
				{
					Read_coil_status();	
				}
				break;
			case 2:
				{
					Read_switch_status();
				}
				break;
			case 3:
				{
					Read_hold_register();
				}
				break;
			case 4:
				{
					Read_input_register();					
				}
				break;
			case 5:
				{
					force_set_coil();	
				}
				break;
			case 6:
				{
					pre_single_register();
				}
				break;
			case 15:
				{
					Set_multi_coils();
				}
				break;
			case 16:
				{
					Pre_set_multi_register();
				}
				break;
			default:
				break;
		}		
	}
	
			
}

U16 Make_word(U8 a,U8 b)
{
    CHAR_CONVERT temp;
	
    temp.convert.high=a;    
    temp.convert.low=b;
    return (temp.item);
	    
}

////////////////////////////////////////////////////////////////////////////////////
void read_coil_status_value()
{
	U8 value;
	P2 = 0xff;
	value = P2;
	Coil_Status_TBL[0] = value;
		
}
void Read_coil_status()
{
	U16 address;
	U8 count;
	U8 coil_status;
	U16 temp_crc;
	U8 i;
	
	Write_Char_To_Buffer(uart_recv_data.Recv_buffer[1]);
	
	address = (uart_recv_data.Recv_buffer[2]<<8)+uart_recv_data.Recv_buffer[3];
	count = (uart_recv_data.Recv_buffer[4]<<8)+uart_recv_data.Recv_buffer[5];
	if(count%8 != 0)
	{
		count = count/8 + 1;
	}
	else
	{
		count = count/8;
	}
	Write_Char_To_Buffer(count);
	
	read_coil_status_value();
	
	for(i = 0;i < count; i++)
	{
		coil_status = Coil_Status_TBL[address + i];
		Write_Char_To_Buffer(coil_status);	
	}
	temp_crc = Crc16(uart_tran_data.Tran_buffer,uart_tran_data.Out_waiting_index_G);
	Write_Char_To_Buffer((U8)(temp_crc>>8));
	Write_Char_To_Buffer((U8)(temp_crc));
				
}


/////////////////////////////////////////////////////////////////////////////////

void read_switch_status_value()
{
	U8 value;
	P2 = 0xff;
	value = P1;
	Switch_Status_TBL[0] = value;
		
}

void Read_switch_status()
{
	U16 address;
	U8 count;
	U8 switch_status;
	U16 temp_crc;
	U8 i;
	
	Write_Char_To_Buffer(uart_recv_data.Recv_buffer[1]);
	
	address = (uart_recv_data.Recv_buffer[2]<<8)+uart_recv_data.Recv_buffer[3];
	count = (uart_recv_data.Recv_buffer[4]<<8)+uart_recv_data.Recv_buffer[5];
	if(count%8 != 0)
	{
		count = count/8 + 1;
	}
	else
	{
		count = count/8;
	}
	Write_Char_To_Buffer(count);
	
	read_switch_status_value();
	
	for(i = 0;i < count; i++)
	{
		switch_status = Switch_Status_TBL[address + i];
		Write_Char_To_Buffer(switch_status);	
	}
	temp_crc = Crc16(uart_tran_data.Tran_buffer,uart_tran_data.Out_waiting_index_G);
	Write_Char_To_Buffer((U8)(temp_crc>>8));
	Write_Char_To_Buffer((U8)(temp_crc));	
}


//////////////////////////////////////////////////////////////////////////////////////
void Read_hold_register()
{
	
}
//////////////////////////////////////////////////////////////////////////////////////
void Read_input_register()
{

}
//////////////////////////////////////////////////////////////////////////////////////
void force_set_coil()
{
	
}
//////////////////////////////////////////////////////////////////////////////////////
void pre_single_register()
{

}
//////////////////////////////////////////////////////////////////////////////////////

void Set_coil_output_value()
{
//¸ù¾Ý¾ßÌåÓ¦ÓÃÌí¼Ó´úÂë

	P0 = Coil_Output_TBL[0];
		
}

void Set_multi_coils()
{
	U16 address;
	U8 count;
	U16 temp_crc;
	U8 i;
	
	Write_Char_To_Buffer(uart_recv_data.Recv_buffer[1]);
	Write_Char_To_Buffer(uart_recv_data.Recv_buffer[2]);
	Write_Char_To_Buffer(uart_recv_data.Recv_buffer[3]);
	
	address = (uart_recv_data.Recv_buffer[2]<<8)+uart_recv_data.Recv_buffer[3];
	count = (uart_recv_data.Recv_buffer[4]<<8)+uart_recv_data.Recv_buffer[5];
	if(count%8 != 0)
	{
		count = count/8 + 1;
	}
	else
	{
		count = count/8;
	}
	Write_Char_To_Buffer(uart_recv_data.Recv_buffer[4]);
	Write_Char_To_Buffer(uart_recv_data.Recv_buffer[5]);
		
	for(i = 0;i < count; i++)
	{
	    Coil_Output_TBL[address + i] =uart_recv_data.Recv_buffer[7+i] ;	
	}
	temp_crc = Crc16(uart_tran_data.Tran_buffer,uart_tran_data.Out_waiting_index_G);
	Write_Char_To_Buffer((U8)(temp_crc>>8));
	Write_Char_To_Buffer((U8)(temp_crc));
	Set_coil_output_value();
			
}
///////////////////////////////////////////////////////////////////////////////////////
void Pre_set_multi_register()
{
	
}

modbus.h:

#ifndef MODBUS_H
#define MODBUS_H

U16 Crc16(U8 *buf, U16 DataLen);
bit frame_Parse();
U16 Make_word(U8 a,U8 b);
void Read_coil_status();
void Read_switch_status();
void Read_hold_register();
void Read_input_register();
void force_set_coil();
void pre_single_register();
void Set_multi_coils();
void Pre_set_multi_register();


#endif

 

 

 

 

你可能感兴趣的:(嵌入式)