小华HC32L136K8TA 单片机PRINTF (四)

小华HC32L136K8TA 单片机PRINTF
一、将前面建立好的工程文件LED_TEST文件夹复制一份,命名为PRINTF. 将LED_TEST\MDK\LED_TEST.uvprojx,改为PRINTF.uvprojx.双击这个文件打开工程。

二、修改工程配置
1.组driver下面添加uart.c
在这里插入图片描述

2.source下面添加usart.c,usart.h
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

usart.c的文件内容如下

#include "usart.h"
#include "gpio.h"
#include "uart.h"


//串口引脚配置
void UART0_PortInit(void)
{
  	stc_gpio_cfg_t stcGpioCfg;
    DDL_ZERO_STRUCT(stcGpioCfg);
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE); //使能GPIO模块时钟

    ///<TX
    stcGpioCfg.enDir = GpioDirOut;	
#if defined(DEBUG_UART0_B6B7)			
    Gpio_Init(GpioPortB, GpioPin6, &stcGpioCfg);
    Gpio_SetAfMode(GpioPortB, GpioPin6, GpioAf2);          //配置Pb6 端口为 010 ---- UART0_TXD UART0模块TXD信号	
#elif defined(DEBUG_UART0_B8B9)
	Gpio_Init(GpioPortB, GpioPin8, &stcGpioCfg);
    Gpio_SetAfMode(GpioPortB, GpioPin8, GpioAf7);          //配置Pb8 端口为 ---- UART0_TXD UART0模块TXD信号	
#elif defined(DEBUG_UART0_A9A10)
	Gpio_Init(GpioPortA, GpioPin9, &stcGpioCfg);
    Gpio_SetAfMode(GpioPortA, GpioPin9, GpioAf1);   
#endif
	
    ///<RX
    stcGpioCfg.enDir = GpioDirIn;
#if defined(DEBUG_UART0_B6B7)		
    Gpio_Init(GpioPortB, GpioPin7, &stcGpioCfg);
    Gpio_SetAfMode(GpioPortB, GpioPin7, GpioAf2);          //配置Pb7 端口010 ---- UART0_RXD UART0模块RXD信号
#elif defined(DEBUG_UART0_B8B9)
	Gpio_Init(GpioPortB, GpioPin9, &stcGpioCfg);
    Gpio_SetAfMode(GpioPortB, GpioPin9, GpioAf7);          //配置Pb9 端口 ---- UART0_RXD UART0模块RXD信号			
#elif defined(DEBUG_UART0_A9A10)
	Gpio_Init(GpioPortA, GpioPin10, &stcGpioCfg);
    Gpio_SetAfMode(GpioPortA, GpioPin10, GpioAf1); 
#endif	
		
}



//串口配置
void Uart0Cfg(uint32_t baud)
{
    stc_uart_cfg_t    stcCfg;

    DDL_ZERO_STRUCT(stcCfg);

    ///< 开启外设时钟
    Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0,TRUE);///<使能uart0模块时钟

    ///<UART Init
    stcCfg.enRunMode        = UartMskMode1;          ///<模式1
    stcCfg.enStopBit        = UartMsk1bit;           ///<1bit停止位
    //stcCfg.enMmdorCk        = UartMskEven;           ///<偶检验
	stcCfg.enMmdorCk        = UartMskDataOrAddr;//
    stcCfg.stcBaud.u32Baud  = baud;                  ///<波特率
    stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;       ///<通道采样分频配置 模式1/3 8分频
    stcCfg.stcBaud.u32Pclk  = Sysctrl_GetPClkFreq(); ///<获得外设时钟(PCLK)频率值
    Uart_Init(M0P_UART0, &stcCfg);                   ///<串口初始化

    ///<UART中断使能
    Uart_ClrStatus(M0P_UART0,UartRC);                ///<清接收请求
    Uart_ClrStatus(M0P_UART0,UartTC);                ///<清接收请求
    Uart_EnableIrq(M0P_UART0,UartRxIrq);             ///<使能串口接收中断
    //Uart_EnableIrq(M0P_UART0,UartTxIrq);             ///<使能串口发送中断
	Uart_DisableIrq(M0P_UART0,UartTxIrq);			//禁止发送中断
    EnableNvic(UART0_IRQn, IrqLevel3, TRUE);       ///<系统中断使能
				
}


Uart.h

//UART1中断
void Uart0_IRQHandler(void)
{
    uint8_t revdata;
	if(Uart_GetStatus(M0P_UART0, UartRC))
    {
        Uart_ClrStatus(M0P_UART0, UartRC);              //清除中断状态位
        revdata=Uart_ReceiveData(M0P_UART0);  //接收到数据
			  Uart_SendDataPoll(M0P_UART0,revdata); 
         //Uart_DisableIrq(M0P_UART1,UartRxIrq);       //禁止接收中断        
    }

    if(Uart_GetStatus(M0P_UART0, UartTC))
    {
        Uart_ClrStatus(M0P_UART0, UartTC);              //清除中断状态位
        //Uart_SendDataIt(M0P_UART0, 0x55);               //发送数据       
		//Uart_DisableIrq(M0P_UART1,UartTxIrq);       //禁止发送中断
        //Uart_EnableIrq(M0P_UART1,UartRxIrq);        //使能接收中断       
    }

}

usart.h

  #ifndef __USART_H
#define __USART_H

#include "ddl.h"

//#define DEBUG_UART0_B6B7          //测试成功
#define DEBUG_UART0_B8B9            //测试成功
//#define DEBUG_UART0_A9A10         //测试成功


void UART0_PortInit(void);
void Uart0Cfg(uint32_t baud);



#endif

Main.c

#include "gpio.h"
#include "usart.h"

static void App_LedInit(void);

int32_t main(void)
{
    UART0_PortInit();
	Uart0Cfg(57600);
	printf("hello world \r\n");
	while(1)
	{ 
		printf("HC32L136K8TA-MINI......\r\n");
		delay1ms(1000);
	}
	
}

Ddl.c修改

int fputc(int ch, FILE *f)
{
	Uart_SendDataPoll(M0P_UART0,ch); 
    return ch;
}

编译下载,烧录后的打印效果

在这里插入图片描述

在本文中,我们将深入探讨如何在大微电子的HC32L130(136)微控制器上实现串口DMA接收以及利用高级定时器6实现空闲超时接收功能。这种方法与STM32F103的串口DMA结合空闲中断实现不定长数据收发具有类似的概念,但针对的是不同的MCU平台。 HC32L130(136)大微电子推出的一款低功耗、高性能的8位微控制器,它集成了丰富的外设接口,如串行通信接口(UART),并提供了DMA(直接存储器访问)功能,这使得数据传输更为高效。在串口通信中,DMA可以显著减轻CPU负担,因为它允许数据在硬件层面直接在内存和外设之间传输,无需CPU干预。 串口DMA接收的设置通常涉及以下几个步骤: 1. **配置串口**:选择合适的波特率、数据位、停止位和校验位。在HC32L130(136)中,这通常通过UART模块的寄存器进行设置。 2. **开启DMA**:选择合适的DMA通道,将其与UART的接收端口连接。设置传输模式,如单次传输或连续传输,并配置数据大小。 3. **配置中断**:设置串口DMA接收完成中断,以便在接收完成后执行相应的处理程序。 4. **启动传输**:启动DMA传输,数据会自动从串口缓冲区传输到指定的内存位置。 接下来,我们讨论如何使用高级定时器6实现空闲超时检测: 1. **初始化高级定时器6**:配置定时器的工作模式、预分频器、计数器值等参数。确保定时器的时基与所需的超时时间匹配。 2. **连接中断**:设置定时器的空闲检测中断,当检测到串口线IDLE位(表示无数据传输)达到设定的超时周期时,触发中断。 3. **处理中断**:在中断服务程序中,检查中断源是否为空闲超时,如果是,则执行相应的超时处理,如重置接收状态或发送错误信号。 4. **同步串口和定时器**:确保定时器与串口操作同步,避免因中断处理不当导致的数据丢失或错误。 在实际应用中,为了实现不定长数据接收,我们需要结合串口DMA接收和空闲超时检测功能。当收到一个完整的数据帧时,可以根据约定的数据帧格式(例如起始符、数据部分、结束符)判断数据帧的边界。一旦检测到数据帧结束,可以清空接收缓冲区,重新启动DMA接收,等待下一个数据帧的到来。 在提供的压缩包文件中,可能包含了工程文件(如`keilkilll.bat`,可能是Keil编译脚本)、驱动代码(`driver`)、中间件(`midware`)、MCU相关资料(`mcu`)、MDK工程(`MDK`)、源代码(`source`)和VSCode工作区配置(`.vscode`)。这些文件将有助于开发者理解和实现上述串口DMA接收与超时检测的完整流程。 通过巧妙地结合HC32L130(136)串口DMA和高级定时器6的功能,可以实现高效且可靠的不定长数据收发,这对于物联网、远程监控等需要实时通信的应用场景尤为重要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

oshan2012

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

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

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

打赏作者

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

抵扣说明:

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

余额充值