阿里物联网

本文提供了RT-Thread操作系统的开发资料,包括hmac_sha1加密算法的实现代码,以及MODSBUS通信模块的详细源码解析。深入探讨了SHA1算法的内部结构,MODSBUS的帧格式和命令解析过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

rt-therad 开发资料:

https://www.rt-thread.org/document/site/submodules/ali-iotkit/docs/principle/

 

hmac_sha1 加密算法

#include <rtthread.h>
#include <rtdevice.h>

#define MAX_MESSAGE_LENGTH 4096

unsigned long int ft(
                    int t,
                    unsigned long int x,
                    unsigned long int y,
                    unsigned long int z
                    )
{
unsigned long int a,b,c;
 
    if (t < 20)
    {
        a = x & y;
        b = (~x) & z;
        c = a ^ b;
    }
    else if (t < 40)
    {
        c = x ^ y ^ z;
    }
    else if (t < 60)
    {
        a = x & y;
        b = a ^ (x & z);
        c = b ^ (y & z);
    }
    else if (t < 80)
    {
        c = (x ^ y) ^ z;
    }
 
    return c;
}

unsigned long int k(int t)
{
unsigned long int c;
 
    if (t < 20)
    {
        c = 0x5a827999;
    }
    else if (t < 40)
    {
        c = 0x6ed9eba1;
    }
    else if (t < 60)
    {
        c = 0x8f1bbcdc;
    }
    else if (t < 80)
    {
        c = 0xca62c1d6;
    }
 
    return c;
}

unsigned long int rotl(int bits, unsigned long int a)
{
unsigned long int c,d,e,f,g;
    c = (0x0001 << (32-bits))-1;
    d = ~c;
 
    e = (a & c) << bits;
    f = (a & d) >> (32 - bits);
 
    g = e | f;
 
    return (g & 0xffffffff );
 
}

void sha1   (
            unsigned char *message,
            int message_length,
            unsigned char *digest
            )
{
int i;
int num_blocks;
int block_remainder;
int padded_length;
 
unsigned long int l;
unsigned long int t;
unsigned long int h[5];
unsigned long int a,b,c,d,e;
unsigned long int w[80];
unsigned long int temp;
 
    /* Calculate the number of 512 bit blocks */
 
    padded_length = message_length + 8; /* Add length for l */
    padded_length = padded_length + 1; /* Add the 0x01 bit postfix */
 
    l = message_length * 8;
 
    num_blocks = padded_length / 64;
    block_remainder = padded_length % 64;
 
 
    if (block_remainder > 0)
    {
        num_blocks++;
    }
 
    padded_length = padded_length + (64 - block_remainder);
 
     /* clear the padding field */
    for (i = message_length; i < (num_blocks * 64); i++)
    {
        message[i] = 0x00;           
    }
 
    /* insert b1 padding bit */
    message[message_length] = 0x80;
    
    /* Insert l */
    message[(num_blocks*64)-1] = (unsigned char)( l        & 0xff);
    message[(num_blocks*64)-2] = (unsigned char)((l >> 8)  & 0xff);
    message[(num_blocks*64)-3] = (unsigned char)((l >> 16) & 0xff);
    message[(num_blocks*64)-4] = (unsigned char)((l >> 24) & 0xff);
 
    /* Set initial hash state */
    h[0] = 0x67452301;
    h[1] = 0xefcdab89;
    h[2] = 0x98badcfe;
    h[3] = 0x10325476;
    h[4] = 0xc3d2e1f0;
 

    for (i = 0; i < num_blocks; i++)
    {
        /* Prepare the message schedule */
        for (t=0; t < 80; t++)
        {
            if (t < 16)
            {
                w[t]  = (256*256*256) * message[(i*64)+(t*4)];
                w[t] += (256*256    ) * message[(i*64)+(t*4) + 1];
                w[t] += (256        ) * message[(i*64)+(t*4) + 2];
                w[t] +=                 message[(i*64)+(t*4) + 3];
            }
            else if (t < 80)
            {
                w[t] = rotl(1,(w[t-3] ^ w[t-8] ^ w[t-14] ^ w[t-16]));
            }
        }
 
        /* Initialize the five working variables */
        a = h[0];
        b = h[1];
        c = h[2];
        d = h[3];
        e = h[4];
 
        /* iterate a-e 80 times */
 
        for (t = 0; t < 80; t++)
        {
            temp = (rotl(5,a) + ft(t,b,c,d)) & 0xffffffff;
            temp = (temp + e) & 0xffffffff;
            temp = (temp + k(t)) & 0xffffffff;
            temp = (temp + w[t]) & 0xffffffff;
            e = d;
            d = c;
            c = rotl(30,b);
            b = a;
            a = temp;
        }
 
        /* compute the ith intermediate hash value */
        h[0] = (a + h[0]) & 0xffffffff;
        h[1] = (b + h[1]) & 0xffffffff;
        h[2] = (c + h[2]) & 0xffffffff;
        h[3] = (d + h[3]) & 0xffffffff;
        h[4] = (e + h[4]) & 0xffffffff;
    }
 
    digest[3]  = (unsigned char) ( h[0]       & 0xff);
    digest[2]  = (unsigned char) ((h[0] >> 8) & 0xff);
    digest[1]  = (unsigned char) ((h[0] >> 16) & 0xff);
    digest[0]  = (unsigned char) ((h[0] >> 24) & 0xff);
 
    digest[7]  = (unsigned char) ( h[1]       & 0xff);
    digest[6]  = (unsigned char) ((h[1] >> 8) & 0xff);
    digest[5]  = (unsigned char) ((h[1] >> 16) & 0xff);
    digest[4]  = (unsigned char) ((h[1] >> 24) & 0xff);
 
    digest[11]  = (unsigned char) ( h[2]       & 0xff);
    digest[10]  = (unsigned char) ((h[2] >> 8) & 0xff);
    digest[9] = (unsigned char) ((h[2] >> 16) & 0xff);
    digest[8] = (unsigned char) ((h[2] >> 24) & 0xff);
 
    digest[15] = (unsigned char) ( h[3]       & 0xff);
    digest[14] = (unsigned char) ((h[3] >> 8) & 0xff);
    digest[13] = (unsigned char) ((h[3] >> 16) & 0xff);
    digest[12] = (unsigned char) ((h[3] >> 24) & 0xff);
 
    digest[19] = (unsigned char) ( h[4]       & 0xff);
    digest[18] = (unsigned char) ((h[4] >> 8) & 0xff);
    digest[17] = (unsigned char) ((h[4] >> 16) & 0xff);
    digest[16] = (unsigned char) ((h[4] >> 24) & 0xff);
}
 
void chex2str( unsigned char *hex, int len, char *str )
{
#define VAL2HEX( a )	( ( a ) < 10 ? ( ( a ) + '0' ) : ( ( a ) - 10 + 'A' ) )
	int idx;

	for( idx = 0; idx < len; idx++ ){	
		str[ idx * 2 ] = VAL2HEX( ( hex[ idx ] & 0xF0 ) >> 4 );
		str[ idx * 2 + 1 ] = VAL2HEX( hex[ idx ] & 0x0F );
	}
}

void hmac_sha1(
                unsigned char *key,
                int key_length,
                unsigned char *data,
                int data_length,
                unsigned char *digest
                )
 
{
    int b = 64; /* blocksize */
    unsigned char ipad = 0x36;
 
    unsigned char opad = 0x5c;
 
    unsigned char k0[64];
    unsigned char k0xorIpad[64];
    unsigned char step7data[64];
    unsigned char step5data[MAX_MESSAGE_LENGTH+128];
    unsigned char step8data[64+20];
    int i;
 
    for (i=0; i<64; i++)
    {
        k0[i] = 0x00;
    }
 
 
 
    if (key_length != b)    /* Step 1 */
    {
        /* Step 2 */
        if (key_length > b)      
        {
            sha1(key, key_length, digest);
            for (i=0;i<20;i++)
            {
                k0[i]=digest[i];
            }
        }
        else if (key_length < b)  /* Step 3 */
        {
            for (i=0; i<key_length; i++)
            {
                k0[i] = key[i];
            }
        }
    }
    else
    {
        for (i=0;i<b;i++)
        {
            k0[i] = key[i];
        }
    }

    /* Step 4 */
    for (i=0; i<64; i++)
    {
        k0xorIpad[i] = k0[i] ^ ipad;
    }

    /* Step 5 */
    for (i=0; i<64; i++)
    {
        step5data[i] = k0xorIpad[i];
    }
    for (i=0;i<data_length;i++)
    {
        step5data[i+64] = data[i];
    }

 
    /* Step 6 */
    sha1(step5data, data_length+b, digest);
 
 
    /* Step 7 */
    for (i=0; i<64; i++)
    {
        step7data[i] = k0[i] ^ opad;
    }
 
    /* Step 8 */
    for (i=0;i<64;i++)
    {
        step8data[i] = step7data[i];
    }
    for (i=0;i<20;i++)
    {
        step8data[i+64] = digest[i];
    }
 
    /* Step 9 */
    sha1(step8data, b+20, digest);
}
 

rt_uint8_t PassWord[21];
char PassWord_hexstr[64];
int hmac_sha1_init(void)
{
  rt_uint8_t count;
	rt_kprintf("start hmac_sha1 thread\r\n");
	hmac_sha1("secret",rt_strlen("secret"),"clientId12345deviceNamedeviceproductKeypktimestamp789",\
	rt_strlen("clientId12345deviceNamedeviceproductKeypktimestamp789"),PassWord);
	
	chex2str(PassWord,20,PassWord_hexstr);
	rt_kprintf("pass word is: %s\r\n",PassWord_hexstr);
	
	
	for(count = 0 ; count < 10 ;count++)
	{       
			rt_kprintf("led on, count : %d\r\n", count);
			rt_thread_mdelay(500);
	
			rt_kprintf("led off\r\n");
			rt_thread_mdelay(500);
	}	
	return 0;
}
MSH_CMD_EXPORT(hmac_sha1_init, RT-Thread hmac_sha1 sample);

modbus_host:

/*
*********************************************************************************************************
*
*	Ä£¿éÃû³Æ : MODSBUSͨÐųÌÐò £¨Ö÷»ú£©
*	ÎļþÃû³Æ : modbus_host.c
*	°æ    ±¾ : V1.4
*	˵    Ã÷ : ÎÞÏßͨÐųÌÐò¡£Í¨ÐÅЭÒé»ùÓÚMODBUS
*	Ð޸ļǼ :
*		°æ±¾ºÅ  ÈÕÆÚ        ×÷Õß    ˵Ã÷
*       V1.4   2015-11-28 ÐÞ¸ÄЭÒé
*
*	Copyright (C), 2015-2016, °²¸»À³µç×Ó www.armfly.com
*
*********************************************************************************************************
*/

#include <hsf.h>
#include <user.h>

#include "modbus_host.h"

#define TIMEOUT		900		/* ½ÓÊÕÃüÁʱʱ¼ä, µ¥Î»ms */
#define NUM			1		/* Ñ­»··¢ËÍ´ÎÊý */

#define MB_TIMER_ID		(1)//modbus ³¬Ê±½ÓÊÕ ¶¨Ê±Æ÷
#define TimeOut_ID 		(2) //modbus ³¬Ê± ´¦Àí±ê־λ

#define uart_receive_mb 0x01 //modbus Êý¾Ý


/* ±£´æÃ¿¸ö´Ó»úµÄ¼ÆÊýÆ÷Öµ */

MODH_T g_tModH;
uint8_t g_modh_timeout = 0;
uint8_t uart_receive_flag;//½ÓÊÕÊý¾Ý ±ê־λÅжϡ£

static void MODH_RxTimeOut(void);
static void MODH_AnalyzeApp(void);

USER_FUNC static void MODH_Read_01H(void);
USER_FUNC static void MODH_Read_02H(void);
USER_FUNC static void MODH_Read_03H(void);
USER_FUNC static void MODH_Read_04H(void);
USER_FUNC static void MODH_Read_05H(void);
USER_FUNC static void MODH_Read_06H(void);
USER_FUNC static void MODH_Read_10H(void);

VAR_T g_tVar;
hftimer_handle_t mb_receive_timer = NULL,mb_receive_timeout_timer;//modbus ½ÓÊÕ ³¬Ê±¶¨Ê±Æ÷

USER_FUNC extern void uart_printf(char *buf, uint32_t len);
USER_FUNC extern void uart_SendBuf(uint8_t *_buf, uint16_t _len);
USER_FUNC extern uint16_t CRC16_Modbus(uint8_t *_pBuf, uint16_t _usLen);
USER_FUNC extern uint16_t BEBufToUint16(uint8_t *_pBuf);
void bsp_Idle(void)
{
	MODH_Poll();
}
void USER_FUNC test_timer_callback( hftimer_handle_t htimer )
{
		if(hftimer_get_timer_id(htimer)==MB_TIMER_ID)
		{
//			g_modh_timeout = 1;
//      MODH_RxTimeOut();
			hftimer_start(mb_receive_timeout_timer);
			u_printf("create timer 1 fail\n");		
		}
		
		if(hftimer_get_timer_id(htimer)==TimeOut_ID)
		{
			if(uart_receive_flag & uart_receive_mb)
			{
				uart_receive_flag ^= uart_receive_mb;//Çå±ê־λ
			}
		}		
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_SendPacket
*	¹¦ÄÜ˵Ã÷: ·¢ËÍÊý¾Ý°ü COM1¿Ú
*	ÐÎ    ²Î: _buf : Êý¾Ý»º³åÇø
*			  _len : Êý¾Ý³¤¶È
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
void MODH_SendPacket(uint8_t *_buf, uint16_t _len)
{
	static bool mb_timer_flag = 0;
	if(mb_timer_flag == 0)
	{
		mb_timer_flag = 1;
		//´´½¨ ¶¨Ê±Æ÷ 
		if((mb_receive_timer = hftimer_create("TEST-TIMER",200, false,MB_TIMER_ID,test_timer_callback,0))==NULL)
		{
			u_printf("create timer 1 fail\n");
		}
		//´´½¨ ¶¨Ê±Æ÷ 
		if((mb_receive_timeout_timer = hftimer_create("TEST-TIMER",1000, false,TimeOut_ID,test_timer_callback,0))==NULL)
		{
			u_printf("create timer 1 fail\n");
		}		
	}
	else
	{
		
	}
	g_modh_timeout = 0;//Çå 0 
	//¿ªÆôÒ»¸ö Èí¼þ¶¨Ê±Æ÷
	u_printf("\nsend mb cmd->:");//´òÓ¡´®¿ÚÊý¾Ý
	uart_printf((char *)_buf, _len);//´òÓ¡´®¿ÚÊý¾Ý
	uart_SendBuf(_buf, _len);
	hftimer_start(mb_receive_timer);
	uart_receive_flag |= uart_receive_mb;
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_SendAckWithCRC
*	¹¦ÄÜ˵Ã÷: ·¢ËÍÓ¦´ð,×Ô¶¯¼ÓCRC.  
*	ÐÎ    ²Î: ÎÞ¡£·¢ËÍÊý¾ÝÔÚ g_tModH.TxBuf[], [g_tModH.TxCount
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
static void MODH_SendAckWithCRC(void)
{
	uint16_t crc;
	
	crc = CRC16_Modbus(g_tModH.TxBuf, g_tModH.TxCount);
	g_tModH.TxBuf[g_tModH.TxCount++] = crc >> 8;
	g_tModH.TxBuf[g_tModH.TxCount++] = crc;	
	MODH_SendPacket(g_tModH.TxBuf, g_tModH.TxCount);
	
#if 0	/* ´Ë²¿·ÖΪÁË´®¿Ú´òÓ¡½á¹û,ʵ¼ÊÔËÓÃÖпɲ»Òª */
	g_tPrint.Txlen = g_tModH.TxCount;
	memcpy(g_tPrint.TxBuf, g_tModH.TxBuf, g_tModH.TxCount);
#endif
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_AnalyzeApp
*	¹¦ÄÜ˵Ã÷: ·ÖÎöÓ¦ÓòãЭÒé¡£´¦ÀíÓ¦´ð¡£
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
static void MODH_AnalyzeApp(void)
{	
	switch (g_tModH.RxBuf[1])			/* µÚ2¸ö×Ö½Ú ¹¦ÄÜÂë */
	{
		
		case 0x03:	/* ¶ÁÈ¡±£³Ö¼Ä´æÆ÷ ÔÚÒ»¸ö»ò¶à¸ö±£³Ö¼Ä´æÆ÷ÖÐÈ¡µÃµ±Ç°µÄ¶þ½øÖÆÖµ */
			MODH_Read_03H();
			break;		
		
		case 0x01:	/* ¶ÁÈ¡ÏßȦ״̬ */
			MODH_Read_01H();
			break;

		case 0x02:	/* ¶ÁÈ¡ÊäÈë״̬ */
			MODH_Read_02H();
			break;

		case 0x04:	/* ¶ÁÈ¡ÊäÈë¼Ä´æÆ÷ */
			MODH_Read_04H();
			break;

		case 0x05:	/* Ç¿ÖÆµ¥ÏßȦ */
			MODH_Read_05H();
			break;

		case 0x06:	/* дµ¥¸ö¼Ä´æÆ÷ */
			MODH_Read_06H();
			break;		

		case 0x10:	/* д¶à¸ö¼Ä´æÆ÷ */
			MODH_Read_10H();
			break;
		
		default:
			
			break;
	}
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Send01H
*	¹¦ÄÜ˵Ã÷: ·¢ËÍ01HÖ¸Á²éѯ1¸ö»ò¶à¸ö±£³Ö¼Ä´æÆ÷
*	ÐÎ    ²Î: _addr : ´ÓÕ¾µØÖ·
*			  _reg : ¼Ä´æÆ÷±àºÅ
*			  _num : ¼Ä´æÆ÷¸öÊý
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
void MODH_Send01H(uint8_t _addr, uint16_t _reg, uint16_t _num)
{
	g_tModH.TxCount = 0;
	g_tModH.TxBuf[g_tModH.TxCount++] = _addr;		/* ´ÓÕ¾µØÖ· */
	g_tModH.TxBuf[g_tModH.TxCount++] = 0x01;		/* ¹¦ÄÜÂë */	
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg >> 8;	/* ¼Ä´æÆ÷±àºÅ ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg;		/* ¼Ä´æÆ÷±àºÅ µÍ×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _num >> 8;	/* ¼Ä´æÆ÷¸öÊý ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _num;		/* ¼Ä´æÆ÷¸öÊý µÍ×Ö½Ú */
	
	MODH_SendAckWithCRC();		/* ·¢ËÍÊý¾Ý£¬×Ô¶¯¼ÓCRC */
	g_tModH.fAck01H = 0;		/* Çå½ÓÊÕ±êÖ¾ */
	g_tModH.RegNum = _num;		/* ¼Ä´æÆ÷¸öÊý */
	g_tModH.Reg01H = _reg;		/* ±£´æ03HÖ¸ÁîÖеļĴæÆ÷µØÖ·£¬·½±ã¶ÔÓ¦´ðÊý¾Ý½øÐзÖÀà */	
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Send02H
*	¹¦ÄÜ˵Ã÷: ·¢ËÍ02HÖ¸Á¶ÁÀëÉ¢ÊäÈë¼Ä´æÆ÷
*	ÐÎ    ²Î: _addr : ´ÓÕ¾µØÖ·
*			  _reg : ¼Ä´æÆ÷±àºÅ
*			  _num : ¼Ä´æÆ÷¸öÊý
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
void MODH_Send02H(uint8_t _addr, uint16_t _reg, uint16_t _num)
{
	g_tModH.TxCount = 0;
	g_tModH.TxBuf[g_tModH.TxCount++] = _addr;		/* ´ÓÕ¾µØÖ· */
	g_tModH.TxBuf[g_tModH.TxCount++] = 0x02;		/* ¹¦ÄÜÂë */	
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg >> 8;	/* ¼Ä´æÆ÷±àºÅ ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg;		/* ¼Ä´æÆ÷±àºÅ µÍ×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _num >> 8;	/* ¼Ä´æÆ÷¸öÊý ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _num;		/* ¼Ä´æÆ÷¸öÊý µÍ×Ö½Ú */
	
	MODH_SendAckWithCRC();		/* ·¢ËÍÊý¾Ý£¬×Ô¶¯¼ÓCRC */
	g_tModH.fAck02H = 0;		/* Çå½ÓÊÕ±êÖ¾ */
	g_tModH.RegNum = _num;		/* ¼Ä´æÆ÷¸öÊý */
	g_tModH.Reg02H = _reg;		/* ±£´æ03HÖ¸ÁîÖеļĴæÆ÷µØÖ·£¬·½±ã¶ÔÓ¦´ðÊý¾Ý½øÐзÖÀà */	
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Send03H
*	¹¦ÄÜ˵Ã÷: ·¢ËÍ03HÖ¸Á²éѯ1¸ö»ò¶à¸ö±£³Ö¼Ä´æÆ÷
*	ÐÎ    ²Î: _addr : ´ÓÕ¾µØÖ·
*			  _reg : ¼Ä´æÆ÷±àºÅ
*			  _num : ¼Ä´æÆ÷¸öÊý
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
void MODH_Send03H(uint8_t _addr, uint16_t _reg, uint16_t _num)
{
	g_tModH.TxCount = 0;
	g_tModH.TxBuf[g_tModH.TxCount++] = _addr;		/* ´ÓÕ¾µØÖ· */
	g_tModH.TxBuf[g_tModH.TxCount++] = 0x03;		/* ¹¦ÄÜÂë */	
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg >> 8;	/* ¼Ä´æÆ÷±àºÅ ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg;		/* ¼Ä´æÆ÷±àºÅ µÍ×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _num >> 8;	/* ¼Ä´æÆ÷¸öÊý ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _num;		/* ¼Ä´æÆ÷¸öÊý µÍ×Ö½Ú */
	
	MODH_SendAckWithCRC();		/* ·¢ËÍÊý¾Ý£¬×Ô¶¯¼ÓCRC */
	g_tModH.fAck03H = 0;		/* Çå½ÓÊÕ±êÖ¾ */
	g_tModH.RegNum = _num;		/* ¼Ä´æÆ÷¸öÊý */
	g_tModH.Reg03H = _reg;		/* ±£´æ03HÖ¸ÁîÖеļĴæÆ÷µØÖ·£¬·½±ã¶ÔÓ¦´ðÊý¾Ý½øÐзÖÀà */	
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Send04H
*	¹¦ÄÜ˵Ã÷: ·¢ËÍ04HÖ¸Á¶ÁÊäÈë¼Ä´æÆ÷
*	ÐÎ    ²Î: _addr : ´ÓÕ¾µØÖ·
*			  _reg : ¼Ä´æÆ÷±àºÅ
*			  _num : ¼Ä´æÆ÷¸öÊý
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
void MODH_Send04H(uint8_t _addr, uint16_t _reg, uint16_t _num)
{
	g_tModH.TxCount = 0;
	g_tModH.TxBuf[g_tModH.TxCount++] = _addr;		/* ´ÓÕ¾µØÖ· */
	g_tModH.TxBuf[g_tModH.TxCount++] = 0x04;		/* ¹¦ÄÜÂë */	
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg >> 8;	/* ¼Ä´æÆ÷±àºÅ ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg;		/* ¼Ä´æÆ÷±àºÅ µÍ×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _num >> 8;	/* ¼Ä´æÆ÷¸öÊý ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _num;		/* ¼Ä´æÆ÷¸öÊý µÍ×Ö½Ú */
	
	MODH_SendAckWithCRC();		/* ·¢ËÍÊý¾Ý£¬×Ô¶¯¼ÓCRC */
	g_tModH.fAck04H = 0;		/* Çå½ÓÊÕ±êÖ¾ */
	g_tModH.RegNum = _num;		/* ¼Ä´æÆ÷¸öÊý */
	g_tModH.Reg04H = _reg;		/* ±£´æ03HÖ¸ÁîÖеļĴæÆ÷µØÖ·£¬·½±ã¶ÔÓ¦´ðÊý¾Ý½øÐзÖÀà */	
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Send05H
*	¹¦ÄÜ˵Ã÷: ·¢ËÍ05HÖ¸ÁдǿÖõ¥ÏßȦ
*	ÐÎ    ²Î: _addr : ´ÓÕ¾µØÖ·
*			  _reg : ¼Ä´æÆ÷±àºÅ
*			  _value : ¼Ä´æÆ÷Öµ,2×Ö½Ú
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
void MODH_Send05H(uint8_t _addr, uint16_t _reg, uint16_t _value)
{
	g_tModH.TxCount = 0;
	g_tModH.TxBuf[g_tModH.TxCount++] = _addr;			/* ´ÓÕ¾µØÖ· */
	g_tModH.TxBuf[g_tModH.TxCount++] = 0x05;			/* ¹¦ÄÜÂë */	
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg >> 8;		/* ¼Ä´æÆ÷±àºÅ ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg;			/* ¼Ä´æÆ÷±àºÅ µÍ×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _value >> 8;		/* ¼Ä´æÆ÷Öµ ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _value;			/* ¼Ä´æÆ÷Öµ µÍ×Ö½Ú */
	
	MODH_SendAckWithCRC();		/* ·¢ËÍÊý¾Ý£¬×Ô¶¯¼ÓCRC */

	g_tModH.fAck05H = 0;		/* Èç¹ûÊÕµ½´Ó»úµÄÓ¦´ð£¬ÔòÕâ¸ö±êÖ¾»áÉèΪ1 */
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Send06H
*	¹¦ÄÜ˵Ã÷: ·¢ËÍ06HÖ¸Áд1¸ö±£³Ö¼Ä´æÆ÷
*	ÐÎ    ²Î: _addr : ´ÓÕ¾µØÖ·
*			  _reg : ¼Ä´æÆ÷±àºÅ
*			  _value : ¼Ä´æÆ÷Öµ,2×Ö½Ú
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
void MODH_Send06H(uint8_t _addr, uint16_t _reg, uint16_t _value)
{
	g_tModH.TxCount = 0;
	g_tModH.TxBuf[g_tModH.TxCount++] = _addr;			/* ´ÓÕ¾µØÖ· */
	g_tModH.TxBuf[g_tModH.TxCount++] = 0x06;			/* ¹¦ÄÜÂë */	
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg >> 8;		/* ¼Ä´æÆ÷±àºÅ ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg;			/* ¼Ä´æÆ÷±àºÅ µÍ×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _value >> 8;		/* ¼Ä´æÆ÷Öµ ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _value;			/* ¼Ä´æÆ÷Öµ µÍ×Ö½Ú */
	
	MODH_SendAckWithCRC();		/* ·¢ËÍÊý¾Ý£¬×Ô¶¯¼ÓCRC */
	
	g_tModH.fAck06H = 0;		/* Èç¹ûÊÕµ½´Ó»úµÄÓ¦´ð£¬ÔòÕâ¸ö±êÖ¾»áÉèΪ1 */
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Send10H
*	¹¦ÄÜ˵Ã÷: ·¢ËÍ10HÖ¸ÁÁ¬ÐøÐ´¶à¸ö±£³Ö¼Ä´æÆ÷. ×î¶àÒ»´ÎÖ§³Ö23¸ö¼Ä´æÆ÷¡£
*	ÐÎ    ²Î: _addr : ´ÓÕ¾µØÖ·
*			  _reg : ¼Ä´æÆ÷±àºÅ
*			  _num : ¼Ä´æÆ÷¸öÊýn (ÿ¸ö¼Ä´æÆ÷2¸ö×Ö½Ú) ÖµÓò
*			  _buf : n¸ö¼Ä´æÆ÷µÄÊý¾Ý¡£³¤¶È = 2 * n
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
void MODH_Send10H(uint8_t _addr, uint16_t _reg, uint8_t _num, uint8_t *_buf)
{
	uint16_t i;
	
	g_tModH.TxCount = 0;
	g_tModH.TxBuf[g_tModH.TxCount++] = _addr;		/* ´ÓÕ¾µØÖ· */
	g_tModH.TxBuf[g_tModH.TxCount++] = 0x10;		/* ´ÓÕ¾µØÖ· */	
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg >> 8;	/* ¼Ä´æÆ÷±àºÅ ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _reg;		/* ¼Ä´æÆ÷±àºÅ µÍ×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _num >> 8;	/* ¼Ä´æÆ÷¸öÊý ¸ß×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = _num;		/* ¼Ä´æÆ÷¸öÊý µÍ×Ö½Ú */
	g_tModH.TxBuf[g_tModH.TxCount++] = 2 * _num;	/* Êý¾Ý×Ö½ÚÊý */
	
	for (i = 0; i < 2 * _num; i++)
	{
		if (g_tModH.TxCount > H_RX_BUF_SIZE - 3)
		{
			return;		/* Êý¾Ý³¬¹ý»º³åÇø³¬¶È£¬Ö±½Ó¶ªÆú²»·¢ËÍ */
		}
		g_tModH.TxBuf[g_tModH.TxCount++] = _buf[i];		/* ºóÃæµÄÊý¾Ý³¤¶È */
	}
	
	MODH_SendAckWithCRC();	/* ·¢ËÍÊý¾Ý£¬×Ô¶¯¼ÓCRC */
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_ReciveNew
*	¹¦ÄÜ˵Ã÷: ´®¿Ú½ÓÊÕÖжϷþÎñ³ÌÐò»áµ÷Óñ¾º¯Êý¡£µ±ÊÕµ½Ò»¸ö×Ö½Úʱ£¬Ö´ÐÐÒ»´Î±¾º¯Êý¡£
*	ÐÎ    ²Î: 
*	·µ »Ø Öµ: 1 ±íʾÓÐÊý¾Ý
*********************************************************************************************************
*/
void MODH_ReciveNew(uint8_t _data)
{
	/*
		3.5¸ö×Ö·ûµÄʱ¼ä¼ä¸ô£¬Ö»ÊÇÓÃÔÚRTUģʽÏÂÃæ£¬ÒòΪRTUģʽûÓпªÊ¼·ûºÍ½áÊø·û£¬
		Á½¸öÊý¾Ý°üÖ®¼äÖ»ÄÜ¿¿Ê±¼ä¼ä¸ôÀ´Çø·Ö£¬Modbus¶¨ÒåÔÚ²»Í¬µÄ²¨ÌØÂÊÏ£¬¼ä¸ôʱ¼äÊDz»Ò»ÑùµÄ£¬
		ËùÒÔ¾ÍÊÇ3.5¸ö×Ö·ûµÄʱ¼ä£¬²¨ÌØÂʸߣ¬Õâ¸öʱ¼ä¼ä¸ô¾ÍС£¬²¨ÌØÂʵͣ¬Õâ¸öʱ¼ä¼ä¸ôÏàÓ¦¾Í´ó

		4800  = 7.297ms
		9600  = 3.646ms
		19200  = 1.771ms
		38400  = 0.885ms
	*/
//	uint32_t timeout;

	g_modh_timeout = 0;
	
//	timeout = 35000000 / HBAUD485;		/* ¼ÆË㳬ʱʱ¼ä£¬µ¥Î»us 35000000*/
	
	/* Ó²¼þ¶¨Ê±Öжϣ¬¶¨Ê±¾«¶Èus Ó²¼þ¶¨Ê±Æ÷2ÓÃÓÚMODBUS´Ó»ú, ¶¨Ê±Æ÷3ÓÃÓÚMODBUS´Ó»úÖ÷»ú*/
//	bsp_StartHardTimer(3, timeout, (void *)MODH_RxTimeOut);

	if (g_tModH.RxCount < H_RX_BUF_SIZE)
	{
		g_tModH.RxBuf[g_tModH.RxCount++] = _data;
	}
}

void MODH_RecivePack(uint8_t *_buf, uint16_t _len)
{
	if(_len < H_RX_BUF_SIZE)
	{
		g_modh_timeout = 1;
		memcpy(g_tModH.RxBuf,_buf,_len);
		g_tModH.RxCount = _len;
	}
}
/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_RxTimeOut
*	¹¦ÄÜ˵Ã÷: ³¬¹ý3.5¸ö×Ö·ûʱ¼äºóÖ´Ðб¾º¯Êý¡£ ÉèÖÃÈ«¾Ö±äÁ¿ g_rtu_timeout = 1; ֪ͨÖ÷³ÌÐò¿ªÊ¼½âÂë¡£
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
static void MODH_RxTimeOut(void)
{
	g_modh_timeout = 1;
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Poll
*	¹¦ÄÜ˵Ã÷: ½ÓÊÕ¿ØÖÆÆ÷Ö¸Áî. 1ms ÏìӦʱ¼ä¡£
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: 0 ±íʾÎÞÊý¾Ý 1±íʾÊÕµ½ÕýÈ·ÃüÁî
*********************************************************************************************************
*/
void MODH_Poll(void)
{	
	uint16_t crc1;
	
	if (g_modh_timeout == 0)	/* ³¬¹ý3.5¸ö×Ö·ûʱ¼äºóÖ´ÐÐMODH_RxTimeOut()º¯Êý¡£È«¾Ö±äÁ¿ g_rtu_timeout = 1 */
	{
		/* ûÓг¬Ê±£¬¼ÌÐø½ÓÊÕ¡£²»ÒªÇåÁã g_tModH.RxCount */
		return ;
	}

	/* ÊÕµ½ÃüÁî
		05 06 00 88 04 57 3B70 (8 ×Ö½Ú)
			05    :  ÊýÂë¹ÜÆÁµÄºÅÕ¾£¬
			06    :  Ö¸Áî
			00 88 :  ÊýÂë¹ÜÆÁµÄÏÔʾ¼Ä´æÆ÷
			04 57 :  Êý¾Ý,,,ת»»³É 10 ½øÖÆÊÇ 1111.¸ßλÔÚǰ,
			3B70  :  ¶þ¸ö×Ö½Ú CRC Âë	´Ó05µ½ 57µÄУÑé
	*/
	g_modh_timeout = 0;

	if (g_tModH.RxCount < 4)
	{
		goto err_ret;
	}

	/* ¼ÆËãCRCУÑéºÍ */
	crc1 = CRC16_Modbus(g_tModH.RxBuf, g_tModH.RxCount);
	if (crc1 != 0)
	{
		goto err_ret;
	}
	
	/* ·ÖÎöÓ¦ÓòãЭÒé */
	MODH_AnalyzeApp();

err_ret:
#if 0	/* ´Ë²¿·ÖΪÁË´®¿Ú´òÓ¡½á¹û,ʵ¼ÊÔËÓÃÖпɲ»Òª */
	g_tPrint.Rxlen = g_tModH.RxCount;
	memcpy(g_tPrint.RxBuf, g_tModH.RxBuf, g_tModH.RxCount);
#endif
	
	g_tModH.RxCount = 0;	/* ±ØÐëÇåÁã¼ÆÊýÆ÷£¬·½±ãÏ´Î֡ͬ²½ */
}


/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Read_01H
*	¹¦ÄÜ˵Ã÷: ·ÖÎö01HÖ¸ÁîµÄÓ¦´ðÊý¾Ý
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
static void MODH_Read_01H(void)
{
	uint8_t bytes;
	uint8_t *p;
	
	if (g_tModH.RxCount > 0)
	{
		bytes = g_tModH.RxBuf[2];	/* Êý¾Ý³¤¶È ×Ö½ÚÊý */				
		switch (g_tModH.Reg01H)
		{
			case REG_D01:
				if (bytes == 8)
				{
					p = &g_tModH.RxBuf[3];	
					
					g_tVar.D01 = BEBufToUint16(p); p += 2;	/* ¼Ä´æÆ÷ */	
					g_tVar.D02 = BEBufToUint16(p); p += 2;	/* ¼Ä´æÆ÷ */	
					g_tVar.D03 = BEBufToUint16(p); p += 2;	/* ¼Ä´æÆ÷ */	
					g_tVar.D04 = BEBufToUint16(p); p += 2;	/* ¼Ä´æÆ÷ */
					
					g_tModH.fAck01H = 1;
				}
				break;
		}
	}
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Read_02H
*	¹¦ÄÜ˵Ã÷: ·ÖÎö02HÖ¸ÁîµÄÓ¦´ðÊý¾Ý
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
static void MODH_Read_02H(void)
{
	uint8_t bytes;
	uint8_t *p;
	
	if (g_tModH.RxCount > 0)
	{
		bytes = g_tModH.RxBuf[2];	/* Êý¾Ý³¤¶È ×Ö½ÚÊý */				
		switch (g_tModH.Reg02H)
		{
			case REG_T01:
				if (bytes == 6)
				{
					p = &g_tModH.RxBuf[3];	
					
					g_tVar.T01 = BEBufToUint16(p); p += 2;	/* ¼Ä´æÆ÷ */	
					g_tVar.T02 = BEBufToUint16(p); p += 2;	/* ¼Ä´æÆ÷ */	
					g_tVar.T03 = BEBufToUint16(p); p += 2;	/* ¼Ä´æÆ÷ */	
					
					g_tModH.fAck02H = 1;
				}
				break;
		}
	}
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Read_04H
*	¹¦ÄÜ˵Ã÷: ·ÖÎö04HÖ¸ÁîµÄÓ¦´ðÊý¾Ý
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
static void MODH_Read_04H(void)
{
	uint8_t bytes;
	uint8_t *p;
	
	if (g_tModH.RxCount > 0)
	{
		bytes = g_tModH.RxBuf[2];	/* Êý¾Ý³¤¶È ×Ö½ÚÊý */				
		switch (g_tModH.Reg04H)
		{
			case REG_T01:
				if (bytes == 2)
				{
					p = &g_tModH.RxBuf[3];	
					
					g_tVar.A01 = BEBufToUint16(p); p += 2;	/* ¼Ä´æÆ÷ */	
					
					g_tModH.fAck04H = 1;
				}
				break;
		}
	}
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Read_05H
*	¹¦ÄÜ˵Ã÷: ·ÖÎö05HÖ¸ÁîµÄÓ¦´ðÊý¾Ý
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
static void MODH_Read_05H(void)
{
	if (g_tModH.RxCount > 0)
	{
		if (g_tModH.RxBuf[0] == SlaveAddr)		
		{
			g_tModH.fAck05H = 1;		/* ½ÓÊÕµ½Ó¦´ð */
		}
	};
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Read_06H
*	¹¦ÄÜ˵Ã÷: ·ÖÎö06HÖ¸ÁîµÄÓ¦´ðÊý¾Ý
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
static void MODH_Read_06H(void)
{
	if (g_tModH.RxCount > 0)
	{
		if (g_tModH.RxBuf[0] == SlaveAddr)		
		{
			g_tModH.fAck06H = 1;		/* ½ÓÊÕµ½Ó¦´ð */
		}
	}
}


/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Read_03H
*	¹¦ÄÜ˵Ã÷: ·ÖÎö03HÖ¸ÁîµÄÓ¦´ðÊý¾Ý
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
void MODH_Read_03H(void)
{
	uint8_t bytes;
	uint8_t *p;
	
	if (g_tModH.RxCount > 0)
	{
		bytes = g_tModH.RxBuf[2];	/* Êý¾Ý³¤¶È ×Ö½ÚÊý */				
		switch (g_tModH.Reg03H)
		{
			case REG_P01:
				if (bytes == 32)
				{
					p = &g_tModH.RxBuf[3];	
					
					g_tVar.P01 = BEBufToUint16(p); p += 2;	/* ¼Ä´æÆ÷ */	
					g_tVar.P02 = BEBufToUint16(p); p += 2;	/* ¼Ä´æÆ÷ */	
		
					g_tModH.fAck03H = 1;
				}
				break;
		}
	}
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_Read_10H
*	¹¦ÄÜ˵Ã÷: ·ÖÎö10HÖ¸ÁîµÄÓ¦´ðÊý¾Ý
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: ÎÞ
*********************************************************************************************************
*/
void MODH_Read_10H(void)
{
	/*
		10HÖ¸ÁîµÄÓ¦´ð:
			´Ó»úµØÖ·                11
			¹¦ÄÜÂë                  10
			¼Ä´æÆ÷ÆðʼµØÖ·¸ß×Ö½Ú	00
			¼Ä´æÆ÷ÆðʼµØÖ·µÍ×Ö½Ú    01
			¼Ä´æÆ÷ÊýÁ¿¸ß×Ö½Ú        00
			¼Ä´æÆ÷ÊýÁ¿µÍ×Ö½Ú        02
			CRCУÑé¸ß×Ö½Ú           12
			CRCУÑéµÍ×Ö½Ú           98
	*/
	if (g_tModH.RxCount > 0)
	{
		if (g_tModH.RxBuf[0] == SlaveAddr)		
		{
			g_tModH.fAck10H = 1;		/* ½ÓÊÕµ½Ó¦´ð */
		}
	}
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: bsp_GetRunTime
*	¹¦ÄÜ˵Ã÷: »ñÈ¡CPUÔËÐÐʱ¼ä£¬µ¥Î»1ms¡£×¿ÉÒÔ±íʾ 24.85Ì죬Èç¹ûÄãµÄ²úÆ·Á¬ÐøÔËÐÐʱ¼ä³¬¹ýÕâ¸öÊý£¬Ôò±ØÐ뿼ÂÇÒç³öÎÊÌâ
*	ÐÎ    ²Î:  ÎÞ
*	·µ »Ø Öµ: CPUÔËÐÐʱ¼ä£¬µ¥Î»1ms
*********************************************************************************************************
*/
uint32_t bsp_GetRunTime()
{
  return HSF_API hfsys_get_time();
}
/*
*********************************************************************************************************
*	º¯ Êý Ãû: bsp_CheckRunTime
*	¹¦ÄÜ˵Ã÷: ¼ÆË㵱ǰÔËÐÐʱ¼äºÍ¸ø¶¨Ê±¿ÌÖ®¼äµÄ²îÖµ¡£´¦ÀíÁ˼ÆÊýÆ÷Ñ­»·¡£
*	ÐÎ    ²Î:  _LastTime Éϸöʱ¿Ì
*	·µ »Ø Öµ: µ±Ç°Ê±¼äºÍ¹ýȥʱ¼äµÄ²îÖµ£¬µ¥Î»1ms
*********************************************************************************************************
*/
uint32_t time_diff;
uint32_t bsp_CheckRunTime(uint32_t _LastTime)
{
  uint32_t now_time = HSF_API hfsys_get_time();

  if(now_time >= _LastTime)
  {
    time_diff = now_time - _LastTime;
  }
  else
  {
    time_diff = _LastTime - now_time;
  }
	msleep(5);
  return time_diff;
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_ReadParam_01H
*	¹¦ÄÜ˵Ã÷: µ¥¸ö²ÎÊý. ͨ¹ý·¢ËÍ01HÖ¸ÁîʵÏÖ£¬·¢ËÍÖ®ºó£¬µÈ´ý´Ó»úÓ¦´ð¡£
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: 1 ±íʾ³É¹¦¡£0 ±íʾʧ°Ü£¨Í¨Ðų¬Ê±»ò±»¾Ü¾ø£©
*********************************************************************************************************
*/
uint8_t MODH_ReadParam_01H(uint16_t _reg, uint16_t _num)
{
	 int32_t time1;
	uint8_t i;
	
	for (i = 0; i < NUM; i++)
	{
		MODH_Send01H (SlaveAddr, _reg, _num);		  /* ·¢ËÍÃüÁî */
		time1 = bsp_GetRunTime();	/* ¼Ç¼ÃüÁî·¢Ë͵Äʱ¿Ì */
		
		while (1)				/* µÈ´ýÓ¦´ð,³¬Ê±»ò½ÓÊÕµ½Ó¦´ðÔòbreak  */
		{
			bsp_Idle();

			if (bsp_CheckRunTime(time1) > TIMEOUT)		
			{
				break;		/* ͨÐų¬Ê±ÁË */
			}
			
			if (g_tModH.fAck01H > 0)
			{
				break;		/* ½ÓÊÕµ½Ó¦´ð */
			}
		}
		
		if (g_tModH.fAck01H > 0)
		{
			break;			/* Ñ­»·NUM´Î£¬Èç¹û½ÓÊÕµ½ÃüÁîÔòbreakÑ­»· */
		}
	}
	
	if (g_tModH.fAck01H == 0)
	{
		return 0;
	}
	else 
	{
		return 1;	/* 01H ¶Á³É¹¦ */
	}
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_ReadParam_02H
*	¹¦ÄÜ˵Ã÷: µ¥¸ö²ÎÊý. ͨ¹ý·¢ËÍ02HÖ¸ÁîʵÏÖ£¬·¢ËÍÖ®ºó£¬µÈ´ý´Ó»úÓ¦´ð¡£
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: 1 ±íʾ³É¹¦¡£0 ±íʾʧ°Ü£¨Í¨Ðų¬Ê±»ò±»¾Ü¾ø£©
*********************************************************************************************************
*/
uint8_t MODH_ReadParam_02H(uint16_t _reg, uint16_t _num)
{
	 int32_t time1;
	uint8_t i;
	
	for (i = 0; i < NUM; i++)
	{
		MODH_Send02H (SlaveAddr, _reg, _num);
		time1 = bsp_GetRunTime();	/* ¼Ç¼ÃüÁî·¢Ë͵Äʱ¿Ì */
		
		while (1)
		{
			bsp_Idle();

			if (bsp_CheckRunTime(time1) > TIMEOUT)		
			{
				break;		/* ͨÐų¬Ê±ÁË */
			}
			
			if (g_tModH.fAck02H > 0)
			{
				break;
			}
		}
		
		if (g_tModH.fAck02H > 0)
		{
			break;
		}
	}
	
	if (g_tModH.fAck02H == 0)
	{
		return 0;
	}
	else 
	{
		return 1;	/* 02H ¶Á³É¹¦ */
	}
}
/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_ReadParam_03H
*	¹¦ÄÜ˵Ã÷: µ¥¸ö²ÎÊý. ͨ¹ý·¢ËÍ03HÖ¸ÁîʵÏÖ£¬·¢ËÍÖ®ºó£¬µÈ´ý´Ó»úÓ¦´ð¡£
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: 1 ±íʾ³É¹¦¡£0 ±íʾʧ°Ü£¨Í¨Ðų¬Ê±»ò±»¾Ü¾ø£©
*********************************************************************************************************
*/
uint8_t MODH_ReadParam_03H(uint16_t _reg, uint16_t _num)
{
	int32_t time1;
	uint8_t i;
	
	for (i = 0; i < NUM; i++)
	{
		MODH_Send03H (SlaveAddr, _reg, _num);
		time1 = bsp_GetRunTime();	/* ¼Ç¼ÃüÁî·¢Ë͵Äʱ¿Ì */
//		time1 = HSF_API hfsys_get_time();//
		while (1)
		{
			bsp_Idle();

			if (bsp_CheckRunTime(time1) > TIMEOUT)		
			{
				i = i;
				break;		/* ͨÐų¬Ê±ÁË */
			}
//			if(HSF_API hfsys_get_time() - time1 > TIMEOUT)
//			{
//				break;
//			}
			if (g_tModH.fAck03H > 0)
			{
				i = i;
				break;
			}
//			 msleep(10);
		}
		
		if (g_tModH.fAck03H > 0)
		{
			break;
		}
	}
	
	if (g_tModH.fAck03H == 0)
	{
		return 0;	/* ͨÐų¬Ê±ÁË */
	}
	else 
	{
		return 1;	/* дÈë03H²ÎÊý³É¹¦ */
	}
}


/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_ReadParam_04H
*	¹¦ÄÜ˵Ã÷: µ¥¸ö²ÎÊý. ͨ¹ý·¢ËÍ04HÖ¸ÁîʵÏÖ£¬·¢ËÍÖ®ºó£¬µÈ´ý´Ó»úÓ¦´ð¡£
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: 1 ±íʾ³É¹¦¡£0 ±íʾʧ°Ü£¨Í¨Ðų¬Ê±»ò±»¾Ü¾ø£©
*********************************************************************************************************
*/
uint8_t MODH_ReadParam_04H(uint16_t _reg, uint16_t _num) 
{
	 int32_t time1;
	uint8_t i;
	
	for (i = 0; i < NUM; i++)
	{
		MODH_Send04H (SlaveAddr, _reg, _num);
		time1 = bsp_GetRunTime();	/* ¼Ç¼ÃüÁî·¢Ë͵Äʱ¿Ì */
		
		while (1)
		{
			bsp_Idle();

			if (bsp_CheckRunTime(time1) > TIMEOUT)		
			{
				break;		/* ͨÐų¬Ê±ÁË */
			}
			
			if (g_tModH.fAck04H > 0)
			{
				break;
			}
		}
		
		if (g_tModH.fAck04H > 0)
		{
			break;
		}
	}
	
	if (g_tModH.fAck04H == 0)
	{
		return 0;	/* ͨÐų¬Ê±ÁË */
	}
	else 
	{
		return 1;	/* 04H ¶Á³É¹¦ */
	}
}
/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_WriteParam_05H
*	¹¦ÄÜ˵Ã÷: µ¥¸ö²ÎÊý. ͨ¹ý·¢ËÍ05HÖ¸ÁîʵÏÖ£¬·¢ËÍÖ®ºó£¬µÈ´ý´Ó»úÓ¦´ð¡£
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: 1 ±íʾ³É¹¦¡£0 ±íʾʧ°Ü£¨Í¨Ðų¬Ê±»ò±»¾Ü¾ø£©
*********************************************************************************************************
*/
uint8_t MODH_WriteParam_05H(uint16_t _reg, uint16_t _value)
{
	 int32_t time1;
	uint8_t i;

	for (i = 0; i < NUM; i++)
	{
		MODH_Send05H (SlaveAddr, _reg, _value);
		time1 = bsp_GetRunTime();	/* ¼Ç¼ÃüÁî·¢Ë͵Äʱ¿Ì */
		
		while (1)
		{
			bsp_Idle();
			
			/* ³¬Ê±´óÓÚ TIMEOUT£¬ÔòÈÏΪÒì³£ */
			if (bsp_CheckRunTime(time1) > TIMEOUT)		
			{
				break;	/* ͨÐų¬Ê±ÁË */
			}
			
			if (g_tModH.fAck05H > 0)
			{
				break;
			}
		}
		
		if (g_tModH.fAck05H > 0)
		{
			break;
		}
	}
	
	if (g_tModH.fAck05H == 0)
	{
		return 0;	/* ͨÐų¬Ê±ÁË */
	}
	else
	{
		return 1;	/* 05H д³É¹¦ */
	}
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_WriteParam_06H
*	¹¦ÄÜ˵Ã÷: µ¥¸ö²ÎÊý. ͨ¹ý·¢ËÍ06HÖ¸ÁîʵÏÖ£¬·¢ËÍÖ®ºó£¬µÈ´ý´Ó»úÓ¦´ð¡£Ñ­»·NUM´ÎдÃüÁî
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: 1 ±íʾ³É¹¦¡£0 ±íʾʧ°Ü£¨Í¨Ðų¬Ê±»ò±»¾Ü¾ø£©
*********************************************************************************************************
*/
uint8_t MODH_WriteParam_06H(uint16_t _reg, uint16_t _value)
{
	 int32_t time1;
	uint8_t i;
	
	for (i = 0; i < NUM; i++)
	{	
		MODH_Send06H (SlaveAddr, _reg, _value);
		time1 = bsp_GetRunTime();	/* ¼Ç¼ÃüÁî·¢Ë͵Äʱ¿Ì */
				
		while (1)
		{
			bsp_Idle();
		
			if (bsp_CheckRunTime(time1) > TIMEOUT)		
			{
				break;
			}
			
			if (g_tModH.fAck06H > 0)
			{
				break;
			}
		}
		
		if (g_tModH.fAck06H > 0)
		{
			break;
		}
	}
	
	if (g_tModH.fAck06H == 0)
	{
		return 0;	/* ͨÐų¬Ê±ÁË */
	}
	else
	{
		return 1;	/* дÈë06H²ÎÊý³É¹¦ */
	}
}

/*
*********************************************************************************************************
*	º¯ Êý Ãû: MODH_WriteParam_10H
*	¹¦ÄÜ˵Ã÷: µ¥¸ö²ÎÊý. ͨ¹ý·¢ËÍ10HÖ¸ÁîʵÏÖ£¬·¢ËÍÖ®ºó£¬µÈ´ý´Ó»úÓ¦´ð¡£Ñ­»·NUM´ÎдÃüÁî
*	ÐÎ    ²Î: ÎÞ
*	·µ »Ø Öµ: 1 ±íʾ³É¹¦¡£0 ±íʾʧ°Ü£¨Í¨Ðų¬Ê±»ò±»¾Ü¾ø£©
*********************************************************************************************************
*/
uint8_t MODH_WriteParam_10H(uint16_t _reg, uint8_t _num, uint8_t *_buf)
{
	int32_t time1;
	uint8_t i;
	
	for (i = 0; i < NUM; i++)
	{	
		MODH_Send10H(SlaveAddr, _reg, _num, _buf);
		time1 = bsp_GetRunTime();	/* ¼Ç¼ÃüÁî·¢Ë͵Äʱ¿Ì */
				
		while (1)
		{
			bsp_Idle();
		
			if (bsp_CheckRunTime(time1) > TIMEOUT)		
			{
				break;
			}
			
			if (g_tModH.fAck10H > 0)
			{
				break;
			}
		}
		
		if (g_tModH.fAck10H > 0)
		{
			break;
		}
	}
	
	if (g_tModH.fAck10H == 0)
	{
		return 0;	/* ͨÐų¬Ê±ÁË */
	}
	else
	{
		return 1;	/* дÈë10H²ÎÊý³É¹¦ */
	}
}

/***************************** °²¸»À³µç×Ó www.armfly.com (END OF FILE) *********************************/

usart_modbus:

#include <hsf.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "user.h"
#include "modbus_host.h"


//*! define
#define uart_receive_mb 0x01 //modbus Êý¾Ý


//*! ±äÁ¿
extern uint8_t uart_receive_flag;//½ÓÊÕÊý¾Ý ±ê־λÅжϡ£


USER_FUNC extern void uart_printf(char *buf, uint32_t len);
USER_FUNC extern uint8_t MODH_ReadParam_01H(uint16_t _reg, uint16_t _num);               
USER_FUNC extern uint8_t MODH_ReadParam_02H(uint16_t _reg, uint16_t _num);               
USER_FUNC extern uint8_t MODH_ReadParam_03H(uint16_t _reg, uint16_t _num);               
USER_FUNC extern uint8_t MODH_ReadParam_04H(uint16_t _reg, uint16_t _num);               
USER_FUNC extern uint8_t MODH_WriteParam_05H(uint16_t _reg, uint16_t _value);            
USER_FUNC extern uint8_t MODH_WriteParam_06H(uint16_t _reg, uint16_t _value);            
USER_FUNC extern uint8_t MODH_WriteParam_10H(uint16_t _reg, uint8_t _num, uint8_t *_buf);
USER_FUNC void uart_process(char *_buf, uint16_t _len);//´®¿Ú´¦Àíº¯Êý
USER_FUNC void MODH_Poll(void);//modbus poll
USER_FUNC void MODH_RecivePack(uint8_t *_buf, uint16_t _len);//½ÓÊÕÊý¾Ý¿½±´
void uart_process(char *_buf,uint16_t _len)
{
	if(_buf[_len - 1] == '\n')//»»ÐÐ
	{
		if( (_buf[0] == 'A' || _buf[0] == 'a') && ( _buf[1] == 'T' || _buf[1] == 't' ))
		{
			u_printf("at_cmd_chuli # len = %d ,RX_Buffer=%s\r\n",_len,_buf);
		}
	}
	else 
	{
		u_printf("UART_Data_Process # Rev_len = %d,mb_flag=%d\r\n",_len,1);
		if(_buf[0] == SlaveAddr)// modbus µØÖ·
		{
			if(uart_receive_flag  & uart_receive_mb)
			{
				MODH_RecivePack((uint8_t *)_buf, _len);
				uart_receive_flag ^= uart_receive_mb;
			}
//			MODH_Poll();
		}
	}

	
}
//void uart_Recv
void uart_SendBuf(uint8_t *_buf, uint16_t _len)
{
	hfuart_send(HFUART0,(char *)_buf,_len,600);
}
USER_FUNC void uart_test(void* arg)
{
	hfuart_handle_t huart0;
	char *words[6]={NULL};
	char rsp[64]={0};
	hfat_send_cmd("AT+E=Off\r\n",sizeof("AT+E=Off\r\n"),rsp,64);
	if(hfat_get_words(rsp,words, 6)>0)
	{
		u_printf("\nAT+E=Off \r\n %s %s %s\r\n",words[0],words[1],words[2]);
	}		
	char *buf = NULL;
	huart0 = hfuart_open(0);
	if(huart0==NULL)
	{
		u_printf("open uart1 fail\n");
		goto exit_thread;
	}
	buf = (char*)hfmem_malloc(1000);
	if(buf==NULL)
	{
		u_printf("memory alloc fail\n");
		goto exit_thread;
	}
	msleep(1000 * 20);
	while(1)
	{
//		recv_bytes = hfuart_recv(huart0,buf,1000,1000);
//		if(recv_bytes>0)
//		{
//			//u_printf("uart1 recv %d bytes\n",recv_bytes);
//			hfuart_send(huart0,buf,recv_bytes,100);
//		}
//		hfuart_send(huart0,send_buf,6,100);
		
//		MODH_ReadParam_01H(REG_D01,4);
		msleep(4000);//Ïß³ÌÐÝÃß 10s
		if( MODH_ReadParam_03H(REG_P01,16) == 0)
		{
			MODH_ReadParam_03H(REG_P01,5);
			msleep(500);
			
		}
	}

exit_thread:
	if(buf!=NULL)
	{
		hfmem_free(buf);
	}
	hfuart_close(huart0);
	hfthread_destroy(NULL);
	return ;
}

USER_FUNC void uart_receive(void* arg)
{
	msleep(1000 * 30);
	while(1)
	{
		MODH_Poll();
		msleep(50);
	}
}

modbus_host_h:

/*
*********************************************************************************************************
*
*	Ä£¿éÃû³Æ : MODEBUS ͨÐÅÄ£¿é (Ö÷»ú³ÌÐò£©
*	ÎļþÃû³Æ : modbus_host.h
*	°æ    ±¾ : V1.4
*	˵    Ã÷ : Í·Îļþ
*
*	Copyright (C), 2015-2016, °²¸»À³µç×Ó www.armfly.com
*
*********************************************************************************************************
*/
#ifndef __MOSBUS_HOST_H
#define __MOSBUS_HOST_H

#define SlaveAddr		0x01			/* 面板作为时,主板作从机 */
#define HBAUD485		UART3_BAUD

/* 01H 读强制单线圈 */
/* 05H 写强制单线圈 */
#define REG_D01		0x0101
#define REG_D02		0x0102
#define REG_D03		0x0103
#define REG_D04		0x0104
#define REG_DXX 	REG_D04

/* 02H 读取输入状态 */
#define REG_T01		0x0201
#define REG_T02		0x0202
#define REG_T03		0x0203
#define REG_TXX		REG_T03

/* 03H 读保持寄存器 */
/* 06H 写保持寄存器 */
/* 10H 写多个保存寄存器 */
#define REG_P01		0x0001		
#define REG_P02		0x0302	

/* 04H 读取输入寄存器(模拟信号) */
#define REG_A01		0x0401
#define REG_AXX		REG_A01

/* RTU 应答代码 */
#define RSP_OK				0		/* 成功 */
#define RSP_ERR_CMD			0x01	/* 不支持的功能码 */
#define RSP_ERR_REG_ADDR	0x02	/* 寄存器地址错
#define RSP_ERR_VALUE		0x03	/* 数据值域错误 */
#define RSP_ERR_WRITE		0x04	/* 写入失败 */

#define H_RX_BUF_SIZE		256
#define H_TX_BUF_SIZE      	128

typedef struct
{
	uint8_t RxBuf[H_RX_BUF_SIZE];
	uint8_t RxCount;
	uint8_t RxStatus;
	uint8_t RxNewFlag;

	uint8_t RspCode;

	uint8_t TxBuf[H_TX_BUF_SIZE];
	uint8_t TxCount;
	
	uint16_t Reg01H;		/* 保存主机发送的寄存器首地址 */
	uint16_t Reg02H;
	uint16_t Reg03H;		
	uint16_t Reg04H;

	uint8_t RegNum;			/* 寄存器个数 */

	uint8_t fAck01H;		/* 应答命令标志 0 表示执行失败 1表示执行成功 */
	uint8_t fAck02H;
	uint8_t fAck03H;
	uint8_t fAck04H;
	uint8_t fAck05H;		
	uint8_t fAck06H;		
	uint8_t fAck10H;
	
}MODH_T;

typedef struct
{
	/* 03H 06H 读写保持寄存器 */
	uint16_t P01;
	uint16_t P02;
	uint16_t P03;
	uint16_t P04;
	uint16_t P05;
	uint16_t P06;
	uint16_t P07;
	
	/* 02H 读写离散输入寄存器 */
	uint16_t T01;
	uint16_t T02;
	uint16_t T03;
	
	/* 04H 读取模拟量寄存器 */
	uint16_t A01;
	
	/* 01H 05H 读写单个强制线圈 */
	uint16_t D01;
	uint16_t D02;
	uint16_t D03;
	uint16_t D04;
	
}VAR_T;

//串口打印数据 MODBUS 调试数据
typedef struct
{
	uint8_t Rxlen;
	char RxBuf[20];
	uint8_t Txlen;
	char TxBuf[20];
}PRINT_MODS_T;

extern PRINT_MODS_T g_tPrint;

void MODH_Poll(void);
uint8_t MODH_ReadParam_01H(uint16_t _reg, uint16_t _num);
uint8_t MODH_ReadParam_02H(uint16_t _reg, uint16_t _num);
uint8_t MODH_ReadParam_03H(uint16_t _reg, uint16_t _num);
uint8_t MODH_ReadParam_04H(uint16_t _reg, uint16_t _num);
uint8_t MODH_WriteParam_05H(uint16_t _reg, uint16_t _value);
uint8_t MODH_WriteParam_06H(uint16_t _reg, uint16_t _value);
uint8_t MODH_WriteParam_10H(uint16_t _reg, uint8_t _num, uint8_t *_buf);

extern MODH_T g_tModH;

#endif

/***************************** °²¸»À³µç×Ó www.armfly.com (END OF FILE) *********************************/

f107以太网

#include "bsp_stm32_eth.h"
#include "stm32_eth.h"

/* Define those to better describe your network interface. */
#define IFNAME0 's'
#define IFNAME1 't'
#define  ETH_DMARxDesc_FrameLengthShift           16
#define  ETH_ERROR              ((u32)0)
#define  ETH_SUCCESS            ((u32)1)

#define DP83848_PHY        /* Ethernet pins mapped on STM3210C-EVAL Board */
#define PHY_ADDRESS       0x01 /* Relative to STM3210C-EVAL Board */

//#define MII_MODE          /* MII mode for STM3210C-EVAL Board (MB784) (check jumpers setting) */
#define RMII_MODE       /* RMII mode for STM3210C-EVAL Board (MB784) (check jumpers setting) */

#define ETH_RXBUFNB        	4
#define ETH_TXBUFNB        	2

static ETH_DMADESCTypeDef  DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB];
static uint8_t Rx_Buff[ETH_RXBUFNB][ETH_MAX_PACKET_SIZE], Tx_Buff[ETH_TXBUFNB][ETH_MAX_PACKET_SIZE];

ETH_DMADESCTypeDef  *DMATxDesc = DMATxDscrTab;
extern ETH_DMADESCTypeDef  *DMATxDescToSet;
extern ETH_DMADESCTypeDef  *DMARxDescToGet;

#define MAX_ADDR_LEN 6

typedef struct{
u32 length;
u32 buffer;
ETH_DMADESCTypeDef *descriptor;
}FrameTypeDef;

FrameTypeDef LwIP_Pkt_Handle(void);

/* interrupt service routine for ETH */
void ETH_IRQHandler(void)
{
    rt_uint32_t status;
		uint32_t frameLength;
    /* enter interrupt */
    rt_interrupt_enter();

	/* get DMA IT status */
	status = ETH->DMASR;
		rt_kprintf("\n\r ETH_IRQHandler !!!\r\n");
    if ( (status & ETH_DMA_IT_R) != (u32)RESET ) /* packet receiption */
    {
        /* a frame has been received */
//        eth_device_ready(&(stm32_eth_device.parent));
				
				/* Handles all the received frames */
				frameLength = ETH_GetRxPktSize();
				rt_kprintf("\n\r r: Receive %d !!!\r\n",frameLength);
				if(frameLength != 0)
				{
					LwIP_Pkt_Handle();
				}
				
        ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
    }

    if ( (status & ETH_DMA_IT_T) != (u32)RESET ) /* packet transmission */
    {
//        rt_sem_release(&tx_buf_free);
        ETH_DMAClearITPendingBit(ETH_DMA_IT_T);
    }

    /* Clear received IT */
    if ((status & ETH_DMA_IT_NIS) != (u32)RESET)
        ETH->DMASR = (u32)ETH_DMA_IT_NIS;
    if ((status & ETH_DMA_IT_AIS) != (u32)RESET)
        ETH->DMASR = (u32)ETH_DMA_IT_AIS;
    if ((status & ETH_DMA_IT_RO) != (u32)RESET)
        ETH->DMASR = (u32)ETH_DMA_IT_RO;

    if ((status & ETH_DMA_IT_RBU) != (u32)RESET)
    {
        ETH_ResumeDMAReception();
        ETH->DMASR = (u32)ETH_DMA_IT_RBU;
    }

    if ((status & ETH_DMA_IT_TBU) != (u32)RESET)
    {
        ETH_ResumeDMATransmission();
        ETH->DMASR = (u32)ETH_DMA_IT_TBU;
    }

    /* leave interrupt */
    rt_interrupt_leave();
}

static void RCC_Configuration(void)
{
    /* Enable ETHERNET clock  */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ETH_MAC | RCC_AHBPeriph_ETH_MAC_Tx |
                          RCC_AHBPeriph_ETH_MAC_Rx, ENABLE);

	/* Enable GPIOs clocks */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |	RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
		RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);
}

static void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    /* Enable the EXTI0 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

/*
 * GPIO Configuration for ETH
 */
static void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	/* ETHERNET pins remapp in STM3210C-EVAL board: RX_DV and RxD[3:0] */
	GPIO_PinRemapConfig(GPIO_Remap_ETH, ENABLE);

	/* MII/RMII Media interface selection */
#ifdef MII_MODE /* Mode MII with STM3210C-EVAL  */
	GPIO_ETH_MediaInterfaceConfig(GPIO_ETH_MediaInterface_MII);

	/* Get HSE clock = 25MHz on PA8 pin(MCO) */
	RCC_MCOConfig(RCC_MCO_HSE);

#elif defined RMII_MODE  /* Mode RMII with STM3210C-EVAL */
	GPIO_ETH_MediaInterfaceConfig(GPIO_ETH_MediaInterface_RMII);

	/* Get HSE clock = 25MHz on PA8 pin(MCO) */
	/* set PLL3 clock output to 50MHz (25MHz /5 *10 =50MHz) */
	RCC_PLL3Config(RCC_PLL3Mul_10);
	/* Enable PLL3 */
	RCC_PLL3Cmd(ENABLE);
	/* Wait till PLL3 is ready */
	while (RCC_GetFlagStatus(RCC_FLAG_PLL3RDY) == RESET)
	{}

	/* Get clock PLL3 clock on PA8 pin */
	RCC_MCOConfig(RCC_MCO_PLL3CLK);
#endif

	/* ETHERNET pins configuration */
	/* AF Output Push Pull:
	- ETH_MII_MDIO / ETH_RMII_MDIO: PA2
	- ETH_MII_MDC / ETH_RMII_MDC: PC1
	- ETH_MII_TXD2: PC2
	- ETH_MII_TX_EN / ETH_RMII_TX_EN: PB11
	- ETH_MII_TXD0 / ETH_RMII_TXD0: PB12
	- ETH_MII_TXD1 / ETH_RMII_TXD1: PB13
	- ETH_MII_PPS_OUT / ETH_RMII_PPS_OUT: PB5
	- ETH_MII_TXD3: PB8 */

	/* Configure PA2 as alternate function push-pull */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/* Configure PC1, PC2 and PC3 as alternate function push-pull */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	/* Configure PB5, PB11, PB12 and PB13 as alternate function push-pull */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_11 |//PB5和can冲突
								  GPIO_Pin_12 | GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	/**************************************************************/
	/*               For Remapped Ethernet pins                   */
	/*************************************************************/
	/* Input (Reset Value):
	- ETH_MII_CRS CRS: PA0
	- ETH_MII_RX_CLK / ETH_RMII_REF_CLK: PA1
	- ETH_MII_COL: PA3
	- ETH_MII_RX_DV / ETH_RMII_CRS_DV: PD8
	- ETH_MII_TX_CLK: PC3
	- ETH_MII_RXD0 / ETH_RMII_RXD0: PD9
	- ETH_MII_RXD1 / ETH_RMII_RXD1: PD10
	- ETH_MII_RXD2: PD11
	- ETH_MII_RXD3: PD12
	- ETH_MII_RX_ER: PB10 */

	/* Configure PA0, PA1 and PA3 as input */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/* Configure PD8, PD9, PD10, PD11 and PD12 as input */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOD, &GPIO_InitStructure); /**/

	/* MCO pin configuration------------------------------------------------- */
	/* Configure MCO (PA8) as alternate function push-pull */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

/*
*********************************************************************************************************
*	函 数 名: bsp_stm32_eth_init
*	功能说明: 初始化 eth 时钟 GPIO
* 创 建 人:LLF
* 日    期:2019-06-05
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
void bsp_stm32_eth_init(void)
{
		ETH_InitTypeDef ETH_InitStructure;
    RCC_Configuration();
		NVIC_Configuration();	
    GPIO_Configuration();
		uint8_t eth_dev_addr[MAX_ADDR_LEN];
		/* Reset ETHERNET on AHB Bus */
		ETH_DeInit();
			
		/* Software reset */
		ETH_SoftwareReset();		
		
		/* Wait for software reset */
		while (ETH_GetSoftwareResetStatus() == SET);		

		uint16_t REG_PHYIDR[2];
		REG_PHYIDR[0] = ETH_ReadPHYRegister(PHY_ADDRESS,2);
		REG_PHYIDR[1] = ETH_ReadPHYRegister(PHY_ADDRESS,3);

    /* ETHERNET Configuration ------------------------------------------------------*/
    /* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */
    ETH_StructInit(&ETH_InitStructure);		
		
		/*------------------------   MAC   -----------------------------------*/
		ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable  ;
		//ETH_InitStructure.ETH_Speed = ETH_Speed_100M; 
		ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
		//ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;  
		ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;
		ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
		ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;
		ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;
		ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
		ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
		ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
#ifdef CHECKSUM_BY_HARDWARE
	ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
#endif		

  /*------------------------   DMA   -----------------------------------*/  
  
  /* When we use the Checksum offload feature, we need to enable the Store and Forward mode: 
  the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum, 
  if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */
  ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable; 
  ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;         
  ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;     
 
  ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;       
  ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;   
  ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable;                                                          
  ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;      
  ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable;                
  ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat;          
  ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat;                                                                 
  ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;

  /* Configure Ethernet */
  ETH_Init(&ETH_InitStructure, PHY_ADDRESS);
	
  /* Enable the Ethernet Rx Interrupt */
	//  ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE);	//官网的资料
	
	/* Enable DMA Receive interrupt (need to enable in this case Normal interrupt) */
  ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R | ETH_DMA_IT_T, ENABLE); //rtt的资料
	
  /* Initialize Tx Descriptors list: Chain Mode */
  ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);// 初始化DMA
  /* Initialize Rx Descriptors list: Chain Mode  */
  ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);// 初始化DMA

  /* Enable Ethernet Rx interrrupt *///2019-06-05 20:16:01
	int i;
  { 
    for(i=0; i<ETH_RXBUFNB; i++)
    {
      ETH_DMARxDescReceiveITConfig(&DMARxDscrTab[i], ENABLE);
    }
  }
	/* Enable the checksum insertion for the Tx frames */ //CHECKSUM_BY_HARDWARE //2019-06-05 20:16:01
	for(i=0; i<ETH_TXBUFNB; i++)
	{
		ETH_DMATxDescChecksumInsertionConfig(&DMATxDscrTab[i], ETH_DMATxDesc_ChecksumTCPUDPICMPFull);
	}	
	
	eth_dev_addr[0] = 0X08;
	eth_dev_addr[1] = 0XFE;
	eth_dev_addr[2] = 0X55;

	eth_dev_addr[3] = *(rt_uint8_t*)(0x1FFFF7E8+7);
	eth_dev_addr[4] = *(rt_uint8_t*)(0x1FFFF7E8+8);
	eth_dev_addr[5] = *(rt_uint8_t*)(0x1FFFF7E8+9);
  /* MAC address configuration */
  ETH_MACAddressConfig(ETH_MAC_Address0, (u8*)&eth_dev_addr[0]);
	
  /* Enable MAC and DMA transmission and reception */
  ETH_Start(); 	
}

/*
*********************************************************************************************************
*	函 数 名: LwIP_Pkt_Handle
*	功能说明: 接受包处理
* 创 建 人:LLF
* 日    期:2019-06-06
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
FrameTypeDef LwIP_Pkt_Handle(void)
{
	u32 framelength = 0;
	FrameTypeDef frame = {0, 0};	


  /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
  if((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) != (u32)RESET)
  {	
	frame.length = ETH_ERROR;

    if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)  
    {
      /* Clear RBUS ETHERNET DMA flag */
      ETH->DMASR = ETH_DMASR_RBUS;
      /* Resume DMA reception */
      ETH->DMARPDR = 0;
    }

	/* Return error: OWN bit set */
    return frame; 
  }

	
  if(((DMARxDescToGet->Status & ETH_DMARxDesc_ES) == (u32)RESET) && 
     ((DMARxDescToGet->Status & ETH_DMARxDesc_LS) != (u32)RESET) &&  
     ((DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (u32)RESET))  
  {      
    /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
    framelength = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> ETH_DMARxDesc_FrameLengthShift) - 4;
	
	/* Get the addrees of the actual buffer */
	frame.buffer = DMARxDescToGet->Buffer1Addr;	
		rt_kprintf("\r\n-->ok\r\n");
  }
  else
  {
    /* Return ERROR */
    framelength = ETH_ERROR;
  }	
	
	frame.length = framelength;
	
	frame.descriptor = DMARxDescToGet;
  /* Update the ETHERNET DMA global Rx descriptor with next Rx decriptor */      
  /* Chained Mode */    
  /* Selects the next DMA Rx descriptor list for next buffer to read */ 
  DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);  	
	
	//清除标志位
  /* Set Own bit of the Rx descriptor Status: gives the buffer back to ETHERNET DMA */
  frame.descriptor->Status = ETH_DMARxDesc_OWN; 	
	
  /* When Rx Buffer unavailable flag is set: clear it and resume reception */
  if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)  
  {
    /* Clear RBUS ETHERNET DMA flag */
    ETH->DMASR = ETH_DMASR_RBUS;
    /* Resume DMA reception */
    ETH->DMARPDR = 0;
  }	
	
	/* Return Frame */
  return (frame);  
}

 

【基于QT的调色板】是一个使用Qt框架开发的色彩选择工具,类似于Windows操作系统中常见的颜色选取器。Qt是一个跨平台的应用程序开发框架,广泛应用于桌面、移动和嵌入式设备,支持C++和QML语言。这个调色板功能提供了横竖两种渐变模式,用户可以方便地选取所需的颜色值。 在Qt中,调色板(QPalette)是一个关键的类,用于管理应用程序的视觉样式。QPalette包含了一系列的颜色角色,如背景色、前景色、文本色、高亮色等,这些颜色可以根据用户的系统设置或应用程序的需求进行定制。通过自定义QPalette,开发者可以创建具有独特视觉风格的应用程序。 该调色板功能可能使用了QColorDialog,这是一个标准的Qt对话框,允许用户选择颜色。QColorDialog提供了一种简单的方式来获取用户的颜色选择,通常包括一个调色板界面,用户可以通过滑动或点击来选择RGB、HSV或其他色彩模型中的颜色。 横渐变取色可能通过QGradient实现,QGradient允许开发者创建线性或径向的色彩渐变。线性渐变(QLinearGradient)沿直线从一个点到另一个点过渡颜色,而径向渐变(QRadialGradient)则以圆心为中心向外扩散颜色。在调色板中,用户可能可以通过滑动条或鼠标拖动来改变渐变的位置,从而选取不同位置的颜色。 竖渐变取色则可能是通过调整QGradient的方向来实现的,将原本水平的渐变方向改为垂直。这种设计可以提供另一种方式来探索颜色空间,使得选取颜色更为直观和便捷。 在【colorpanelhsb】这个文件名中,我们可以推测这是与HSB(色相、饱和度、亮度)色彩模型相关的代码或资源。HSB模型是另一种常见且直观的颜色表示方式,与RGB或CMYK模型不同,它以人的感知为基础,更容易理解。在这个调色板中,用户可能可以通过调整H、S、B三个参数来选取所需的颜色。 基于QT的调色板是一个利用Qt框架和其提供的色彩管理工具,如QPalette、QColorDialog、QGradient等,构建的交互式颜色选择组件。它不仅提供了横竖渐变的色彩选取方式,还可能支持HSB色彩模型,使得用户在开发图形用户界面时能更加灵活和精准地控制色彩。
标题基于Spring Boot的二手物品交易网站系统研究AI更换标题第1章引言阐述基于Spring Boot开发二手物品交易网站的研究背景、意义、现状及本文方法与创新点。1.1研究背景与意义介绍二手物品交易的市场需求和Spring Boot技术的适用性。1.2国内外研究现状概述当前二手物品交易网站的发展现状和趋势。1.3论文方法与创新点说明本文采用的研究方法和在系统设计中的创新之处。第2章相关理论与技术介绍开发二手物品交易网站所涉及的相关理论和关键技术。2.1Spring Boot框架解释Spring Boot的核心概念和主要特性。2.2数据库技术讨论适用的数据库技术及其在系统中的角色。2.3前端技术阐述与后端配合的前端技术及其在系统中的应用。第3章系统需求分析详细分析二手物品交易网站系统的功能需求和性能需求。3.1功能需求列举系统应实现的主要功能模块。3.2性能需求明确系统应满足的性能指标和安全性要求。第4章系统设计与实现具体描述基于Spring Boot的二手物品交易网站系统的设计和实现过程。4.1系统架构设计给出系统的整体架构设计和各模块间的交互方式。4.2数据库设计详细阐述数据库的结构设计和数据操作流程。4.3界面设计与实现介绍系统的界面设计和用户交互的实现细节。第5章系统测试与优化说明对系统进行测试的方法和性能优化的措施。5.1测试方法与步骤测试环境的搭建、测试数据的准备及测试流程。5.2测试结果分析对测试结果进行详细分析,验证系统是否满足需求。5.3性能优化措施提出针对系统性能瓶颈的优化建议和实施方案。第6章结论与展望总结研究成果,并展望未来可能的研究方向和改进空间。6.1研究结论概括本文基于Spring Boot开发二手物品交易网站的主要发现和成果。6.2展望与改进讨论未来可能的系统改进方向和新的功能拓展。
1. 用户与权限管理模块 角色管理: 学生:查看个人住宿信息、提交报修申请、查看卫生检查结果、请假外出登记 宿管人员:分配宿舍床位、处理报修申请、记录卫生检查结果、登记晚归情况 管理员:维护楼栋与房间信息、管理用户账号、统计住宿数据、发布宿舍通知 用户操作: 登录认证:对接学校统一身份认证(模拟实现,用学号 / 工号作为账号),支持密码重置 信息管理:学生完善个人信息(院系、专业、联系电话),管理员维护所有用户信息 权限控制:不同角色仅可见对应功能(如学生无法修改床位分配信息) 2. 宿舍信息管理模块 楼栋与房间管理: 楼栋信息:名称(如 "1 号宿舍楼")、层数、性别限制(男 / 女 / 混合)、管理员(宿管) 房间信息:房间号(如 "101")、户型(4 人间 / 6 人间)、床位数量、已住人数、可用状态 设施信息:记录房间内设施(如空调、热水器、桌椅)的配置与完好状态 床位管理: 床位编号:为每个床位设置唯一编号(如 "101-1" 表示 101 房间 1 号床) 状态标记:标记床位为 "空闲 / 已分配 / 维修中",支持批量查询空闲床位 历史记录:保存床位的分配变更记录(如从学生 A 调换到学生 B 的时间与原因) 3. 住宿分配与调整模块 住宿分配: 新生分配:管理员导入新生名单后,宿管可按专业集中、性别匹配等规则批量分配床位 手动分配:针对转专业、复学学生,宿管手动指定空闲床位并记录分配时间 分配结果公示:学生登录后可查看自己的宿舍信息(楼栋、房间号、床位号、室友列表) 调整管理: 调宿申请:学生提交调宿原因(如室友矛盾、身体原因),选择意向宿舍(需有空位) 审批流程:宿管审核申请,通过后执行床位调换,更新双方住宿信息 换宿记录:保存调宿历史(申请人、原床位、新床位、审批人、时间) 4. 报修与安全管理模块 报修管理: 报修提交:学生选择宿舍、设施类型(如 "
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值