Power's Wiki -

AD 常用技巧

—— 收纳整理了一些实用的小技巧。 原理图库部分 引脚名称上划线(低电平有效) 方法:给需要加上划线的每个字母后面加 “\” 符号 示例:RESET 加上划线 - R\E\S\E\T PCB 封装库部分 (待更新) 原理图部分 禁止 Add Room 操作 原因:Room 操作在多通道布线中比较有用,可将一个通道内的布线直接应用到其他通道。单通道可以不用 Room. 方法: 菜单栏 - 工程 - 工程选择 - Class Generation 选项卡 取消勾选 “生成 Room” PCB 部分 Logo 及标识的添加 原因:如果用直接导入图片的方式,创建的 Logo 无法自由调整大小。 方法:使用字库软件 Font Creator, 在 GitHub 下载我的字库作为模板,定制自己的专属字库。字库制作完成后,安装 .ttf 文件,即可在 Altium 内用相应字符调出 Logo 。 字符对应 Logo 如下图: 自动排布元器件至划定区域 原因:原理图更新到 PCB 时,有些元件会跑很远。 方法:全选 - TOL - 框选 圆形阵列布局 方法: 选中对象 - 复制 EA - 勾选 粘贴到当前层 点击 粘贴阵列 - 设置对象数量与间距 快捷打过孔并换层 方法:布线时用小键盘 + / - 切换 统一设置过孔网络属性 方法: 右键单击任意无属性过孔 - 查找相似对象 - 设置 Net 为 Same 在属性面板中统一添加过孔网络属性 添加泪滴 原因:泪滴的作用是提高信号的完整性,减少信号损失和反射,降低外力冲撞时导线与过孔接触点断裂的风险。 方法:使用快捷键 TE 导线开窗 原因:导线开窗上锡可增加载流量。 方法:将所需走线复制,特殊粘贴到相应 Top / Bottom Solder 层 3D 预览下的操作 方法: 按数字键 “3” 进入 3D 预览界面 按数字键 “2” 返回 PCB 编辑 按数字键 “0” 恢复默认视角 Ctrl + F 翻面 Ctrl + 滚轮 缩放 Shift + 右键 改变视角 复制粘贴中保持网络属性 原因:复制粘贴具有电气属性时,网络属性会丢失。 方法:复制对象 - EA - 勾选 保持网络名称 - 粘贴 焊接位号图的输出 (待更新) 如何在 PCB 上开槽 在 PCB 上的 机械 1 层 绘制开槽的封闭图形,选中并使用快捷键 T - V - B 即可生成开槽(最好切换 3D 视角进行确认)。 参考与致谢 Altium Designer19 设计宝典:实战操作技巧与问题解决方法 原文地址:https://wiki-power.com/ 本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

AI生成摘要 本文介绍了AD常用技巧,包括原理图库部分的引脚名称上划线方法,PCB封装库部分的待更新内容,原理图部分的禁止Add Room操作方法,PCB部分的Logo及标识添加方法,自动排布元器件至划定区域方法,圆形阵列布局方法,快捷打过孔并换层方法,统一设置过孔网络属性方法,添加泪滴方法,导线开窗方法,3D预览下的操作方法,复制粘贴中保持网络属性方法,焊接位号图的输出待更新内容,以及在PCB上开槽的方法。

相关推荐 去reddit讨论

Power's Wiki -

Homelab - 内网穿透工具 frp

frp 是一种内网穿透的方法。你可以通过有公网 IP 的服务器,将内网主机端口暴露到互联网。frp 支持 TCP、UDP、HTTP、HTTPS 等多种协议多种协议。 服务端 frps 部署(Docker Compose) 首先创建 compose.yaml 文件,并粘贴以下内容: yaml title="compose.yaml" version: "3" services: frps: container_name: ${STACK_NAME}_app image: snowdreamtech/frps:${APP_VERSION} network_mode: host volumes: - ${STACK_DIR}/frps.ini:/etc/frp/frps.ini restart: always (可选)推荐在 compose.yaml 同级目录下创建 .env 文件,并自定义你的环境变量。如果不想使用环境变量的方式,也可以直接在 compose.yaml 内自定义你的参数(比如把 ${STACK_NAME} 替换为 frps)。 ```dotenv title=".env" STACK_NAME=frps STACK_DIR=xxx # 自定义项目储存路径,例如 ./frps frps APP_VERSION=latest ``` 在你的项目储存路径 ${STACK_DIR} 中添加配置文件 frps.ini: ini title="frps.ini" [common] bind_port = 7000 # 客户端和服务端连接的端口,在之后配置客户端时会用上。 dashboard_port = 7500 # 服务端 dashboard 的端口 token = ${TOKEN-FRPS} # 客户端和服务端连接的口令,请自行设置。 dashboard_user = ${USERNAME-FRPS} # 用户名 dashboard_pwd = ${PASSWORD-FRPS} # 密码 最后,在 compose.yaml 同级目录下执行 docker compose up -d 命令即可启动编排的容器。 如果你不用 docker 的方法,也可以参考这篇文章:服务端配置·如何实现外网 RDP 远控(frp)。 客户端 frpc 部署(Docker Compose) 首先创建 compose.yaml 文件,并粘贴以下内容: yaml title="compose.yaml" version: "3.3" services: frpc: container_name: ${STACK_NAME}_app image: stilleshan/frpc:${APP_VERSION} network_mode: "host" volumes: - ${STACK_DIR}/frpc.ini:/frp/frpc.ini restart: always (可选)推荐在 compose.yaml 同级目录下创建 .env 文件,并自定义你的环境变量。如果不想使用环境变量的方式,也可以直接在 compose.yaml 内自定义你的参数(比如把 ${STACK_NAME} 替换为 replace)。 ```dotenv title=".env" STACK_NAME=replace STACK_DIR=xxx # 自定义项目储存路径,例如 ./replace replace APP_VERSION=latest ``` 在你的项目储存路径 ${STACK_DIR} 中添加配置文件 frps.ini: ```ini title="frpc.ini" [common] server_addr = xx.xx.xx.xx # 服务器的公网 IP server_port = 7000 # 与服务端的端口保持一致 tls_enable = true token = ${TOKEN-FRPS} # 与服务端的 token 保持一致 [xxx] type = tcp remote_port = xx # 公网访问的端口号 local_ip = localhost local_port = xx # 内网的端口号 ``` 最后,在 compose.yaml 同级目录下执行 docker compose up -d 命令即可启动编排的容器。 参考与致谢 GitHub repo · snowdreamtech/frps GitHub repo · stilleshan/frpc Docker Hub · snowdreamtech/frps Docker Hub · stilleshan/frpc 如何实现外网 RDP 远控(frp) 使用 frp 访问群晖 NAS 原文地址:https://wiki-power.com/ 本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

AI生成摘要 frp是一种内网穿透的方法,可以通过有公网IP的服务器将内网主机端口暴露到互联网。frp支持多种协议。部署frps服务端需要创建compose.yaml文件,并添加配置信息。在项目储存路径中添加frps.ini配置文件。执行docker compose up -d命令启动容器。部署frpc客户端也需要创建compose.yaml文件,并添加配置信息。在项目储存路径中添加frpc.ini配置文件。执行docker compose up -d命令启动容器。

相关推荐 去reddit讨论

Power's Wiki -

AD 基本操作 - 原理图绘制

—— Altium Designer 系列教程 背景 经过上一章节的预热,从这一章开始,我们进入原理图绘制环节。 绘制原理图 调整图纸 按照前文提到的基本流程,我们新建了一个项目,将原理图文件添加到项目中。此时,出现了一张空白的图纸。我们可以直接在上绘制原理图。如果原理图变得复杂,也可以 更改图纸的尺寸,使元器件不显得过于拥挤: 双击 图纸任意空白处, 在 Properties 面板内找到 Page Options 栏目, 点击 Sheet Size 下拉框更改图纸尺寸。 放置元件 接下来我们开始放置元件。库的安装在前一章已讲解,我们打开 Components 面板,点击显示为库的名称的下拉框,即可切换已经安装的库。切换之后。在搜索框搜索所需的元器件(键入后不用按回车),找到对应的之后,可用鼠标左键 直接拖进 原理图中,这就成功放置了一个元件。 如果忘记元件是属于哪个库的,也可以用全局搜索的功能。点击库名称左边的 三条杠 标志,在下拉框选择 File-based Librarys Search ,即可搜索所有可用的库。 元件属性 放置的元件有几个关键属性: Designator:元件位号。元件唯一标识,不可重名。通常用 R1, R2 ... 代表电阻,C1, C2 ... 代表电容(参考上一章的知识点), Comment:元件大小参数,如阻值、容值、芯片型号等, Description:元件的功能描述, Footprint:链接到封装库,将元件与某个 PCB 封装对应上, Models:包括 Simulation(仿真模型)、Signal Integrity(信号完整性)等。 基本操作 左键单击:选择命令 左键长按:拖动对象 左键双击:设置对象属性 右键单击:取消或弹出命令菜单 右键长按:拖动原理图页面 Ctrl + 滚轮:缩放页面 Shift + 左键单击/框选:选择多个元器件 更高级的操作,使用命令 S(Select),弹出命令菜单: | 快捷键 | 详细命令 | 功能 | | :----- | :---------------- | :------------------------------------------------------------------- | | E | Lasso Select | 套索,选择范围内元件;单击左键开始绘制套索,再次单击完成范围结束绘制 | | I | Inside Area | 框选,选中区域内所有的元件 | | O | Outside Area | 反选,选中区域外所有的元件 | | L | Touching Line | 线选,选中被线条触碰到的元件 | | C | Connection | 选中网络名称相同的元件 | | A | All | 选择所有元件 | | T | Toggle Select | 反选,单击原来选中的将取消选中,原来未选中的将选中 | 元件的旋转:选中元件后按 Space 空格键 复制剪切粘贴:Ctrl + C,Ctrl + X,Ctrl + V 复制后自动填充位号:选中元件,按住 Shift 同时拖动,即可粘贴递增位号的元件。步长可在 TP(Tools-Preference-Schematic-General)中设置。 绘制导线:Ctrl + W 绘制网络标签:PN 放置电源/地:直接在工具栏中左键选取,右键则可以选择不同样式 全局元件自动编号 当原理图工程比较庞大,元件比较多,有时候可能会出现元件位号重名、缺失的情况。这时候可以用全局位号管理:TAA,代替手动检查。 勾选需要自动排号的元器件,点击 更新更改列表,再点击 接收更改(创建 ECO),执行变更,即可完成元件的自动编号。 总结 以上仅仅是绘制原理图的最基本操作,就像提供了一套厨具。至于怎么做出更香的饭菜,更多靠的是 想象力 与 不断的练习 。 参考与致谢 Altium 公司 Altium Designer 专栏 原文地址:https://wiki-power.com/ 本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

AI生成摘要 本文介绍了Altium Designer软件中绘制原理图的基本操作。首先是调整图纸尺寸,然后放置元件。放置的元件有几个关键属性,包括元件位号、大小参数、功能描述、链接到封装库和模型。接下来介绍了一些基本操作,如选择命令、拖动对象、设置对象属性等。还介绍了一些快捷键和高级操作,如套索选择、框选、反选、线选等。最后介绍了元件的旋转、复制粘贴、绘制导线、绘制网络标签和放置电源/地的方法。最后提到了全局元件自动编号的功能。

相关推荐 去reddit讨论

Power's Wiki -

Homelab - 极简个人书签导航站 Flare

Flare 是一个轻量、快速、美观的个人导航页面,无任何数据库依赖,应用数据完全开放透明,支持在线编辑,内置 Material Design Icons 6k+ 图标。 部署(Docker Compose) 首先创建 compose.yaml 文件,并粘贴以下内容: ```yaml title="compose.yaml" version: "3.6" services: flare: container_name: ${STACK_NAME}_app image: soulteary/flare:${APP_VERSION} # 更多启动参数请参考文档 https://github.com/soulteary/docker-flare/blob/main/docs/advanced-startup.md ports: - ${APP_PORT}:5005 volumes: - ${STACK_DIR}:/app command: flare --nologin=0 # 开启用户登录模式,需要先设置 nologin 启动参数为 0 environment: - FLARE_USER= ${APP_USER} # 如开启用户登录模式,且未设置 FLARE_USER,则默认用户为 flare - FLARE_PASS= ${APP_PASS} # 如开启用户登录模式,且未设置 FLARE_USER,则会默认生成密码并展示在应用启动日志中 restart: always ``` (可选)推荐在 compose.yaml 同级目录下创建 .env 文件,并自定义你的环境变量。如果不想使用环境变量的方式,也可以直接在 compose.yaml 内自定义你的参数(比如把 ${STACK_NAME} 替换为 flare)。 ```dotenv title=".env" STACK_NAME=flare STACK_DIR=xxx # 自定义项目储存路径,例如 ./flare flare APP_VERSION=latest APP_PORT=xxxx # 自定义访问端口,选择不被占用的即可 APP_USER=xxxx # 自定义用户名 APP_PASS=xxxx # 自定义密码 ``` 最后,在 compose.yaml 同级目录下执行 docker compose up -d 命令即可启动编排的容器。 配置说明 可在修改 ${DIR}/flare 内的 apps.yml 与 bookmarks.yml 配置应用和书签的地址。容器会实时更新。也可在 url 后面加上以下参数进行调试: 引导操作:/guide 设置页面:/settings 在线编辑:/editor 图标获取:/icons 帮助页面:/help 参考与致谢 官网 文档 / GitHub repo Docker Hub

AI生成摘要 Flare是一个轻量、快速、美观的个人导航页面,无数据库依赖,支持在线编辑,内置6k+图标。使用Docker Compose部署,创建compose.yaml文件,设置环境变量,执行docker compose up -d命令启动容器。可通过修改配置文件和添加参数进行调试和编辑。

相关推荐 去reddit讨论

Power's Wiki -

ADC - Dynamic Parameters

Dynamic Parameters ADC's dynamic parameters mainly contain: Signal to Noise Ratio (SNR) Total Harmonic Distortion (THD) Signal to Noise and Distortion Ratio (SINAD) Inter-modulation Error (IM) Signal to Noise Ratio (SNR) Signal to Noise Ratio (SNR) of an ADC is defined as the ratio of the Measured Signal Power's RMS (excluding Harmonic Distortion) to the Noise Power's RMS: $$ SNR(dB)=20log(\frac{V_{Signal(RMS)}}{V_{Noise(RMS)}}) $$ Since SNR is an ratio of power, $20$ in the equation means the square of the ratio of voltage. Although the Harmonic Distortion is not included in the measurement of SNR, but the Quantization, Thermal and other residual noise in converter are included. Total Harmonic Distortion (THD) Total Harmonic Distortion (THD) of an ADC is defined as the ratio of the fundamental to all the harmonic distortion: $$ THD(dB)=20log(\frac{\sqrt{V^2_{2(RMS)}+V^2_{3(RMS)}+...+V^2_{n(RMS)}}}{V_{1(RMS)}}) $$ How to Test Dynamic Parameters Test System Setup Test system setup for ADC dynamic parameter tests: Resolution of AC SRC should be at least 2 to 4 bits better than DUT. Tests Concept ADC has a theoretical best ever SNR of: $$ SNR = (6.02N + 1.76) dB $$ Where $N$ is the number of ADC's bits. Procedure of testing the dynamic parameters of an ADC DUT is listed below. 1. Make a continuous input signal with the tester for the ADC to convert It is common practice to ensure that the analog/digital clock are referenced to a common master clock, so that the relationship of the clock sources's frequency is fixed and synchronized, which making test results highly repeatable. 2. Collect a set of samples with the ADC coherently For AC Source: $$ \frac{Fs}{Fi}=\frac{Ns}{Ms} $$ Where $Fs$ is the samping rate of AC Source, $Fi$ is signal frequency, $Ns$ is the number of samples (does not have to be a 2x number), $Ms$ is the number of integer cycles (does not have to be odd). For Digital Capture: $$ \frac{Fs(dut)}{Fi}=\frac{Ncap}{Mc} $$ Where $Fs(dut)$ is the ADC sampling rate also the Digital Capture's sample rate, $Fi$ is the signal frequency, $Ncap$ is the number of samples captured (2x number), $Mc$ is the number of integer cycles (odd). 3. Send the collected set of time samples to the DSP to perform DFT / FFT analysis ? 4. Analyze the frequency bins of interest using equations or tester algorithms for SNR, THD and compare to specification 5. Make a pass / fail decision based on the results References & Acknowledgements Fundamentals of Testing Using ATE The-Fundamentals-of-Mixed-Signal-Testing_Brian-Lowe Original: https://wiki-power.com/ This post is protected by CC BY-NC-SA 4.0 agreement, should be reproduced with attribution.

AI生成摘要 ADC的动态参数主要包括:信噪比(SNR)、总谐波失真(THD)、信噪和失真比(SINAD)和互调误差(IM)。测试动态参数的步骤包括:生成连续输入信号、采集ADC的样本、使用DSP进行DFT/FFT分析、使用方程或测试仪算法分析感兴趣的频率区间的SNR和THD,并根据结果做出通过/不通过的决定。

相关推荐 去reddit讨论

Power's Wiki -

HAL 库开发笔记 - 外部中断

上一篇文章我们提到,用轮询的方法消除按键抖动、检测输入,有可能会消耗过多的系统资源并导致卡机,也有可能会错过检测。这就是为什么我们需要使用中断了。 基本原理 轮询与中断 什么是轮询和中断?以取外卖举个例子,轮询就是每分钟我都要去一趟门口,看看外卖小哥来了没。那么这段时间我做不了别的事情了,就光盯着外卖;但假如外卖小哥在我恰好离开门口的时候送到了,那么就错过了外卖。相反的,中断就是让外卖小哥来的时候打个电话,我搁下手中的活去拿外卖,这样我既能够安心干活,又不怕错过外卖。 外部中断 中断分外部(Interrupt)和内部(Exception)。外部中断由外部外设来打断 MCU,内部中断由内部的软件程序自行打断 MCU. NVIC NVIC 全称为 Nested Vectored Interrupt Controller,翻译过来就是 嵌套向量中断控制器 。它主要有三个参数,分别是:中断使能,抢占优先级,响应优先级。(优先级数值越小,优先级越高) 中断使能:指的就是是否开启中断。如果开启中断,那么当满足中断触发条件的时候,会跳到中断服务程序运行;否则不理会中断服务程序,继续运行主程序。 抢占优先级:用于判断一个中断是否可以打断另一个中断的服务程序,抢先运行。举个例子,条件触发了 A 中断,A 中断的服务程序正在运行中,此时条件触发了 B 中断。此时如果 B 中断的抢占优先级比 A 的高,那么 A 的服务程序就会被打断,先去执行 B 的服务程序,执行完之后再继续执行 A,这也称为中断嵌套。如果 B 的抢占优先级不比 A 高,那还是乖乖先执行完 A,再去执行 B. 响应优先级:如果抢占优先相同的几个中断同时被触发,那么响应优先级高的最先运行。 欲判断中断的优先级,首先要先比较的是抢占优先级。抢占优先级相同的情况下,响应优先高的中断优先级别高。如果两个优先级都一样,那么就要根据中断向量表来确定。 中断回调函数参考 配置了 GPIO 中断和 NVIC 优先级之后,在 stm32f4xx_it.c 文件末尾重写中断回调函数即可实现功能。 ```c / USER CODE BEGIN 1 / void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { } / USER CODE END 1 / ``` 外部中断按键控灯 在进行下一步实验之前,需要在 CubeMX 里配置串口下载、时钟等各类参数。 具体步骤请跳转文章 HAL 库开发笔记 - 环境配置 中的方法进行配置。 在 CubeMX 内配置中断 如图,LED 还是按照上一篇文章的方法,配置为输出;按键因为是低电平触发,也就是在按下的一瞬间会产生一个下降沿,所以引脚应该配置为下降沿触发的中断。 在我的板子上,就是将 PI8 配置为 GPIO_EXTI8 模式(外部中断,挂载在中断线 8 上的),并配置为下降沿触发,根据原理图,选择内部上拉(Pull-up)。如图所示: 接着,点击跳转 NVIC 标签页面,使能我们配置的中断: 另外,要把抢占优先级降低一位(从 0 变为 1,原因下文会解释)。 在代码内配置中断 只需要在 stm32f4xx_it.c 末尾添加如下代码: ```c title="stm32f4xx_it.c" / USER CODE BEGIN 1 / void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0) { HAL_Delay(100); if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 0) { HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin); } } } / USER CODE END 1 / ``` 这段代码的作用是重写中断的回调函数,增加用按键切换灯开关的功能。但是这里的 HAL_Delay() 延时函数有坑,因为其来源是 SysTick 定时器(在固定时间间隔内产生中断),所以就有所属的中断优先级。在上面配置 NVIC 的图中可以看出,SysTick 和我们配置的中断抢占优先级都是 0,所以便无法在外部中断触发时接着触发 SysTick 了。所以,我们要把外部中断的抢占优先级改低(由 0 改为 1)。 编译上传后即可通过按下按键,切换 LED 灯的亮灭状态了。 参考与致谢 进阶篇 II [Interrupt] STM32CubeMX 实战教程(三)—— 外部中断(中断及 HAL_Delay 函数避坑) 原文地址:https://wiki-power.com/ 本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

AI生成摘要 本文介绍了HAL库开发笔记中的外部中断部分。首先解释了轮询和中断的概念,并通过外卖的例子进行了比喻。然后介绍了外部中断和内部中断的区别,以及NVIC的参数和作用。接着讲解了如何配置GPIO中断和NVIC优先级,并提供了代码示例。最后指出了HAL_Delay()函数的问题,并给出了解决方法。

相关推荐 去reddit讨论

Power's Wiki -

HAL 库开发笔记 - 串口通信

本篇基于自研 RobotCtrl 开发套件,单片机内核为 STM32F407ZET6,RS-232 通信使用 SP3232EEN 芯片,原理图及详细介绍请见 RobotCtrl - STM32 通用开发套件。 基本原理 串口通信的基本原理请跳转文章 通信协议-串口通信。 串口通讯实验 在进行下一步实验之前,需要在 CubeMX 里配置串口下载、时钟等各类参数。 具体步骤请跳转文章 HAL 库开发笔记 - 环境配置 中的方法进行配置。 在 CubeMX 内配置串口 根据原理图,我们用来进行通讯实验的串口是 USART1 ,即 PA9 PA10 引脚。那么,我们首先需要在 CubeMX 内将这两个引脚配置为 USART1 的发送和接受功能,然后点击左侧 USART1 标签页,将模式(Mode)设为异步(Asynchronous),并在下方修改波特率(Baud Rate)等参数: 参数详情如下: 波特率设置(Baud Rate):没有哪种波特率最好,根据实际情况进行修改,要与串口调试助手上一致。 数据位数(Word Length):如果使能了奇偶校验,那么实际数据将在该位数上减一。 校验(Parity):可选择奇偶校验或不校验。 停止位(Stop Bits):额外一位或两位用于作为发送或接收完毕信号位。 数据方向(Data Direction):可选择仅发送,仅接收或收发模式。 过采样(Over Sampling):8 倍或 16 倍采样率可以有效防止数据出错。 最后,在 NVIC 标签页使能 USART1 的串口中断,如图: 在代码内配置串口 首先需要在 stm32f4xx_it.c 末尾添加如下代码: c title="stm32f4xx_it.c" /* USER CODE BEGIN 1 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance==USART1) { HAL_UART_Receive_IT(huart, &aRxBuffer, 1); // 接收并写入 aRxBuffer HAL_UART_Transmit(huart, &aRxBuffer, 10, 0xFFFF); // 把接收到的 aRxBuffer 发回去 } } /* USER CODE END 1 */ 其中,Buffer 是在 main.c 中定义的 uint8_t 类型全局变量。这里每接受的一个字节后就产生中断,将该字节数据返回并重新开启中断。我们需要分别在 main.c 和 stm32f4xx_it.c 中定义它: ```c title="main.c" / Private variables -----------------------------------------------------------/ / USER CODE BEGIN PV / uint8_t aTxBuffer[] = "USART TEST\r\n"; //用于发送的字符串 uint8_t aRxBuffer[20]; //用于接收的字符串 / USER CODE END PV / ``` ```c title="stm32f4xx_it.c" / Private variables -----------------------------------------------------------/ / USER CODE BEGIN PV / extern uint8_t aTxBuffer; extern uint8_t aRxBuffer; / USER CODE END PV / ``` 另外,在 main.c 中,我们需要在串口初始化后、主循环前,添加接收中断开启函数: ```c title="main.c" / USER CODE BEGIN 2 / HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 1); // 接收中断开启函数 / USER CODE END 2 / ``` 也可以发送一条初始化消息,代表串口已启动: ```c title="main.c" / USER CODE BEGIN 2 / HAL_UART_Transmit(&huart1, (uint8_t*) aTxBuffer, sizeof(aTxBuffer) - 1, 0xFFFF); // 发上一次自定义的 aTxBuffer / USER CODE END 2 / ``` 如果需要对 printf 进行重定向(把 printf 函数用在 STM32 中做串口输出功能),请参考 STM32CubeIDE 串口重定向(printf)及输出浮点型。 下载验证 程序烧录成功后,我们打开串口助手,配置对应的端口和波特率。 连上串口后,会先打印一行 aTxBuffer 的内容,然后将会把接收到的 aRxBuffer 回传打印出来。如图: 参考与致谢 STM32CubeMX 实战教程(六)—— 串口通信 进阶篇 III [UART & USART] STM32 非阻塞 HAL_UART_Receive_IT 解析与实际应用 HAL 库教程 6:串口数据接收 原文地址:https://wiki-power.com/ 本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

AI生成摘要 本文介绍了使用HAL库进行串口通信的基本原理和实验步骤。首先在CubeMX中配置串口参数,包括波特率、数据位数、校验、停止位等。然后在代码中配置串口中断和接收函数。最后通过串口助手验证通信是否成功。

相关推荐 去reddit讨论

Power's Wiki -

Hack.init( ) 黑客马拉松

—— Wight · 基于云平台的去线缆化照明系统。 项目仓库:linyuxuanlin / Wight 背景 项目制作于 2017 hack.init() 创客马拉松。 20 多个小时的敲代码、建模、调试各种乱七八糟的 bug、等待打印、展示 & 演讲,终于有点成品的样子。 这个项目主要用于乡村偏远地区的路灯照明系统。 模型有点抽象,其实它正扮演的是一杆路灯。 项目创新点 太阳能供电。 自给自足(经查阅详细资料,太阳能发电量足以点亮 LED) 去线缆化。 为偏远山区不方便铺线缆提供便利 智能算法。 检测到夜晚,自动开灯;检测到人或车辆经过,提高 LED 亮度 云平台统一控制。 用的是 GSM 主控,可以批量远程调试 拓展性。 对个别有自定义照明需求的特殊用户提供各种自定义的功能 原理及实现 代码: ```cpp define BUTTONS_address "channel/widget4_0/cmd/control" //开关命令 define LIGHT_STATUS_address "channel/widget4_0/data/light"//开关状态 define ITENSITY_DATA_address "channel/widget4_0/data/lightsensor" define LEDPIN1 D1 //定义灯泡控制引脚 define LEDPIN2 D2 define LEDPIN3 D3 define LEDPIN4 D5 define CHECKIN1 A0 define CHECKIN2 D4 int autostate = 2; int light_state = 2; void buttons_function(uint8_t payload, uint32_t len)//自动&浇水按钮 { uint8_t SwitchKey; uint8_t SwitchKey2; aJsonClass aJson; aJsonObject root = aJson.parse((char )payload); if(root == NULL) { aJson.deleteItem(root); return; } aJsonObject _switch = aJson.getObjectItem(root, "mode"); if(_switch != NULL) { SwitchKey = atoi(_switch->valuestring); if(SwitchKey) { SerialUSB.println("auto on"); autostate=1; IntoRobot.publish(LIGHT_STATUS_address,"1"); } else { SerialUSB.println("auto off"); autostate=0; IntoRobot.publish(LIGHT_STATUS_address,"0"); } } aJsonObject *_switch2 = aJson.getObjectItem(root, "manual"); if(_switch2 != NULL) { SwitchKey2 = atoi(_switch2->valuestring); if(SwitchKey2) { SerialUSB.println("manual on"); light_state=1; IntoRobot.publish(LIGHT_STATUS_address,"1"); } else { SerialUSB.println("manual off"); light_state=0; IntoRobot.publish(LIGHT_STATUS_address,"0"); } } else { } aJson.deleteItem(root); } void lightup() { digitalWrite(LEDPIN1, HIGH); // 打开灯泡 digitalWrite(LEDPIN2, HIGH); // 打开灯泡 digitalWrite(LEDPIN3, HIGH); // 打开灯泡 digitalWrite(LEDPIN4, HIGH); // 打开灯泡 } void light_half_up() { analogWrite(LEDPIN1, 80); // 打开灯泡 analogWrite(LEDPIN2, 80); // 打开灯泡 analogWrite(LEDPIN3, 80); // 打开灯泡 analogWrite(LEDPIN4, 80); // 打开灯泡 } void lightdown() { digitalWrite(LEDPIN1, LOW); digitalWrite(LEDPIN2, LOW); digitalWrite(LEDPIN3, LOW); digitalWrite(LEDPIN4, LOW); } int getlight() { int k = analogRead(CHECKIN1); SerialUSB.println(k); return k; } int get_IR_data() { int b = digitalRead(CHECKIN2); SerialUSB.println(b); return b; } void automode() { if(getlight()>=400) { IntoRobot.publish(LIGHT_STATUS_address,"1"); if (get_IR_data()==0) lightup(); else light_half_up(); } else { IntoRobot.publish(LIGHT_STATUS_address,"0"); lightdown(); } } void HUMIDITY_print_function(uint8_t *payload, uint32_t len) { } // IntoRobot.publish(LIGHT_STATUS_address,"1"); // IntoRobot.publish(LIGHT_STATUS_address,"0"); void setup() { pinMode(D4,INPUT); SerialUSB.begin(115200); SerialUSB.println("hello world"); pinMode(LEDPIN1, OUTPUT); //初始化 pinMode(LEDPIN2, OUTPUT); //初始化 pinMode(LEDPIN3, OUTPUT); //初始化 pinMode(LEDPIN4, OUTPUT); //初始化 //设备接收云平台的灯开关命令 IntoRobot.subscribe(BUTTONS_address,NULL,buttons_function); IntoRobot.subscribe(ITENSITY_DATA_address,NULL,HUMIDITY_print_function); } void loop() { int a =map(getlight() ,0,1024,100,0); IntoRobot.publish(LIGHT,a); SerialUSB.println(getlight()); if(autostate==0) { if(light_state ==1) lightup(); else lightdown(); } else if (autostate==1) { SerialUSB.println("state=1"); automode(); } delay(100); } ``` 因比赛时间所限,只能粗略画出模型,打印出来组装。 FAQ Q:项目后期还有跟进吗? A:暂时没有跟进的计划。创新点挺不错,但是否有商业应用价值,还有待验证。 总结 我们在这次比赛中并没有获奖。不过,比赛锻炼了赶代码和路演的能力,也让我提前体验了加班上线的感受,也认识了很多人,收获了好多纪念品。 参考与致谢 团队成员:林沛杰,黄岳峰,张梓宜 IntoRobot 云平台 原文地址:https://wiki-power.com/ 本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

AI生成摘要 这个项目是在2017年hack.init()创客马拉松上制作的,主要用于乡村偏远地区的路灯照明系统。项目的创新点包括太阳能供电、去线缆化、智能算法和云平台统一控制。通过使用GSM主控,可以实现批量远程调试。项目的代码实现了自动开灯和调节亮度的功能。虽然没有获奖,但比赛锻炼了能力,认识了很多人。

相关推荐 去reddit讨论

Power's Wiki -

HAL 库开发笔记 - TIM 基本定时器

在 STM32 中,有基本定时器、通用定时器和高级定时器这三类定时器,用于处理各类周期任务。在本篇文章中,我将对基本定时器展开详细介绍。 基本原理 我们常用的定时器分基本、通用和高级定时器三类,在 STM32F4 系列单片机上,其对应关系如下: 基本定时器 TIM6 TIM7 通用定时器 TIM2-TIM5 TIM9-TIM14 高级定时器 TIM1 TIM8 (SysTick 定时器) 通常,我们拿基本定时器当计时器用,拿通用定时器输出 PWM 信号用。 基本定时器的特性 在 STM32F4 系列单片机上,TIM6 和 TIM7 这两个基本定时器的特性如下: 挂载在 APB1 总线上 16 位自动重载递增计数器 16 位可编程预分频器,用于对计数器时钟频率进行分频(即运行时修改),分频系数介于 1 和 65536 之间 用于触发 DAC 的同步电路 发生计数器上溢更新事件时会生成中断 / DMA 请求 常用的定时器函数参考 HAL_TIM_Base_Init():初始化定时器时基单元 HAL_TIM_Base_DeInit():禁用定时器,与初始化相反 HAL_TIM_Base_MspInit():MSP 初始化函数,定时器初始化时会自动调用 HAL_TIM_Base_MspDeInit():与上一个相反 HAL_TIM_Base_Start():开启定时器 HAL_TIM_Base_Stop():停止定时器 HAL_TIM_Base_Start_IT():以中断模式开启定时器 HAL_TIM_Base_Stop_IT():关闭中断模式的定时器 HAL_TIM_Base_Start_DMA():以 DMA 模式开启定时器 HAL_TIM_Base_Stop_DMA():关闭 DMA 模式的定时器 用基本定时器使 LED 定时闪烁 本次实验是用基本定时器实现计时功能,让 LED 0.5 秒变换一次开关状态。 在 CubeMX 内配置基本定时器 首先,我们打开 Clock Configuratgion 时钟树配置页面,找到并记下最右侧 APB1 Timer clocks 的数值: 这是因为,STM32F4 系列的 TIM2-TIM7,TIM12-TIM14 是挂载在低速 APB1 总线上,而 TIM1,TIM8-TIM11 是挂载在高速 APB2 总线上,我们这里用到基本定时器 TIM6,所以要看 APB1 的速率(这里经过分频倍频后是 90 MHz)。 接着,我们找到侧边栏 Timer 中找到 TIM6,先勾选 Activated 激活定时器,并在下方配置以下的参数: 各参数的含义: Prescaler(预分频系数):8999 Counter Mode(计数模式):Up(从 0 开始向上计数至预分频系数后溢出) Counter Period(计时周期 / 装载值):4999 auto-reload preload(是否自动重装载):Enable(溢出时会自动重装初值) 因为我这里用的时钟源为 90 MHz,因此将预分频系数设置为 8999(也就是 9000 分频),分频后为 10 kHz(90 MHz/9000)。装载值设置为 4999(每周期计数 5000 次),所以得到 500 ms 一个周期。 接着我们在其 NVIC 标签页,对中断进行使能: 在代码内配置基本定时器 在 main.c 中开启定时器: ```c title="main.c" / USER CODE BEGIN 2 / HAL_TIM_Base_Start_IT(&htim6); / USER CODE END 2 / ``` 在 stm32f4xx_it.c 中添加回调函数: ```c title="stm32f4xx_it.c" / USER CODE BEGIN 1 / void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim->Instance == TIM6) { HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } } / USER CODE END 1 / ``` 关于 LED 的配置,可以参考前面的文章 HAL 库开发笔记-GPIO。 下载烧录,可以看到 LED 按我们预设的 500 ms 周期切换开关状态(也就是每 500 ms 发生溢出并产生一个上溢事件,我们在回调函数中对 LED 灯进行了翻转操作)。 参考与致谢 STM32CubeMX 实战教程(四)—— 基本定时器(还是点灯) 进阶篇 VI [Timer & PWM] 原文地址:https://wiki-power.com/ 本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

AI生成摘要 本文介绍了STM32中的基本定时器,包括其特性和常用的定时器函数。通过配置基本定时器,可以实现LED定时闪烁功能。文章提供了在CubeMX和代码中配置基本定时器的步骤,并给出了LED的配置参考。最后,通过下载烧录,可以看到LED按照预设的500毫秒周期切换开关状态。

相关推荐 去reddit讨论

Power's Wiki -

HAL 库开发笔记 - TIM 通用定时器

在上一篇文章中,简单介绍了 STM32F4 的三类定时器,也详细讲解了基本定时器。在本篇文章中,我们将继续介绍通用定时器。 基本原理 在 STM32F4 中,通用定时器有 TIM2-TIM5,TIM9-TIM14。 通用定时器的特性 在 STM32F4 中,通用定时器的特性如下: 16/32 位递增、递减和递增 / 递减自动重载计数器 16 位可编程预分频器,用于对计数器时钟频率进行分频(分频系数为 1-65536) 4 个独立通道,分别可用于: 输入捕获 输出比较 PWM 生成(边沿和中心对齐模式) 单脉冲模式输出 使用外部信号控制定时器且可实现多个定时器互连的同步电路 发生如下事件时生成中断 / DMA 请求: 更新:计数器上溢 / 下溢、计数器初始化(通过软件或内部 / 外部触发) 触发事件(计数器启动、停止、初始化或通过内部 / 外部触发计数) 输入捕获 输出比较 支持定位用增量(正交)编码器和霍尔传感器电路 外部时钟触发输入或逐周期电流管理 常用的定时器函数参考 以下是常用的定时器函数参考,与基本定时器的函数相同。 HAL_TIM_Base_Init():初始化定时器时基单元 HAL_TIM_Base_DeInit():禁用定时器,与初始化相反 HAL_TIM_Base_MspInit():MSP 初始化函数,定时器初始化时会自动调用 HAL_TIM_Base_MspDeInit():与上一个相反 HAL_TIM_Base_Start():开启定时器 HAL_TIM_Base_Stop():停止定时器 HAL_TIM_Base_Start_IT():以中断模式开启定时器 HAL_TIM_Base_Stop_IT():关闭中断模式的定时器 HAL_TIM_Base_Start_DMA():以 DMA 模式开启定时器 HAL_TIM_Base_Stop_DMA():关闭 DMA 模式的定时器 用通用定时器输出 1 kHz/50% 占空比的 PWM 本次实验使用通用定时器输出 1 kHz,50% 占空比的 PWM 信号,可用示波器显示输出的波形。 在 CubeMX 内配置通用定时器 首先,我们打开 Clock Configuratgion 时钟树配置页面,因通用定时器挂载在挂载在高速 APB2 总线上,所以我们找到并记下 APB2 Timer clocks 的时钟频率(180 MHz): 接着,我们找到侧边栏 Timer 中找到 TIM8,设置通道 1(Channel 1)为 PWM 生成(PWM Generation CH1),为了能生成 1 kHz 频率的 PWM 方波,我们需要在下方配置以下参数: Prescaler(预分频系数):180-1 Counter Mode(计数模式):Up(从 0 开始向上计数至预分频系数后溢出) Counter Period(计时周期 / 装载值):1000-1 auto-reload preload(是否自动重装载):Enable(溢出时会自动重装初值) 因此处选用的时钟源为 180 MHz,因此将预分频系数设置为 180-1 = 179,分频后为 1 MHz,将装载值设置为 1000-1 = 9999,所以得到 1 kHz 的频率。 在代码内配置基本定时器 在 main.c 中开启定时器: ```c title="main.c" / USER CODE BEGIN 2 / HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1); // 设置占空比为 500(500 Hz/1 kHz=50%) __HAL_TIM_SetCompare(&htim8,TIM_CHANNEL_1,500); / USER CODE END 2 / ``` 编译并烧录,用示波器可以看出波形: 参考与致谢 STM32CubeMX 实战教程(五)—— 通用定时器(PWM 输出) 原文地址:https://wiki-power.com/ 本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。

AI生成摘要 本文介绍了STM32F4的通用定时器,包括其基本原理和特性。通用定时器具有16/32位递增、递减和递增/递减自动重载计数器,可编程预分频器,4个独立通道等特点。文章还提供了常用的定时器函数参考,并演示了如何使用通用定时器输出1kHz/50%占空比的PWM信号。

相关推荐 去reddit讨论