STM32端与C#端的连接与交互[外设][代码记录]

1. 通过UART串口进行通信

STM32 端代码(UART通信):
#include "stm32f1xx_hal.h"UART_HandleTypeDef huart1;void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();char message[] = "Hello from STM32!\r\n";while (1){HAL_UART_Transmit(&huart1, (uint8_t*)message, sizeof(message), HAL_MAX_DELAY);HAL_Delay(1000);  // 发送间隔1秒}
}static void MX_USART1_UART_Init(void)
{huart1.Instance = USART1;huart1.Init.BaudRate = 9600;huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_TX_RX;HAL_UART_Init(&huart1);
}static void SystemClock_Config(void)
{// 时钟配置代码
}static void MX_GPIO_Init(void)
{// GPIO初始化代码
}
C# 端代码(通过串口读取STM32的数据):
using System;
using System.IO.Ports;class Program
{static void Main(){SerialPort port = new SerialPort("COM3", 9600); // 使用串口3, 波特率9600port.Open();port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);Console.WriteLine("等待数据...");Console.ReadLine(); // 保持程序运行port.Close();}private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e){SerialPort sp = (SerialPort)sender;string inData = sp.ReadExisting(); // 读取接收到的数据Console.WriteLine($"接收到的数据: {inData}");}
}

2. 通过USB-CDC进行通信

STM32 端代码(配置为USB CDC虚拟串口):
  1. 使用STM32CubeMX生成USB CDC代码。
  2. usbd_cdc_if.c 文件中修改发送数据的部分:
#include "usbd_cdc_if.h"uint8_t usb_data[] = "Hello from STM32 via USB!\r\n";void send_usb_data(void)
{CDC_Transmit_FS(usb_data, sizeof(usb_data)); // 通过USB发送数据
}int main(void)
{HAL_Init();SystemClock_Config();MX_USB_DEVICE_Init(); // 初始化USB设备while (1){send_usb_data();HAL_Delay(1000);  // 每秒发送一次}
}
C# 端代码(通过虚拟串口与STM32通信):
using System;
using System.IO.Ports;class Program
{static void Main(){SerialPort usbPort = new SerialPort("COM4", 115200); // 设置虚拟串口COM4usbPort.Open();usbPort.DataReceived += new SerialDataReceivedEventHandler(USBDataReceivedHandler);Console.WriteLine("USB 连接已打开...");Console.ReadLine(); // 保持程序运行usbPort.Close();}private static void USBDataReceivedHandler(object sender, SerialDataReceivedEventArgs e){SerialPort sp = (SerialPort)sender;string inData = sp.ReadExisting();Console.WriteLine($"通过USB接收到的数据: {inData}");}
}

3. 通过I²C通信(使用FTDI USB-I²C适配器)

STM32 端代码(配置为I²C主机):
#include "stm32f1xx_hal.h"I2C_HandleTypeDef hi2c1;void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_I2C1_Init();uint8_t data[] = {0x01, 0x02, 0x03}; // 要发送的I2C数据HAL_I2C_Master_Transmit(&hi2c1, 0x68 << 1, data, sizeof(data), HAL_MAX_DELAY); // 发送数据到I2C从设备地址0x68while (1) {}
}static void MX_I2C1_Init(void)
{hi2c1.Instance = I2C1;hi2c1.Init.ClockSpeed = 100000;hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;hi2c1.Init.OwnAddress1 = 0;hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;HAL_I2C_Init(&hi2c1);
}static void SystemClock_Config(void)
{// 时钟配置代码
}static void MX_GPIO_Init(void)
{// GPIO初始化代码
}
C# 端代码(使用USB-I²C适配器读取STM32发送的数据):

C# 端需要使用FTDI提供的库,例如 D2XX 驱动库。

// 假设使用 FTDI I2C 适配器,调用 FTDI 的 D2XX 库

4. 通过以太网进行TCP通信

STM32 端代码(配置为TCP服务器):
  1. 使用 STM32CubeMX 生成 LWIP 网络栈,配置以太网和 TCP 服务器。
  2. 在主程序中实现TCP通信。
#include "lwip/opt.h"
#include "lwip/tcp.h"
#include "lwip.h"
#include <string.h>void tcp_server_init(void);err_t recv_callback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{if (p != NULL){tcp_recved(tpcb, p->tot_len);tcp_write(tpcb, "Hello from STM32 TCP Server!", strlen("Hello from STM32 TCP Server!"), 1);pbuf_free(p);}return ERR_OK;
}void tcp_server_init(void)
{struct tcp_pcb *pcb;pcb = tcp_new();tcp_bind(pcb, IP_ADDR_ANY, 80); // 绑定到端口80pcb = tcp_listen(pcb);tcp_accept(pcb, recv_callback);
}int main(void)
{HAL_Init();SystemClock_Config();MX_LWIP_Init(); // 初始化以太网栈tcp_server_init(); // 启动TCP服务器while (1){MX_LWIP_Process(); // 处理以太网数据}
}
C# 端代码(作为TCP客户端连接到STM32):
using System;
using System.Net.Sockets;
using System.Text;class Program
{static void Main(){TcpClient client = new TcpClient("192.168.0.10", 80); // STM32的IP地址和端口NetworkStream stream = client.GetStream();byte[] data = Encoding.ASCII.GetBytes("Hello STM32 via Ethernet");stream.Write(data, 0, data.Length);byte[] response = new byte[256];int bytes = stream.Read(response, 0, response.Length);Console.WriteLine($"收到的回复: {Encoding.ASCII.GetString(response, 0, bytes)}");stream.Close();client.Close();}
}

当然,下面是关于通过CAN总线通信(使用USB-CAN适配器)的完整示例,包括STM32端和C#端的代码。

5. 通过CAN总线通信(使用USB-CAN适配器)

STM32 端代码(配置为CAN节点):
#include "stm32f1xx_hal.h"CAN_HandleTypeDef hcan1;void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN1_Init(void);int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_CAN1_Init();CAN_TxHeaderTypeDef TxHeader;uint32_t TxMailbox;uint8_t TxData[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};TxHeader.StdId = 0x321;  // 标准IDTxHeader.ExtId = 0x01;   // 扩展ID(如果需要)TxHeader.RTR = CAN_RTR_DATA;  // 数据帧TxHeader.IDE = CAN_ID_STD;     // 标准IDTxHeader.DLC = 8;               // 数据长度while (1){HAL_CAN_AddTxMessage(&hcan1, &TxHeader, TxData, &TxMailbox); // 发送CAN数据HAL_Delay(1000); // 每秒发送一次}
}static void MX_CAN1_Init(void)
{hcan1.Instance = CAN1;hcan1.Init.Prescaler = 16; // 设置分频器hcan1.Init.Mode = CAN_MODE_NORMAL; // 正常模式hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ; // 同步跳宽hcan1.Init.TimeSeg1 = CAN_BS1_8TQ; // 时间段1hcan1.Init.TimeSeg2 = CAN_BS2_3TQ; // 时间段2hcan1.Init.AutoBusOff = DISABLE; // 自动总线关闭hcan1.Init.AutoWakeUp = DISABLE; // 自动唤醒hcan1.Init.ReceiveFifoLocked = DISABLE; // 接收FIFO锁定hcan1.Init.TransmitFifoPriority = DISABLE; // 发送FIFO优先级HAL_CAN_Init(&hcan1);
}static void SystemClock_Config(void)
{// 时钟配置代码
}static void MX_GPIO_Init(void)
{// GPIO初始化代码
}

C# 端代码(通过USB-CAN适配器读取CAN数据):

using System;
using System.IO.Ports;class Program
{static void Main(){// 假设使用特定厂商的CAN库与USB-CAN适配器通信SerialPort canPort = new SerialPort("COM5", 115200); // 根据实际连接的COM端口canPort.Open();while (true){string message = canPort.ReadLine(); // 假设CAN数据以行分隔Console.WriteLine($"接收到的CAN数据: {message}");}canPort.Close();}
}

总结

  1. STM32代码

    • STM32配置为CAN节点,周期性地发送数据帧。
    • 使用HAL_CAN_AddTxMessage函数发送CAN数据。
  2. C#代码

    • C#端通过USB-CAN适配器接收CAN数据,假设使用SerialPort进行串口通信。
    • 可以根据实际需要将COM5替换为相应的串口号。

注意事项:

  • 确保STM32的CAN总线连接正确,并且终端电阻已正确配置。
  • C#端可能需要特定的CAN库,具体取决于所使用的USB-CAN适配器。
  • 根据实际应用,可能需要对发送的数据格式进行调整。

好的,以下是更多关于STM32外设与C#的实战示例,继续展示不同的外设连接和通信方式:

6. 通过SPI通信

STM32 端代码(配置为SPI主机):
#include "stm32f1xx_hal.h"SPI_HandleTypeDef hspi1;void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_SPI1_Init();uint8_t dataToSend[3] = {0xAA, 0xBB, 0xCC}; // 要发送的数据uint8_t receivedData[3];while (1){HAL_SPI_TransmitReceive(&hspi1, dataToSend, receivedData, sizeof(dataToSend), HAL_MAX_DELAY);HAL_Delay(1000); // 每秒发送一次}
}static void MX_SPI1_Init(void)
{hspi1.Instance = SPI1;hspi1.Init.Mode = SPI_MODE_MASTER;hspi1.Init.Direction = SPI_DIRECTION_2LINES;hspi1.Init.DataSize = SPI_DATASIZE_8BIT;hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;hspi1.Init.NSS = SPI_NSS_SOFT;hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;hspi1.Init.TIMode = SPI_TIMODE_DISABLE;HAL_SPI_Init(&hspi1);
}static void SystemClock_Config(void)
{// 时钟配置代码
}static void MX_GPIO_Init(void)
{// GPIO初始化代码
}
C# 端代码(使用SPI与STM32通信):
using System;
using System.Device.Spi;
using System.Device.Spi.Drivers;class Program
{static void Main(){// 假设使用 SPI 设备, SPI 0 为主设备using (SpiDevice spiDevice = new SpiDevice(new SpiConnectionSettings(0, 0))){byte[] dataToSend = { 0xAA, 0xBB, 0xCC }; // 要发送的数据byte[] receivedData = new byte[dataToSend.Length];while (true){spiDevice.Write(dataToSend); // 发送数据spiDevice.Read(receivedData); // 读取返回的数据Console.WriteLine($"接收到的数据: {BitConverter.ToString(receivedData)}");System.Threading.Thread.Sleep(1000); // 每秒发送一次}}}
}

7. 通过PWM控制LED

STM32 端代码(配置为PWM输出):
#include "stm32f1xx_hal.h"TIM_HandleTypeDef htim2;void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_TIM2_Init();HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); // 启动PWMwhile (1){for (uint32_t pulse = 0; pulse < 1000; pulse += 10){__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pulse); // 设置PWM占空比HAL_Delay(100); // 延时}}
}static void MX_TIM2_Init(void)
{TIM_OC_InitTypeDef sConfigOC = {0};htim2.Instance = TIM2;htim2.Init.Prescaler = 72 - 1; // 设置时钟htim2.Init.CounterMode = TIM_COUNTERMODE_UP;htim2.Init.Period = 1000 - 1; // 设置PWM周期htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;HAL_TIM_PWM_Init(&htim2);sConfigOC.OCMode = TIM_OCMODE_PWM1;sConfigOC.Pulse = 0; // 初始占空比sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
}static void SystemClock_Config(void)
{// 时钟配置代码
}static void MX_GPIO_Init(void)
{// GPIO初始化代码
}
C# 端代码(控制PWM的占空比):
using System;
using System.IO.Ports;class Program
{static void Main(){SerialPort port = new SerialPort("COM3", 9600);port.Open();while (true){for (int pulse = 0; pulse <= 1000; pulse += 10){port.WriteLine(pulse.ToString()); // 发送PWM占空比System.Threading.Thread.Sleep(100); // 延时}}port.Close();}
}

8. 通过ADC读取模拟传感器数据

STM32 端代码(配置为ADC读取):
#include "stm32f1xx_hal.h"ADC_HandleTypeDef hadc1;void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_ADC1_Init();uint32_t adcValue;while (1){HAL_ADC_Start(&hadc1);HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);adcValue = HAL_ADC_GetValue(&hadc1); // 读取ADC值HAL_ADC_Stop(&hadc1);HAL_Delay(1000); // 每秒读取一次}
}static void MX_ADC1_Init(void)
{hadc1.Instance = ADC1;hadc1.Init.Resolution = ADC_RESOLUTION_12B;hadc1.Init.ScanConvMode = DISABLE;hadc1.Init.ContinuousConvMode = ENABLE;hadc1.Init.DiscontinuousConvMode = DISABLE;hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;HAL_ADC_Init(&hadc1);
}static void SystemClock_Config(void)
{// 时钟配置代码
}static void MX_GPIO_Init(void)
{// GPIO初始化代码
}
C# 端代码(读取ADC数据并处理):
using System;
using System.IO.Ports;class Program
{static void Main(){SerialPort port = new SerialPort("COM3", 9600);port.Open();while (true){string adcValue = port.ReadLine(); // 读取ADC值Console.WriteLine($"ADC值: {adcValue}");}port.Close();}
}

9. 通过RTC获取实时时钟

STM32 端代码(配置RTC):
#include "stm32f1xx_hal.h"RTC_HandleTypeDef hrtc;void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_RTC_Init(void);int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_RTC_Init();RTC_TimeTypeDef sTime;RTC_DateTypeDef sDate;while (1){HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);HAL_Delay(1000); // 每秒获取一次时间}
}static void MX_RTC_Init(void)
{hrtc.Instance = RTC;hrtc.Init.HourFormat = RTC_HOURFORMAT_24;hrtc.Init.AsynchPrediv = 127;hrtc.Init.SynchPrediv = 255;HAL_RTC_Init(&hrtc);
}static void SystemClock_Config(void)
{// 时钟配置代码
}static void MX_GPIO_Init(void)
{// GPIO初始化代码
}
C# 端代码(获取RTC数据):
using System;
using System.IO.Ports;class Program
{static void Main(){SerialPort port = new SerialPort("COM3", 9600);port.Open();while (true){string timeData = port.ReadLine(); // 读取RTC数据Console.WriteLine($"当前时间: {timeData}");}port.Close();}
}

10. 通过SD卡进行文件读写

STM32 端代码(使用FATFS读写SD卡):
#include "ff.h" // FATFS头文件
#include "stm32f1xx_hal.h"FATFS FatFs;   // FatFs工作区
FIL fil;       // 文件对象
char buffer[100];void SystemClock_Config(void);
static void MX_GPIO_Init(void);int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();f_mount(&FatFs, "", 1); //挂载文件系统f_open(&fil, "test.txt", FA_WRITE | FA_CREATE_ALWAYS); // 打开文件f_write(&fil, "Hello, STM32!", sizeof("Hello, STM32!"), NULL); // 写入数据f_close(&fil); // 关闭文件while (1);
}static void SystemClock_Config(void)
{// 时钟配置代码
}static void MX_GPIO_Init(void)
{// GPIO初始化代码
}
C# 端代码(读取SD卡文件):
using System;
using System.IO;class Program
{static void Main(){string path = @"\\path_to_sd_card\\test.txt"; // SD卡路径while (true){if (File.Exists(path)){string content = File.ReadAllText(path); // 读取文件内容Console.WriteLine($"文件内容: {content}");}System.Threading.Thread.Sleep(1000); // 每秒检查一次}}
}

总结

这些示例展示了如何使用STM32微控制器的多种外设进行实际应用,同时与C#进行数据通信。可以根据实际需求,选择合适的外设和通信方式进行开发。作为一版笔记记录下来!

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

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

相关文章

手撕布隆过滤器:原理解析与面试心得

前言 说来话长&#xff0c;话来说长。前些天我投了一些日常实习的简历&#xff0c;结果足足等了两个礼拜才收到面试通知&#xff0c;看来如今的行情确实是挺紧张的。当时我是满怀信心去的&#xff0c;心想这次一定要好好拷打面试官一番&#xff0c;结果没想到&#xff0c;自我…

QT程序报错解决方案:Cannot queue arguments of type ‘QTextCharFormat‘ 或 ‘QTextCursor‘

项目场景&#xff1a; 项目场景&#xff1a;基于QT实现的C某程序&#xff0c;搭载在Linux环境中。 问题描述 执行程序时&#xff0c;发现log中报错如下内容&#xff1a; QObject::connect: Cannot queue arguments of type QTextCharFormat (Make sure QTextCharFormat is r…

Cesium for UE-04-一些说明

目前主要做webgis的工作&#xff0c;UE官方对web的支持截止到了4.23版本&#xff0c;即使是4.23版本之后的4.xx版本也有办法支持&#xff0c;已经有大佬开源了一些方法和工具&#xff0c;不再介绍。即使是4.23想要输出为h5&#xff0c;也是有一定的折腾门槛的。最重要的是【Ces…

腰背肌筋膜炎有哪些治疗方法

腰背肌筋膜炎主要表现为腰背部的疼痛、酸胀、僵硬、活动受限等症状。在疾病初期&#xff0c;症状可能相对较轻&#xff0c;通过休息、保暖、适当的物理治疗等&#xff0c;往往可以缓解症状&#xff0c;此时病情不算严重。如果患者不重视&#xff0c;继续保持不良的生活习惯&…

微服务架构 --- 使用RabbitMQ进行异步处理

目录 一.什么是RabbitMQ&#xff1f; 二.异步调用处理逻辑&#xff1a; 三.RabbitMQ的基本使用&#xff1a; 1.安装&#xff1a; 2.架构图&#xff1a; 3.RabbitMQ控制台的使用&#xff1a; &#xff08;1&#xff09;Exchanges 交换机&#xff1a; &#xff08;2&#…

MES系列-报表和分析

MES系列-报表和分析 MES系列文章目录 ISA-95制造业中企业和控制系统的集成的国际标准-(1) ISA-95制造业中企业和控制系统的集成的国际标准-(2) ISA-95制造业中企业和控制系统的集成的国际标准-(3) ISA-95制造业中企业和控制系统的集成的国际标准-(4) ISA-95制造业中企业和控制…

1.1_Metasploit (MSF) 工具使用

MetaSploit 漏洞利用框架 模块功能 模块功能Auxiliary信息收集&#xff0c;漏洞扫描等辅助功能Payloads漏洞验证代码Exploits包含漏洞利用脚本Encoders绕过检测和过滤Evasion绕过杀软PostExploits 执行成功&#xff0c;向目标主机发送的一些功能指令Nops溢出攻击 目录说明 目录…

Fuse.js 的原理:背后的算法与机制

前言 了解 Fuse.js 的原理&#xff0c;有助于我们更好地理解它的强大之处以及它是如何实现高效模糊搜索的。Fuse.js 的核心原理主要涉及两个方面&#xff1a;模糊搜索算法和数据结构处理。 模糊搜索算法 Fuse.js 使用了一种基于 Bitap 算法&#xff08;也叫做 Shift-Or、Shi…

【Flutter】Dart:运算符

在 Dart 中&#xff0c;运算符是非常重要的组成部分&#xff0c;它们可以对变量和常量进行多种运算操作。理解和掌握 Dart 中的各种运算符不仅可以帮助你编写更加高效、简洁的代码&#xff0c;还能更好地理解其背后的逻辑和设计。本文将深入探讨 Dart 中的运算符&#xff0c;包…

什么是不同类型的微服务测试?

大家好&#xff0c;我是锋哥。今天分享关于【什么是不同类型的微服务测试&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; 什么是不同类型的微服务测试&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 微服务架构中的测试可以分为多种类…

WPF基础权限系统

一.开发环境 VisualStudio 2022NET SDK 8.0Prism 版本 8.1.97Sqlite 二. 功能介绍 WPF 基础权限系统&#xff0c;是一个支持前后端分离设计的 客户端(C/S)项目&#xff0c;该示例项目前端xaml使用UI库 &#xff0c;Material Design Themes UI 来构建用户界面&#xff0c;确保…

【into outfile写文件】

简介 select * from user into outfile C:/Users/ichunqiu/Desktop/PhpStudy2018/PHPTutorial/WWW/1.txt;用法的意思就是把user表中查询到的所有字段都导出到1.txt文件中 我们之前还有学到dumpfile&#xff0c;单是它只能导出一条数据 写入shell 测试注入点 usernameadmin&…

【工具】使用perf抓取火焰图

背景 当程序存在cpu性能问题时&#xff0c;我们需要找到是哪个函数占用较多的CPU&#xff0c;也就是找出热点函数&#xff1b;perf的火焰图就是这个用途 安装 在Linux系统中&#xff0c;perf 是 Linux 内核提供的性能分析工具&#xff0c;它通常包含在内核源代码包中。大多数…

编码方式知识整理【ASCII、Unicode和UTF-8】

编码方式 一、ASCII编码二、Unicode 编码三、UTF-8编码四、GB2312编码五、GBK编码 计算机中对数据的存储为二进制形式&#xff0c;但采用什么样的编码方式存储&#xff0c;效率更高。主要编码方式有 ASCII、Unicode、UTF-8等。 英文一般为1个字节&#xff0c;汉字一般为3个字节…

Linux 线程互斥

1.相关背景概念 临界资源&#xff1a;多线程执行流共享的资源就叫做临界资源 临界区&#xff1a;每个线程内部&#xff0c;访问临界资源的代码&#xff0c;就叫做临界区 #include <iostream> #include <pthread.h> #include <string> #include <vector…

mac安装jdk8

这里写自定义目录标题 一、下载JDK8二、安装JDK8三、配置环境变量3.1 找到JDK安装目录3.2 打开终端&#xff1a;3.3 输入如下配置&#xff1a;3.3 查看配置是否成功&#xff1a; 一、下载JDK8 oracle官网下载或从下面链接获取 https://download.csdn.net/download/qq_44107684…

【小沐学Golang】基于Go语言搭建静态文件服务器

文章目录 1、简介2、安装2.1 安装版2.2 压缩版 3、基本操作3.1 go run3.2 go build3.3 go install3.4 go env3.5 go module 4、文件服务器4.1 filebrowser4.2 gohttpserver4.3 goFile 5、FAQ5.1 go.mod 为空5.2 超时 结语 1、简介 https://golang.google.cn/ Go语言诞生于2007…

练习题 - Scrapy爬虫框架 Spider Middleware 爬虫页中间件

在 web 爬虫开发中,Scrapy 是一个非常强大且灵活的框架,它可以帮助开发者轻松地从网页中提取数据。Scrapy 的下载器中间件(Downloader Middleware)是 Scrapy 处理下载请求和响应的一个重要组件。通过使用和编写下载器中间件,开发者可以自定义请求的处理过程,增加请求头信…

day02 -- docker

1.docker的介绍 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go语言 并遵从 Apache2.0 协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使…

●day 35 动态规划part01

第九章 动态规划part01 动态规划的类别 理论基础 动态规划下五步曲&#xff1a; 1、确定dp数组&#xff08;dp table&#xff09;以及下标的含义 2、确定递推公式 3、dp数组如何初始化 4、确定遍历顺序 5、打印dp数组 代码随想录 斐波那契数 代码随想录 动态规划5部曲 cla…