华大单片机 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);//使能发送