5-HC32F460(华大单片机)-串口(基本使用)

<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/LearnHC32F460" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>

 

说明

HC32F460基础例程源码下载链接: https://github.com/yangfengwu45/learnHC32F460.git

基础外设例程是提供给已经开发过M0或M1或M3或M4等ARM内核单片机的开发人员!

例程精简扼要, 力求让开发人员快速使用华大单片机做项目!

这节说一下串口.

 

先提示一个事情

1.打开数据手册

 

 

 

 

2.第33页(我以自己使用的HC32F460JETA为例)

主要说一下后面的 Func_Grp

 

 

 

 

3.然后找到38页

 

 

 

 

4.列如:PC0

PC0后面写的是 Func_Grp1

那么这个引脚可以作为这些功能使用

 

 

 

 

 

5.单片机的USART ,SPI, I2C, I2S, 不是固定的引脚,自己根据表格去指定

 

6.华大给了好几个串口的例子

 

 

 

 

基本使用

 

 

1.串口基本的初始化

usart.c

#define USART_C_

#include "usart.h"


/*******************************************************************************
 ** \brief USART RX irq callback function.//串口接收中断函数
 ** \param [in] None
 ** \retval None
 ******************************************************************************/
static void Usart1RxIrqCallback(void)
{
    uint16_t m_u16RxData;
    m_u16RxData = USART_RecData(M4_USART1);//获取串口接收的数据
}

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

    /* 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);

    /* 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;//中断名称
    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; 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, UsartRx, Enable);//使能接收 USART_FuncCmd(M4_USART1, UsartRxInt, Enable);//使能接收中断 USART_FuncCmd(M4_USART1, UsartTx, Enable);//使能发送 }

 

usart.h

#ifndef USART_H_
#define USART_H_

#ifndef USART_C_
#define USART_C_ extern
#else
#define USART_C_ 
#endif


#include "hc32_ddl.h"

/* 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)


void usart_init(void);

#endif

 

2.在头文件里面设置串口1波特率,还有使用哪个引脚作为串口1的发送和接收引脚

我配置了波特率为115200;  PA9作为串口1的发送数据引脚;  PA10作为串口1的串口接收引脚

 

 

 

 

3.串口基本的配置

 

 

 

4,配置串口中断接收回调函数

注意:中断向量有144个:   Int000_IRQn,  Int001_IRQn,  Int002_IRQn .... Int142_IRQn,  Int143_IRQn;数字越小,越优先执行

所谓中断向量实际上就是中断地址,Int000_IRQn,  Int001_IRQn .... Int143_IRQn 都是代表不同的中断地址.

程序执行中断的时候是从Int000_IRQn,  Int001_IRQn .... Int143_IRQn 依次执行.

设置中断向量其实就是把这个回调函数放到相应的中断地址上执行,所以每个中断必须设置不同的中断向量.

下面是把串口接收中断函数放到了 Int000_IRQn, 就是说运行 Int000_IRQn地址就是执行串口接收中断函数

-------------------------------------------------------------------------

下面还有个中断优先级,中断优先级共15个

NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);//设置中断优先级

中断优先级控制着中断嵌套优先的顺序,

假设串口1接收中断向量是Int000_IRQn, 中断优先级是 2

假设串口2接收中断向量是Int001_IRQn, 中断优先级也是 2

假设同时来中断,因为他们的中断优先级是一样的,那么就会对比中断向量, 所以就会先执行串口1,再执行串口2;

--------------------------------------------------------------------------

 

假设串口1接收中断向量是Int000_IRQn, 中断优先级是 2

 

假设串口2接收中断向量是Int001_IRQn, 中断优先级是 1

 

假设同时来中断,串口2的中断优先级大于串口1, 所以就会先执行串口2,再执行串口1;

 

假设串口1在执行中断,串口2来了中断, 由于串口2的中断优先级大于串口1, 所以也会去执行串口2,再执行串口1;

 

 

 

 

 

 

 

 

 

 

4,配置串口接收错误中断回调函数

这个应该是固定处理形式,然后应该可以去掉.

 

 

 

 

 

5.使能

注意!要一句一句写!不要用 USART_FuncCmd(M4_USART1, UsartRx | XXXX | XXXX , Enable);  不可以这样子用

注意!要一句一句写!不要用 USART_FuncCmd(M4_USART1, UsartRx | XXXX | XXXX , Enable);  不可以这样子用

注意!要一句一句写!不要用 USART_FuncCmd(M4_USART1, UsartRx | XXXX | XXXX , Enable);  不可以这样子用

 

 

6.测试每隔一段时间发送一个字符1

 

 

 

        //发送字符1
        USART_SendData(M4_USART1, '1');
        //等待串口发送完成
        while (Reset == USART_GetStatus(M4_USART1, UsartTxEmpty));

 

 

 

7.对于一般的用户接收数据呢用户可以按照自己的习惯去写就可以了

 

 

 

 

 

增加空闲中断 (空闲中断需要用到定时器,在后面的章节介绍)

 

posted on 2021-06-01 09:09  广源时代  阅读(6876)  评论(0编辑  收藏  举报

导航

支付宝 QQ群