ESP8266+STM32 AT驱动程序,心知天气API 记录时间: 2025年5月26日13:24:11

 接线为 串口2 接入ESP8266

esp8266.c


#include "stm32f10x.h"//8266预处理文件
#include "esp8266.h"//硬件驱动
#include "delay.h"
#include "usart.h"//用得到的库
#include <string.h>
#include <stdio.h>
#include <cJSON.h>
#include <stdlib.h>
#include <ctype.h>   // for isspace
#include <string.h>  // for strlen
#include <stddef.h>
#include <stdarg.h>char city_name[32]="beijing"; //用于存储你要获取的城市名字(拼音或地址码)
char wifi_ssid[32]="0000"; //用于存储你要连接的热点名字
char wifi_pass[32]="0000"; //用于存储你要连接的热点密码
int is_wifi_connected;//联网标志位
const char *blacklist[] = {
//过滤显示设置"Host:","Date:","Connection:","Content-Type:","access-control-allow-origin:","Content-Length:","etag:","x-powered-by:","x-ratelimit-limit:","x-ratelimit-remaining:","x-ratelimit-reset:","x-request-id:","x-tenant-id:",NULL // 结束标志
};
//用于在杂乱的数据中找到关键词
const char *ExtractField(const char *buf, const char *key, char *out, size_t out_size);
//用于屏蔽关键词输出 
void Filtered_Usart_Printf(const char *line);//======================
//      初始化ESP8266
//======================
void ESP8266_Init(void)
{is_wifi_connected=0;//初始化联网标志位Usart_Printf(USART1, "Send AT\r\n"); //输出到串口一// 查询AT指令有效度ESP8266_SendCmd("AT\r\n","OK");Usart_Printf(USART1, "Send AT+CWJAP?\r\n");// 查询是否已经连上网络if(ESP8266_SendCmd("AT+CWJAP?\r\n",wifi_ssid)) {is_wifi_connected=1;} else {if(ConnectToWiFi()) {is_wifi_connected=1;//表示已经连上网络} else {Usart_Printf(USART_DEBUG, "No Connect  WiFi\r\n");}}}//判断联网是否成功
_Bool ConnectToWiFi(void)
{char cmd[64];Usart_Printf(USART1, "Send AT\r\n");// 启动8266 客户端模式 尝试联网ESP8266_SendCmd("AT\r\n","OK");Usart_Printf(USART1, "Send AT+CWMODE=1\r\n");//尝试连接到网络ESP8266_SendCmd("AT+CWMODE=1\r\n","OK");if(sizeof(wifi_ssid)!=0 &&sizeof(wifi_pass)!=0) {//网络信息没设置不执行联网程序sprintf(cmd, "AT+CWJAP=\"%s\",\"%s\"\r\n", wifi_ssid, wifi_pass);Usart_Printf(USART_DEBUG, "Try to connect WiFi: %s pass:%s\r\n", wifi_ssid,wifi_pass);ESP8266_SendCmd(cmd,"CONNECTED");Usart_Printf(USART_DEBUG, "connected %s\r\n", wifi_ssid);return 1;//不设置逻辑运行成功即返回1表联网成功}}//=================================
//  cmd:命令 res:需要检查的返回指令
// 传递字符串从串口2打印
//=================================
int ESP8266_SendCmd( char *cmd,char *res)
{Usart_Printf(USART2, cmd);char uart_buf[128];//数据缓存机制while(1) {if (USART2_GetLine(uart_buf, sizeof(uart_buf)) > 0) {// 缓冲数据中查找对应的关键词if (strstr(uart_buf, res) != NULL) {// 判断成功才打印(节约资源),收到的内容到串口1Usart_Printf(USART_DEBUG, "Recv: ");Usart_Printf(USART_DEBUG, uart_buf);Usart_Printf(USART_DEBUG, "\r\n");break;}if (strstr(uart_buf, "ERROR") != NULL) {// 判断成功才打印(节约资源),收到的内容到串口1Usart_Printf(USART_DEBUG, "ERROR Recv: ");Usart_Printf(USART_DEBUG, uart_buf);Usart_Printf(USART_DEBUG, "\r\n");}}delay(500);}return 1;//返回1表执行成功
}//=================================
//发送给服务端以获取数据的 GET/POST
//=================================
void GetWeatherAPI(void)
{Usart_Printf(USART_DEBUG, "AT+CIPMUX=0\r\n");ESP8266_SendCmd("AT+CIPMUX=0\r\n", "OK");  // 单连接模式Usart_Printf(USART_DEBUG, "AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n");ESP8266_SendCmd("AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n", "CONNECT");Usart_Printf(USART_DEBUG, "AT+CIPMODE=0\r\n");  // 确保是非透传模式ESP8266_SendCmd("AT+CIPMODE=0\r\n", "OK");httpget();}void httpget(void)
{// 计算 GET 请求长度(根据你构造的 redata)char redata[256];char key[] = "心知天气密匙";sprintf(redata,"GET /v3/weather/now.json?key=%s&location=%s&language=zh-Hans&unit=c HTTP/1.1\r\n""Host: api.seniverse.com\r\n""Connection: close\r\n""\r\n",key, city_name);char cmd[64];sprintf(cmd, "AT+CIPSEND=%d\r\n", strlen(redata));  // 指定长度Usart_Printf(USART_DEBUG, "%d", strlen(redata));ESP8266_SendCmd(cmd, ">");  // 等待 > 提示符// 发送实际内容Usart_Printf(USART_DEBUG, "%s", redata);Usart_Printf(USART2,redata);  // 直接发送原始数据,不带 \r\n 请求体内部已经定义好了char uart_buf[256];//数据缓存机制char temperature_str[16];char text_str[16];while(1) {if (USART2_GetLine(uart_buf, sizeof(uart_buf)) > 0) {Filtered_Usart_Printf(uart_buf);if (ExtractField(uart_buf, "text", text_str, sizeof(text_str)))
{Usart_Printf(USART_DEBUG,"\r\n城市:%s\r\n",city_name);Usart_Printf(USART_DEBUG,"\r\n当前天气:%s\r\n",text_str);
} if (ExtractField(uart_buf, "temperature", temperature_str, sizeof(temperature_str))) {int temperature = atoi(temperature_str);Usart_Printf(USART_DEBUG,"temperature:%d\r\n",temperature);}}Usart_Printf(USART2,"AT+CIPCLOSE\r\n");//关闭服务器
}const char *ExtractField(const char *buf, const char *key, char *out, size_t out_size)
{char search_key[64];snprintf(search_key, sizeof(search_key), "\"%s\":\"", key);const char *start = strstr(buf, search_key);if (!start) return NULL;start += strlen(search_key);const char *end = strchr(start, '"');if (!end) return NULL;size_t len = end - start;if (len >= out_size) len = out_size - 1;strncpy(out, start, len);out[len] = '\0';return out;
}
//屏蔽输出函数
void Filtered_Usart_Printf(const char *line) {for (int i = 0; blacklist[i] != NULL; i++) {if (strstr(line, blacklist[i])) {return;}}Usart_Printf(USART_DEBUG, "%s", line);
}

esp8266.h

#ifndef __ESP8266_H
#define __ESP8266_H
#define USART_DEBUG   USART1// 全局变量声明(外部可见)extern  int is_wifi_connected;void ESP8266_Init(void); //初始化操作
void httpget(void);
int ESP8266_SendCmd( char *cmd,char *res);
void GetWeatherAPI(void);
_Bool ConnectToWiFi(void); #endif

 usart.c

#include "usart.h"
#include <stdarg.h>
#include <string.h>
#include <stdio.h>#include "stm32f10x_usart.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "misc.h"
#include "esp8266.h"uint16_t usart2_index = 0;
uint8_t usart2_rx_buffer[USART2_RX_BUFFER_SIZE];
volatile uint16_t usart2_rx_head = 0;  // 写指针
volatile uint16_t usart2_rx_tail = 0;  // 读指针uint8_t usart1_buf[USART1_BUF_SIZE];
uint8_t usart2_buf[USART2_BUF_SIZE];
// 串口1接收缓冲及状态
u8 USART1_RX_BUF[USART1_REC_LEN];
u16 USART1_RX_STA = 0;// 串口2接收缓冲及状态
u8 USART2_RX_BUF[USART2_REC_LEN];
u16 USART2_RX_STA = 0;
void USART1_Init(u32 bound) {GPIO_InitTypeDef GPIO_InitStruct;USART_InitTypeDef USART_InitStruct;NVIC_InitTypeDef NVIC_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);// PA9 - TXDGPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);// PA10 - RXDGPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStruct);// 配置串口1USART_InitStruct.USART_BaudRate = bound;USART_InitStruct.USART_WordLength = USART_WordLength_8b;USART_InitStruct.USART_StopBits = USART_StopBits_1;USART_InitStruct.USART_Parity = USART_Parity_No;USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_Init(USART1, &USART_InitStruct);// 中断配置USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);USART_Cmd(USART1, ENABLE);// NVIC配置NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 3;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct);
}
void USART2_Init(u32 bound) {GPIO_InitTypeDef GPIO_InitStruct;USART_InitTypeDef USART_InitStruct;NVIC_InitTypeDef NVIC_InitStruct;// 使能时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // PA2/PA3RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);// PA2 - TXDGPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);// PA3 - RXDGPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStruct);// 配置串口2USART_InitStruct.USART_BaudRate = bound;USART_InitStruct.USART_WordLength = USART_WordLength_8b;USART_InitStruct.USART_StopBits = USART_StopBits_1;USART_InitStruct.USART_Parity = USART_Parity_No;USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_Init(USART2, &USART_InitStruct);// 中断配置USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);USART_Cmd(USART2, ENABLE);// NVIC中断配置NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 3;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct);
}
void Usart_SendString(USART_TypeDef *USARTx, const char *str) {while (*str) {USART_SendData(USARTx, (uint8_t)*str++);while (USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);}
}void Usart_Printf(USART_TypeDef *USARTx, const char *fmt, ...) {while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);//等待空闲char buffer[256];va_list ap;va_start(ap, fmt);vsnprintf(buffer, sizeof(buffer), fmt, ap);va_end(ap);Usart_SendString(USARTx, buffer);
}
void USART1_IRQHandler(void) {if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {uint8_t ch = USART_ReceiveData(USART1);if ((USART1_RX_STA & 0x8000) == 0) {if ((USART1_RX_STA & 0x4000) != 0) {if (ch == '\n') {USART1_RX_STA |= 0x8000; // 完整帧接收完成} else {USART1_RX_STA = 0; // 出错重置}} else {if (ch == '\r') {USART1_RX_STA |= 0x4000;} else {USART1_RX_BUF[USART1_RX_STA++ & 0x7FFF] = ch;if (USART1_RX_STA >= USART1_REC_LEN)USART1_RX_STA = 0;}}}}
}
void USART2_IRQHandler(void) {if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {uint8_t data = USART_ReceiveData(USART2);uint16_t next_head = (usart2_rx_head + 1) % USART2_RX_BUFFER_SIZE;if (next_head != usart2_rx_tail) {  // 如果没有发生缓冲区满的情况usart2_rx_buffer[usart2_rx_head] = data;  // 存入数据usart2_rx_head = next_head;               // 更新写指针return;
}   if (next_head == usart2_rx_tail) {// 缓冲区满,允许覆盖usart2_rx_tail = (usart2_rx_tail + 1) % USART2_RX_BUFFER_SIZE;}
usart2_rx_buffer[usart2_rx_head] = data;usart2_rx_head = next_head;}  }
/*** @brief  从 USART2 的 Ring Buffer 中读取一个字节* @param  data: 用于保存读取到的数据* @retval 1: 成功读取, 0: 缓冲区为空*/int USART2_GetLine(char *buf, int max_len) {int i = 0;while (i < max_len - 1) {if (usart2_rx_tail == usart2_rx_head) {break; // 缓冲区为空}char ch = usart2_rx_buffer[usart2_rx_tail];usart2_rx_tail = (usart2_rx_tail + 1) % USART2_RX_BUFFER_SIZE;buf[i++] = ch;if (ch == '\n') { // 遇到换行符结束buf[i] = '\0';return i;}}buf[i] = '\0'; // 补上字符串结束符return i;
}int USART1_WaitRecive(void) {u32 timeout = 0xFFFFF;while ((USART1_RX_STA & 0x8000) == 0) {if (--timeout == 0) return -1;}memcpy(usart1_buf, USART1_RX_BUF, USART1_RX_STA & 0x7FFF);usart1_buf[USART1_RX_STA & 0x7FFF] = '\0';USART1_ClearRxBuffer();return 0;
}void USART1_ClearRxBuffer(void) {memset(USART1_RX_BUF, 0, USART1_REC_LEN);USART1_RX_STA = 0;
}int USART2_WaitRecive(char *res) {u32 timeout = 0xFFFFF;while ((USART2_RX_STA & 0x8000) == 0) {if (--timeout == 0) return -1;}memcpy(usart2_buf, USART2_RX_BUF, USART2_RX_STA & 0x7FFF);usart1_buf[USART2_RX_STA & 0x7FFF] = '\0';USART1_ClearRxBuffer();return 0;}void USART2_ClearRxBuffer(void) {memset(USART2_RX_BUF, 0, USART2_REC_LEN);USART2_RX_STA = 0;
}
#pragma import(__use_no_semihosting)struct __FILE { int handle; };
FILE __stdout;void _sys_exit(int x) { x = x; }
void _ttywrch(int ch) { ch = ch; }int __io_putchar(int ch) {USART_SendData(USART1, (uint8_t)ch);while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);return ch;
}int __io_getchar(FILE *f) {f = f;while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);return USART_ReceiveData(USART1);
}

 usart.h 

 

#ifndef __USART_H__
#define __USART_H__#include "stm32f10x.h"// 接收缓冲大小#define USART1_REC_LEN    256
#define USART2_REC_LEN    256
// 主程序访问接收数据用的缓冲区
#define USART1_BUF_SIZE   256
#define USART2_BUF_SIZE   256
#define USART2_RX_BUFFER_SIZE 2048
// 接收缓冲和状态变量
extern u8 USART1_RX_BUF[USART1_REC_LEN];
extern u16 USART1_RX_STA;extern u8 USART2_RX_BUF[USART2_REC_LEN];
extern u16 USART2_RX_STA;// 数据缓冲(供主程序读取)
extern u8 usart1_buf[USART1_BUF_SIZE];
extern u8 usart2_buf[USART2_BUF_SIZE];// 初始化函数
void USART1_Init(u32 bound);
void USART2_Init(u32 bound);// 发送函数
void Usart_SendString(USART_TypeDef *USARTx, const char *str);
void Usart_Printf(USART_TypeDef *USARTx, const char *fmt, ...);// 接收处理函数
int USART1_WaitRecive(void);
void USART1_ClearRxBuffer(void);
int USART2_GetLine(char *buf, int max_len);int USART2_WaitRecive(char *res);
void USART2_ClearRxBuffer(void);#endif // __USART_H__

main.c 

//头文件
#include "stm32f10x.h"
#include "GPIOLIKE51.h"
#include "usart.h"
#include "esp8266.h"
int main(void)
{    USART1_Init(9600);USART2_Init(115200);Usart_Printf(USART1, "Connect  WiFi\r\n");ESP8266_Init();if(is_wifi_connected==1){GetWeatherAPI();  //更新天气}else{Usart_Printf(USART1,"No connect to");}
}

调试信息展示 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/82978.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CDN安全加速:HTTPS加密最佳配置方案

CDN安全加速的HTTPS加密最佳配置方案需从证书管理、协议优化、安全策略到性能调优进行全链路设计&#xff0c;以下是核心实施步骤与注意事项&#xff1a; ​​一、证书配置与管理​​ ​​证书选择与格式​​ ​​证书类型​​&#xff1a;优先使用受信任CA机构颁发的DV/OV/EV证…

【前端】Twemoji(Twitter Emoji)

目录 注意使用Vue / React 项目 验证 Twemoji 的作用&#xff1a; Twemoji 会把你网页/应用中的 Emoji 字符&#xff08;如 &#x1f604;&#xff09;自动替换为 Twitter 风格的图片&#xff08;SVG/PNG&#xff09;&#xff1b; 它不依赖系统字体&#xff0c;因此在 Android、…

GCN图神经网络的光伏功率预测

一、GCN图神经网络的核心优势 图结构建模能力 GCN通过邻接矩阵&#xff08;表示节点间关系&#xff09;和节点特征矩阵&#xff08;如气象数据、历史功率&#xff09;进行特征传播&#xff0c;能够有效捕捉光伏电站间的空间相关性。其核心公式为&#xff1a; H ( l 1 ) σ (…

按照状态实现自定义排序的方法

方法一&#xff1a;使用 MyBatis-Plus 的 QueryWrapper 自定义排序 在查询时动态构建排序规则&#xff0c;通过 CASE WHEN 语句实现优先级排序&#xff1a; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.stereotype.Ser…

【计算机网络】IPv6和NAT网络地址转换

IPv6 IPv6协议使用由单/双冒号分隔一组数字和字母&#xff0c;例如2001:0db8:85a3:0000:0000:8a2e:0370:7334&#xff0c;分成8段。IPv6 使用 128 位互联网地址&#xff0c;有 2 128 2^{128} 2128个IP地址无状态地址自动配置&#xff0c;主机可以通过接口标识和网络前缀生成全…

【Redis】string

String 字符串 字符串类型是 Redis 最基础的数据类型&#xff0c;关于字符串需要特别注意&#xff1a; 首先 Redis 中所有的键的类型都是字符串类型&#xff0c;而且其他几种数据结构也都是在字符串的基础上构建的。字符串类型的值实际可以是字符串&#xff0c;包含一般格式的…

基于ELK的分布式日志实时分析与可视化系统设计

目录 一、ELK平台介绍 1.ELK概述 2.Elasticsearch 3.Logstash 4.Kibana 二、部署ES群集 1.资源清单 2.基本配置 3.安装Elasticsearch&#xff08;elk1上、elk2上、elk3上&#xff09; 4.安装logstash&#xff08;elk1上&#xff09; 5.Filebeat 6.安装Kibana&#x…

电机控制选 STM32 还是 DSP?技术选型背后的现实博弈

现在搞电机控制&#xff0c;圈里人都门儿清 —— 主流方案早就被 STM32 这些 Cortex-M 单片机给拿捏了。可要是撞上系统里的老甲方&#xff0c;技术认知还停留在诺基亚砸核桃的年代&#xff0c;非揪着 DSP 不放&#xff0c;咱也只能赔笑脸&#xff1a;“您老说的对&#xff0c;…

【案例分享】蓝牙红外线影音遥控键盘:瑞昱RTL8752CJF

蓝牙红外线影音遥控键盘 Remotec的无线控制键盘采用瑞昱蓝牙RTL8752CJF解决方案&#xff0c;透过蓝牙5.0与手机配对后&#xff0c;连线至 Remotec 红外 code server 取得对应影音视觉设备的红外 code后&#xff0c;即可控制多达2个以上的影音视觉设备&#xff0c;像是智能电视…

PostgreSQL如何更新和删除表数据

这节说下怎样更新和删除表数据&#xff0c;当然认识命令了&#xff0c;可以问AI帮忙写。 接上节先看下天气表weather的数据&#xff0c;增加了杭州和西安的数据&#xff1a; 一.UPDATE更新命令 用UPDATE命令更新现有的行。 假设所有 杭州 5月12日的温度低了两度&#xff0c;用…

简单三步FastAdmin 开源框架的安装

简单三步FastAdmin 开源框架的安装 第一步&#xff1a;新建站点1&#xff0c;在宝塔面板中&#xff0c;创建一个新的站点&#xff0c;并填写项目域名。 第二步&#xff1a;上传框架1&#xff0c;框架下载2&#xff0c;上传解压缩 第三步&#xff1a;配置并安装1&#xff0c;进入…

使用 pytesseract 构建一个简单 OCR demo

简介 pytesseract 库是 Google Tesseract OCR &#xff08;光学字符识别&#xff09;引擎的一个 Python 封装库&#xff0c;使用广泛且功能强大。 构建 使用 pytesseract 构建一个简单 OCR demo。 步骤一&#xff1a;安装必要的库 您需要在您的 Python 环境中安装 pytessera…

十三: 神经网络的学习

这里所说的“学习”是指从训练数据中自动获取最优权重参数的过程。为了使神经网络能进行学习&#xff0c;将导入损失函数这一指标。而学习的目的就是以该损失函数为基准&#xff0c;找出能使它的值达到最小的权重参数。为了找出尽可能小的损失函数的值&#xff0c;我们将介绍利…

AWS 创建VPC 并且添加权限控制

AWS 创建VPC 并且添加权限控制 以下是完整的从0到1在AWS中创建VPC并配置权限的步骤&#xff08;包含网络配置、安全组权限和实例访问&#xff09;&#xff1a; 1. 创建VPC 步骤&#xff1a; 登录AWS控制台 访问 AWS VPC控制台&#xff0c;点击 创建VPC。 配置基础信息 名称…

ICASSP2025丨融合语音停顿信息与语言模型的阿尔兹海默病检测

阿尔兹海默病&#xff08;Alzheimers Disease, AD&#xff09;是一种以认知能力下降和记忆丧失为特征的渐进性神经退行性疾病&#xff0c;及早发现对于其干预和治疗至关重要。近期&#xff0c;清华大学语音与音频技术实验室&#xff08;SATLab&#xff09;提出了一种将停顿信息…

C# 导出word 插入公式问题

最近遇到了一个问题&#xff0c;下载一个文档时需要下载word可编辑的公式。找了很久终于找到了一种解决办法。下面是以C#代码来实现在Word中插入公式的功能。 目录 一、引入dll程序集文件1、通过 NuGet 引入dll&#xff08;2种方法&#xff09;的方法&#xff1a;2、手动添加d…

智汇云舟携最新无人机2D地图快速重建技术亮相广西国际矿业展览会

5月22至25日&#xff0c;广西国际矿业展览会&#xff08;以下简称 “矿业展”&#xff09;在南宁国际会展中心成功举办。智汇云舟与合作伙伴广西空驭数智信息技术有限公司携无人机 2D地图快速重建技术&#xff0c;以及视频孪生智慧矿山解决方案参会&#xff0c;为矿山行业数字化…

OpenSSL 签名验证详解:PKCS7* p7、cafile 与 RSA 验签实现

OpenSSL 签名验证详解&#xff1a;PKCS7* p7、cafile 与 RSA 验签实现 摘要 本文深入剖析 OpenSSL 中 PKCS7* p7 数据结构和 cafile 的作用及相互关系&#xff0c;详细讲解基于 OpenSSL 的 RSA 验签字符串的 C 语言实现&#xff0c;涵盖签名解析、证书加载、验证流程及关键要…

9:OpenCV—模板匹配

模版匹配 1、模板匹配概念 模板匹配是一项在一副图像中寻找与另一幅模板图像最匹配&#xff08;相似&#xff09;部分的技术。模板匹配不是基于直方图的&#xff0c;而是通过在输入图像上滑动图像块&#xff08;模板&#xff09;同时对比相似度&#xff0c;来对模板和输入图像…

Composer 常规操作说明与问题处理

目录 一、 Composer 简介&#xff0c;安装二、全局配置三、项目配置&#xff08;composer.json&#xff09;3.1 composer.json 文件1. 基础字段信息2. **require&#xff08;生产环境依赖&#xff09;**3. **require-dev&#xff08;开发环境依赖&#xff09;** 3.2 composer.l…