HT5017平台串口通信整体设计V1.0-底层驱动配置

一.底层驱动配置

1.手册解读

5017共支持6路串口,且均可配置38k载波红外输出,主要功能与普通串口一致,不做赘述,直接看寄存器;

如图1,是主要的串口配置寄存器:

                                                                                                     图1

2.原理图解读

我们的表共有三中通信方式,分别是载波、红外以及485,均通过串口方式进行数据的读取和发送:

如图2:RXD485接芯片RX3管脚,TXD485接芯片TX4管脚;

                                                                                                            图2

3.软件配置

想要我们的硬件串口模块正常工作就需要配置使能,主要从以下方面进行配置:

.1串口模块时钟使能;

.2确定一种串口工作方式,然后配置寄存器;

3.1芯片库函数

下面是芯片提供的配置串口库函数,我们在配置串口的时候可以直接调用,只需给定必要的参数即可:

/*
*********************************************************************************************************
*                                         INITIAL UART MODULE
*
* 函数说明: 初始化UART模块
*
* 入口参数: UARTx               只能是HT_UART0/HT_UART1/HT_UART2/HT_UART3/HT_UART4/HT_UART5中一个
*
*           UART_InitStruct     UART初始化结构体指针,主要包含7个参数: 
*                               1) UART_Logic      : UART通讯逻辑设定
*                               2) UART_StopBits   : UART通讯停止位设定
*                               3) UART_WordLength : UART通讯数据位长度设定
*                               4) UART_Parity     : UART通讯奇偶校验设定 
*                               5) UART_BaudRate   : UART通讯波特率
*                               6) ReceiveEN       : UART接收使能控制
*                               7) SendEN          : UART发送使能控制
*
* 返回参数: 无                                      
* 
* 特殊说明: 1) HT_UART3/HT_UART4与ISO7816功能复用,如果这边有对HT_UART3/HT_UART4初始化,则不能再使用
*              HT_ISO7816_0/HT_ISO7816_1功能,其对应关系为:
*              HT_UART3 <----->HT_ISO7816_1             
*              HT_UART4 <----->HT_ISO7816_0
*           2) 由于涉及到波特率计算,所以用户在调用此函数时应先配置好系统时钟。否则如果已经配置好波特率,
*              再改变系统时钟,则波特率配置将失效
*           3) 用户在配置UART寄存器前应先使能UART模块,具体参见HT_CMU_ClkCtrl1Config()函数
*********************************************************************************************************
*/
void HT_UART_Init(HT_UART_TypeDef* UARTx, UART_InitTypeDef* UART_InitStruct)
{
    /*  assert_param  */
    
    uint32_t tempreg,sysclk;
    
    UARTx->MODESEL = UART_MODESEL_UART;                                   /*!< 选择为UART功能         */
                                                                          /*!< 只对Uart3/4有效        */

    tempreg = UARTx->UARTCON & (UART_UARTCON_TXIE | UART_UARTCON_RXIE);   /*!< 保留TXIE,RXIE不变     */
    
    if(UART_InitStruct->UART_Parity != UartParity_Disable )
    {
        tempreg |= UART_UARTCON_PARITYEN;
        tempreg |= UART_InitStruct->UART_Parity;                          /*!< 配置奇偶校验位         */
    }
    tempreg |= UART_InitStruct->UART_Logic;                               /*!< 配置UART通讯逻辑       */
    tempreg |= UART_InitStruct->UART_StopBits;                            /*!< 配置停止位             */
    tempreg |= UART_InitStruct->UART_WordLength;                          /*!< 配置通讯数据长度       */
    
    if(UART_InitStruct->ReceiveEN != DISABLE)
    {
        tempreg |= UART_UARTCON_RXEN;                                     /*!< 配置接收使能           */
    }
    if(UART_InitStruct->SendEN != DISABLE)
    {
        tempreg |= UART_UARTCON_TXEN;                                     /*!< 配置发送使能           */
    }
    
    UARTx->UARTCON = tempreg;                                             /*!< 配置寄存器             */   
        
    sysclk = HT_CMU_SysClkGet()>>1;                                       /*!< 获取当前系统时钟频率/2 */
    UARTx->SREL = sysclk/UART_InitStruct->UART_BaudRate-1;                /*!< 计算波特率             */
    
    UARTx->IRCON &= ~UART_IRCON_IRTX;                                     /*!< 关闭红外调制输出功能   */
} 

3.2底层驱动

3.2.1数据结构

typedef struct
{
    UARTLogic_TypeDef  UART_Logic;                      /*!< 串口逻辑设置                       */                                                                          
    UARTStopBits_TypeDef  UART_StopBits;                /*!< 串口停止位设置                     */                                                                         
    UARTWordLength_TypeDef  UART_WordLength;            /*!< 串口通讯数据长度设置               */ 
    UARTParity_TypeDef  UART_Parity;                    /*!< 串口奇偶校验位设置                 */
    uint32_t  UART_BaudRate;                            /*!< 串口波特率, 比如1200, 2400         */
    FunctionalState  ReceiveEN;                         /*!< 串口接收使能控制                   */ 
    FunctionalState  SendEN;                            /*!< 串口发送使能控制                   */ 
}UART_InitTypeDef;                                      /*!< end of group UART_InitTypeDef      */

3.2.2打开串口

u08 OpenMcuUart (u08 *pSrc, u08 ChannelNo)
{
    u08 ReturnData;

    UART_InitTypeDef UartInitStruct;
    IR_InitTypeDef   IrInitStruct;

    ReturnData = GAL_YES;

    /* 先关闭, 再打开 */
    CloseMcuUart(ChannelNo);

    /* 停止位 */
    if (2 == *(pSrc + 0))
    {
        UartInitStruct.UART_StopBits = TwoStopBits;
    }
    else
    {
        UartInitStruct.UART_StopBits = OneStopBits;
    }
    /* 数据长度 */
    if (7 == *(pSrc + 1))
    {
        UartInitStruct.UART_WordLength = WordLength_7Bits;
    }
    else
    {
        UartInitStruct.UART_WordLength = WordLength_8Bits;
    }
    /* 校验位 */
    if (0 == *(pSrc + 2))
    {
        UartInitStruct.UART_Parity = UartParity_Disable;
    }
    else if (1 == *(pSrc + 2))
    {
        UartInitStruct.UART_Parity = UartParity_ODD;
    }
    else
    {
        UartInitStruct.UART_Parity = UartParity_EVEN;
    }

    UartInitStruct.UART_Logic      = UartLogicPositive;
    UartInitStruct.UART_BaudRate   = TabBaudRate[*(pSrc + 3)];
    UartInitStruct.ReceiveEN       = ENABLE;
    UartInitStruct.SendEN          = ENABLE;

    HT_UART_Init(HT_UART3, &UartInitStruct);
    InitUartIO(UART_DRV_CHNL_3, SYSTEM_POWERON);
}

3.2.3中断配置

内核中断向量配置及优先级配置:

/*******************************************************************************
 * FUNCTION:    InitMcuNvic
 * DESCRIPTION: 中断向量及优先级初始化
 * INPUT:       无
 * OUTPUT:      无
 * RETURN:      无
 * OTHERS:      
 * HISTORY:     
*******************************************************************************/
void InitMcuNvic (u08 SystemMode)
{
	NVIC_ClearPendingIRQ(UART3_IRQn);
	NVIC_EnableIRQ(UART3_IRQn);        /* 串口3中断, 红外 */
	NVIC_SetPriority(UART3_IRQn, 2);
}

置接收状态:

/*******************************************************************************
 * FUNCTION:    SetMcuUartReceive
 * DESCRIPTION: 切换MCU内部UART到接收状态
 * INPUT:       u08 ChannelNo
 *                - 串口通道号
 * OUTPUT:      
 * RETURN:      
 * OTHERS:      
 * HISTORY:     
*******************************************************************************/
void SetMcuUartReceive (u08 ChannelNo)
{
    UartDrvStatus[ChannelNo] = UART_RECV_STATUS;
	
	/* 串口切换到接收 */
    HT_UART_ITConfig(HT_UART3, UART_UARTCON_TXIE, DISABLE);
    HT_UART_ITConfig(HT_UART3, UART_UARTCON_RXIE, ENABLE);

    break;	
    default:
    
     break;
    
}

置发送状态:

/*******************************************************************************
 * FUNCTION:    SetMcuUartSend
 * DESCRIPTION: 切换MCU内部UART到发送状态
 * INPUT:       u08 ChannelNo
 *                - 串口通道号
 * OUTPUT:      
 * RETURN:      
 * OTHERS:      
 * HISTORY:     
*******************************************************************************/
void SetMcuUartSend (u08 ChannelNo)
{
  /* 置状态 */
    UartDrvStatus[ChannelNo] = UART_SEND_STATUS;
	case UART_DRV_CHNL_3:
    /* 关闭接收使能 */
    // HT_UART3->UARTCON &= ~UART_UARTCON_RXEN;

	/* 485串口切换到发送 */
	HT_UART_ITConfig(HT_UART3, UART_UARTCON_RXIE, DISABLE);
	HT_UART_ITConfig(HT_UART3, UART_UARTCON_TXIE, ENABLE);
	break;
}

中断处理函数,在配置好串口模式以及中断后,当我们接收或发送数据完成时,均会触发中断从而进入到中断处理函数,这里主要是完成对标志位的清除和对串口SBUF缓存数据的捞取:

/*******************************************************************************
 * FUNCTION:    UART3_IRQHandler
 * DESCRIPTION: 串口3中断处理函数, 用于红外通讯
 * INPUT:       
 * OUTPUT:      
 * RETURN:      
 * OTHERS:      
 * HISTORY:     
*******************************************************************************/
void UART3_IRQHandler (void)
{

    /* 接收中断 */
    if (SET == HT_UART_ITFlagStatusGet(HT_UART3, UART_UARTSTA_RXIF))
    {
        HT_UART_ClearITPendingBit(HT_UART3, UART_UARTSTA_RXIF);
        /* 先判断校验状态 */
        if (RESET == HT_UART_ITFlagStatusGet(HT_UART3, UART_UARTSTA_PARITY))
        {
            UartDrvBuff[UART_DRV_CHNL_3].Buff[UartDrvBuff[UART_DRV_CHNL_3].In++] = HT_UART_ReceiveData(HT_UART3);
    		if(UartDrvBuff[UART_DRV_CHNL_3].In >= UART_DRV_LEN)
    		{
    			UartDrvBuff[UART_DRV_CHNL_3].In = 0;
    		}
        }
        else
        {
            HT_UART_ClearITPendingBit(HT_UART3, UART_UARTSTA_PARITY);
        }
    }
    /* 发送中断 */
    if (SET == HT_UART_ITFlagStatusGet(HT_UART3, UART_UARTSTA_TXIF))
    {
        HT_UART_ClearITPendingBit(HT_UART3, UART_UARTSTA_TXIF);

        if(UartDrvBuff[UART_DRV_CHNL_3].Out != UartDrvBuff[UART_DRV_CHNL_3].In)
		{
			HT_UART_SendData(HT_UART3, UartDrvBuff[UART_DRV_CHNL_3].Buff[UartDrvBuff[UART_DRV_CHNL_3].Out++]);
		}
		else
		{
            UartDrvBuff[UART_DRV_CHNL_3].In  = 0;
            UartDrvBuff[UART_DRV_CHNL_3].Out = 0;
            SetMcuUartReceive(UART_DRV_CHNL_3);
		}
    }

}

总结:


猜你喜欢

转载自blog.csdn.net/wwsj123/article/details/81389482
今日推荐