串口接收方式

本文详细介绍了在A31G12x平台上如何使用USART进行通信,包括初始化、数据接收处理以及XModemCRC-16校验算法的应用,确保数据传输的准确性。
摘要由CSDN通过智能技术生成
*源文件 
 @bef  WTO  file  
*/

#include <stdio.h>
#include "A31G12x_int.h"
#include "A31G12x_usart1n.h"
#include "A31G12x_pcu.h"
#include "Wto_uart.h"
#include "Wto_Time.h" 
#include "flash.h"
extern void Delay_ms(uint16_t t_ms);

uint8_t Rxbuffer[RX_BUFFER_SIZE];
uint8_t Txbuffer[RX_BUFFER_SIZE];
uint8_t rxStates = TO_START;
//定义与初始化
UartHandle Usart11_Handle ={
 .RxHead   = 0,
 .Rxtail   = 0,
 .RxStatus = 0,
 .RxSize   = 0,
 .RxBuf    = Rxbuffer,
 .TxHead   = 0,
 .Txtail   = 0,
 .RxSize   = 0,
 .TxStatus = 0,
 .TxBuf    = Txbuffer,
};


void USART11_Receive_Data(void);
void USART11_Init(void);

struct __FILE { int handle; /* Add whatever needed */ };
FILE __stdout;
FILE __stdin;

int fputc(int ch, FILE *f) 
{
  while( UST_CheckBusy(USART11));
  UST_SendByte(USART11,ch);
  return(ch);
}

/*****************************************************************************************/
/*									串口USART											*/
/*****************************************************************************************/
void USART11_Init(void)
{
  UST_CFG_Type USTConfigStruct;
	
	PCU_SetDirection(PD, 3, ALTERN_FUNC);   
	PCU_ConfigureFunction(PD, 3, FUNC1);
	PCU_ConfigurePullupdown(PD,3, ENPU);

	PCU_SetDirection(PD, 2, ALTERN_FUNC);  
	PCU_ConfigureFunction(PD, 2, FUNC1);
  
	// 115200-8-无-1	
	USTConfigStruct.Mode = UST_UART_MODE;
	USTConfigStruct.Baud_rate = 115200;       
	USTConfigStruct.Databits  = UST_DATABIT_8;
	USTConfigStruct.Parity = UST_PARITY_NONE;
	USTConfigStruct.Stopbits = UST_STOPBIT_1;
  
	UST_Init(USART11, &USTConfigStruct);
	
	UST_IntConfig((USART1n_Type *)USART11, UST_INTCFG_RXC, ENABLE);
  
	NVIC_SetPriority(USART11_IRQn, 3);
	NVIC_EnableIRQ(USART11_IRQn);
	EInt_MaskDisable(UST11_MASK);
	UST_Enable(USART11, ENABLE);  
	
	__enable_irq();	
	
}


void USART11_Handler(void)
{
	uint32_t intsrc, tmp;	
	intsrc = UST_GetStatus(USART11);
	tmp = intsrc & UST_SR_BITMASK;  
	if ((tmp & UST_SR_RXC) == UST_SR_RXC)
	{
    USART11_Receive_Data();
	}  
	if ((tmp & UST_SR_TXC) == UST_SR_TXC)
	{
    //		 UST_ClearStatus(USART11, UST_STATUS_TXC);
	}
}

void USART11_Receive_Data(void)
{
  uint8_t date;
  uint32_t rLen;
  
  while(1)
  {   
    rLen = UST_Receive((USART1n_Type *)USART11, &date, 1, NONE_BLOCKING);
    if (rLen)
    {
      if( 0== Usart11_Handle.RxSize ){
      
        Usart11_Handle.RxHead = 0;
        Usart11_Handle.Rxtail = 0;
      } 
      Usart11_Handle.RxBuf[ Usart11_Handle.Rxtail] =  date;
      Usart11_Handle.Rxtail++;
     if( ++Usart11_Handle.RxSize >= RX_BUFFER_SIZE )
     {
        Usart11_Handle.RxSize = RX_BUFFER_SIZE;
        if( ++Usart11_Handle.RxHead >= RX_BUFFER_SIZE ){
              Usart11_Handle.RxHead = 0;        
        }
     }
     Usart11_Handle.RxStatus = IS_BUSY;  //  receive data now
     Usart11_Handle.RxTim = GetTickSystemTime();
    }
    else 
    {
      break;
    }
  }
}

//获取uart的接收状态
uint8_t GetUartRxStatus( void )
{
	uint32_t ticknow = GetTickSystemTime();
	if( Usart11_Handle.RxStatus == IS_BUSY )
	{	
		if( ticknow > Usart11_Handle.RxTim )
		{	
			if( ( ticknow - Usart11_Handle.RxTim ) >= 30 ) //30ms
			{
				Usart11_Handle.RxStatus = IS_IDLE;
			}
		} else {
			if( ( ( 0xffffffff - Usart11_Handle.RxTim ) + ticknow ) >= 30 )
			{
				Usart11_Handle.RxStatus = IS_IDLE;
			}
		}
	}
	return Usart11_Handle.RxStatus;
}

void UartSendCmd(uint8_t Cmd)
{
 UST_Send(USART11, &Cmd, 1, BLOCKING);
}

// 使用XModem多项式而不是Modbus多项式

// CRC算法名称	  多项式公式	         宽度  多项式	 初始值	结果异或值	输入反转	  输出反转
// CRC-16/XMODEM	 x16 + x12 + x5 + 1	  16   0x1021	  0000	 0000	    false	  false
uint16_t XModem_Crc16(const uint8_t *buffer, uint16_t len)
{
  uint16_t polynom = 0x1021; // XModem_CRC多项式
  uint8_t i;
  uint16_t crc16 = 0x0000;

  if (len == 0)
  {
    return ERROR;
  }

  while (len--)
  {
    crc16 ^= ((*buffer) << 8);
    for (i = 0; i < 8; i++)
    {
      if (crc16 & 0x8000)
      {
        crc16 <<= 1;
        crc16 ^= polynom;
      }
      else
      {
        crc16 <<= 1;
      }
    }
    buffer++;
  }
  return crc16;
}


void UsartReceiveHandle(void)
{
  extern uint16_t do_crc(uint16_t reg_init,uint8_t* data,uint16_t length);
  static uint8_t rxBuf[RX_BUFFER_SIZE] = {0};
  static uint8_t rxBuf_OK[128] = {0};
  static uint16_t CurrentRxSize = 0;
  static uint16_t receiveNum = 0; //计数接收数量
  static uint8_t receiveFlag = 0; //接收数据标志
  uint16_t crc16Check =0;
  uint16_t i;
  uint8_t chekL,chekH;
  uint32_t Tcnt =0;
  static uint32_t Tcnlast =0;
  static uint16_t TimerTriggle = 10000;

  if( GetUartRxStatus( ) == IS_IDLE )  //判断接收为空闲30ms时,认为接收完数据
  {     
    
    if( Usart11_Handle.RxSize )
    {
      printf("Rdata[");
      for(i=0; i< Usart11_Handle.RxSize; i++ ){
        rxBuf[i] =  Usart11_Handle.RxBuf[i];
        printf("%02x ", rxBuf[i]);       
      }
      printf("]\n");
     // printf("dataSize:%02d\n",Usart11_Handle.RxSize);
    
    CurrentRxSize = Usart11_Handle.RxSize;
    for(i =0;i< 128;i++)
    {
      rxBuf_OK[i] = rxBuf[i+3];
    }
    Usart11_Handle.RxSize = 0;
    Usart11_Handle.RxHead = 0;
    Usart11_Handle.Rxtail = 0;
   }
    crc16Check = XModem_Crc16(&rxBuf_OK[0],128);
    chekH = (uint8_t)(crc16Check >> 8);
    chekL = (uint8_t)crc16Check ;
  
     if( rxBuf[0] == SOH )  //128字节一包数据
     {
            
      if((rxBuf[1] == 0x00) && (rxBuf[2] ==(uint8_t)(~rxBuf[1])) && (rxStates == TO_START ) && ( chekH == rxBuf[CurrentRxSize-2])&&(chekL == rxBuf[CurrentRxSize-1])) 
      {
         rxStates = TO_RECEIVE_DATA; //开始状态,第一包数据
         UartSendCmd(ACK);
         Delay_ms(500);//等电压稳定
         UartSendCmd(CCC);
         receiveNum = 0;
         printf("start first pack OK \n"); 
      }
      else if( (rxBuf[2] ==(uint8_t)(~rxBuf[1])) && (rxStates == TO_RECEIVE_DATA) && (receiveFlag == 0)) 
      {
       
        FlashPageWrite(80+receiveNum,(uint8_t *)rxBuf_OK);  //10K开始写
        ++receiveNum; 
        printf(" rx data OK \n");
        receiveFlag = 1;
       // UartSendCmd(ACK);    
      }
     }
    else if( rxBuf[0] == STX )//1024字节一包数据  
    {
    
    
    }     
    else if(rxBuf[0] == EOT) //通讯结束
    {
       if(rxStates == TO_RECEIVE_DATA)
       {
         UartSendCmd(ACK);
         rxStates = TO_START;
         receiveFlag = 0;
       }
       receiveNum = 0;
    }
            
  
  }
  
   Tcnt = GetTickSystemTime();
  if((uint32_t)( Tcnt - Tcnlast ) > TimerTriggle )
  {
  Tcnlast = Tcnt; 
    if(rxStates != TO_RECEIVE_DATA)
    {
      UartSendCmd(CCC); //10秒请求主机发送一次 
      receiveFlag = 0 ;
      TimerTriggle = 10000; 
    }
    else{
      if(receiveFlag && rxStates == TO_RECEIVE_DATA ){ 
       receiveFlag = 0; 
       UartSendCmd(ACK); 
       TimerTriggle = 500;
      }
    
    }
  }
   
}

头文件--------------------------------------

#ifndef _WTO_UART_H_
#define _WTO_UART_H_

#define SOH		0x01
#define STX		0x02
#define ACK		0x06
#define NACK	0x15
#define EOT		0x04
#define CCC		0x43

/* 升级的步骤 */
enum UPDATE_STATE
{
	TO_START = 0x01,
	TO_RECEIVE_DATA = 0x02,
	TO_RECEIVE_EOT1 = 0x03,
	TO_RECEIVE_EOT2 = 0x04,
	TO_RECEIVE_END = 0x05
};

#define PACKET_HEADER           (3)
#define PACKET_TRAILER          (2)
#define PACKET_OVERHEAD         (PACKET_HEADER + 128 + PACKET_TRAILER )
#define PACKET_SIZE             (128)
#define PACKET_1K_SIZE          (1024)
#define RX_BUFFER_SIZE          (( PACKET_SIZE + PACKET_OVERHEAD ) * 2 )  //133*2=266 Bytes

#define IS_IDLE  0
#define IS_BUSY  1
typedef  struct{
uint16_t RxHead;
uint16_t Rxtail;
uint16_t RxSize;
uint32_t RxTim;
uint8_t  RxStatus;
uint8_t  *RxBuf;
uint16_t TxHead;
uint16_t Txtail;
uint16_t TxSize;
uint8_t  TxStatus;
uint8_t  *TxBuf;
}UartHandle;

extern void USART11_Init(void);
extern uint8_t GetUartRxStatus(void);
extern void UsartReceiveHandle(void);


#endif



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值