首页 > 其他分享 >家庭能源网关开发历程(三)JSY-MK-163串口中断发送接收

家庭能源网关开发历程(三)JSY-MK-163串口中断发送接收

时间:2024-09-02 09:54:41浏览次数:12  
标签:UART1 网关 Uart void uint8 MK 发送 串口 com

 前言

        大家好,我是菜菜,在上一期我们主要介绍了关于JSY-MK-163串口通讯配置流程。由于上期没有打印结果,我怕有一些小伙伴还是不懂,本期我们就来实现项目主控MCU华大HC32F005的UART中断发送和接收数据的结果打印。首先,我们先看看用到UART的那些功能函数。

UART功能函数

UART发送

 1.以查询的方式发送数据。

en_result_t Uart_SendDataPoll(M0P_UART_TypeDef* UARTx, uint8_t u8Data)
{
    UARTx->SBUF_f.SBUF = u8Data;
    while(FALSE == Uart_GetStatus(UARTx,UartTC))
    {}
    Uart_ClrStatus(UARTx,UartTC);       
    return Ok;
}

 2.以中断的方式发送数据

en_result_t Uart_SendDataIt(M0P_UART_TypeDef* UARTx, uint8_t u8Data)
{ 
    UARTx->SBUF_f.SBUF = u8Data; 
    
    return Ok;
}

         注:本期我们讲的是中断发送,所以等下我们调用的是该方式发送数据。

 UART接收

1.uart接收数据功能函数

uint8_t Uart_ReceiveData(M0P_UART_TypeDef* UARTx)
{
    return (UARTx->SBUF_f.SBUF);
}

 UART中断发送接收流程

uart发送单个

//串口发送字节(查询方式)
void UART1_SendByte(uint8_t  Data)
{
	Uart_SendDataPoll(M0P_UART1, Data);                                  
}

uart发送一串 

//串口发送一串
void UART1_SendString(char *u8Data)
{	
	int k=0;
while(*(u8Data+k)!='\0') 
		{
	Uart_SendDataPoll(M0P_UART1, *(u8Data+k));  
		k++;		  
		}
}

uart发送数组

//串口发送数组
void UART1_Sendarr(uint8_t * data,uint32_t len)
{
	uint32_t i=0;
	for(i=0;i<len;i++){
		UART1_SendByte(*data);
		data++;
	}
}

uart接收数据

//串口接收字节
uint8_t Uart_ReceByte(uint8_t *data)
{
	if(Uart_GetStatus(M0P_UART1, UartRC)==SET)         //UART1数据发送
    {  
		Uart_ClrStatus(M0P_UART1,UartRC);
		data[0]=Uart_ReceiveData(M0P_UART1);	
		return 1;
	}
	return 0;	
}

 首先,我们先定义一个结构,用于发送和接收多个数据准备。

typedef struct {
	uint8_t rbuf[11];
	uint16_t rcnt;
	uint8_t tbuf[11];
	uint16_t tcnt;
	uint16_t txp;
}com_type;

 接着写发送数据函数

com_type com_1 = {0};
// 使用中断方式发送数据的函数
void fnUart_SendIR(void){
    // 如果发送指针txp小于发送计数tcnt,说明还有数据未发送
    if(com_1.txp < com_1.tcnt){
        // 使用中断服务发送当前指针指向的数据
        Uart_SendDataIt(M0P_UART1, com_1.tbuf[com_1.txp]);
        // 更新发送指针,使用取模运算确保指针在0-255之间循环
        com_1.txp = (com_1.txp + 1) % 256;
    } else {
        // 如果所有数据已发送,重置发送指针
        com_1.txp = 0;
        // 禁用UART1的发送中断(这里是为了让串口实现半双工发送接收数据)
        Uart_DisableIrq(M0P_UART1, UartTxIrq);
    }
}

 获取发送的数据

// 获取已接收到的数据长度的函数
uint16_t fnUart_GETReadIR_BUF(void){
    uint16_t len;
    // 读取当前接收计数器的值,该值表示已接收数据的长度
    len = com_1.rcnt;
    // 重置接收计数器,为下一次接收做准备
    com_1.rcnt = 0;
    // 返回接收到的数据长度
    return len;
}

 设置要发送的数据长度

// 设置要发送的数据长度的函数
void fnUart_SendIR_BUF(uint16_t len){
    // 设置发送计数器为要发送的数据长度
    com_1.tcnt = len;
    // 重置发送指针,准备从头开始发送数据
    com_1.txp = 0;
    // 启用UART1的发送中断,开始发送数据
    Uart_EnableIrq(M0P_UART1, UartTxIrq);
    // 调用发送函数,开始发送数据
    fnUart_SendIR();
}

 设置复制函数

//复制功能函数
void fnmemcpy(uint8_t *srt,uint8_t *det,uint16_t len){
uint16_t i;
	for(i=0; i<len; i++){ det[i]=srt[i];}
}

 设置接收缓冲区

//接收缓冲区
uint8_t rec_buf[100];
uint16_t cnt1=0;
void fninputbuf(uint8_t dat){
	rec_buf[cnt1]=dat; // 将数据存储在当前位置
	cnt1=(cnt1+1)%100; // 更新数据,使用取模运算实现缓冲
}

 设置接收函数

//接收函数
void fncoming(void){
uint8_t temp;
	// 尝试从串口接收一个字节,如果失败则返回
	if(0==Uart_ReceByte(&temp)){return;}
	fninputbuf(temp);
	UART1_SendByte(temp); 
}

最后就是主函数的调用

int main(void)
{
uint16_t x;
	App_PortInit();
	SystemClock_Init();
	UartBaudCfg_Init();
//	GX30_I2C_Init();
    while(1) {
		fncoming();
		delay1ms(100);
		x=fnUart_GETReadIR_BUF();
		fnmemcpy(com_1.rbuf,com_1.tbuf,x);
		fnUart_SendIR_BUF(x);
	}
}

打印结果 

1.结果乱码

根据上面的流程,我们明明可以实现了串口中断的发送和接收数据,但是你会发现接收到的数据是乱的,这是怎么回事?

2.解决方法

        原来啊,是我们漏了一个比较重要的流程没有配置,那就是HC32F005要配置时钟。我们又回过头来配置时钟。

 时钟配置

//系统时钟配置
static void App_ClkCfg(void)
{
    stc_sysctrl_clk_cfg_t stcCfg;
   ///< 开启FLASH外设时钟
    Sysctrl_SetPeripheralGate(SysctrlPeripheralFlash, TRUE);
    ///< 因要使用的时钟源HCLK小于24M:此处设置FLASH 读等待周期为0 cycle(默认值也为0 cycle)
    Flash_WaitCycle(FlashWaitCycle0);

    ///< 时钟初始化前,优先设置要使用的时钟源:此处设置RCH为4MHz(默认值为4MHz)
    Sysctrl_SetRCHTrim(SysctrlRchFreq4MHz);

    ///< 选择内部RCH作为HCLK时钟源;
    stcCfg.enClkSrc = SysctrlClkRCH;
    ///< HCLK SYSCLK/2
    stcCfg.enHClkDiv = SysctrlHclkDiv1;
    ///< PCLK 为HCLK/8
    stcCfg.enPClkDiv = SysctrlPclkDiv1;
    ///< 系统时钟初始化
    Sysctrl_ClkInit(&stcCfg);
}

 设置频率

//将时钟从RCH4MHz切换至RCH24MHz,
void App_Rch4MHzTo24MHz(void)
{
    ///<============== 将时钟从RCH4MHz切换至RCH24MHz ==============================
    ///< RCH时钟不同频率的切换,需要先将时钟切换到RCL,设置好频率后再切回RCH
    Sysctrl_SetRCLTrim(SysctrlRclFreq32768);
    Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE);
    Sysctrl_SysClkSwitch(SysctrlClkRCL);

    ///< 加载目标频率的RCH的TRIM值
    Sysctrl_SetRCHTrim(SysctrlRchFreq24MHz);
    ///< 使能RCH(默认打开,此处可不需要再次打开)
   // Sysctrl_ClkSourceEnable(SysctrlClkRCH, TRUE);
    ///< 时钟切换到RCH
    Sysctrl_SysClkSwitch(SysctrlClkRCH);
    ///< 关闭RCL时钟
    Sysctrl_ClkSourceEnable(SysctrlClkRCL, FALSE);
}

时钟初始化

void SystemClock_Init(void) //华大单片机严格按照规格书切换时钟
{

    App_ClkCfg();
    delay1ms(10);
    App_Rch4MHzTo24MHz();
     delay1ms(10);
    SystemCoreClockUpdate();
    delay1ms(10);
}

         最后,我们在主函数调用就可以解决乱码的问题啦,如下图是配置时钟之后的打印结果:

总结 

        到这里我们就完全实现了HC32F005的中断发送接收数据,如果有需要工程的小伙伴可以私信我,我们下一期见。

标签:UART1,网关,Uart,void,uint8,MK,发送,串口,com
From: https://blog.csdn.net/qq_58309387/article/details/141792094

相关文章

  • 基于.NET开源、免费的跨平台物联网网关:IoTGateway
    一个.NET开源、免费的跨平台物联网网关  前言今天大姚给大家分享一个基于.NET开源、免费的跨平台物联网网关:IoTGateway。项目介绍IoTGateway是一个基于.NET6的跨平台物联网网关。通过可视化配置,轻松的连接到你的任何设备和系统(如PLC、扫码枪、CNC、数据库、串口设备、上位......
  • 基于Keil软件实现串口收发HEX数据包(江协科技HAL库)
    ​串口收发HEX数据包实验是基于江协科技STM32的HAL库工程模板创建的(可以在作品“基于江科大STM32创建的HAL库工程模板”中的结尾处获取工程模板的百度网盘链接)复制“OLED显示”的工程文件——“4-1 OLED显示屏”,并命名为“9-3 串口收发HEX数据包 ”。打开工程,把下面的程序......
  • 小尺寸BLE 5.2低功耗串口透传蓝牙模块 - ANS-BT103M
    ANS-BT103M是安朔科技自主开发的一款小尺寸BLE蓝牙5.2模块,它支持HID、GATT、ATT和其他配置文件,使用UART作为编程接口,用户可以使用AT命令通过UART读取或写入模块的配置,支持空中升级。支持蓝牙主从一体,一对多连接,透传速率可达60KB/s,支持定制开发。产品参数:模块型号      ......
  • 5G RedCap工业网关的应用场景与优势
    在工业物联网领域,5GRedCap工业网关凭借其低功耗、低成本和高性能的特点,广泛应用于各种工业设备、传感器和控制系统之间的高效连接。不仅支持实时数据采集传输,还能大幅降低部署成本,提升数据传输的可靠性和效率,从而提高生产效率和产品质量。 物通博联推出的5GRedCap工业网关是一款......
  • 四博智联OpenMQTTGateway蓝牙网关,支持100多种蓝牙传感器
    以下是一篇关于OpenMQTTGateway的软文,包含了相关图片,以更好地展示该项目的功能和优势。模组规格OpenMQTTGateway:一站式解决物联网协议整合的强大工具OpenMQTTGateway是一个开源项目,旨在将多种不同的物联网协议整合到一个统一的固件中。通过这一创新性的解决方案,开发......
  • 边缘计算网关:开启高速数据传输的新篇章
    一、引言随着物联网、大数据和人工智能技术的飞速发展,数据传输速度和效率成为制约系统性能的关键因素。我们自主生产的Mbox边缘计算网关,以其高速数据传输能力,为各类应用场景提供了强大的支持。本文将为您介绍边缘计算网关的高速数据传输原理及其在现实各行各业中的应用。二、边缘计......
  • AI 网关零代码解决 AI 幻觉问题
    作者:邢云阳,HigressContributor前言什么是AIAgent随着大模型技术的快速发展,越来越多的公司在实际业务中落地了大模型应用。但是人们逐渐发现了大模型能力的不足。例如:由于大模型的训练数据是有限的,因此一些垂直领域的知识,如金融,医疗等等,大模型无法回答,或者容易出现幻觉。并且......
  • 基于.NET开源、免费的跨平台物联网网关:IoTGateway
    思维导航前言项目介绍项目源代码项目演示项目源码地址优秀项目和框架精选前言今天大姚给大家分享一个基于.NET开源、免费的跨平台物联网网关:IoTGateway。项目介绍IoTGateway是一个基于.NET6的跨平台物联网网关。通过可视化配置,轻松的连接到你的任何设备和系统(如PLC、......
  • Android经典实战之存储方案对比:SharedPreferences vs MMKV vs DataStore
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点在Android开发中,键值对存储(Key-ValueStorage)是一种经常用到的轻量级数据存储方案。它主要用于保存一些简单的配置数据或状态信息,例如用户设置、缓存数据等。常......
  • 一个.NET开源、免费的跨平台物联网网关
    前言今天大姚给大家分享一个基于.NET开源、免费的跨平台物联网网关:IoTGateway。项目介绍IoTGateway是一个基于.NET6的跨平台物联网网关。通过可视化配置,轻松的连接到你的任何设备和系统(如PLC、扫码枪、CNC、数据库、串口设备、上位机、OPCServer、OPCUAServer、MqttServer......