【STM32CubeMX】STM32H7-RTOS-SPI-W5500

2023-05-16

工程源码下载:基于裸机和Freertos的W5500网络通信工程

目录

1. 移植W5500步骤

2. Cobemx配置步骤

2.1 时钟配置Clock Configuration

2.2 Trace and Debug配置

2.3 使能CPU ICache与DCache

2.4 USART配置

2.5 硬件SPI配置

2.6 GPIO的LED配置

2.7 烧录程序时注意

2.8 FREERTOS配置

2.9 下载程序后不能运行

2.10 提升编译速度

2.11 下载完程序自动启动

 3. W5500硬件连接

3.1 初始化SPI

3.2 初始化GPIO

4. W5500程序移植

4.1 修改wizchip_conf.h文件

5. 我们要实现的函数bsp_spi_w5500.c

5.1 W5500芯片复位

5.2 将SPI函数进行与W5500进行注册

5.3 收发缓存设置

5.4 获取芯片ID

5.5 设置网络配置

5.6 读取网络配置

5.7 配置超时

5.8 打印配置信息

6. 实验现象


1. 移植W5500步骤

  1. 初始化SPI引脚
  2. 初始化SCS引脚(片选)
  3. 下载官方库文件 
  4. 添加官方库到工程目录
  5. 实现SPI接口和库文件的对接
  6. 调用官方库提供的函数实现连接

2. Cobemx配置步骤

2.1 时钟配置Clock Configuration

所使用的单片机是正点原子的阿波罗底板STM32H743IIT6。

我们看原理图是再29.30引脚接的25MHz的无源晶振。

RCC 配置界面。以外部时钟为例,STM32CubeMX中外部时钟配置可选类型为

Disable 

BYPASS Clock Source(旁路时钟源)

Crystal/Ceramic Resonator(石英/陶瓷 晶振)

三种类型,参考手册也将链接电路展示出来了,我们这里用的是无源晶振,故选择第三个方案。

 H743凭借外部晶振的加持,最高主频可以达到480MHz。

 呢么我们就通过配置时钟树使H743发挥出它最佳状态。

STM32H7 主频在 400~480MHz 下,SPI1SPI2 SPI3 的最高时钟是 200MHz,而 SPI4,5,6 是 100MHz。这里特别注意一点,SPI 工作时最少选择二分频,也就是说 SPI1,2,3 实际通信时钟是100MHz

2.2 Trace and Debug配置

2.3 使能CPU ICache与DCache

STM32F7使用CubeMX生产代码时,可以在Cortex-M7设置里选择是否开启ART ACCLERATOR,ICache,DCache等,如下图 

2.4 USART配置

配置调试串口,确定物理引脚PA10\PA9。

 时钟配置完成以后,可以在 Connectivity 栏开启UART功能,USART1可以开启的模式有Asynchronous——异步通讯synchronous——同步通讯Single Wire(Half-Duplex)——单线(半双工)通讯,此处配置为异步通讯。

2.5 硬件SPI配置

 

2.6 GPIO的LED配置

PB0和PB1对应开发板LED0和LED1。

2.7 烧录程序时注意

为什么SWD烧录STM32时BOOT0脚要接高电平,否则SWD下载失败。

对配置的程序进行测试测试成功。

2.8 FREERTOS配置

2.9 下载程序后不能运行

进行软件仿真的时候寻踪按键需要执行三次程序测能启动,每次仿真程序都停留在:

解决办法:

记得将Uis Micro LIB勾选。

2.10 提升编译速度

在CobeMX生成的freertos之后,如果我们选择V6编译器会出现很多编译错误,解决办法是:

替换这两个文件,替换的路径如下:

Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM4F

替换之后编译就不会报错,而且在Browse information勾选的情况下快速编译。

链接在我提供的程序源文件里面:

2.11 下载完程序自动启动

 3. W5500硬件连接

10个引脚中,真正使用的也就只有vcc gnd miso mosi sclk scs 这几个脚,RST和int引脚如果是引用官方的库的话,是不需要的(RST是复位引脚,INT是中断触发引脚)。我们这次也需要用到RST引脚。

 

3.1 初始化SPI

因为W5500模块内部自己实现了TCP/IP协议,在外部只需要通过提供的接口利用SPI把相关的参数传递进去就行了,比如物理地址,本机IP,本机端口,目标端口,目标IP等等。

3.2 初始化GPIO

除去SPI口之外还有一个片选引脚SCS,这个引脚很重要,在官方协议实现的4个函数中,起到的很关键的作用。同时也初始化了复位引脚。

#define CSPin(n)    (n? HAL_GPIO_WritePin(SPI1_CS_GPIO_Port,SPI1_CS_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(SPI1_CS_GPIO_Port,SPI1_CS_Pin,GPIO_PIN_RESET)) 
#define RSTNPin(n)  (n? HAL_GPIO_WritePin(SPI1_RST_GPIO_Port,SPI1_RST_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(SPI1_RST_GPIO_Port,SPI1_RST_Pin,GPIO_PIN_RESET))

4. W5500程序移植

最新程序下载网址如下:

https://github.com/Wiznet/ioLibrary_Driver

我们解压后需要下面几个

下面介绍以下主要的功能:

application/loopback是一个回环测试的示例程序。
Internet里则是上层多种协议的驱动程序。

socket.c 文件夹里面主要是socket的一些函数,比如close connect socket等等函数,实现了一些应用层的封装
w5500.c 文件主要实现的是对W5500模块寄存器的读写和操作,包括读写那些寄存器,地址是多少等等,
wizchip_conf.c 就是一个公共文件主要包括和SPI的连接以及连接W5500读写寄存器函数和socket函数。有用户用于注册函数的几个api以及配置W5X00的一些驱动函数。
DHCP.c 主要就是初始化DHCP,启动DHCP,获取ip,端口等函数

4.1 修改wizchip_conf.h文件

5. 我们要实现的函数bsp_spi_w5500.c

首先根据提供的结构体,将我们要定义的网络配置信息进行赋值:

static wiz_NetInfo NetConf = {
      .mac = {0x0c, 0x29, 0xab, 0x7c, 0x04, 0x02}, //mac地址
      .ip = {192, 168, 0, 215},                   //本机IP地址
      .sn = {255, 255, 255, 0},                   //子网掩码
      .gw = {192, 168, 0, 1},                     //网关地址
      .dns = {0, 0, 0, 0},                         //DNS服务器地址
      .dhcp = NETINFO_STATIC                        //使用静态IP
};

这个结构体存在于wizchip_conf.c,其中NetConf是一个wiz_NetInfo类型的结构体变量,该结构体在wizchip_conf.h中定义,用于设置mac地址、IP地址等网络参数,具体如下:

typedef struct wiz_NetInfo_t
{
   uint8_t mac[6];  ///< Source Mac Address
   uint8_t ip[4];   ///< Source IP Address
   uint8_t sn[4];   ///< Subnet Mask 
   uint8_t gw[4];   ///< Gateway IP Address
   uint8_t dns[4];  ///< DNS server IP Address
   dhcp_mode dhcp;  ///< 1 - Static, 2 - DHCP
}wiz_NetInfo;

接下来我们就要编写网络初始化的配置函数,先把程序贴出来,然后再慢慢分解:

void set_w5500_conf(void)
{
   reset();//芯片复位
   //注册函数,用户通过实现SPI注册回调函数来访问WIZCHP
   reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit);   //注册临界区函数 
   reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);  //注册SPI片选信号函数
   reg_wizchip_spi_cbfunc(SPI_ReadByte, SPI_WriteByte);    //注册读写函数  
/***********************物理层配置*************************/
   //初始化芯片参数
   ctlwizchip(CW_RESET_WIZCHIP,(void *)0);//软件重置
   uint8_t memsize[16] = {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};
   uint8_t tmp;
   //WIZCHIP SOCKET缓存区初始化 
   ctlwizchip(CW_INIT_WIZCHIP, &memsize);
   //PHY物理层连接状态检查
   ctlwizchip(CW_GET_PHYLINK, (void*)&tmp);
/*******************获取芯片ID********************/

  uint8_t id[6];//获取芯片ID
  ctlwizchip(CW_GET_ID,(void*)id);//获取ID
   
/*******************设置网络配置********************/    
  ctlnetwork(CN_SET_NETINFO, (void*)&NetConf);

/*******************读取网络配置********************/
  wiz_NetInfo conf;
  ctlnetwork(CN_GET_NETINFO, (void*)&conf); //读取设置网络状态  
  if(memcmp(&conf,&NetConf,sizeof(wiz_NetInfo)) == 0){
      printf("set network parameters success");// 配置成功
  }else{
      printf("set network parameters fail"); // 配置失败
  }
/*******************配置超时********************/   
  wiz_NetTimeout timeout;
  timeout.retry_cnt = 8;   // 重试次数,默认8次
  timeout.time_100us = 2000; // 超时时间,默认2000*100us = 200ms
  wizchip_settimeout(&timeout);

/*******************打印配置信息********************/     
    printf("w5500 network infomation:\r\n");
    printf("w5500 -mac:%d:%d:%d:%d:%d:%d\r\n", conf.mac[0], conf.mac[1], conf.mac[2], 
            conf.mac[3], conf.mac[4], conf.mac[5]);
    printf("w5500 -ip:%d.%d.%d.%d\r\n", conf.ip[0], conf.ip[1], conf.ip[2], conf.ip[3]);
    printf("w5500 -sn:%d.%d.%d.%d\r\n", conf.sn[0], conf.sn[1], conf.sn[2], conf.sn[3]);
    printf("w5500 -gw:%d.%d.%d.%d\r\n", conf.gw[0], conf.gw[1], conf.gw[2], conf.gw[3]);
    printf("w5500 -dns:%d.%d.%d.%d\r\n", conf.dns[0], conf.dns[1], conf.dns[2], conf.dns[3]);

}  

5.1 W5500芯片复位

   reset();//芯片复位
void reset()
{
  RSTNPin(0);
  HAL_Delay(100);
  RSTNPin(1);
  HAL_Delay(1500);
}

5.2 将SPI函数进行与W5500进行注册

   //注册函数,用户通过实现SPI注册回调函数来访问WIZCHP
   reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit);   //注册临界区函数 
   reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);  //注册SPI片选信号函数
   reg_wizchip_spi_cbfunc(SPI_ReadByte, SPI_WriteByte);    //注册读写函数

在spi里实现一些函数,然后把函数名赋值给wizchip_conf.c里面的一些函数指针,这样W5500.c里面的函数实现读写的时候,就能够直接使用SPI接口了,具体实现的函数有以下6个。

void SPI1_WriteByte(u8 TxData)
uint8_t  SPI1_ReadByte()
void SPI_CrisEnter(void)
void SPI_CrisExit(void)
void SPI_CS_Select(void)
void SPI_CS_Deselect(void)

/**
  * @brief  写1字节数据到SPI总线
  * @param  TxData 写到总线的数据
  * @retval None
  */
void SPI_WriteByte(uint8_t TxData)
{               
  HAL_SPI_Transmit(&SPI_HANDLE, &TxData, 1, 0xFF);     
}
/**
  * @brief  从SPI总线读取1字节数据
  * @retval 读到的数据
  */
uint8_t SPI_ReadByte(void)
{           
  uint8_t send = 0xff;
  uint8_t recv;
  HAL_SPI_TransmitReceive(&SPI_HANDLE, &send, &recv, 1, 0xff);
  return recv;                          
}
/**
  * @brief  进入临界区
  * @retval None
  */
void SPI_CrisEnter(void)
{
    __set_PRIMASK(1);
}
/**
  * @brief  退出临界区
  * @retval None
  */
void SPI_CrisExit(void)
{
    __set_PRIMASK(0);
}
/**
  * @brief  片选信号输出低电平
  * @retval None
  */
void SPI_CS_Select(void)
{
    CSPin(0); //低电平有效
}
/**
  * @brief  片选信号输出高电平
  * @retval None
  */
void SPI_CS_Deselect(void)
{
    CSPin(1);
}

实现了这几个函数之后,需要把他们注册到库函数里面,利用函数指针对上述函数进行调用。

前面说了库文件wizchip_conf.c 里面就包括了和SPI口的对接实现指针函数。例如:

void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb))
{
   while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_));
   
   if(!spi_rb || !spi_wb)
   {
      WIZCHIP.IF.SPI._read_byte   = wizchip_spi_readbyte;
      WIZCHIP.IF.SPI._write_byte  = wizchip_spi_writebyte;
   }
   else
   {
      WIZCHIP.IF.SPI._read_byte   = spi_rb;
      WIZCHIP.IF.SPI._write_byte  = spi_wb;
   }
}

5.3 收发缓存设置

分别指定16个端口上收和发缓冲区的大小(KB),收和发分别加起来不能超过16K。默认每个端口的收发端口分别为2K。

/***********************物理层配置*************************/
   //初始化芯片参数
   ctlwizchip(CW_RESET_WIZCHIP,(void *)0);//软件重置
   uint8_t memsize[16] = {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2};
   uint8_t tmp;
   //WIZCHIP SOCKET缓存区初始化 
   ctlwizchip(CW_INIT_WIZCHIP, &memsize);
   //PHY物理层连接状态检查
   ctlwizchip(CW_GET_PHYLINK, (void*)&tmp);

5.4 获取芯片ID

id里是固定的 “W5500”。

/*******************获取芯片ID********************/

  uint8_t id[6];//获取芯片ID
  ctlwizchip(CW_GET_ID,(void*)id);//获取ID

5.5 设置网络配置

/*******************设置网络配置********************/    
  ctlnetwork(CN_SET_NETINFO, (void*)&NetConf);

5.6 读取网络配置

/*******************读取网络配置********************/
  wiz_NetInfo conf;
  ctlnetwork(CN_GET_NETINFO, (void*)&conf); //读取设置网络状态  
  if(memcmp(&conf,&NetConf,sizeof(wiz_NetInfo)) == 0){
      printf("set network parameters success");// 配置成功
  }else{
      printf("set network parameters fail"); // 配置失败
  }

配置成功会串口打印

5.7 配置超时

如发起tcp链接、发送数据等的时候,如果一段时间没有答复(即超过超时时间),W5500会重发,直到超过重试次数还没有得到答复,就会触发超时中断。

/*******************配置超时********************/   
  wiz_NetTimeout timeout;
  timeout.retry_cnt = 8;   // 重试次数,默认8次
  timeout.time_100us = 2000; // 超时时间,默认2000*100us = 200ms
  wizchip_settimeout(&timeout);

5.8 打印配置信息

 加在配置网络函数内void set_w5500_ip(void),配置完成即可通过串口进行打印。

/*******************打印配置信息********************/     
    printf("w5500 network infomation:\r\n");
    printf("  -mac:%d:%d:%d:%d:%d:%d\r\n", conf.mac[0], conf.mac[1], conf.mac[2], 
            conf.mac[3], conf.mac[4], conf.mac[5]);
    printf("  -ip:%d.%d.%d.%d\r\n", conf.ip[0], conf.ip[1], conf.ip[2], conf.ip[3]);
    printf("  -sn:%d.%d.%d.%d\r\n", conf.sn[0], conf.sn[1], conf.sn[2], conf.sn[3]);
    printf("  -gw:%d.%d.%d.%d\r\n", conf.gw[0], conf.gw[1], conf.gw[2], conf.gw[3]);
    printf("  -dns:%d.%d.%d.%d\r\n", conf.dns[0], conf.dns[1], conf.dns[2], conf.dns[3]);

6. 实验现象

 

 网络配置到这里就算完成了,将这个函数进行初始化后就可以ping通了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【STM32CubeMX】STM32H7-RTOS-SPI-W5500 的相关文章

  • 沁恒CH32V307使用记录:SPI基础使用

    文章目录 目的 基础说明 使用演示 其它补充 总结 目的 SPI是单片机中比较常用的一个功能 这篇文章将对CH32V307中相关内容进行说明 本文使用沁恒官方的开发板 CH32V307 EVT R1沁恒RISC V模块MCU赤兔评估板 进行
  • 关于IKEv2中安全策略索引SPI的生成

    首先引入一个PF key的概念 PF KEY Key Management API 提供IKE模块和IPSec核心之间的接口 在RFC 2367中 有一个SADB GETSPI消息 这个消息就是实现允许一个进程获取SPI值 该值标识所给的s
  • DIY简单的RTOS(二)任务切换

    从系统的角度看 任务是竞争系统资源的最小运行单元 任务可以使用或等待CPU 使用内存空间等系统资源 并独立于其它任务运行 项目地址 任务控制块 在其他RTOS中 任务一般是由 任务堆栈 任务控制块和任务函数三部分组成 任务堆栈 上下文切换的
  • FreeRTOS ------- 任务(task)

    在学习RTOS的时候 个人觉得带着问题去学习 会了解到更多 1 什么是任务 在FreeRTOS中 每个执行线程都被称为 任务 每个任务都是在自己权限范围内的一个小程序 其具有程序入口每个任务都是在自己权限范围内的一个小程序 其具有程序入口通
  • STM32CUBEMX F103 HAL库开发 两路定时器的Encoder编码器模式

    机器人开发过程中 对于直流电机来说 编码器至关重要 它不仅可以使我们对电极进行精确的速度闭环 位置闭环 还可以通过时间积分 根据运动学关系 获得速度 位置等信息 STM32的定时器有编码器模式 大大的方便我们的开发 使用STM32cubeM
  • FreeRTOS(1):任务

    目录 一 FreeRTOS 介绍 什么是 FreeRTOS 为什么选择 FreeRTOS FreeRTOS 资料与源码下载 FreeRTOS 实现多任务的原理 二 移植 FreeRTOS 到STM32 手动移植 使用CubeMX快速移植 快
  • OSAL

    OSAL为 Operating System Abstraction Layer 即操作系统抽象层 支持多任务运行 它并不是一个传统意义上的操作系统 但是实现了部分类似操作系统的功能 OSAL概念是由TI公司在ZIGBEE协议栈引入 他的意
  • micropython-SPI通讯

    micropython SPI通讯 1 什么是SPI 2 SPI通讯原理 3 Micropython中的SPI 4 ZTMR测试SPI 1 ZTMR中SPI引脚 2 ZTMRSPI自测 2 SPI 2板之间通讯测试 1 什么是SPI SPI
  • SPI菊花链原理和配置

    一 概述 在一个主机和多个从器件的典型 SPI 系统中 通常采用专门的片选信号来寻址从器件 随着从器件数量不断增加 片选线也随之增多 这种情况将给电路板布板带来很大的挑战 一个布板方法就是采用菊链结构 本文详细讲述了 SPI 系统的菊链配置
  • FreeRTOS-创建删除任务

    1 FreeRTOSConfig h文件 FreeRTOSConfig h配置文件作用 对FreeRTOS进行功能配置和裁剪 以及API函数的使能 相关的宏可以分为三大类 INCLUDE 配置FreeRTOS中可选的API函数 config
  • 搭建STM32F407的SPI-Flash(基于STM32CubeMX)

    网上有不少例子 都对 但对我来说碰到几个坑 避免以后再犯错 mark下 目标 通过SPI接口 对Nor Flash进行读写 开发板上Nor Flash 是W25Q128 128Mbit 也就是16MB样子 CubeMx端配置 配置要分两个
  • 自己动手写RTOS:02-在M3内核上实现pendsvc

    自己动手写RTOS 自己动手写RTOS 01基础知识和理论部分 自己动手写RTOS 02 在M3内核上实现pendsvc 文章目录 自己动手写RTOS 一 M3内核的相关知识 1 1寄存器 1 2特殊寄存器 1 3堆栈 二 pendSVC实
  • STM32CubeMX学习六 之ADC配置

    文章目录 前言 一 本地环境 二 开始 1 定时器配置 2 引脚配置 在这里插入图片描述 https img blog csdnimg cn e5b6f155a1b8468cb15046a0a9d031cd png 3 内部时钟配置 4 A
  • Nuttx操作系统(三):构建模式

    1 1 Nuttx构建配置以及模式 Nuttx有三种不同的构建配置 FLAT构建 这种构建是所代码驻留在公共地址空间中 1 应用 内核以及board logic在一个flat地址环境中 2 所有的地址空间具有相同的属性 PROTECTED构
  • FreeRTOS 配置TICK_RATE_HZ

    我使用的是带有 5 4 版 FreeRTOS 的 MSP430f5438 我有一个有趣的问题 我无法弄清楚 基本上 当我将 configTICK RATE HZ 设置为不同的值时 LED 闪烁得更快或更慢 它应该保持相同的速率 我将 con
  • 多线程嵌入式软件中的原子操作

    我一直在用 C 语言开发基于 RTOS 的嵌入式软件 并且遇到了有关从多个线程访问共享资源的问题 我有两个问题 第一个是在状态机中设置和获取状态变量的值 下面是 StateMachine object 的头文件 typedef enum S
  • VS Code 有没有办法导入 Makefile 项目?

    正如标题所说 我可以从现有的 Makefile 自动填充 c cpp properties json 吗 Edit 对于其他尝试导入 makefile 的人 我找到了一组脚本 它们完全可以实现我想要实现的目标 即通过 VS Code 管理
  • 在 Atollic TrueStudio、STM32CubeMX 中导入 C 库

    我目前正在开发 STM32F767ZI Nucleo 板和一个小安全芯片 microchip atecc508a 通过 i2c 连接进行连接 该芯片有一个可用的库加密验证库 https github com MicrochipTech cr
  • SPI 电子墨水显示屏与 PIC 18F46K22 连接时出现问题

    我正在使用一个图18F46K22 https ww1 microchip com downloads en DeviceDoc 40001412G pdf在 SPI 主模式下与Waveshare 1 54 电子纸模组 https www w
  • STM32F4 板上的 SPI 从机设置

    我正在尝试通过主从配置中的 SPI 在两个 STM32F4 发现板之间进行通信 我已经有了主设备的代码 但我对需要对从设备的 SPI 初始化进行的更改感到有点困惑 我还想在主机发送数据时实现中断 而不是让从机一直轮询 RXNE 寄存器 但是

随机推荐

  • ROS使用注意事项

    看到一篇总结 xff0c 感觉很有用 摘抄下来 转自 xff1a https www cnblogs com pk28 p 7625838 html
  • Python time模块 时间戳转换

    时间戳转换 时间戳获取 import time time time 时间戳转时间字符串 时间戳 gt 时间数组 gt 格式化时间字符串 时间字符串转时间戳 格式时间字符串 gt 时间数组 gt 时间数组 时间戳转换时间字符串 time st
  • 图漾深度摄像头基本使用方法

    搞到一款图漾的3d相机 xff08 型号为FM810 C xff09 有好久了 xff0c 一直也只是编译了sample代码跑起来看看样子 xff0c 并没有着手看SDK以及开发的事 近几日对照SDK以及其中的SimpleView Fetc
  • Xilinx FPGA的约束设计和时序分析总结 (转)

    在进行FPGA的设计时 xff0c 经常会需要在综合 实现的阶段添加约束 xff0c 以便能够控制综合 实现过程 xff0c 使设计满足我们需要的运行速度 引脚位置等要求 通常的做法是设计编写约束文件并导入到综合实现工具 xff0c 在进行
  • STM32学习笔记-串口

    所用的STM32主要有3个串口 xff0c 3个串口的物理位置如图中所示 串口的驱动编写流程 待续
  • 工业以太网EtherCat学习

    一 简单介绍 EtherCAT是由德国Beckhoff公司提出的实时以太网解决方案 xff0c 它是国际现场总线标准的组成部分 在现场总线级的高速I O控制和高速运动控制方面有突出的表现 EtherCAT使用标准的以太网卡作为主站 xff0
  • AVstream驱动学习

    Step 1 Learn about Windows architecture and drivers AVStream AVStream is a Microsoft provided multimedia class driver th
  • 制作一个舵机云台【内附资料下载链接】

    1 运动功能说明 舵机云台下方的舵机可以提供一个左右摆动的动作 xff0c 同时上方横置的关节模组可以提供一个上下摆动的动作 在这两部分的配合下 xff0c 云台的执行端端 xff08 即 xff1a 关节模组的U型支架 xff09 可以灵
  • UART控制器LIN功能模式(NUC029LAN阅读笔记)

    UART控制器LIN功能模式 xff08 NUC029LAN阅读笔记 xff09 LIN总线帧格式字节域格式 xff08 LIN标准 xff09 帧头 xff08 Header xff09 同步间隔域 xff08 Break Field x
  • 关于新唐NUC029LAN库函数操作无法打开定时器2和定时器3的问题(库函数中的bug)

    结论 xff1a 问题 xff1a 使用NUC029LAN库函数中的设备时钟使能函数时 xff0c 无法正常打开定时器TMR2和TMR3 原因 xff1a clk h中 xff0c 定时器2模块 xff08 TMR2 MODULE xff0
  • STC12系列单片机的1T模式和12T模式

    STC12系列单片机的1T模式和12T模式 总结STC12系列单片机的1T模式和12T模式基本原理以定时器为例 总结 1T 模式 不分频 1个系统基本时钟 xff0c 执行一个动作 xff1b 12T模式 12分频 12个系统基本时钟 xf
  • 函数指针及其定义和用法,C语言函数指针详解

    声明 xff1a 转载 函数指针及其定义和用法 xff0c C语言函数指针详解 版权归原作者所有 xff0c 若有侵权请联系删除 函数指针及其定义和用法 xff0c C语言函数指针详解 函数指针大家了解一下就行了 xff0c 用得不多 xf
  • Python md5、sha256、sha1、加密方法

    需要使用 hashlib 这个库 xff0c python 自带的 xff0c 可以直接用 要加密的数据需要先使用 encode 进行编码 import hashlib data 61 34 你好 34 要进行加密的数据 data sha
  • 通信方式、通信接口、通信总线、通信协议的关系

    通信方式通信接口通信总线通信协议接口 总线 协议之间的关系 通信方式 通信方式是指通信双方之间的工作方式或信号传输方式 终端与其他设备 xff08 例如其他终端 计算机和外部设备 xff09 通过数据传输进行通信 xff0c 根据数据的传输
  • 通信方式的分类(串行通信和并行通信)

    通信方式的分类串行通信和并行通信串行通信同步通信和异步通信单工 半双工和双工 并行通信 通信方式的分类 通信方式是指通信双方之间的工作方式或信号传输方式 终端与其他设备 xff08 例如其他终端 计算机和外部设备 xff09 通过数据传输进
  • 为什么需要使用栈结构?

    在以往学习高级语言时 xff0c 提到栈 xff0c 下意识都会反映上来FILO xff0c 它是暂存数据的一种数据结构 xff0c 但是为什么会用到栈 xff1f 却一直讳莫如深 xff0c 这是高级语言不会涉及到的底层的实现 xff0c
  • C语言中define的用法

    define顾名思义 xff0c 就是下定义 xff0c 那么在C中它也发挥着下定义的作用 1 提前定义变量 include lt stdio h gt define N 100 int main int a 61 10 printf 34
  • C++编译时出现未定义的引用问题解决

    未定义的引用 xff08 undefined reference xff09 出现的原因是生成可执行文件所在的cpp包含头文件时 xff0c 头文件中声明的函数定义未被可执行文件所识别 xff0c 解决办法如下 xff1a add libr
  • 【仿真】手把手学会基于Simulink下的模糊控制系统(上)

    目录 前言 xff1a 什么是模糊控制 1 模糊控制器MATLAB教程 xff08 初级 xff09 1 1 模糊PD控制器 前言 xff1a 什么是模糊控制 控制专业并且写过论文的同学想必一定听说过模糊控制 xff0c 但多数人对于什么是
  • 【STM32CubeMX】STM32H7-RTOS-SPI-W5500

    工程源码下载 xff1a 基于裸机和Freertos的W5500网络通信工程 目录 1 移植W5500步骤 2 Cobemx配置步骤 2 1 时钟配置Clock Configuration 2 2 Trace and Debug配置 2 3