2325|2

36

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

HC32F4A0-串口中断接收与中断发送 [复制链接]

 

上篇HC32F4A0开发板内容:HC32F4A0-Keil环境搭建与点灯 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)

 

        根据官方手册可知,HC32F4A0SITB这款芯片具有10个串口资源,本次测试只用到了USART1。测试内容是,使用串口调试助手以1ms间隔向单片机发送数据,随后单片机上电,查看单片机串口是否会有问题,由于板载没有485,没办法将设备挂在总线上测试。曾经,485总线上有数据,设备上电时,串口初始化顺序问题,导致单片机串口卡死过,进了错误中断,因此想测试下,竟然没有485电路。

 

        使用的是USART1,对用开发板的管脚是USART1_TX_PIN是PH15,USART1_RX_PIN是PH13;首先我们需要对串口进行管脚配置,其次是管脚功能复用,第三是串口参数配置,最后是中断配置。在手册中可以知道,PH15和PH13的通讯复用位FG1(Func32~63),那个表格太难看了,字太小了,然后再去看Func32~63这个表格,可以对应USART1_TX是Func32,USART1_RX是Func33;说实话这个看起来有点繁琐,不想其他手册,一目了然。不光如此,程序中还没有定义好,像ST或GD直接是一目了然,这个固件库直接是GPIO_FUNC_33,但凡名字换成USART1_AF_xx这种,我也不至于去查手册。

        接着是串口中断配置,这个配置也是与ST或GD大不相同,hc32f4a0.h中定义了大量的中断号,我们可以随意使用,但也不是每个都能用,具体需要查看表格,下表是USART1的中断可使用的中断号表格。这里HC32F4A0这个单片机中断都是单独分开的,接收、发送、错误等中断都需要单独配置。

        以下是USART1的串口配置代码,代码均有注释:

/**************************************************************
  * [url=home.php?mod=space&uid=32621]@name[/url] bsp_Usart_Init
  * [url=home.php?mod=space&uid=159083]@brief[/url] * @param   None
  * @retval
  * [url=home.php?mod=space&uid=1315547]@author[/url] Zachary
  * [url=home.php?mod=space&uid=34591]@data[/url] 2023-02-22
 **************************************************************/
void bsp_Usart_Init( void )
{
	stc_gpio_init_t Gpio_InitStruct;
    stc_usart_uart_init_t Usart_InitStruct;
    stc_irq_signin_config_t stcIrqSigninConfig;

    LL_PERIPH_WE( LL_PERIPH_FCG | LL_PERIPH_GPIO | LL_PERIPH_INTC );				/* ---解保护--- */
	
	Gpio_InitStruct.u16PinDir = PIN_DIR_OUT;				/* --方向 输入或输出--- */
	Gpio_InitStruct.u16PinDrv = PIN_HIGH_DRV;				/* --驱动能力--- */
	Gpio_InitStruct.u16PinAttr = PIN_ATTR_DIGITAL;			/* --数字量或模拟量--- */
	Gpio_InitStruct.u16PinOutputType = PIN_OUT_TYPE_CMOS;	/* --正常CMOS电平输出或NMOS开漏输出--- */
	Gpio_InitStruct.u16PinState = PIN_STAT_SET;				/* --初始化后电平状态--- */
	Gpio_InitStruct.u16PullUp = PIN_PU_ON;					/* --上拉输出--- */
	Gpio_InitStruct.u16ExtInt = PIN_EXTINT_OFF;				/* --中断功能不开启--- */
	Gpio_InitStruct.u16Invert = PIN_INVT_OFF;				/* --反向功能不开启--- */
	Gpio_InitStruct.u16Latch = PIN_LATCH_OFF;				/* --输出锁存功能不开启--- */
	GPIO_Init( USART1_TX_PORT, USART1_TX_PIN, &Gpio_InitStruct );
	
	Gpio_InitStruct.u16PinDir = PIN_DIR_IN;					/* --方向 输入或输出--- */
	Gpio_InitStruct.u16PinDrv = PIN_HIGH_DRV;				/* --驱动能力--- */
	Gpio_InitStruct.u16PinAttr = PIN_ATTR_DIGITAL;			/* --数字量或模拟量--- */
	Gpio_InitStruct.u16PinOutputType = PIN_OUT_TYPE_CMOS;	/* --正常CMOS电平输出或NMOS开漏输出--- */
	Gpio_InitStruct.u16PinInputType = PIN_IN_TYPE_CMOS;		/* --施密特输入或CMOS输入--- */
	Gpio_InitStruct.u16PinState = PIN_STAT_SET;				/* --初始化后电平状态--- */
	Gpio_InitStruct.u16PullUp = PIN_PU_ON;					/* --上拉输出--- */
	Gpio_InitStruct.u16ExtInt = PIN_EXTINT_OFF;				/* --中断功能不开启--- */
	Gpio_InitStruct.u16Invert = PIN_INVT_OFF;				/* --反向功能不开启--- */
	Gpio_InitStruct.u16Latch = PIN_LATCH_OFF;				/* --输出锁存功能不开启--- */
	GPIO_Init( USART1_RX_PORT, USART1_RX_PIN, &Gpio_InitStruct );

    /* Configure USART RX/TX pin. */
    GPIO_SetFunc( USART1_RX_PORT, USART1_RX_PIN, GPIO_FUNC_33 );
    GPIO_SetFunc( USART1_TX_PORT, USART1_TX_PIN, GPIO_FUNC_32 );

    USART1_FCG_ENABLE();		/* ---使能串口1功能时钟--- */

    USART_UART_StructInit( &Usart_InitStruct );
    Usart_InitStruct.u32ClockSrc = USART_CLK_SRC_INTERNCLK;			/* ---选择内部时钟--- */
    Usart_InitStruct.u32ClockDiv = USART_CLK_DIV16;					/* ---时钟64分频--- */
    Usart_InitStruct.u32CKOutput = USART_CK_OUTPUT_DISABLE;			/* ---不输出时钟--- */
    Usart_InitStruct.u32Baudrate = 115200UL;						/* ---波特率过高程序卡死时 请调整时钟分频因子--- */
    Usart_InitStruct.u32Parity = USART_PARITY_NONE;
    Usart_InitStruct.u32DataWidth = USART_DATA_WIDTH_8BIT;
    Usart_InitStruct.u32StopBit = USART_STOPBIT_1BIT;
    Usart_InitStruct.u32FirstBit = USART_FIRST_BIT_LSB;				/* ---LSB先行--- */
    Usart_InitStruct.u32HWFlowControl = USART_HW_FLOWCTRL_NONE;
    Usart_InitStruct.u32StartBitPolarity = USART_START_BIT_LOW;		/* ---起始位为低--- */
    Usart_InitStruct.u32OverSampleBit = USART_OVER_SAMPLE_16BIT;	/* ---16倍过采样--- */

    if ( LL_OK != USART_UART_Init( CM_USART1, &Usart_InitStruct, NULL ) )
    {
        for ( ;; )
        {
        }
    }

    stcIrqSigninConfig.enIRQn = INT137_IRQn;						/* ---中断向量号--- */
    stcIrqSigninConfig.enIntSrc = INT_SRC_USART1_RI;				/* ---中断类型--- */
    stcIrqSigninConfig.pfnCallback = &USART1_RxCpltCallback;		/* ---中断回调函数--- */
    INTC_IrqSignIn( &stcIrqSigninConfig );
    NVIC_ClearPendingIRQ( stcIrqSigninConfig.enIRQn );				/* ---清中断--- */
    NVIC_SetPriority( stcIrqSigninConfig.enIRQn, 0UL );				/* ---设置中断优先级--- */
    NVIC_EnableIRQ( stcIrqSigninConfig.enIRQn );

    stcIrqSigninConfig.enIRQn = INT001_IRQn;						/* ---中断向量号--- */
    stcIrqSigninConfig.enIntSrc = INT_SRC_USART1_TI;				/* ---中断类型--- */
    stcIrqSigninConfig.pfnCallback = &USART1_TxCpltCallback;		/* ---中断回调函数--- */
    INTC_IrqSignIn( &stcIrqSigninConfig );
    NVIC_ClearPendingIRQ( stcIrqSigninConfig.enIRQn );				/* ---清中断--- */
    NVIC_SetPriority( stcIrqSigninConfig.enIRQn, 0UL );				/* ---设置中断优先级--- */
    NVIC_EnableIRQ( stcIrqSigninConfig.enIRQn );

    LL_PERIPH_WP( LL_PERIPH_FCG | LL_PERIPH_GPIO | LL_PERIPH_INTC );				/* ---上保护--- */

    USART_FuncCmd( CM_USART1, ( USART_TX | USART_RX | USART_INT_RX ), ENABLE );		/* ---打开发送接收功能、中断接收功能--- */
    USART_FuncCmd( CM_USART1, USART_INT_TX_EMPTY, DISABLE );

    COM1_Info.pRxBuf = RxBuf;
	COM1_Info.pTxBuf = TxBuf;
}

        以下是串口中断接收回调函数代码:

/**************************************************************
  * @Name    USART1_RxCpltCallback
  * @brief
  * @param   None
  * @retval
  * @author  Zachary
  * @Data    2023-02-20
 **************************************************************/
static void USART1_RxCpltCallback( void )
{
    uint8_t u8Data = 0x0;
    if( USART_GetStatus( CM_USART1, USART_FLAG_RX_FULL ) != RESET )
    {
        u8Data = ( uint8_t )USART_ReadData( CM_USART1 );
        COM1_Info.pRxBuf[COM1_Info.RxCnt] = u8Data;
        USART_WriteData( CM_USART1, COM1_Info.pRxBuf[COM1_Info.RxCnt] );
        COM1_Info.RxCnt++;
    }
}

        以下是串口中断发送回调函数代码:

/**************************************************************
  * @Name    USART1_TxCpltCallback
  * @brief
  * @param   None
  * @retval
  * @author  Zachary
  * @Data    2023-02-21
 **************************************************************/
static void USART1_TxCpltCallback( void )
{
    if( USART_GetStatus( CM_USART1, USART_FLAG_TX_EMPTY ) != RESET )
    {
        if( COM1_Info.TxLen > 0x00 )
        {
            CM_USART1->DR = COM1_Info.pTxBuf[COM1_Info.TxCnt] & 0X01FF;
            COM1_Info.TxCnt++;
            COM1_Info.TxLen--;
        }
        else
        {
            COM1_Info.TxLen = 0x00;
            COM1_Info.TxCnt = 0x00;
            USART_FuncCmd( CM_USART1, USART_INT_TX_EMPTY, DISABLE );
        }
    }
}

/**************************************************************
  * @Name    USART1_SendData_UseIT
  * @brief
  * @param   pBuf: [输入/出]
**			 pLen: [输入/出]
  * @retval
  * @author  Zachary
  * @Data    2023-02-23
 **************************************************************/
void USART1_SendData_UseIT( uint8_t *pBuf, uint8_t pLen )
{
    COM1_Info.TxCnt = 0x00;
    COM1_Info.TxLen = pLen;
	memcpy( COM1_Info.pTxBuf, pBuf, COM1_Info.TxLen );
    CM_USART1->DR = pBuf[COM1_Info.TxCnt];
    COM1_Info.TxCnt++;
    COM1_Info.TxLen--;
    USART_FuncCmd( CM_USART1, USART_INT_TX_EMPTY, ENABLE );
}

以下是主程序代码:

/**************************************************************
  * @Name    main
  * @brief
  * @param   None
  * @retval
  * @author  Zachary
  * @Data    2022-02-13
 **************************************************************/
int32_t main( void )
{
    char SendBuf[] = "Hello World\n";
    SysInit();
	
	printf("This is HC32F4A0 USART1 test.\n");
	USART1_SendData_UseIT( ( uint8_t * )SendBuf, strlen( SendBuf ) );
	
    while( 1 )
    {
		
        LED10_TOGGLE();
        LED11_TOGGLE();
		delay_ms( 500 );
//		printf("This is HC32F4A0 USART1 test.\n");
//		USART1_SendData_UseIT( ( uint8_t * )SendBuf, strlen( SendBuf ) );
    }
}

/**************************************************************
  * @Name    SysInit
  * @brief
  * @param   None
  * @retval
  * @author  Zachary
  * @Data    2023-02-13
 **************************************************************/
static void SysInit( void )
{
	NVIC_SetPriorityGrouping( 0x00000003U );	/* ---设置为4位抢占优先级 */
    bsp_SetSysClk();
	CLK_GetClockFreq( &sysclk );	/* ---检查时钟是否正确--- */
	delay_init( 240 );				/* ---系统滴答定时器初始化--- */
//	delay_ms( 1000 );
    bsp_Gpio_Init();				/* ---初始化Gpio--- */
	bsp_Usart_Init();
}

        以下是串口查询发送与中断发送测试图片,This is HC32F4A0 USART1 test.用的是查询发送,hello world用的是中断发送。

以下是串口中断回显测试图片:
HC32F4A0_USART.7z (1.08 MB, 下载次数: 33)

 

 

最新回复

谢谢,有用!!   详情 回复 发表于 2023-7-6 10:57
点赞(1) 关注
 
 

回复
举报

6972

帖子

11

TA的资源

版主

沙发
 

谢谢对串口配置的详细讲解,这样讲一下,明白多了。

 
 
 

回复

6

帖子

1

TA的资源

一粒金砂(初级)

板凳
 

谢谢,有用!!

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表