蓝牙小车的具体实现
title: 蓝牙小车开发时的一些细节
cover: >-
https://tse1-mm.cn.bing.net/th/id/OIP-C.BrSgB91U1MPHGyaaZEqcbwHaEo?w=273&h=180&c=7&r=0&o=5&dpr=1.3&pid=1.7
abbrlink: 842d5faf
date:
tags:
#小车基本运动之最重要的—PWM
##1.PWM(Pulse Width Modulation)脉冲宽度调制是什么?
为何这个PWM(脉冲宽度)如此重要呢?因为在具有惯性的系统中,我们可以通过对一系列脉冲的宽度进行调制,来等效地获得我们所需要的模拟量,经常用于电机控速等领域(属于是常客了)
举一个例子:比如说我的占空比为50%,那么在这个一个PWM的周期内,电机处于高电平的时间是只有周期的一半,低电平默认为0,那么我们计算等效电压—( T(on) * 5v + T(off) * 0v ) / Ts = 等效电压V 所以50%占空比可以等效为2.5v电压
通过这个等效电压的例子,也为我们如何控制电机的速度以及呼吸灯等等一系列工业生产提供了新的思路—通过PWM(即控制占空比)来控制等效电压—从而GPIO配置为复用推挽输出,定时器的四个通道(STM32外设)来控制引脚输出
##2.如何实现PWM?
实现PWM,我们需要用到定时器和OC(输出比较),通过定时器不断计数然后和RCC(参考比较值)不断比较,当计数小于RCC时,输出的电平为高电平,而当计数大于RCC时,输出的电平为低电平—这个过程叫输出比较—然后统计高电平在总的计数期间的比值—占空比。
请看此图
我们三步走战略,1.初始化时基单元,2.GPIO串口复用AFIO初始化 3.定时器初始化。 以及知道参数计算的公式:1. PWMFreq = CK_PSC / (PSC+1) / (ARR+1)
2.PWM占空比Duty = CCR / (ARR + 1)
3.PWM分辨率Reso = 1 / (ARR + 1)
##3.PWM代码实现
放在***\Hardware中**那么请看具体代码
这是PWM.h的具体代码
#ifndef __PWM_H__
#define __PWM_H__void PWM_Init(void);#endif
这是PWM.c的具体代码
#include "stm32f10x.h" // Device header//1.时基单元
//2.oc输出比较
//3.GPIO初始化void PWM_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //开启TIM4的外部时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//PB6-PB9 开启GPIOB的外部时钟GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //配置为复用推挽输出,定时器的四个通道来控制引脚输出GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStruct);//定义时基单元TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //从0开始向上计数TIM_TimeBaseInitStruct.TIM_Period = 100 - 1; //ARR重装值TIM_TimeBaseInitStruct.TIM_Prescaler = 36 - 1; //PSCTIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; //高级定时器才有的,我们用不到这里TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; //预分频 DIV1是0预分频TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStruct);// OC 输出比较 初始化OC比较的属性TIM_OCInitTypeDef TIM_OCInitStruct;//OC1 输出比较通道口1TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //以高电平为有效电平TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStruct.TIM_Pulse = 0; //CCR 预期值 CNT 与 CCR进行比较TIM_OC1Init(TIM4,&TIM_OCInitStruct);//oc2TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //以高电平为有效电平TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStruct.TIM_Pulse = 0; //CCR 预期值 CNT 与 CCR进行比较TIM_OC2Init(TIM4,&TIM_OCInitStruct);//oc3TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //以高电平为有效电平TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStruct.TIM_Pulse = 0; //CCR 预期值 CNT 与 CCR进行比较TIM_OC3Init(TIM4,&TIM_OCInitStruct);//oc4TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //以高电平为有效电平TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStruct.TIM_Pulse = 0; //CCR 预期值 CNT 与 CCR进行比较TIM_OC4Init(TIM4,&TIM_OCInitStruct);//在需要不断切换定时器的周期时,而且周期都比较短, T = 1 / F
//程序员需要通过预加载寄存器配合自动重装载寄存器,来操作定时器 缓存TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable);TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable);TIM_OC4PreloadConfig(TIM4,TIM_OCPreload_Enable);TIM_ARRPreloadConfig(TIM4, ENABLE);TIM_Cmd(TIM4,ENABLE);
}
我们来设置小车的移动和速度。
我们分别将它们命名为Motor.c,Motor.h并放到\Hardware文件中
此为Motor.h
#ifndef __MOTOR_H__
#define __MOTOR_H__void Motor_Init(void);
void Motor_SetSpeed(uint8_t left_1,uint8_t left_2,uint8_t right_1,uint8_t right_2);
void Motor_Run(uint8_t Speed,uint16_t time);
void Motor_Back(uint8_t Speed,uint16_t time);
void Motor_TurnLeft(uint8_t Speed,uint16_t time);
void Motor_Spin_Left(uint8_t Speed,uint16_t time);
void Motor_TurnRight(uint8_t Speed,uint16_t time);
void Motor_Spin_Right(uint8_t Speed,uint16_t time);
void Motor_Brake(uint16_t time);#endif
此为Motor.c
#include "stm32f10x.h" // Device header
#include "PWM.h"
#include "Delay.h"//机器人初始化
void Motor_Init(void)
{PWM_Init();
}//控制小车轮子的速度,分别设置四个通道的RCC,每两个通道,控制一个轮子
void Motor_SetSpeed(uint8_t left_1,uint8_t left_2,uint8_t right_1,uint8_t right_2)
{TIM_SetCompare1(TIM4,left_1); //TIM_SetCompare是为了改变我们设置在时基单元里的RCC的大小TIM_SetCompare2(TIM4,left_2);TIM_SetCompare3(TIM4,right_1);TIM_SetCompare4(TIM4,right_2);
}//车子向前开动
void Motor_Run(uint8_t Speed,uint16_t time)
{if (Speed > 100){Speed = 100;}else if (Speed < 0){Speed = 0;}Motor_SetSpeed(Speed,0,Speed,0); //可以从输出比较的图看出来Delay_ms(time);Motor_SetSpeed(0,0,0,0); //最后车子停止运动
}//车子后退
void Motor_Back(uint8_t Speed,uint16_t time)
{if (Speed > 100){Speed = 100;}else if (Speed < 0){Speed = 0;}Motor_SetSpeed(0,Speed,0,Speed); //可以从输出比较的图看出来Delay_ms(time);Motor_SetSpeed(0,0,0,0); //最后车子停止运动}//车子左转
void Motor_TurnLeft(uint8_t Speed,uint16_t time)
{if (Speed > 100){Speed = 100;}else if (Speed < 0){Speed = 0;}Motor_SetSpeed(0,0,Speed,0); //可以从输出比较的图看出来Delay_ms(time);Motor_SetSpeed(0,0,0,0); //最后车子停止运动}//小车左旋转
void Motor_Spin_Left(uint8_t Speed,uint16_t time)
{if (Speed > 100){Speed = 100;}else if (Speed < 0){Speed = 0;}Motor_SetSpeed(0,Speed,Speed,0); //可以从输出比较的图看出来Delay_ms(time);Motor_SetSpeed(0,0,0,0); //最后车子停止运动
}//车子右转
void Motor_TurnRight(uint8_t Speed,uint16_t time)
{if (Speed > 100){Speed = 100;}else if (Speed < 0){Speed = 0;}Motor_SetSpeed(Speed,0,0,0); //可以从输出比较的图看出来Delay_ms(time);Motor_SetSpeed(0,0,0,0); //最后车子停止运动}
//小车右旋转
void Motor_Spin_Right(uint8_t Speed,uint16_t time)
{if (Speed > 100){Speed = 100;}else if (Speed < 0){Speed = 0;}Motor_SetSpeed(Speed,0,0,Speed); //可以从输出比较的图看出来Delay_ms(time);Motor_SetSpeed(0,0,0,0); //最后车子停止运动
}//小车刹车
void Motor_Brake(uint16_t time)
{Motor_SetSpeed(0,0,0,0);Delay_ms(time);
}
#小车的蓝牙模块—Serial(串口)
1.通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统
2.通信协议:制定通信的规则,通信双方按照协议规则进行数据收发
##串口的性质
USART:
1.引脚—TX和RX 2.双工—全双工(发送双方可以同时收发数据) 3.时钟:异步 4.电平:单端 5.设备:点对点—就是说只能双方进行通信
串口接线是交叉的,蓝牙串口不是独立供电的,所以我们是要将蓝牙模块与stm32连接,以stm32供电给蓝牙。
##USART(串口)性质
1.USART,(Universal Synchronous/Asynchronous Receiver/Transmitte)通用同步/异步收发器
2.USART是STM32内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可以自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里
3.自带波特率发生器,最高达4.5Mbits/s
4.可配置数据为长度(8/9),停止位长度(0.5/1/1.5/2)
5.可选校验位(无校验/奇校验/偶校验)
6.支持同步模式,硬件流控制,DMA,智能卡,IrDA,LIN
7.STM32F103C8T6 USART资源:USART1,USART2,USART3 在这里,商家给我指定了串口资源—USART3,所以后面的代码篇用到的都为USART3
##Serial代码篇(\Hardware)
1.Serial.h
#ifndef __SERIAL_H__
#define __SERIAL_H__//接收数据的结构体
typedef struct
{uint8_t Data[100]; //这个是用来接收文本数据的uint8_t flag; //这个是后面main里面判断要用到的uint8_t Length; //接收到的文本数据的大小}MyUsart;extern MyUsart MYUSART3;
void Serial_Init(void);
#endif
2.Serial.c
#include "stm32f10x.h" // Device header
#include "Serial.h" //在.h文件里面定义的结构体,你需要在这个文件里面引用
MyUsart MYUSART3;// 1.GPIO的配置
//2.USART的配置
//3.NVIC的配置 接收文本void Serial_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //USART3RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
//GPIO配置GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStruct);//NIVC中断配置NVIC_InitTypeDef NVIC_InitStruct; //谁来触发中断NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;NVIC_Init(&NVIC_InitStruct);USART_ITConfig(USART3,USART_IT_RXNE,ENABLE); //配置USART中断如何触发 接收中断USART_ITConfig(USART3,USART_IT_IDLE,ENABLE); //空闲中断USART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_BaudRate = 9600; USART_InitStruct.USART_HardwareFlowControl = DISABLE;USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //接收和发送USART_InitStruct.USART_Parity = USART_Parity_No; //不校验USART_InitStruct.USART_StopBits = 8;USART_InitStruct.USART_WordLength = USART_WordLength_8b;USART_Init(USART3,&USART_InitStruct);USART_Cmd(USART3,ENABLE);
}//中断函数
void USART3_IRQHandler(void)
{//接收判断if (USART_GetITStatus(USART3,USART_IT_RXNE) == SET){USART_ClearITPendingBit(USART3,USART_IT_RXNE); //清除后为了下一次接收数据做准备MYUSART3.Data[MYUSART3.Length++] = USART_ReceiveData(USART3); //我接收好一次数据后,指针指向新的位置}if (USART_GetITStatus(USART3,USART_IT_IDLE) == SET){MYUSART3.Data[MYUSART3.Length] = '\0'; //字符串的最后一位是'\0'MYUSART3.flag = 1;MYUSART3.Length = 0;USART_ReceiveData(USART3);}//空闲判断
}//发送函数
这样,我们便完成了Serial的定义,我们继续再main.c里面完成编码
#蓝牙小车的最终引用
#include "stm32f10x.h" // Device header
#include "Serial.h"
#include "Motor.h"
#include <string.h>
#include <stdio.h>
#include "Myu3.h"int main(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组分2组
// Serial_Init();USART3_init(9600);Motor_Init();while(1){if (MyUsart3.flag){MyUsart3.flag = 0;if (strcmp((const char*)MyUsart3.buff,"ONA") == 0){Motor_Run(80,100);}if (strcmp((const char*)MyUsart3.buff,"ONB") == 0){Motor_Back(80,100);}if (strcmp((const char*)MyUsart3.buff,"ONC") == 0){Motor_Spin_Left(80,100);}if (strcmp((const char*)MyUsart3.buff,"OND") == 0){Motor_Spin_Right(80,100);}if (strcmp((const char*)MyUsart3.buff,"ONF") == 0){Motor_Brake(100);}if (strcmp((const char*)MyUsart3.buff,"ONE") == 0){Motor_Brake(100);}}}}
#致谢
最后,感谢你阅读完整个Blog,希望我的文章对你有所启发,有所帮助。感谢!
相关文章:

蓝牙小车的具体实现
title: 蓝牙小车开发时的一些细节 cover: >- https://tse1-mm.cn.bing.net/th/id/OIP-C.BrSgB91U1MPHGyaaZEqcbwHaEo?w273&h180&c7&r0&o5&dpr1.3&pid1.7 abbrlink: 842d5faf date: tags: #小车基本运动之最重要的—PWM ##1.PWM(Pulse …...
污染修复乙级设计资质中关于设计成果保护的规定
关于污染修复乙级设计资质中设计成果的保护,虽然直接针对该资质的设计成果保护规定可能未在公开资料中有详细阐述,但根据中国知识产权法律体系和行业惯例,设计成果作为智力成果的一部分,主要受以下几个方面的法律保护:…...

##10 卷积神经网络(CNN):深度学习的视觉之眼
文章目录 前言1. CNN的诞生与发展2. CNN的核心概念3. 在PyTorch中构建CNN4. CNN的训练过程5. 应用:使用CNN进行图像分类5. 应用:使用CNN进行时序数据预测代码实例7. 总结与展望前言 在深度学习的领域中,卷积神经网络(CNN)已经成为视觉识别任务的核心技术。自从AlexNet在2…...
Linux下添加自己的服务脚本(service)
systemd服务文件(service file)是用来定义和配置systemd服务的文件,通常以.service为后缀。以下是service文件的详细格式和内容说明: 1 文件路径 /etc/systemd/system(供系统管理员和用户使用)系统服务,开机不需要登录就能运行的程序/usr/lib/systemd/system(供发行版…...

C++:内存管理
C:内存管理 一、C/C内存分布二、C语言中动态内存管理方式:malloc/calloc/realloc/free三、C内存管理方式1.new/delete操作内置类型2.new和delete操作自定义类型 四、operator new与operator delete函数(重点)五、new和delete的实现原理1.内置…...

Veeam - 数据保护和管理解决方案_Windows平台部署备份还原VMware手册
Veeam - - 数据保护和管理解决方案 Veeam Backup & Replication Console Veeam Data Platform Veeam Backup & Replication是一款强大的虚拟机备份、恢复和复制解决方案 安全备份、干净恢复和数据弹性 — 即时交付 在混合云中随时随地管理、控制、备份和恢复您的所有数…...

易基因:Nature子刊:ChIP-seq等揭示c-di-AMP与DasR互作以调控细菌生长、发育和抗生素合成|项目文章
大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 c-di-AMP是一种在细菌信号中普遍存在且至关重要的核苷酸第二信使,对于大多数c-di-AMP合成生物体来说,c-di-AMP稳态及其信号转导的分子机制非常值得关注。 2024年…...
stm32学习探究:利用TB6612驱动直流电机
在这篇文章中,我们将探讨如何使用STM32微控制器和TB6612FNG直流电机驱动模块来驱动直流电机。TB6612FNG是一款基于MOSFET的H桥集成电路,能够独立双向控制两个直流电机,非常适合用于小型机器人或双轮车等项目。 一、TB6612FNG 驱动模块介绍 …...
SpringBatch快速入门
Job监听 Spring Batch的Job监听是一种机制,用于在Job的不同阶段插入自定义的逻辑。它允许开发人员在Job开始、结束、失败等不同的事件发生时执行特定的操作。 具体来说,Spring Batch提供了以下几个Job监听器: JobExecutionListenerÿ…...

下载Node.js及其他环境推荐nvm
文章目录 项目场景:下载Node.js环境配置配置环境变量 安装脚手架安装依赖安装淘宝镜像安装 cnpm(我需要安装)nvm 安装 Node.js (推荐) 项目场景: 提示:这里简述项目相关背景: 项目…...

STM32 ADC学习
ADC Analog-to-Digital Converter,即模拟/数字转换器 常见ADC类型 分辨率和采样速度相互矛盾,分辨率越高,采样速率越低。 ADC的特性参数 分辨率:表示ADC能辨别的最小模拟量,用二进制位数表示,比如8,10…...
详解AI作画算法原理
在人工智能领域,AI作画技术已经成为一个引人入胜的研究方向。AI作画算法利用机器学习技术,尤其是深度学习,来生成具有艺术性的图像。本文将深入剖析AI作画的基本原理,包括其技术架构、关键组件以及工作流程。 引言 AI作画技术不…...

每日Attention学习3——Cross-level Feature Fusion
模块出处 [link] [code] [PR 23] Cross-level Feature Aggregation Network for Polyp Segmentation 模块名称 Cross-level Feature Fusion (CFF) 模块作用 双级特征融合 模块结构 模块代码 import torch import torch.nn as nnclass BasicConv2d(nn.Module):def __init__(…...

华为eNSP学习—IP编址
IP编址 IP编址子网划分例题展示第一步:机房1的子网划分第二步:机房2的子网划分第三步:机房3的子网划分IP编址 明确:IPv4地址长度32bit,点分十进制的形式 ip地址构成=网络位+主机位 子网掩码区分网络位和主机位 学此篇基础: ①学会十进制与二进制转换 ②学会区分网络位和…...
数据库的要求
本来我是不准备写数据库的。而且是准备从零开始,学习python,学完语言学,会c和写作技法,再来学习数据库 那样做的复杂度是天量的,按部就班什么的具备,因为你完全不清楚什么时候就有这个基础和条件࿰…...
Spring MVC(二)
1. 注解RequestMapping修饰类 在Spring MVC中一般都是使用注解RequestMapping来映射请求,也就是通过它来指定控制器可以处理哪些URL请求,相当于Servlet中在web.xml中配置的映射地址作用一致。在上一节的内容中,我们通过注解RequestMapping改进…...

ECP44304T-76是一款增强型通信处理器吗?
ABB ECP44304T-76是一款增强型通信处理器,专为ABB的PLC控制系统设计。 这款通信处理器的主要功能是提供PLC与其他设备或网络之间的通信接口。它支持多种通讯协议,包括但不限于Profibus、Ethernet、Modbus等,使得PLC可以轻松集成到复杂的工业…...

mongoDB分组查询
完整代码 //根据医院编号 和 科室编号 ,查询排班规则数据Overridepublic Map<String, Object> getRuleSchedule(long page, long limit, String hoscode, String depcode) {//1 根据医院编号 和 科室编号 查询Criteria criteria Criteria.where("hosco…...

【Java 刷题记录】位运算
位运算 33. 位1的个数 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中 设置位 的个数(也被称为汉明重量)。 示例 1: 输入:n 11 输出:3 解释…...

WINDOWS下zookeeper突然无法启动但是端口未占用的解决办法(用了WSL)
windows下用着用着时候突然zookeeper启动不了了。netstat查也没有找到端口占用,就是起不来。控制台报错 java.lang.reflect.UndeclaredThrowableException: nullat org.springframework.util.ReflectionUtils.rethrowRuntimeException(ReflectionUtils.java:147) ~…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能
指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

Element-Plus:popconfirm与tooltip一起使用不生效?
你们好,我是金金金。 场景 我正在使用Element-plus组件库当中的el-popconfirm和el-tooltip,产品要求是两个需要结合一起使用,也就是鼠标悬浮上去有提示文字,并且点击之后需要出现气泡确认框 代码 <el-popconfirm title"是…...