第三章 DW_apb_uart初始化和使用

目录

1. DW_apb_uart初始化流程

2. DW_apb_uart初始化编程

2.1 定义UART寄存器

2.2 定义UART初始化结构体

2.3 定义UART控制结构体

 2.4 UART初始化

3. DW_apb_uart 打印测试


1. DW_apb_uart初始化流程

DW_apb_uart协议第七章有常规场景下的初始化流程介绍,发送数据配置流程如下图:

接收数据配置流程如下图:

简单整理初始化流程:

(1)配置MCR寄存器,配置红外sir模式、自动流控模式、loop back模式和modem控制输出值;

(2) 将 LCR.dlab写入1,允许配置波特率分频参数寄存器;

(3)根据需求,计算波特率整数和小数分频系数,分别配置DLL、DLH、DLF寄存器;

(4)将 LCR.dlab写入0,禁止配置波特率分频参数寄存器;

(5)配置LCR寄存器,配置数据长度、停止位长度、奇偶校验等参数;

(6)配置RCR寄存器,配置TX FIFO、RX FIFO水线阈值;

(7)配置IE寄存器,使能相关中断;

(8)如果要发送数据,则把要发送的数据写到THR寄存器中,然后读取IIR中断状态寄存器的值,当IIR中断状态寄存器的值为0x2时,说明TX FIFO为空,可以继续发送数据;如果要接收数据,则等待IIR中断状态寄存器为0x4,表明有数据进入RX FIFO,CPU可以读取RBR寄存器来获取接收的数据。

2. DW_apb_uart初始化编程

2.1 定义UART寄存器

/*定义联合体用于访问 RBR/DLL/THR 寄存器 */
typedef union
{
    volatile const uart_rbr_reg_s       rbr;     /* Receive Buffer Register    Address offset: 0x00 */
    volatile uart_dll_reg_s             dll;     /* Divisor Latch (Low)        Address offset: 0x00 */
    volatile uart_thr_reg_s             thr;     /* Transmit Holding Register  Address offset: 0x00 */
} uart_rdt_typedef_u;

/* 定义联合体用于访问 DLH/IER 寄存器 */
typedef union
{
    volatile uart_dlh_reg_s             dlh;     /* Divisor Latch High          Address offset: 0x04 */
    volatile uart_ier_reg_s             ier;     /* Interrupt Enable Register   Address offset: 0x04 */
} uart_dhie_typedef_u;

/* 定义联合体用于访问 FCR/IIR 寄存器 */
typedef union
{
    volatile uart_fcr_reg_s             fcr;    /* FIFO Control Register               Address offset: 0x08 */
    volatile const uart_iir_reg_s       iir;    /* Interrupt Identification Register   Address offset: 0x08 */
} uart_fcii_typedef_u;

上面这几个寄存器很特殊,使用的相同的偏移地址,读写的时候分别表示不同的含义,所以用联合体来定义。(吐槽一下,这个设计有点坑爹 =_=) 

接下来是定义所有的寄存器。

typedef struct {
    uart_rdt_typedef_u               rdt;           /* 0x00 Union type to access RBR,DLL,THR */
    uart_dhie_typedef_u              dhie;          /* 0x04 Union type to access DLH,IER */
    uart_fcii_typedef_u              fcii;          /* 0x08 Union type to access FCR,IIR */
    volatile uart_lcr_reg_s          lcr;           /* 0x0c UART Line Control Register */
    volatile uart_mcr_reg_s          mcr;           /* 0x10 UART Modem Control Register */
    volatile const uart_lsr_reg_s    lsr;           /* 0x14 UART Line Status Register */
    volatile const uart_msr_reg_s    msr;           /* 0x18 UART Modem Status Register */
    volatile uart_scr_reg_s          scr;           /* 0x1c UART Scratchpad Register */
    volatile uart_lpdll_reg_s        lpdll;         /* 0x20 UART Low Power Divisor Latch Low */
    volatile uart_lpdlh_reg_s        lpdlh;         /* 0x24 UART Low Power Divisor Latch High */
    volatile uart_misc_ctrl_reg_s    misc_ctrl;     /* 0x28 UART Functional control register */
    unsigned char                    space0[68];    /* Reserved:0x2c~0x6c UART space0 */
    volatile uart_far_reg_s          fasr;          /* 0x70 UART Fifo Access Register */
    volatile uart_tfr_reg_s          tfr;           /* 0x74 UART Tx Fifo Read Register */
    volatile uart_rfw_reg_s          rfw;           /* 0x78 UART Rx Fifo Write Register */
    volatile uart_usr_reg_s          usr;           /* 0x7c UART Status Register */
    volatile uart_tfl_reg_s          tfl;           /* 0x80 UART Transmit FIFO Level Register */
    volatile uart_rfl_reg_s          rfl;           /* 0x84 UART Receive FIFO Level Register */
    volatile uart_srr_reg_s          srr;           /* 0x88 UART Software Reset Register */
    volatile uart_srts_reg_s         srts;          /* 0x8c UART Shadow Request to Send Register */
    volatile uart_sbcr_reg_s         sbcr;          /* 0x90 UART Shadow Break Control Register */
    volatile uart_sdmam_reg_s        sdmam;         /* 0x94 UART Shadow DMA Mode Register */
    volatile uart_sfe_reg_s          sfe;           /* 0x98 UART Shadow FIFO Enable Register */
    volatile uart_srt_reg_s          srt;           /* 0x9c UART  Shadow RCVR Trigger Register */
    volatile uart_stet_reg_s         stet;          /* 0xa0 UART  Shadow TX Empty Trigger Register */
    volatile uart_htx_reg_s          htx;           /* 0xa4 UART Halt tx */
    unsigned char                    dmasa;         /* 0xa8 UART Dma software Acknowledge Register */
    volatile uart_tcr_reg_s          tcr;           /* 0xac UART Transceiver Control Register */
    volatile uart_de_en_reg_s        de_en;         /* 0xb0 UART Driver Output Enable Register */
    volatile uart_re_en_reg_s        re_en;         /* 0xb4 UART Receiver Output Enable Register */
    volatile uart_det_reg_s          det;           /* 0xb8 UART Driver Output Enable Timing Register */
    volatile uart_tat_reg_s          tat;           /* 0xbc UART TurnAround Timing Register */
    volatile uart_dlf_reg_s          dlf;           /* 0xc0 UART Divisor Latch Fraction Register */
    volatile uart_rar_reg_s          rar;           /* 0xc4 UART Receive Address Register */
    volatile uart_tar_reg_s          tar;           /* 0xc8 UART Transmit Address Register */
    volatile uart_lcr_ext_reg_s      lcr_ext;       /* 0xcc UART Line Extended Control Register */
    unsigned int                     space1[9];     /* Reserved:0xd0 0xd4 0xd8 0xdc 0xe0 0xe4 0xe8 0xec 0xf0 */
    volatile uart_cpr_reg_s          cpr;           /* 0xf4 UART Component Parameter Register */
    volatile uart_ucv_reg_s          ucv;           /* 0xf8 UART Component Version Register */
    volatile uart_ucv_reg_s          ctr;           /* 0xfc UART Component Type Register */
} uart_reg_s;

2.2 定义UART初始化结构体

该结构体包含UART初始化相关参数,用于配置UART的寄存器。

typedef struct {
    uart_clk_sel_e         clk_sel;         /*!< 配置 uart 时钟源 */
    uart_baudrate_e        baudrate;        /*!< 配置 uart 波特率 */
    uart_data_length_e     data_length;     /*!< 配置 uart 数据位宽 */
    uart_stop_bits_e       stop_bits;       /*!< 配置 uart 停止位宽 */
    uart_parity_en_e       parity;          /*!< uart 校验使能控制 */
    uart_parity_sel_e      par_sel;         /*!< uart 奇偶校验模式选择 */
    uart_stick_parity_e    stick_par;       /*!< uart 固定校验模式控制.*/
    uart_fifo_mode_e       fifo_mode;       /*!< uart FIFO 模式使能控制 */
    uart_dma_mode_e        dma_mode;        /*!< uart DMA 模式使能控制 */
    uart_sir_mode_e        sir_mode;        /*!< uart 红外模式使能控制 */
    uart_loopback_mode_e   loop_back;       /*!< uart 环回模式使能控制 */
    uart_hw_control_e      hw_flow_ctrl;	/*!< uart 硬件流控使能控制 */		
    uart_tx_rx_9bit_s      tx_rx_9bit;		/*!< uart 9bit 模式使能控制 */
    uart_rs485_cfg_s       rs485_cfg;		/*!< uart RS485 模式使能控制 */
    uart_rx_trig_e         rcv_trig;	    /*!< uart 接收水线配置 */
    uart_tx_trig_e         tx_trig;         /*!< uart 发送水线配置 */
} uart_init_s;

2.3 定义UART控制结构体

该结构体包含UART工作需要用到的相关控制参数,主要用于工作流程的控制。

typedef struct {
    uart_reg_s                   *instance;			/*!< 指向 uart 寄存器地址 */
    unsigned int                 irq_control;		/*!< uart 中断使能控制 */
    unsigned int                 irq_num;			/*!< uart 中断号配置 */
    uart_init_s                  init;				/*!< uart 初始化参数结构体 */
    unsigned char                *p_tx_buffer_ptr;	/*!< uart 发送buf */
    unsigned short               tx_xfer_size;		/*!< uart 发送数据量配置 */
    volatile unsigned short      tx_xfer_count;		/*!< uart 已发送数据量统计 */
    unsigned char                *p_rx_buffer_ptr;	/*!< uart 接收buf */
    unsigned short               rx_xfer_size;		/*!< uart 接收数据量配置 */
    volatile unsigned short      rx_xfer_count;		/*!< uart 已接收数据量统计 */
    volatile unsigned int        error_code;		/*!< uart 错误码 */
    volatile unsigned int        interrupt_flags;	/*!< uart 中断标记位 */
} uart_handle_s;

 2.4 UART初始化

void uart_init(uart_handle_s *huart) 
{
    //1.开启时钟门控
    uart_clk_enable(huart, 0x1);

    //2.uart时钟源选择
    uart_clk_sel(huart);

    //3.CRG模块软复位
    uart_crg_rst_en(huart);

    //4.管脚复用设置
    uart_io_config(huart);

    //5.UART 软复位
    uart_software_reset(huart);

	//6.UART错误码清零
    huart->error_code = UART_ERROR_NONE;

	//7.硬件流控配置
    if (huart->init.hw_flow_ctrl == UART_HWCONTROL_ENABLE){
        uart_auto_flow_control(huart, ENABLE);
        uart_rts_control(huart, ENABLE);
    }else{
        uart_auto_flow_control(huart, DISABLE);
    }

    //8.IRDA配置
    if (huart->init.sir_enable == UART_SIR_ENABLE) {
        uart_sir_mode_control(huart, ENABLE);
    }else{
        uart_sir_mode_control(huart, DISABLE);
    }

    /9. 配置波特率
    uart_divisor_latch_access_control(huart, ENABLE);
    uart_set_div_latch(huart);
    uart_divisor_latch_access_control(huart, DISABLE);

    //10.配置数据位长度,停止位宽,奇偶校验等
    uart_data_length_select(huart, huart->init.word_length);
    uart_stop_bits_select(huart, huart->init.stop_bits);
    uart_parity_enable_control(huart,huart->init.parity);
    uart_even_parity_control(huart,huart->init.par_sel);
    uart_stick_parity_control(huart, huart->init.stick_par);

    //11.配置FIFO mode,DMA水线设置
    if(huart->init.fifo_mode == UART_FIFO_ENABLE){
        uart_fifo_mode_enable_control(huart, UART_FIFO_ENABLE);
        uart_tx_empty_trigger_level_set(huart, huart->init.tx_trig);
        uart_rx_trigger_level_set(huart,huart->init.rcv_trig);
        uart_txfifo_reset(huart);
        uart_rxfifo_reset(huart);
    }else{
        uart_fifo_mode_enable_control(huart, UART_FIFO_DISABLE);
    }
	
	//12.配置DMA
    uart_dma_mode_select(huart, huart->init.dma_mode);

    //13.配置 THRE interrupt
    uart_programmable_ther_interrupt_control(huart, DISABLE);

    //14.配置9bit
    if (huart->init.tx_rx_9bit.en == UART_TX_RX_9BIT_ENABLE) {
        uart_9bit_enable_control(huart, UART_TX_RX_9BIT_ENABLE);
        uart_receice_address_set(huart, huart->init.tx_rx_9bit.recv.addr);
        uart_transmit_address_set(huart, huart->init.tx_rx_9bit.trans.addr);
        uart_9bit_transmit_mode_set(huart, huart->init.tx_rx_9bit.trans.mode);
        uart_9bit_address_match_mode_set(huart, huart->init.tx_rx_9bit.recv.mode);
        uart_9bit_send_address_mode_set(huart, huart->init.tx_rx_9bit.trans.addr_en);
    }else{
        uart_9bit_enable_control(huart, UART_TX_RX_9BIT_DISABLE);
    }

    //15.配置RS485
    if(huart->init.rs485_cfg.en == UART_RS485_MODE_ENABLE){
        uart_rs485_enable_control(huart,UART_RS485_MODE_ENABLE);
        uart_rs485_re_polarity_set(huart, huart->init.rs485_cfg.re_pol);
        uart_rs485_de_polarity_set(huart,huart->init.rs485_cfg.de_pol );
        uart_rs485_transfer_mode_set(huart, huart->init.rs485_cfg.duplex);
        uart_rs485_de_assertion_time_set(huart, huart->init.rs485_cfg.det.de_assert_time);
        uart_rs485_de_deassertion_time_set(huart,  huart->init.rs485_cfg.det.de_deassert_time);
        uart_rs485_de_to_re_turnaround_time_set(huart, huart->init.rs485_cfg.tat.de_to_re);
        uart_rs485_re_to_de_turnaround_time_set(huart, huart->init.rs485_cfg.tat.re_to_de);
        uart_rs485_de_enable_control(huart, huart->init.rs485_cfg.de_en);
        uart_rs485_re_enable_control(huart, huart->init.rs485_cfg.re_en);
    }else{
        uart_rs485_enable_control(huart,UART_RS485_MODE_DISABLE);
    }

    //16.中断使能控制
    if(huart->irq_control == UART_IRQ_ENABLE){
        drv_irq_register(huart->irq_num, uart0_irq_handle, huart);
        drv_irq_enable(huart->irq_num, IRQ_TYPE_VECTOR_HIGH_LEVEL, IRQ_PRIORITY_1);
    }
}

3. DW_apb_uart 打印测试

void uart_default_cfg(uart_handle_s *huart)
{
    memset(huart, 0, sizeof(uart_handle_s));					//对结构体清零
    huart->init.clk_sel         = CLK_LS;						//选择100M低速时钟
    huart->init.baudrate        = UART_BAUDRATE_115200;			//波特率115200
    huart->init.word_length     = UART_DATA_LEN_8;				//数据位宽8bit
    huart->init.stop_bits       = UART_STOP_BITS_1;				//停止位宽1bit
    huart->init.parity          = UART_PARITY_DISABLE;			//禁止校验功能
    huart->init.par_sel         = UART_PARITY_ODD;				//选择偶校验
    huart->init.stick_par       = UART_STICK_PARITY_DISABLE;	//禁止固定校验模式
    huart->init.fifo_mode       = UART_FIFO_ENABLE;				//使能FIFO
    huart->init.dma_mode        = UART_DMAM_0;					//选择DMA0
	huart->init.sir_enable      = UART_SIR_DISABLE;				//禁止红外模式
    huart->init.loop_back       = UART_LOOPBACK_DISABLE;		//禁止环回模式
    huart->init.hw_flow_ctrl    = UART_HWCONTROL_DISABLE;		//禁止硬件流控
    huart->init.tx_rx_9bit.en   = UART_TX_RX_9BIT_DISABLE;		//禁止9bit功能
    huart->init.rs485_cfg.en    = UART_RS485_MODE_DISABLE;		//禁止RS485
    huart->init.rcv_trig        = UART_RT_FIFO_CHAR_1;			//接收水线配置为1byte
    huart->init.tx_trig         = UART_TX_FIFO_EMPTY; 			//发送水线配置为0
    huart->irq_control          = UART_IRQ_ENABLE;				//使能中断
    huart->irq_num              = IRQ_NUM_UART0;				//选择中断号
}

int main(void)
{
    uart_handle_s uhandle;
    sysctrl_init();
    crg_init();
	uart_default_cfg(&uhandle);
	uart_init(&g_dbg_uart);

    print("hello word 1\r\n");
    print("hello word 2\r\n");
    print("hello word 3\r\n");
}

测试结果:

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原海青木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值