华大单片机 HC32F460 串口调试

华大单片机 HC32F460 串口调试

吐槽下,华大官方例程写到太复杂了,不熟练的一时摸不上手.

#include "drvs.h"
/*******************************************************************************
 * 云平台接口
 * AP9  USART1_TX
 * PA10 USART1_RX
 ******************************************************************************/
 
/*******************************************************************************
 * 局部类型定义('typedef')
 ******************************************************************************/
/* USART1 baudrate definition */
#define USART1_BAUDRATE                  (115200ul)
/* USART1 TX Port/Pin definition */
#define USART1_TX_PORT                   (PortA)
#define USART1_TX_PIN                    (Pin09)
/* USART1 RX Port/Pin definition */
#define USART1_RX_PORT                   (PortA)
#define USART1_RX_PIN                    (Pin10)
#define UART1_REC_LEN  			64  	//定义USART1最大接收字节数
#define USART_COUNTER_9600    3      	//接收超时

typedef struct _UART_FLAG_STRUCT
{
    
    
	uint8_t UART1_Flag;					//数据接受完成标志
	uint8_t UART1_String[UART1_REC_LEN];//最大长度,自定义
	uint8_t UART1_Counter;				//收到的数据长度,计数作用
	uint8_t usart1_start;				//接收开始,定时器计时启动
	uint8_t usart1_counter;				//定时器计时次数
}	Uart1_FlagSt;

Uart1_FlagSt Uart1FlagData;//申请结构体变量

/*******************************************************************************
 ** \brief USART RX irq callback function.//串口接收中断函数
 ** \param [in] None
 ** \retval None
 ******************************************************************************/
static void Usart1RxIrqCallback(void)
{
    
    	
	if(Uart1FlagData.UART1_Counter<UART1_REC_LEN)//总长度
	{
    
    
		Uart1FlagData.UART1_String[Uart1FlagData.UART1_Counter]=USART_RecData(M4_USART1);//读数据	
		Uart1FlagData.UART1_Counter++;//收到的数据个数+1
		Uart1FlagData.usart1_start=1;//定时器开始工作
		Uart1FlagData.usart1_counter=0;
	}else Uart1FlagData.UART1_Counter=0;//如果接受的数据超过设定值,则清空接收值,防止数据溢出	
}

/*******************************************************************************
 ** \brief USART RX error irq callback function.(串口接收错误中断处理函数)
 ** \param [in] None
 ** \retval None
 ******************************************************************************/
static void Usart1ErrIrqCallback(void)
{
    
    
    if (Set == USART_GetStatus(M4_USART1, UsartFrameErr)){
    
     USART_ClearStatus(M4_USART1, UsartFrameErr);}
    else{
    
    }

    if (Set == USART_GetStatus(M4_USART1, UsartParityErr)) {
    
    USART_ClearStatus(M4_USART1, UsartParityErr);}
    else{
    
    }

    if (Set == USART_GetStatus(M4_USART1, UsartOverrunErr)) {
    
    USART_ClearStatus(M4_USART1, UsartOverrunErr);}
    else{
    
    }
}

/*******************************************************************************
 ** \brief 串口初始化
 ** \param [in] None
 ** \retval None
 ******************************************************************************/
void usart_init(void)
{
    
    
		en_result_t enRet = Ok;
		stc_irq_regi_conf_t stcIrqRegiCfg;
		
		/* Enable peripheral clock *//*打开时钟*/
		PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_USART1 | PWC_FCG1_PERIPH_USART2 | \
		PWC_FCG1_PERIPH_USART3 | PWC_FCG1_PERIPH_USART4, Enable);
	 
		/* Initialize USART IO */ /*配置相应的IO作为串口的TX,RX引脚*/
		PORT_SetFunc(USART1_RX_PORT, USART1_RX_PIN, Func_Usart1_Rx, Disable);
		PORT_SetFunc(USART1_TX_PORT, USART1_TX_PIN, Func_Usart1_Tx, Disable);


	    /*配置串口使用的时钟和基本通信配置*/
    const stc_usart_uart_init_t stcInitCfg = {
    
    
        UsartIntClkCkNoOutput, //使用内部时钟源,不需要在其时钟输出IO上输出通信的时钟信号
        UsartClkDiv_1,         //时钟64分频 200000/64
        UsartDataBits8,        //一个字节数据用8位数据位表示
        UsartDataLsbFirst,     //先传输低位
        UsartOneStopBit,       //停止位1位
        UsartParityNone,       //无奇偶校验
        UsartSampleBit8,        //每次传输8位(1字节),也可以传输 UsartSamleBit16(16位,2字节)
        UsartStartBitFallEdge,  //起始位:RD pin下降沿
        UsartRtsEnable,        //使能RTS (串口开始传输前让RTS输出一个高脉冲信号)
    };

    /* Initialize UART *//*初始化串口配置*/
    enRet = USART_UART_Init(M4_USART1, &stcInitCfg);
    if (enRet != Ok)while (1);
    /* Set baudrate *//*设置串口波特率*/
    enRet = USART_SetBaudrate(M4_USART1, USART1_BAUDRATE);
    if (enRet != Ok)while (1);

    /* Set USART RX IRQ *//*设置串口接收中断*/
    stcIrqRegiCfg.enIRQn = Int000_IRQn;//设置中断优先级
    stcIrqRegiCfg.pfnCallback = &Usart1RxIrqCallback;//设置中断回调函数
    stcIrqRegiCfg.enIntSrc = INT_USART1_RI;//中断名称
	enIrqResign(Int000_IRQn);
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    /* Set USART RX error IRQ *//*设置串口接收错误中断*/
    stcIrqRegiCfg.enIRQn = Int001_IRQn;
    stcIrqRegiCfg.pfnCallback = &Usart1ErrIrqCallback;
    stcIrqRegiCfg.enIntSrc = INT_USART1_EI;
	enIrqResign(Int001_IRQn);
    enIrqRegistration(&stcIrqRegiCfg);
    NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

    /*Enable RX && RX interupt function && UsartTx*/

    USART_FuncCmd(M4_USART1, UsartTx, Enable);//使能发送
	USART_FuncCmd(M4_USART1, UsartRx, Enable);//使能接收
    USART_FuncCmd(M4_USART1, UsartRxInt, Enable);//使能接收中断
}	


/*******************************************************************************
 ** \brief 发送一串数据
 ** \param [2] unsigned char *data 
 ** \retval None
 ******************************************************************************/
void Uart1_SendString(unsigned char *data,unsigned char strlen)
{
    
    
	unsigned char dataleng;
	for(dataleng=0;dataleng<strlen;dataleng++)
	{
    
    
		USART_SendData(M4_USART1,data[dataleng]);
		while (Reset == USART_GetStatus(M4_USART1, UsartTxEmpty));//等待发送完成
	}
}


/*******************************************************************************
 ** \brief 串口定时器一帧结束标志          定时器中断10MS调用1次
 ** \param [in] None
 ** \retval None
 ******************************************************************************/
void UART1_InsetTimer(void)
{
    
    
	if(Uart1FlagData.usart1_start==1)//此标志位是在串口接收数据时候会置1
	{
    
    
		Uart1FlagData.usart1_counter++;//定时器计数标志位
		if(Uart1FlagData.usart1_counter>USART_COUNTER_9600)//如果超过波特率为9600时一个字节的所需要的时间,时间计算方法下面有讲解
		{
    
    
			Uart1FlagData.UART1_Flag=1;//接收完成标志
			Uart1FlagData.usart1_counter=0;//计数值清零
			Uart1FlagData.usart1_start=0;//计数器启动标志位置0
		}
	}
}




//串口发送测试	
void USART_CS(void)
{
    
    
	if(Uart1FlagData.UART1_Flag==1)
	{
    
    
		Uart1FlagData.UART1_Flag=0;
		Uart1_SendString(Uart1FlagData.UART1_String,Uart1FlagData.UART1_Counter);
		Uart1FlagData.UART1_Counter=0;
	}
	
}



//串口写函数
int uart_1_w(int fd,void *buf,int len)
{
    
    
		if(len>0 && len<=128)
		{
    
    
				Uart1_SendString(buf,len);
				return len;
		}
	  return -1;
}

//串口读函数
int uart_1_r(int fd,void *buf,int len)
{
    
    
		if(Uart1FlagData.UART1_Flag==1)
	{
    
    
		int uart =0;
		Uart1FlagData.UART1_Flag=0;
		char * data =(char *)buf;
		memcpy(data,Uart1FlagData.UART1_String,Uart1FlagData.UART1_Counter);
		uart =Uart1FlagData.UART1_Counter;
		Uart1FlagData.UART1_Counter = 0;
		return uart;
	}
	return -1;
}


void USART1_INIT_YUN(void)
{
    
    
	usart_init();				   //注册串口初始化
	rxm_reg_w(DEV_UART1,&uart_1_w);//注册串口写驱动
	rxm_reg_r(DEV_UART1,&uart_1_r);//注册串口读驱动
	rxm_addtim(60,&USART_CS);	   //注册软件定时器串口测试函数	
}

DRV_INIT(USART1_INIT_YUN);		//装载函数


在这里插入图片描述

总结:管脚设置和STM32不同 需注意

	/* Initialize USART IO */ /*配置相应的IO作为串口的TX,RX引脚*/
	PORT_SetFunc(USART1_RX_PORT, USART1_RX_PIN, Func_Usart1_Rx, Disable);
	PORT_SetFunc(USART1_TX_PORT, USART1_TX_PIN, Func_Usart1_Tx, Disable);

初始化要一句一句写 需要注意

/*Enable RX && RX interupt function && UsartTx*/
USART_FuncCmd(M4_USART1, UsartRx, Enable);//使能接收
USART_FuncCmd(M4_USART1, UsartRxInt, Enable);//使能接收中断
USART_FuncCmd(M4_USART1, UsartTx, Enable);//使能发送

系统时钟较高时需要调节分频系数需要注意

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42839808/article/details/120059745