1409|1

659

帖子

1

TA的资源

纯净的硅(中级)

楼主
 

【上海航芯 ACM32F070开发板+触控功能评估板】—— UART例程 [复制链接]

 

 

 

 

1.4. UART例程

UART的通讯方式有LOOP(循环读取UART状态寄存器,并根据状态来读、写数据寄存器)、DMA、INT等方式。并且可以使用ABORT函数来中止传输。

由于开发板上板载的USB转UART功能默认连接的是UART2,因此可以将POLL、DMA两个测试代码修改为UART2,IT方式的例程是UART1、2、3均有,无需修改。

1.4.1. TEST_POLL

采用轮询方式读取UART状态寄存器,然后根据状态(写时数据寄存器空、读时数据寄存器满),进行相应的读写。为方便UART2测试,修改代码如下:

/* 循环模式 */
case TEST_LOOP:
{
    for(;;)
    {
        HAL_UART_Receive(&UART2_Handle, gu8_RxBuffer, sizeof(gu8_RxBuffer), 200);

        HAL_UART_Transmit(&UART2_Handle, gu8_RxBuffer, UART2_Handle.lu32_RxCount, 0);

        memset(gu8_RxBuffer, 0, sizeof(gu8_RxBuffer));
    }
}break;

运行效果如图

在调试界面,可以直接在UART2的寄存器中写入数据,即可看到串口终端显示相应的数据。

1.4.2. TEST_UART2

HAL_UART_Receive_IT函数中,设置各项参数后,调用

/* Enable RX and RTI interrupt */
SET_BIT(huart->Instance->IE,UART_IE_RXI|UART_IE_RTI);

使能UART的接收中断,然后在中断例程中,HAL_UART_IRQHandler完成中断后操作,最终调用HAL_UART_RxCpltCallback,即

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance ==UART1)  // receive data by UART1
    {
                gu32_RxCpltStatus= true;
    }
    else if(huart->Instance ==UART2) //receive data by UART2
        {
                gu32_RxCpltStatus2 =true;
        }
        else if(huart->Instance ==UART3) // receive data by UART3
        {
                gu32_RxCpltStatus3 =true;
        }
}

实现的对标志位的设置,应用程序检测到这个标志位后,进行响应的操作,即:

/* 中断模式 */
case TEST_UART2:
{
        while(1)
        {
                HAL_UART_Receive_IT(&UART2_Handle, gu8_RxBuffer, sizeof(gu8_RxBuffer), UART_RX_FIFO_1_2);    // length should <= sizeof(gu8_RxBuffer)

                while(1)
                {
                        while (!gu32_RxCpltStatus2);

                        gu32_RxCpltStatus2=false;

                        memcpy(gu8_TxBuffer, gu8_RxBuffer, UART2_Handle.lu32_RxCount);

                        HAL_UART_Transmit_IT(&UART2_Handle, gu8_TxBuffer, UART2_Handle.lu32_RxCount, UART_TX_FIFO_1_2);

                        while (!gu32_TxCpltStatus2);

                        gu32_TxCpltStatus2 =false;

                        break;
                }
        }
}break;

运行效果如图:

1.4.3. TEST_DMA

UART的DMA模式,相比中断模式,更节省CPU。配置了DMA后,启动DMA传输,DMA自动将数据发送到UART的数据寄存器,当一个UART数据字节发送后,UART自动发送DMA请求到DMA_CH1,DMA控制器根据设置自动递增地址后,获取相应数据并发送到UART,最终完成所有数据发送后,产生一个DMA中断,在DMA中断服务例程中调用UART2_DMA_ITC_Callback函数,该函数设置gu32_DMA_Status标志位,以便下一轮循环。

为调试方便,修改TEST_DMA测试代码为UART2,如下:

        /* DMA模式 */
case TEST_DMA:
{
    DMA_CH1_Handle.Instance              = DMA_Channel0;
    DMA_CH1_Handle.Init.Data_Flow        = DMA_DATA_FLOW_M2P;
    DMA_CH1_Handle.Init.Request_ID       = REQ7_UART2_SEND;
    DMA_CH1_Handle.Init.Source_Inc       = DMA_SOURCE_ADDR_INCREASE_ENABLE;
    DMA_CH1_Handle.Init.Desination_Inc   = DMA_DST_ADDR_INCREASE_DISABLE;
    DMA_CH1_Handle.Init.Source_Width     = DMA_SRC_WIDTH_BYTE;
    DMA_CH1_Handle.Init.Desination_Width = DMA_DST_WIDTH_BYTE;

    DMA_CH1_Handle.DMA_ITC_Callback = UART2_DMA_ITC_Callback;

    HAL_DMA_Init(&DMA_CH1_Handle);

    __HAL_LINK_DMA(UART2_Handle, HDMA_Tx, DMA_CH1_Handle);


    gu32_DMA_Status = true;

    for(;;)
    {
        if (gu32_DMA_Status)
        {
            gu32_DMA_Status = false;

            memset(gu8_RxBuffer, 0, 512);
        }

        lu8_ret=HAL_UART_Receive(&UART2_Handle, gu8_RxBuffer, sizeof(gu8_RxBuffer), 100);

        lu8_ret=HAL_UART_Transmit_DMA(&UART2_Handle, gu8_RxBuffer, UART2_Handle.lu32_RxCount);

    }
}break;

运行效果如下:

1.4.4. TEST_ABORT

UART的ABORT函数主要完成对DMA或者INT的取消,对于轮询发送/接收的,则重置其传输计数,并将其busy标志置位为false。代码如下:

/*********************************************************************************
* Function    : HAL_UART_Abort
* Description : Abort ongoing transfers(blocking mode)
* Input       : UART handle
* Output      :
**********************************************************************************/
HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
{
#if (USE_FULL_ASSERT == 1)
        if (!IS_UART_ALL_INSTANCE(huart->Instance))    return HAL_ERROR;
#endif

        /*disble all interrupt*/
        huart->Instance->IE  =0x00;

        /* Disable the UART DMA Tx request if enable */
        if(READ_BIT(huart->Instance->DMACR, UART_DMACR_TXDMAE))
        {
                CLEAR_BIT(huart->Instance->DMACR, UART_DMACR_TXDMAE);

                /* Abort the UART Tx Channel   */
                if(huart->HDMA_Tx)
                {
                        /*Set the UART DMA Abort callback to Null */
                        huart->HDMA_Tx->DMA_ITC_Callback =NULL;

                        if(HAL_DMA_Abort(huart->HDMA_Tx)!=HAL_OK)
                        {
                                return HAL_TIMEOUT;
                        }
                }
        }

        /* Disable the UART DMA Rx request if enable */
        if(READ_BIT(huart->Instance->DMACR, UART_DMACR_RXDMAE))
        {
                CLEAR_BIT(huart->Instance->DMACR, UART_DMACR_RXDMAE);

                /* Abort the UART Rx Channel   */
                if(huart->HDMA_Rx)
                {
                        /*Set the UART DMA Abort callback to Null */
                        huart->HDMA_Rx->DMA_ITC_Callback =NULL;

                        if(HAL_DMA_Abort(huart->HDMA_Rx)!=HAL_OK)
                        {
                                return HAL_TIMEOUT;
                        }
                }
        }

        /*Reset Tx and Rx Transfer size*/
        huart->lu32_TxSize = 0;
        huart->lu32_RxSize = 0;

        /* Restore huart->lu8_TxBusy and huart->lu8_RxBusy to Ready */
        huart->lu8_TxBusy = false;
        huart->lu8_RxBusy = false;

        return HAL_OK;
}

UART的ABORT函数测试代码和运行效果如下:

对于UART1和UART2,则在板子上用杜邦线连接SWD排针的Target_VCP_RX/Target_VCP_TX到UART1或者UART3的对应的TX/RX引脚(或者用额外的USB转串口模块连接),如图:

对应的运行效果截图:

最新回复

用轮询方式读取UART状态寄存器,再根据状态,进行相应的读写,比较方便UART2测试,方法不错     详情 回复 发表于 2022-11-12 09:13
点赞 关注
 
 

回复
举报

6802

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

用轮询方式读取UART状态寄存器,再根据状态,进行相应的读写,比较方便UART2测试,方法不错
 

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表