직렬 주종 통신 방식 단편기 종기 실현

6411 단어
여기 있는 데모는 1대 1의 통신입니다. 1대 다중 수정 프로토콜은 기기 주소 필드를 추가하고 관련 사용을 수정하면 됩니다. 여기에서 항목의 통신 임무를 캡처할 수 있습니다.
하드웨어 플랫폼 STM32 시스템 freertos
// #inlcude   



typedef struct{
	uint8_t len;
	uint8_t msg;
	uint8_t payloadLen;
}_msg;

#define FRAME_END_TIME	50//ms  
#define RX_BUFFER_SIZE	256
#define TX_BUFFER_SIZE	256
static uint8_t RxBuffer[RX_BUFFER_SIZE];
static uint8_t TxBuffer[TX_BUFFER_SIZE];
static uint16_t Rx_p=0;
static uint8_t FrameStatus=1;
static int nowRxTick=-1;
static int lastRxTicke=0;

extern uint32_t Sys_ms_Tick;//  
extern uint8_t Source[];
extern uint8_t Destination[];
extern char IMEI[];
extern char IOT_IP[];
extern char NB_IOT_NET[];

static void InterruptReviceCallback(uint8_t a)
{
	
		if(0==FrameStatus)
		{
			if(Rx_p>8;
	HAL_UART_Transmit(&huart1,TxBuffer,len,0xffff);
}


void DebugInit()
{
	UART1_Callback = InterruptReviceCallback;//    
	StartUART_Rx(&huart1);//      
	FrameStatus=1;
	Urt1ReviceBegin();//    
}


void DebugTask()
{
	_msg *rmsg=(_msg*)RxBuffer;
	_msg *tmsg=(_msg*)TxBuffer;
	
	uint8_t *rpayload = &RxBuffer[3];
	uint8_t *tpayload = &TxBuffer[3];
	uint8_t len=0;
	uint16_t temp;
	DebugInit();
	while(1)
	{
		osDelay(FRAME_END_TIME);
		if(GetUsart1Frame())
		{
			if(0==Crc16_Modbus(RxBuffer,Rx_p))
			{
				switch(rmsg->msg)
				{
					case 0x01:
						tmsg->len=5+6;
						tmsg->msg=0x81;
						tmsg->payloadLen=6;
						memcpy(tpayload,Source,6);
						SendFrame();
					break;
					case 0x02:
						if(rmsg->len==11)
						{
							memcpy(Source,rpayload,6);			
						}
						tmsg->len=5+0;
						tmsg->msg=0x82;
						tmsg->payloadLen=0;	
						
						SendFrame();					
					break;
					case 0x03:
						tmsg->len=5+6;
						tmsg->msg=0x83;
						tmsg->payloadLen=6;
						memcpy(tpayload,Destination,6);
						SendFrame();
					break;	
					case 0x04:
						memcpy(Destination,rpayload,6);			
						tmsg->len=5+0;
						tmsg->msg=0x84;
						tmsg->payloadLen=0;	
						SendFrame();					
					break;
					case 0x05:
						tmsg->len=5+strlen(IMEI)+1;
						tmsg->msg=0x85;
						tmsg->payloadLen=strlen(IMEI)+1;
						memcpy(tpayload,IMEI,strlen(IMEI)+1);
						SendFrame();
					break;	
					case 0x06:
						tmsg->len=5+strlen(IOT_IP)+1;
						tmsg->msg=0x86;
						tmsg->payloadLen=strlen(IOT_IP)+1;
						memcpy(tpayload,IOT_IP,strlen(IOT_IP)+1);
						SendFrame();
					break;
					case 0x07:
						len = strlen((char*)rpayload);
						if(len<64)
						{							
							memcpy(IOT_IP,rpayload,strlen((char*)rpayload));		
							tmsg->len=5+1;
							tmsg->msg=0x87;
							tmsg->payloadLen=1;
							tpayload[0] = 0;
							SendFrame();					
						}
						else
						{
							tmsg->len=5+1;
							tmsg->msg=0x87;
							tmsg->payloadLen=1;
							tpayload[0] = 1;
							SendFrame();	
						}
					break;
					case 0x08:
						tmsg->len=5+strlen(NB_IOT_NET)+1;
						tmsg->msg=0x88;
						tmsg->payloadLen=strlen(NB_IOT_NET)+1;
						memcpy(tpayload,NB_IOT_NET,strlen(NB_IOT_NET)+1);
						SendFrame();
					break;
					case 0x09:
						len = strlen((char*)rpayload);
						if(len<64)
						{
							memcpy(NB_IOT_NET,rpayload,strlen((char*)rpayload));		
							tmsg->len=5+1;
							tmsg->msg=0x89;
							tmsg->payloadLen=1;
							tpayload[0] = 0;
							SendFrame();					
						}
						else
						{
							tmsg->len=5+1;
							tmsg->msg=0x89;
							tmsg->payloadLen=1;
							tpayload[0] = 1;
							SendFrame();	
						}
					break;				
					case 0x0a:
						SaveSysInfo();
						tmsg->len=5;
						tmsg->msg=0x8a;
						tmsg->payloadLen=0;
						SendFrame();		
					break;
					case 0x0b:
						memset(Source,0,6);
						Source[5]=1;
						memset(Destination,0,6);
						Destination[5]=1;
						strcpy(IMEI,"000000000");
						strcpy(IOT_IP,"AT+NCDP=180.101.147.115,5683\r
"); strcpy(NB_IOT_NET,"AT+CGDCONT=1,\"IP\",\"ctnet\"\r
"); SaveSysInfo(); SYS.uploadTime = 60; SaveInitInfo(); tmsg->len=5; tmsg->msg=0x8b; tmsg->payloadLen=1; SendFrame(); break; case 0x0c: tmsg->len=5+strlen(COMPY_ID)+1; tmsg->msg=0x8c; tmsg->payloadLen=strlen(COMPY_ID)+1; memcpy(tpayload,COMPY_ID,strlen(COMPY_ID)+1); SendFrame(); break; case 0x0d: SYS.terminalMode=0; SaveInitInfo(); osDelay(50); printf(" \r
"); HAL_NVIC_SystemReset(); break; case 0x0e: SYS.terminalMode=2; SaveInitInfo(); SaveTerminalInfo(); osDelay(50); printf(" \r
"); HAL_NVIC_SystemReset(); break; case 0x0f: printf("det%d ,arc%d ,ocp%d ,mmn%d \r
",SYS.detectorNum,SYS.arcDetectorNum,SYS.ocpNum,SYS.multiMeterNum); break; case 0x10: temp = rpayload[0]|rpayload[1]<<8; if(temp>0&&temp<2000) { SYS.uploadTime = temp; SaveInitInfo(); tmsg->len=5+1; tmsg->msg=0x90; tmsg->payloadLen=1; tpayload[0] = 0; SendFrame(); } else { tmsg->len=5+1; tmsg->msg=0x90; tmsg->payloadLen=1; tpayload[0] = 1; SendFrame(); } break; case 0x11: tmsg->len=5+2; tmsg->msg=0x91; tmsg->payloadLen=2; tpayload[0] = SYS.uploadTime; tpayload[1] = SYS.uploadTime>>8; SendFrame(); break; case 0x7f: tmsg->len=5; tmsg->msg=0xff; tmsg->payloadLen=0; SendFrame(); osDelay(50); HAL_NVIC_SystemReset(); break; default:break; } } ReviceBegin(); } } }

호스트에 따라 제한 시간 매개 변수 설정
FRAME_END_TIME, FRAME을 초과하는 연속 2바이트 시간END_TIME는 한 프레임의 완성으로 판단하는데 여기서modbus-rtu 프레임 끊기 방식을 참고했다.
freertos에서 새 작업을 시작하고 DebugInit ()를while (1) 에 넣으면 됩니다. 기본 하드웨어 초기화 약,UART1Callback () 직렬 인터럽트 함수, Sysms_Tick 1ms 자동 증가 1

좋은 웹페이지 즐겨찾기