当前位置: 首页 > news >正文

三个串口同时打开并指定数据包控制指令思想

可以对嵌入式串口数据包指令设置做一次总结:

首先确定你的数据包大小,传统的接收串口数据到数组存储会出现需要循环遍历数组去读取数据的弊端,所以我设计了一个机制,只有当你想要读取外界指令时,才开始读取外界发过来的指令,并付出一些等待

底层:

下面这个函数的执行时首先要判断一次是否有接受一个字节才能用

不然就要改程序加上提取一次标志位

在底层接收函数基础上添加指定你的指令集是多大的,这样可以提取到你想要的连续指令数据包且·要添加timeout防止超时,你还可以改动这个等待,在第一个数据不是数据头的情况下直接跳过可以更加节省时间

uint8_t* Serial_GetRxDatas(int number)
{
//	for(int timeout_prevent = 0; timeout_prevent<1000 ; timeout_prevent++)int timeout_prevent = 0;Serial_RxDatas[0]=Serial_GetRxData();for( kk=1;kk<number;kk++){while(Serial_GetRxFlag()==0){timeout_prevent++;if(timeout_prevent == 1000){timeout_prevent = 0;break;}}Serial_RxDatas[kk]=Serial_GetRxData();}return Serial_RxDatas;
}

升级版

uint8_t* Serial_GetRxDatas(int number,char message_head)
{
//	for(int timeout_prevent = 0; timeout_prevent<1000 ; timeout_prevent++)int timeout_prevent = 0;Serial_RxDatas[0]=Serial_GetRxData();if(Serial_RxDatas[0] != message_head){return 0;}for( kk=1;kk<number;kk++){while(Serial_GetRxFlag()==0){timeout_prevent++;if(timeout_prevent == 1000){timeout_prevent = 0;break;}}Serial_RxDatas[kk]=Serial_GetRxData();}return Serial_RxDatas;
}

应用层:

因为我的代码量不是很多,所以我直接用while循环检查,避免了延时等待指令的操作,如果代码量不支持你试试去读取你的指令,比如你没rtos的情况下进行多线程循环读取是不可能的,所以见后面的解决方法,加等待指令方法

if(Serial_GetRxFlag() == 1)			//检查串口接收数据的标志位{RxDatas = Serial_GetRxDatas(3);		//获取串口接收的数据if(RxDatas[0] == 0x06 && RxDatas[1] == 0x01 && RxDatas[2] == 0x66)//完成{	Run_forward();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x02 && RxDatas[2] == 0x66)//完成{	Run_back();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x03 && RxDatas[2] == 0x66)//完成{	Run_left();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x04 && RxDatas[2] == 0x66)//完成{	Run_right();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x05 && RxDatas[2] == 0x66)//完成{	Run_up();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x06 && RxDatas[2] == 0x66)//完成{	Run_down();}}if(Serial3_GetRxFlag() == 1)			//检查串口接收数据的标志位{RxDatas = Serial3_GetRxDatas(3);		//获取串口接收的数据if(RxDatas[0] == 0x06 && RxDatas[1] == 0x01 && RxDatas[2] == 0x66)//完成{	Run_forward();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x02 && RxDatas[2] == 0x66)//完成{	Run_back();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x03 && RxDatas[2] == 0x66)//完成{	Run_left();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x04 && RxDatas[2] == 0x66)//完成{	Run_right();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x05 && RxDatas[2] == 0x66)//完成{	Run_up();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x06 && RxDatas[2] == 0x66)//完成{	Run_down();}}

若不能用while循环检测指令,则需要添加等待但又要添加timeout防止超时卡死,等一等你的指令先减小你因为偶然因素接受不到信息的可能

char dec = 1;
int timeout = 0;
while(dec)
{
timeout++;
if(timeout == 1000)
{timeout = 0;break;}
if(Serial_GetRxFlag() == 1)			//检查串口接收数据的标志位{dec = 0;RxDatas = Serial_GetRxDatas(3);		//获取串口接收的数据if(RxDatas[0] == 0x06 && RxDatas[1] == 0x01 && RxDatas[2] == 0x66)//完成{	Run_forward();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x02 && RxDatas[2] == 0x66)//完成{	Run_back();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x03 && RxDatas[2] == 0x66)//完成{	Run_left();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x04 && RxDatas[2] == 0x66)//完成{	Run_right();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x05 && RxDatas[2] == 0x66)//完成{	Run_up();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x06 && RxDatas[2] == 0x66)//完成{	Run_down();}}if(Serial3_GetRxFlag() == 1)			//检查串口接收数据的标志位{dec = 0;RxDatas = Serial3_GetRxDatas(3);		//获取串口接收的数据if(RxDatas[0] == 0x06 && RxDatas[1] == 0x01 && RxDatas[2] == 0x66)//完成{	Run_forward();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x02 && RxDatas[2] == 0x66)//完成{	Run_back();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x03 && RxDatas[2] == 0x66)//完成{	Run_left();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x04 && RxDatas[2] == 0x66)//完成{	Run_right();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x05 && RxDatas[2] == 0x66)//完成{	Run_up();}if(RxDatas[0] == 0x06 && RxDatas[1] == 0x06 && RxDatas[2] == 0x66)//完成{	Run_down();}}
}


 

完整工程:

serial3.c

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>
#include <Serial.h>
uint8_t Serial3_RxDatas[3]={0};
uint8_t Serial3_RxData;		//¶¨Òå´®¿Ú½ÓÊÕµÄÊý¾Ý±äÁ¿
uint8_t Serial3_RxFlag;		//¶¨Òå´®¿Ú½ÓÊյıê־λ±äÁ¿/*** º¯    Êý£º´®¿Ú³õʼ»¯* ²Î    Êý£ºÎÞ* ·µ »Ø Öµ£ºÎÞ*/
void Serial3_Init(void)
{/*¿ªÆôʱÖÓ*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);	//¿ªÆôUSART1µÄʱÖÓRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	//¿ªÆôGPIODµÄʱÖÓ/*GPIO³õʼ»¯*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);					//½«PA9Òý½Å³õʼ»¯Îª¸´ÓÃÍÆÍìÊä³öGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);					//½«PA10Òý½Å³õʼ»¯ÎªÉÏÀ­ÊäÈë/*USART³õʼ»¯*/USART_InitTypeDef USART_InitStructure;					//¶¨Òå½á¹¹Ìå±äÁ¿USART_InitStructure.USART_BaudRate = 9600;				//²¨ÌØÂÊUSART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//Ó²¼þÁ÷¿ØÖÆ£¬²»ÐèÒªUSART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;	//ģʽ£¬·¢ËÍģʽºÍ½ÓÊÕģʽ¾ùÑ¡ÔñUSART_InitStructure.USART_Parity = USART_Parity_No;		//ÆæÅ¼Ð£Ñ飬²»ÐèÒªUSART_InitStructure.USART_StopBits = USART_StopBits_1;	//ֹͣλ£¬Ñ¡Ôñ1λUSART_InitStructure.USART_WordLength = USART_WordLength_8b;		//×Ö³¤£¬Ñ¡Ôñ8λUSART_Init(USART3, &USART_InitStructure);				//½«½á¹¹Ìå±äÁ¿½»¸øUSART_Init£¬ÅäÖÃUSART1/*ÖжÏÊä³öÅäÖÃ*/USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);			//¿ªÆô´®¿Ú½ÓÊÕÊý¾ÝµÄÖжÏ/*NVICÖжϷÖ×é*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);			//ÅäÖÃNVICΪ·Ö×é2/*NVICÅäÖÃ*/NVIC_InitTypeDef NVIC_InitStructure;					//¶¨Òå½á¹¹Ìå±äÁ¿NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;		//Ñ¡ÔñÅäÖÃNVICµÄUSART1ÏßNVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//Ö¸¶¨NVICÏß·ʹÄÜNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;		//Ö¸¶¨NVICÏß·µÄÇÀÕ¼ÓÅÏȼ¶Îª1NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		//Ö¸¶¨NVICÏß·µÄÏìÓ¦ÓÅÏȼ¶Îª1NVIC_Init(&NVIC_InitStructure);							//½«½á¹¹Ìå±äÁ¿½»¸øNVIC_Init£¬ÅäÖÃNVICÍâÉè/*USARTʹÄÜ*/USART_Cmd(USART3, ENABLE);								//ʹÄÜUSART1£¬´®¿Ú¿ªÊ¼ÔËÐÐ
}/*** º¯    Êý£º´®¿Ú·¢ËÍÒ»¸ö×Ö½Ú* ²Î    Êý£ºByte Òª·¢Ë͵ÄÒ»¸ö×Ö½Ú* ·µ »Ø Öµ£ºÎÞ*/
void Serial3_SendByte(uint8_t Byte)
{USART_SendData(USART3, Byte);		//½«×Ö½ÚÊý¾ÝдÈëÊý¾Ý¼Ä´æÆ÷£¬Ð´ÈëºóUSART×Ô¶¯Éú³ÉʱÐò²¨ÐÎwhile (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);	//µÈ´ý·¢ËÍÍê³É/*Ï´ÎдÈëÊý¾Ý¼Ä´æÆ÷»á×Ô¶¯Çå³ý·¢ËÍÍê³É±ê־룬¹Ê´ËÑ­»·ºó£¬ÎÞÐèÇå³ý±ê־λ*/
}/*** º¯    Êý£º´®¿Ú·¢ËÍÒ»¸öÊý×é* ²Î    Êý£ºArray Òª·¢ËÍÊý×éµÄÊ×µØÖ·* ²Î    Êý£ºLength Òª·¢ËÍÊý×éµÄ³¤¶È* ·µ »Ø Öµ£ºÎÞ*/
void Serial3_SendArray(uint8_t *Array, uint16_t Length)
{uint16_t i;for (i = 0; i < Length; i ++)		//±éÀúÊý×é{Serial3_SendByte(Array[i]);		//ÒÀ´Îµ÷ÓÃSerial_SendByte·¢ËÍÿ¸ö×Ö½ÚÊý¾Ý}
}/*** º¯    Êý£º´®¿Ú·¢ËÍÒ»¸ö×Ö·û´®* ²Î    Êý£ºString Òª·¢ËÍ×Ö·û´®µÄÊ×µØÖ·* ·µ »Ø Öµ£ºÎÞ*/
void Serial3_SendString(char *String)
{uint8_t i;for (i = 0; String[i] != '\0'; i ++)//±éÀú×Ö·ûÊý×飨×Ö·û´®£©£¬Óöµ½×Ö·û´®½áÊø±ê־λºóÍ£Ö¹{Serial3_SendByte(String[i]);		//ÒÀ´Îµ÷ÓÃSerial_SendByte·¢ËÍÿ¸ö×Ö½ÚÊý¾Ý}
}/*** º¯    Êý£º´Î·½º¯Êý£¨ÄÚ²¿Ê¹Óã©* ·µ »Ø Öµ£º·µ»ØÖµµÈÓÚXµÄY´Î·½*/
uint32_t Serial3_Pow(uint32_t X, uint32_t Y)
{uint32_t Result = 1;	//ÉèÖýá¹û³õֵΪ1while (Y --)			//Ö´ÐÐY´Î{Result *= X;		//½«XÀ۳˵½½á¹û}return Result;
}/*** º¯    Êý£º´®¿Ú·¢ËÍÊý×Ö* ²Î    Êý£ºNumber Òª·¢Ë͵ÄÊý×Ö£¬·¶Î§£º0~4294967295* ²Î    Êý£ºLength Òª·¢ËÍÊý×ֵij¤¶È£¬·¶Î§£º0~10* ·µ »Ø Öµ£ºÎÞ*/
void Serial3_SendNumber(uint32_t Number, uint8_t Length)
{uint8_t i;for (i = 0; i < Length; i ++)		//¸ù¾ÝÊý×Ö³¤¶È±éÀúÊý×ÖµÄÿһλ{Serial3_SendByte(Number / Serial3_Pow(10, Length - i - 1) % 10 + '0');	//ÒÀ´Îµ÷ÓÃSerial_SendByte·¢ËÍÿλÊý×Ö}
}/*** º¯    Êý£ºÊ¹ÓÃprintfÐèÒªÖØ¶¨ÏòµÄµ×²ãº¯Êý* ²Î    Êý£º±£³Öԭʼ¸ñʽ¼´¿É£¬ÎÞÐè±ä¶¯* ·µ »Ø Öµ£º±£³Öԭʼ¸ñʽ¼´¿É£¬ÎÞÐè±ä¶¯*/
//int fputc(int ch, FILE *f)
//{
//	Serial_SendByte(ch);			//½«printfµÄµ×²ãÖØ¶¨Ïòµ½×Ô¼ºµÄ·¢ËÍ×Ö½Úº¯Êý
//	return ch;
//}/*** º¯    Êý£º×Ô¼º·â×°µÄprinfº¯Êý* ²Î    Êý£ºformat ¸ñʽ»¯×Ö·û´®* ²Î    Êý£º... ¿É±äµÄ²ÎÊýÁбí* ·µ »Ø Öµ£ºÎÞ*/
void Serial3_Printf(char *format, ...)
{char String[100];				//¶¨Òå×Ö·ûÊý×éva_list arg;					//¶¨Òå¿É±ä²ÎÊýÁбíÊý¾ÝÀàÐ͵ıäÁ¿argva_start(arg, format);			//´Óformat¿ªÊ¼£¬½ÓÊÕ²ÎÊýÁÐ±íµ½arg±äÁ¿vsprintf(String, format, arg);	//ʹÓÃvsprintf´òÓ¡¸ñʽ»¯×Ö·û´®ºÍ²ÎÊýÁÐ±íµ½×Ö·ûÊý×éÖÐva_end(arg);					//½áÊø±äÁ¿argSerial3_SendString(String);		//´®¿Ú·¢ËÍ×Ö·ûÊý×飨×Ö·û´®£©
}/*** º¯    Êý£º»ñÈ¡´®¿Ú½ÓÊÕ±ê־λ* ²Î    Êý£ºÎÞ* ·µ »Ø Öµ£º´®¿Ú½ÓÊÕ±ê־룬·¶Î§£º0~1£¬½ÓÊÕµ½Êý¾Ýºó£¬±ê־λÖÃ1£¬¶ÁÈ¡ºó±ê־λ×Ô¶¯ÇåÁã*/
uint8_t Serial3_GetRxFlag(void)
{if (Serial3_RxFlag == 1)			//Èç¹û±ê־λΪ1{Serial3_RxFlag = 0;return 1;					//Ôò·µ»Ø1£¬²¢×Ô¶¯ÇåÁã±ê־λ}return 0;						//Èç¹û±ê־λΪ0£¬Ôò·µ»Ø0
}/*** º¯    Êý£º»ñÈ¡´®¿Ú½ÓÊÕµÄÊý¾Ý* ²Î    Êý£ºÎÞ* ·µ »Ø Öµ£º½ÓÊÕµÄÊý¾Ý£¬·¶Î§£º0~255*/
uint8_t Serial3_GetRxData(void)
{return Serial3_RxData;			//·µ»Ø½ÓÊÕµÄÊý¾Ý±äÁ¿
}
uint8_t* Serial3_GetRxDatas(int number)
{
int timeout_prevent = 0;Serial3_RxDatas[0]=Serial3_GetRxData();for(int kk=1;kk<number;kk++){while(Serial3_GetRxFlag()==0){timeout_prevent++;if(timeout_prevent == 1000){timeout_prevent = 0;break;}}Serial3_RxDatas[kk]=Serial3_GetRxData();}return Serial3_RxDatas;
}/*** º¯    Êý£ºUSART1ÖжϺ¯Êý* ²Î    Êý£ºÎÞ* ·µ »Ø Öµ£ºÎÞ* ×¢ÒâÊÂÏ´Ëº¯ÊýΪÖжϺ¯Êý£¬ÎÞÐèµ÷Óã¬Öжϴ¥·¢ºó×Ô¶¯Ö´ÐÐ*           º¯ÊýÃûΪԤÁôµÄÖ¸¶¨Ãû³Æ£¬¿ÉÒÔ´ÓÆô¶¯Îļþ¸´ÖÆ*           ÇëÈ·±£º¯ÊýÃûÕýÈ·£¬²»ÄÜÓÐÈκβîÒ죬·ñÔòÖжϺ¯Êý½«²»ÄܽøÈë*/
void USART3_IRQHandler(void)
{if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET)		//ÅжÏÊÇ·ñÊÇUSART1µÄ½ÓÊÕʼþ´¥·¢µÄÖжÏ{Serial3_RxData = USART_ReceiveData(USART3);				//¶ÁÈ¡Êý¾Ý¼Ä´æÆ÷£¬´æ·ÅÔÚ½ÓÊÕµÄÊý¾Ý±äÁ¿Serial3_RxFlag = 1;										//ÖýÓÊÕ±ê־λ±äÁ¿Îª1USART_ClearITPendingBit(USART3, USART_IT_RXNE);			//Çå³ýUSART1µÄRXNE±ê־λ//¶ÁÈ¡Êý¾Ý¼Ä´æÆ÷»á×Ô¶¯Çå³ý´Ë±ê־λ//Èç¹ûÒѾ­¶ÁÈ¡ÁËÊý¾Ý¼Ä´æÆ÷£¬Ò²¿ÉÒÔ²»Ö´Ðд˴úÂë}
}

serial2.c

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>
#include <Serial.h>
uint8_t Serial2_RxDatas[3]={0};
uint8_t patience_name[6]={0};
uint8_t Serial2_RxData;		//¶¨Òå´®¿Ú½ÓÊÕµÄÊý¾Ý±äÁ¿
uint8_t Serial2_RxFlag;		//¶¨Òå´®¿Ú½ÓÊյıê־λ±äÁ¿/*** º¯    Êý£º´®¿Ú³õʼ»¯* ²Î    Êý£ºÎÞ* ·µ »Ø Öµ£ºÎÞ*/
void Serial2_Init(void)
{/*¿ªÆôʱÖÓ*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);	//¿ªÆôUSART1µÄʱÖÓRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//¿ªÆôGPIOAµÄʱÖÓ/*GPIO³õʼ»¯*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);					//½«PA9Òý½Å³õʼ»¯Îª¸´ÓÃÍÆÍìÊä³öGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);					//½«PA10Òý½Å³õʼ»¯ÎªÉÏÀ­ÊäÈë/*USART³õʼ»¯*/USART_InitTypeDef USART_InitStructure;					//¶¨Òå½á¹¹Ìå±äÁ¿USART_InitStructure.USART_BaudRate = 9600;				//²¨ÌØÂÊUSART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//Ó²¼þÁ÷¿ØÖÆ£¬²»ÐèÒªUSART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;	//ģʽ£¬·¢ËÍģʽºÍ½ÓÊÕģʽ¾ùÑ¡ÔñUSART_InitStructure.USART_Parity = USART_Parity_No;		//ÆæÅ¼Ð£Ñ飬²»ÐèÒªUSART_InitStructure.USART_StopBits = USART_StopBits_1;	//ֹͣλ£¬Ñ¡Ôñ1λUSART_InitStructure.USART_WordLength = USART_WordLength_8b;		//×Ö³¤£¬Ñ¡Ôñ8λUSART_Init(USART2, &USART_InitStructure);				//½«½á¹¹Ìå±äÁ¿½»¸øUSART_Init£¬ÅäÖÃUSART1/*ÖжÏÊä³öÅäÖÃ*/USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);			//¿ªÆô´®¿Ú½ÓÊÕÊý¾ÝµÄÖжÏ/*NVICÖжϷÖ×é*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);			//ÅäÖÃNVICΪ·Ö×é2/*NVICÅäÖÃ*/NVIC_InitTypeDef NVIC_InitStructure;					//¶¨Òå½á¹¹Ìå±äÁ¿NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;		//Ñ¡ÔñÅäÖÃNVICµÄUSART1ÏßNVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//Ö¸¶¨NVICÏß·ʹÄÜNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;		//Ö¸¶¨NVICÏß·µÄÇÀÕ¼ÓÅÏȼ¶Îª1NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		//Ö¸¶¨NVICÏß·µÄÏìÓ¦ÓÅÏȼ¶Îª1NVIC_Init(&NVIC_InitStructure);							//½«½á¹¹Ìå±äÁ¿½»¸øNVIC_Init£¬ÅäÖÃNVICÍâÉè/*USARTʹÄÜ*/USART_Cmd(USART2, ENABLE);								//ʹÄÜUSART1£¬´®¿Ú¿ªÊ¼ÔËÐÐ
}/*** º¯    Êý£º´®¿Ú·¢ËÍÒ»¸ö×Ö½Ú* ²Î    Êý£ºByte Òª·¢Ë͵ÄÒ»¸ö×Ö½Ú* ·µ »Ø Öµ£ºÎÞ*/
void Serial2_SendByte(uint8_t Byte)
{USART_SendData(USART2, Byte);		//½«×Ö½ÚÊý¾ÝдÈëÊý¾Ý¼Ä´æÆ÷£¬Ð´ÈëºóUSART×Ô¶¯Éú³ÉʱÐò²¨ÐÎwhile (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);	//µÈ´ý·¢ËÍÍê³É/*Ï´ÎдÈëÊý¾Ý¼Ä´æÆ÷»á×Ô¶¯Çå³ý·¢ËÍÍê³É±ê־룬¹Ê´ËÑ­»·ºó£¬ÎÞÐèÇå³ý±ê־λ*/
}/*** º¯    Êý£º´®¿Ú·¢ËÍÒ»¸öÊý×é* ²Î    Êý£ºArray Òª·¢ËÍÊý×éµÄÊ×µØÖ·* ²Î    Êý£ºLength Òª·¢ËÍÊý×éµÄ³¤¶È* ·µ »Ø Öµ£ºÎÞ*/
void Serial2_SendArray(uint8_t *Array, uint16_t Length)
{uint16_t i;for (i = 0; i < Length; i ++)		//±éÀúÊý×é{Serial2_SendByte(Array[i]);		//ÒÀ´Îµ÷ÓÃSerial_SendByte·¢ËÍÿ¸ö×Ö½ÚÊý¾Ý}
}/*** º¯    Êý£º´®¿Ú·¢ËÍÒ»¸ö×Ö·û´®* ²Î    Êý£ºString Òª·¢ËÍ×Ö·û´®µÄÊ×µØÖ·* ·µ »Ø Öµ£ºÎÞ*/
void Serial2_SendString(char *String)
{uint8_t i;for (i = 0; String[i] != '\0'; i ++)//±éÀú×Ö·ûÊý×飨×Ö·û´®£©£¬Óöµ½×Ö·û´®½áÊø±ê־λºóÍ£Ö¹{Serial2_SendByte(String[i]);		//ÒÀ´Îµ÷ÓÃSerial_SendByte·¢ËÍÿ¸ö×Ö½ÚÊý¾Ý}
}/*** º¯    Êý£º´Î·½º¯Êý£¨ÄÚ²¿Ê¹Óã©* ·µ »Ø Öµ£º·µ»ØÖµµÈÓÚXµÄY´Î·½*/
uint32_t Serial2_Pow(uint32_t X, uint32_t Y)
{uint32_t Result = 1;	//ÉèÖýá¹û³õֵΪ1while (Y --)			//Ö´ÐÐY´Î{Result *= X;		//½«XÀ۳˵½½á¹û}return Result;
}/*** º¯    Êý£º´®¿Ú·¢ËÍÊý×Ö* ²Î    Êý£ºNumber Òª·¢Ë͵ÄÊý×Ö£¬·¶Î§£º0~4294967295* ²Î    Êý£ºLength Òª·¢ËÍÊý×ֵij¤¶È£¬·¶Î§£º0~10* ·µ »Ø Öµ£ºÎÞ*/
void Serial2_SendNumber(uint32_t Number, uint8_t Length)
{uint8_t i;for (i = 0; i < Length; i ++)		//¸ù¾ÝÊý×Ö³¤¶È±éÀúÊý×ÖµÄÿһλ{Serial2_SendByte(Number / Serial2_Pow(10, Length - i - 1) % 10 + '0');	//ÒÀ´Îµ÷ÓÃSerial_SendByte·¢ËÍÿλÊý×Ö}
}/*** º¯    Êý£ºÊ¹ÓÃprintfÐèÒªÖØ¶¨ÏòµÄµ×²ãº¯Êý* ²Î    Êý£º±£³Öԭʼ¸ñʽ¼´¿É£¬ÎÞÐè±ä¶¯* ·µ »Ø Öµ£º±£³Öԭʼ¸ñʽ¼´¿É£¬ÎÞÐè±ä¶¯*/
//int fputc(int ch, FILE *f)
//{
//	Serial_SendByte(ch);			//½«printfµÄµ×²ãÖØ¶¨Ïòµ½×Ô¼ºµÄ·¢ËÍ×Ö½Úº¯Êý
//	return ch;
//}/*** º¯    Êý£º×Ô¼º·â×°µÄprinfº¯Êý* ²Î    Êý£ºformat ¸ñʽ»¯×Ö·û´®* ²Î    Êý£º... ¿É±äµÄ²ÎÊýÁбí* ·µ »Ø Öµ£ºÎÞ*/
void Serial2_Printf(char *format, ...)
{char String[100];				//¶¨Òå×Ö·ûÊý×éva_list arg;					//¶¨Òå¿É±ä²ÎÊýÁбíÊý¾ÝÀàÐ͵ıäÁ¿argva_start(arg, format);			//´Óformat¿ªÊ¼£¬½ÓÊÕ²ÎÊýÁÐ±íµ½arg±äÁ¿vsprintf(String, format, arg);	//ʹÓÃvsprintf´òÓ¡¸ñʽ»¯×Ö·û´®ºÍ²ÎÊýÁÐ±íµ½×Ö·ûÊý×éÖÐva_end(arg);					//½áÊø±äÁ¿argSerial2_SendString(String);		//´®¿Ú·¢ËÍ×Ö·ûÊý×飨×Ö·û´®£©
}/*** º¯    Êý£º»ñÈ¡´®¿Ú½ÓÊÕ±ê־λ* ²Î    Êý£ºÎÞ* ·µ »Ø Öµ£º´®¿Ú½ÓÊÕ±ê־룬·¶Î§£º0~1£¬½ÓÊÕµ½Êý¾Ýºó£¬±ê־λÖÃ1£¬¶ÁÈ¡ºó±ê־λ×Ô¶¯ÇåÁã*/
uint8_t Serial2_GetRxFlag(void)
{if (Serial2_RxFlag == 1)			//Èç¹û±ê־λΪ1{Serial2_RxFlag = 0;return 1;					//Ôò·µ»Ø1£¬²¢×Ô¶¯ÇåÁã±ê־λ}return 0;						//Èç¹û±ê־λΪ0£¬Ôò·µ»Ø0
}uint8_t* Serial2_GetRxDatas(int number)
{
int timeout_prevent = 0;Serial2_RxDatas[0]=Serial2_GetRxData();for(int kk=1;kk<number;kk++){while(Serial2_GetRxFlag()==0){timeout_prevent++;if(timeout_prevent == 1000){timeout_prevent = 0;break;}}Serial2_RxDatas[kk]=Serial2_GetRxData();}return Serial2_RxDatas;
}
uint8_t* Serial2_Getname(int number)
{patience_name[0]=Serial2_GetRxData();for(int kk=1;kk<number;kk++){while(Serial2_GetRxFlag()==0);patience_name[kk]=Serial2_GetRxData();}return patience_name;
}/*** º¯    Êý£º»ñÈ¡´®¿Ú½ÓÊÕµÄÊý¾Ý* ²Î    Êý£ºÎÞ* ·µ »Ø Öµ£º½ÓÊÕµÄÊý¾Ý£¬·¶Î§£º0~255*/
uint8_t Serial2_GetRxData(void)
{return Serial2_RxData;			//·µ»Ø½ÓÊÕµÄÊý¾Ý±äÁ¿
}/*** º¯    Êý£ºUSART1ÖжϺ¯Êý* ²Î    Êý£ºÎÞ* ·µ »Ø Öµ£ºÎÞ* ×¢ÒâÊÂÏ´Ëº¯ÊýΪÖжϺ¯Êý£¬ÎÞÐèµ÷Óã¬Öжϴ¥·¢ºó×Ô¶¯Ö´ÐÐ*           º¯ÊýÃûΪԤÁôµÄÖ¸¶¨Ãû³Æ£¬¿ÉÒÔ´ÓÆô¶¯Îļþ¸´ÖÆ*           ÇëÈ·±£º¯ÊýÃûÕýÈ·£¬²»ÄÜÓÐÈκβîÒ죬·ñÔòÖжϺ¯Êý½«²»ÄܽøÈë*/
void USART2_IRQHandler(void)
{if (USART_GetITStatus(USART2, USART_IT_RXNE) == SET)		//ÅжÏÊÇ·ñÊÇUSART1µÄ½ÓÊÕʼþ´¥·¢µÄÖжÏ{Serial2_RxData = USART_ReceiveData(USART2);				//¶ÁÈ¡Êý¾Ý¼Ä´æÆ÷£¬´æ·ÅÔÚ½ÓÊÕµÄÊý¾Ý±äÁ¿Serial2_RxFlag = 1;										//ÖýÓÊÕ±ê־λ±äÁ¿Îª1USART_ClearITPendingBit(USART2, USART_IT_RXNE);			//Çå³ýUSART1µÄRXNE±ê־λ//¶ÁÈ¡Êý¾Ý¼Ä´æÆ÷»á×Ô¶¯Çå³ý´Ë±ê־λ//Èç¹ûÒѾ­¶ÁÈ¡ÁËÊý¾Ý¼Ä´æÆ÷£¬Ò²¿ÉÒÔ²»Ö´Ðд˴úÂë}
}

serial.c:第一个串口配置

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>uint8_t Serial_RxDatas[3]={0};
uint8_t Serial_RxData;		//定义串口接收的数据变量
uint8_t Serial_RxFlag;		//定义串口接收的标志位变量
int kk=0;
/*** 函    数:串口初始化* 参    数:无* 返 回 值:无*/
void Serial_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);	//开启USART1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA9引脚初始化为复用推挽输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA10引脚初始化为上拉输入/*USART初始化*/USART_InitTypeDef USART_InitStructure;					//定义结构体变量USART_InitStructure.USART_BaudRate = 9600;				//波特率USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//硬件流控制,不需要USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;	//模式,发送模式和接收模式均选择USART_InitStructure.USART_Parity = USART_Parity_No;		//奇偶校验,不需要USART_InitStructure.USART_StopBits = USART_StopBits_1;	//停止位,选择1位USART_InitStructure.USART_WordLength = USART_WordLength_8b;		//字长,选择8位USART_Init(USART1, &USART_InitStructure);				//将结构体变量交给USART_Init,配置USART1/*中断输出配置*/USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);			//开启串口接收数据的中断/*NVIC中断分组*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);			//配置NVIC为分组2/*NVIC配置*/NVIC_InitTypeDef NVIC_InitStructure;					//定义结构体变量NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;		//选择配置NVIC的USART1线NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//指定NVIC线路使能NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;		//指定NVIC线路的抢占优先级为1NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		//指定NVIC线路的响应优先级为1NVIC_Init(&NVIC_InitStructure);							//将结构体变量交给NVIC_Init,配置NVIC外设/*USART使能*/USART_Cmd(USART1, ENABLE);								//使能USART1,串口开始运行
}/*** 函    数:串口发送一个字节* 参    数:Byte 要发送的一个字节* 返 回 值:无*/
void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1, Byte);		//将字节数据写入数据寄存器,写入后USART自动生成时序波形while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);	//等待发送完成/*下次写入数据寄存器会自动清除发送完成标志位,故此循环后,无需清除标志位*/
}/*** 函    数:串口发送一个数组* 参    数:Array 要发送数组的首地址* 参    数:Length 要发送数组的长度* 返 回 值:无*/
void Serial_SendArray(uint8_t *Array, uint16_t Length)
{uint16_t i;for (i = 0; i < Length; i ++)		//遍历数组{Serial_SendByte(Array[i]);		//依次调用Serial_SendByte发送每个字节数据}
}/*** 函    数:串口发送一个字符串* 参    数:String 要发送字符串的首地址* 返 回 值:无*/
void Serial_SendString(char *String)
{uint8_t i;for (i = 0; String[i] != '\0'; i ++)//遍历字符数组(字符串),遇到字符串结束标志位后停止{Serial_SendByte(String[i]);		//依次调用Serial_SendByte发送每个字节数据}
}/*** 函    数:次方函数(内部使用)* 返 回 值:返回值等于X的Y次方*/
uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{uint32_t Result = 1;	//设置结果初值为1while (Y --)			//执行Y次{Result *= X;		//将X累乘到结果}return Result;
}/*** 函    数:串口发送数字* 参    数:Number 要发送的数字,范围:0~4294967295* 参    数:Length 要发送数字的长度,范围:0~10* 返 回 值:无*/
void Serial_SendNumber(uint32_t Number, uint8_t Length)
{uint8_t i;for (i = 0; i < Length; i ++)		//根据数字长度遍历数字的每一位{Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');	//依次调用Serial_SendByte发送每位数字}
}/*** 函    数:使用printf需要重定向的底层函数* 参    数:保持原始格式即可,无需变动* 返 回 值:保持原始格式即可,无需变动*/
int fputc(int ch, FILE *f)
{Serial_SendByte(ch);			//将printf的底层重定向到自己的发送字节函数return ch;
}/*** 函    数:自己封装的prinf函数* 参    数:format 格式化字符串* 参    数:... 可变的参数列表* 返 回 值:无*/
void Serial_Printf(char *format, ...)
{char String[100];				//定义字符数组va_list arg;					//定义可变参数列表数据类型的变量argva_start(arg, format);			//从format开始,接收参数列表到arg变量vsprintf(String, format, arg);	//使用vsprintf打印格式化字符串和参数列表到字符数组中va_end(arg);					//结束变量argSerial_SendString(String);		//串口发送字符数组(字符串)
}/*** 函    数:获取串口接收标志位* 参    数:无* 返 回 值:串口接收标志位,范围:0~1,接收到数据后,标志位置1,读取后标志位自动清零*/
uint8_t Serial_GetRxFlag(void)
{if (Serial_RxFlag == 1)			//如果标志位为1{Serial_RxFlag = 0;return 1;					//则返回1,并自动清零标志位}return 0;						//如果标志位为0,则返回0
}/*** 函    数:获取串口接收的数据* 参    数:无* 返 回 值:接收的数据,范围:0~255*/
uint8_t Serial_GetRxData(void)
{
int timeout_prevent = 0;return Serial_RxData;			//返回接收的数据变量
}uint8_t* Serial_GetRxDatas(int number)
{Serial_RxDatas[0]=Serial_GetRxData();for( kk=1;kk<number;kk++){while(Serial3_GetRxFlag()==0){timeout_prevent++;if(timeout_prevent == 1000){timeout_prevent = 0;break;}}Serial_RxDatas[kk]=Serial_GetRxData();}return Serial_RxDatas;
}/*** 函    数:USART1中断函数* 参    数:无* 返 回 值:无* 注意事项:此函数为中断函数,无需调用,中断触发后自动执行*           函数名为预留的指定名称,可以从启动文件复制*           请确保函数名正确,不能有任何差异,否则中断函数将不能进入*/
void USART1_IRQHandler(void)
{if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)		//判断是否是USART1的接收事件触发的中断{Serial_RxData = USART_ReceiveData(USART1);				//读取数据寄存器,存放在接收的数据变量Serial_RxFlag = 1;										//置接收标志位变量为1USART_ClearITPendingBit(USART1, USART_IT_RXNE);			//清除USART1的RXNE标志位//读取数据寄存器会自动清除此标志位//如果已经读取了数据寄存器,也可以不执行此代码}
}

serial.h:包含了所有串口的驱动函数

#ifndef __SERIAL_H
#define __SERIAL_H#include <stdio.h>void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t *Array, uint16_t Length);
void Serial_SendString(char *String);
void Serial_SendNumber(uint32_t Number, uint8_t Length);
void Serial_Printf(char *format, ...);
uint8_t* Serial_GetRxDatas(int number);
uint8_t Serial_GetRxFlag(void);
uint8_t Serial_GetRxData(void);void Serial2_Init(void);
void Serial2_SendByte(uint8_t Byte);
void Serial2_SendArray(uint8_t *Array, uint16_t Length);
void Serial2_SendString(char *String);
void Serial2_SendNumber(uint32_t Number, uint8_t Length);
void Serial2_Printf(char *format, ...);
uint8_t* Serial2_GetRxDatas(int number);
uint8_t Serial2_GetRxFlag(void);
uint8_t Serial2_GetRxData(void);
uint8_t* Serial2_Getname(int number);void Serial3_Init(void);
void Serial3_SendByte(uint8_t Byte);
void Serial3_SendArray(uint8_t *Array, uint16_t Length);
void Serial3_SendString(char *String);
void Serial3_SendNumber(uint32_t Number, uint8_t Length);
void Serial3_Printf(char *format, ...);
uint8_t* Serial3_GetRxDatas(int number);
uint8_t Serial3_GetRxFlag(void);
uint8_t Serial3_GetRxData(void);
#endif

相关文章:

三个串口同时打开并指定数据包控制指令思想

可以对嵌入式串口数据包指令设置做一次总结&#xff1a; 首先确定你的数据包大小&#xff0c;传统的接收串口数据到数组存储会出现需要循环遍历数组去读取数据的弊端&#xff0c;所以我设计了一个机制&#xff0c;只有当你想要读取外界指令时&#xff0c;才开始读取外界发过来…...

“征服HTML引号恶魔:“完全解析手册”!!!(quot;表示双引号)

&#x1f6a8;&#x1f4e2; "征服HTML引号恶魔&#xff1a;“完全解析手册” &#x1f4e2;&#x1f6a8; &#x1f3af; 博客引言&#xff1a;当引号变成"恶魔" &#x1f631; 是否遇到过这种情况&#xff1a; 写HTML时满心欢喜输入<div title"他…...

MQL5教程 04 脚本开发实战、指标开发基础

文章目录 一、脚本开发实战1、给脚本设置快捷键2、运行时显示输入参数界面3、开市价单4、一键平仓5、修改止盈止损6、一键删除当前图表所有挂单 二、指标开发基础 一、脚本开发实战 1、给脚本设置快捷键 在MT5导航栏中&#xff0c;选定脚本&#xff0c;鼠标右击 → 设置热键 …...

【Qt】Ubuntu22.04使用命令安装Qt5和Qt6

1、安装Qt5 注意:Ubuntu22.04已经没有 qt5-default ,因此不能一键安装啦 1)安装核心组件 sudo apt install qtbase5-dev qtchooser qt5-qmake qtcreator2)安装QtCreator sudo apt install qtcreator3)安装工具包、Qt Quick 开发的核心库(qtdeclarative5-dev) sudo a…...

海康设备http监听接收报警事件数据

http监听接收报警事件数据 海康获取设备报警事件数据两种方式&#xff1a; 1、sdk 布防监听报警事件数据&#xff08;前面文章有示例&#xff09; 2、http监听接收报警事件数据 http监听接收报警事件数据&#xff0c;服务端可以使用netty通过端口来监听获取事件数据。 WEB 端…...

【MVCC快照如何实现】

MVCC(多版本并发控制)快照的实现原理 MVCC(Multi-Version Concurrency Control)是现代数据库实现事务隔离级别的核心技术&#xff0c;它通过数据多版本和快照机制来实现高效的并发控制。下面我将详细解析MVCC快照的实现机制。 一、MVCC核心组件 1. 版本链结构 MVCC通过以下…...

STM32中不同FLASH的芯片启动文件选择规则

F103ZET6的FLASH大小是512K&#xff0c;所以选择startup_stm32f10x_hd.s F103C8T6的FLASH大小是64K&#xff0c;所以选择startup_stm32f10x_md.s 移植需要注意的事项&#xff1a; 从ZET6到C8T6&#xff0c;需要更改 1&#xff09;启动文件 2&#xff09;C/C选项卡...

树莓集团商业模式解析:树莓集团是国企吗?

树莓集团作为中国市场的重要企业实体&#xff0c;其所有制性质一直受到业界关注。从公开资料显示&#xff0c;树莓集团并非传统意义上的国有企业&#xff0c;而是一家具有混合所有制特征的现代化企业集团。其股权结构中既包含国有资本成分&#xff0c;也吸纳了社会资本和民营投…...

mock.js模拟数据

MOCK模拟后端数据 1.按照mock.js npm install mockjs2.在src目录下建立mock目录&#xff0c;在该目录下建立index.js文件&#xff0c;该文件中写上你所需要的数据&#xff0c;示例如下&#xff1a; import Mock from mockjs let data Mock.mock("/data/person",&…...

如何自动规整化(格式化)HTML

如果你想要自动规整化&#xff08;格式化&#xff09;HTML&#xff0c;可以使用以下方法&#xff1a; 方法 1&#xff1a;使用 VS Code 进行 HTML 格式化&#xff08;推荐&#xff09; 步骤 安装 Visual Studio Code打开你的 HTML 文件按下 Shift Alt F&#xff08;Windows…...

MySQL数据库入门

目录 前言 一、安装软件 二、普通指令使用 三、MySQL接口API相关函数 1、API函数使用步骤 2、mysql_init-MYSQL对象初始化 3、mysql_real_connect()——数据库引擎建立连接 4、mysql_close()——关闭数据库连接 5、mysql_query()——查询数据库某表内容 6、mysql_stor…...

SpringBoot集成Couchbase开发与实践

1 前言 1.1 什么是Couchbase Couchbase 是一个高性能的 NoSQL 数据库,支持文档存储、内存缓存和分布式计算。它结合了内存数据库的速度和灵活性与传统数据库的持久性和查询能力。 1.2 Couchbase的特点与优势 高性能:利用内存缓存加速数据访问。可扩展性:支持水平扩展,能…...

一周掌握Flutter开发--8. 调试与性能优化(上)

文章目录 8. 调试与性能优化核心技能8.1 使用 Flutter DevTools 分析性能8.2 检查 Widget 重绘&#xff08;debugPaintSizeEnabled&#xff09;8.3 解决 ListView 卡顿&#xff08;ListView.builder itemExtent&#xff09; 其他性能优化技巧8.4 减少 build 方法的调用8.5 使用…...

动态路由机制MoE专家库架构在多医疗AI专家协同会诊中的应用探析

随着医疗人工智能技术的飞速进步,AI在医学领域的应用日益增多,尤其是在复杂疾病的诊断和治疗中,AI技术的应用带来了巨大的潜力。特别是动态路由机制混合专家(Mixture of Experts,MoE)架构,因其灵活、高效的特点,正逐渐成为实现多AI专家协同会诊的关键技术。通过将多个不…...

Linux上位机开发实践(开源框架和开源算法)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 做嵌入式软件开发&#xff0c;如果软件本身比较简单&#xff0c;只是图形界面显示&#xff0c;那么相关的开发工作并不难。最主要的内容也就是数据…...

算法时间复杂度分析

1. 基本概念 大 O 符号 O(f(n)) 表示算法的最坏情况复杂度&#xff0c;即算法在最不利情况下所需的基本操作数不会超过 O(f(n))的级别。例如&#xff0c;表示当输入规模 n 增大时&#xff0c;算法运行时间上界是某个常数乘以 。 Ω 符号 Ω(f(n)) 表示算法的下界&#xff0c;即…...

数据库基础知识点(系列五)

创建表&#xff0c;设置约束&#xff0c;修改表&#xff0c;删除表&#xff0c;表中数据的操作(insert,修改&#xff0c;删除) 1&#xff0e;在第5章习题创建的 “仓库库存”数据库中完成下列操作。 (1)创建“商品”表&#xff0c;表结构如表6-4&#xff1a; 表6-4 “goods”…...

C++中使用ShellExecute函数调用其他窗口程序时,参数设置为隐藏,后续能通过发消息给这个被调用程序显示,能显示出来窗口吗

文章目录 一、可行性分析二、实现步骤1. 启动程序并隐藏窗口2. 获取目标窗口句柄3. 发送消息显示窗口方法1&#xff1a;发送WM_SHOWWINDOW方法2&#xff1a;发送WM_SYSCOMMAND恢复窗口方法3&#xff1a;直接调用ShowWindow&#xff08;推荐&#xff09; 三、代码示例四、关键注…...

使用 AI 生成 页面

当前使用的是 火山引擎 提供的 deepseek-v3-241226 思考 如何让AI可以按自己的想法一步步生成页面&#xff1f; 我们要把要生成的内容分段的给到它&#xff0c;让它按步聚完成。 如生成一个列表页 依据所定义的接口。生成API依赖定义接口 生成 状态管理模块依赖上状态管理…...

【人工智能】机器学习中的评价指标

机器学习中的评价指标 在机器学习中&#xff0c;评估指标&#xff08;Evaluation Metrics&#xff09;是衡量模型性能的工具。选择合适的评估指标能够帮助我们更好地理解模型的效果以及它在实际应用中的表现。 一般来说&#xff0c;评估指标主要分为三大类&#xff1a;分类、…...

shell脚本运行方式 bash 和./区别

在 Linux 或 macOS 这类基于 Unix 的系统里&#xff0c;使用 ./ 运行脚本和使用 bash 运行脚本存在一些差异&#xff0c;下面为你详细说明&#xff1a; 1. 语法与使用方式 使用 ./ 运行脚本&#xff1a; 若要使用 ./ 来运行脚本&#xff0c;需要确保脚本文件具备可执行权限&a…...

ShardingSphere+达梦数据库分表操作

背景 随着数字经济时代的全面到来&#xff0c;数据量呈现爆炸式增长&#xff0c;传统单机数据库在性能、扩展性和可用性方面面临严峻挑战。分布式数据库技术应运而生&#xff0c;成为解决海量数据存储与处理的关键方案。在这一背景下&#xff0c;Apache ShardingSphere作为一款…...

WordPress上传图片时显示“未提供数据”错误

在WordPress中上传图片时显示“未提供数据”的错误&#xff0c;通常是由多种原因引起的&#xff0c;以下是一些常见的问题及其解决方法&#xff1a; 1. 文件权限问题 WordPress需要正确的文件和目录权限才能正常上传图片。如果权限设置不正确&#xff0c;可能会导致无法上传图…...

AP CSA FRQ Q2 Past Paper 五年真题汇总 2023-2019

Author(wechat): bigshuang2020 ap csa tutor, providing 1-on-1 tutoring. 国际教育计算机老师, 擅长答疑讲解&#xff0c;带学生实践学习。 热爱创作&#xff0c;作品&#xff1a;ap csa原创双语教案&#xff0c;真题梳理汇总&#xff0c; AP CSA FRQ专题冲刺, AP CSA MCQ小题…...

海量数据场景题--查找两个大文件的URL

查找两个大文件共同的URL 给定 a、b 两个文件&#xff0c;各存放 50 亿个 URL&#xff0c;每个 URL 各占 64B&#xff0c;找出 a、b 两个文件共同的 URL。内存限制是 4G。 操作逻辑&#xff1a; 使用哈希函数 hash(URL) % 1000​ 将每个URL映射到0-999的编号 文件A切割为a0, a1…...

Spring AI Alibaba 工具(Function Calling)使用

一、工具(Function Calling)简介 Spring AI Alibaba工具(Function Calling)&#xff1a;https://java2ai.com/docs/1.0.0-M6.1/tutorials/function-calling/ 1、工具(Function Calling) “工具&#xff08;Tool&#xff09;”或“功能调用&#xff08;Function Calling&#xf…...

汽车方向盘开关功能测试的技术解析

随着汽车智能化与电动化的发展&#xff0c;方向盘开关的功能日益复杂化&#xff0c;从传统的灯光、雨刷控制到智能语音、自动驾驶辅助等功能的集成&#xff0c;对开关的可靠性、耐久性及安全性提出了更高要求。本文结合北京沃华慧通测控技术有限公司&#xff08;以下简称“慧通…...

9-100V输入替代CYT5030/LM5030高压双路电流模式PWM控制器

产品描述: PC3530高压 PWM 控制器包含实现推挽和桥式拓扑所需的所有功能&#xff0c;采用电流模式控制&#xff0c;提供两个交替栅极驱动器输出。PC3530内置高压启动稳压器&#xff0c;可在 9V~100V 的宽输入电压范围内工作。芯片内部还集成有误差放大器、精密基准、两级过流保…...

详细讲解c++中线程类thread的实现,stl源码讲解之thread

Thread 本节我们来详细介绍一下c中的线程类thread&#xff0c;在讲解的过程中会用到大量模板的知识&#xff0c;可以去看c详解模板泛型编程&#xff0c;详解类模板的实现为什么不能放在cpp文件_泛型函数 cpo-CSDN博客 源码: template <class _Fn, class... _Args, enable_…...

PostgreSQL详解

第一章&#xff1a;环境部署与基础操作 1.1 多平台安装详解 Windows环境 图形化安装 下载EnterpriseDB安装包&#xff08;含pgAdmin&#xff09; 关键配置项说明&#xff1a; # postgresql.conf优化项 max_connections 200 shared_buffers 4GB work_mem 32MB 服务管理命…...

系统思考—第五项修炼

感谢【汇丰】邀请&#xff0c;为其高阶管理者交付系统思考系列项目。这不仅是一次知识的传递&#xff0c;更是一次认知的升级。 系统思考&#xff0c;作为《第五项修炼》的核心能力&#xff0c;正在帮助越来越多的管理者突破碎片化决策的困局&#xff0c;建立看见全貌的智慧与…...

如何使用QuickAPI生成带参数的数据API(基于原生SQL)

目录 一、示例表结构 二、准备工作 三、创建带参数的数据API 步骤 1&#xff1a;登录 QuickAPI 平台 步骤 2&#xff1a;连接数据库 步骤 3&#xff1a;配置基础信息 步骤 4&#xff1a;编写 SQL 并添加参数 步骤 5&#xff1a;测试并发布API 步骤 6&#xff1a;验证A…...

RHINO 转 STL,解锁 3D 打印与工业应用新通道

一、RHINO 格式介绍 RHINO 是一款功能强大的三维建模软件&#xff0c;其对应的文件格式&#xff08;.3dm&#xff09;能够精确地存储复杂的三维模型数据。它支持多种几何类型&#xff0c;包括 NURBS&#xff08;非均匀有理 B 样条曲线&#xff09;、多边形网格等。这种格式的优…...

PySide6属性选择器设置样式避坑

总所周知&#xff0c;Qt中qss语法支持属性选择器&#xff0c;通过setProperty设置key和value&#xff0c;支持在多种样式之前切换。今天使用了一下PySide6的属性选择器&#xff0c;发现了一个问题。完整代码见最后。 首先&#xff0c;先写一段qss样式&#xff0c;用来设置按键样…...

BKA-CNN-BiLSTM、CNN-BiLSTM、BiLSTM、CNN四模型多变量时序光伏功率预测,附模型报告

BKA-CNN-BiLSTM、CNN-BiLSTM、BiLSTM、CNN四模型多变量时序光伏功率预测&#xff0c;附模型报告 目录 BKA-CNN-BiLSTM、CNN-BiLSTM、BiLSTM、CNN四模型多变量时序光伏功率预测&#xff0c;附模型报告预测效果基本介绍程序设计参考资料 预测效果 基本介绍 BKA-CNN-BiLSTM、CNN-…...

ADS 学习和培训资源 - Keysight ADS

在 Signal Edge Solutions&#xff0c;我们是 Keysight ADS 的忠实用户&#xff0c;因此我们明白&#xff0c;使用和学习这款强大的仿真工具有时可能非常困难。 因此&#xff0c;我们编制了一份清单&#xff0c;列出了一些我们最喜欢的 ADS 学习和培训资源&#xff0c;以帮助您…...

【leetcode刷题记录】(java)数组 链表 哈希表

文章目录 四、题目之&#xff1a;代码随想录(1) 代码随想录&#xff1a;数组[704. 二分查找](https://leetcode.cn/problems/binary-search/)[27. 移除元素](https://leetcode.cn/problems/remove-element/)暴力解:双指针&#xff1a; [977. 有序数组的平方](https://leetcode.…...

ngx_http_core_root

定义在 src\http\ngx_http_core_module.c static char * ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {ngx_http_core_loc_conf_t *clcf conf;ngx_str_t *value;ngx_int_t alias;ngx_uint_t …...

大模型在支气管肺癌预测及临床决策中的应用研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目的 二、大模型预测支气管肺癌的原理与技术基础 2.1 大模型简介 2.2 数据收集与预处理 2.3 模型训练与优化 三、术前预测 3.1 病情评估 3.1.1 肿瘤大小、位置及分期预测 3.1.2 转移风险预测 3.2 手术风险预测 3.2.1 患…...

机器人原点丢失后找回原点的解决方案与步骤

机器人原点丢失后找回原点的解决方案与步骤 在机器人运行过程中&#xff0c;原点丢失可能导致定位错误、运动失控等问题&#xff0c;常见于机械臂、AGV&#xff08;自动导引车&#xff09;、3D打印机等设备。以下是针对原点丢失问题的系统性解决方案及详细步骤&#xff0c;涵盖…...

CSS SEO、网页布局、媒体查询

目录 一、SEO 头部三大标签 1. Title 标签&#xff08;标题&#xff09; 核心作用 优化规范 示例 2. Meta Description&#xff08;描述&#xff09; 核心作用 优化规范 示例 3. Viewport 标签&#xff08;视口&#xff09; 核心作用 优化规范 4. 完整 SEO 头部模…...

SolidJS 深度解析:高性能响应式前端框架

SolidJS 是一个新兴的响应式前端框架&#xff0c;以其极致的性能、简洁的语法和接近原生 JavaScript 的开发体验而闻名。它结合了 React 的声明式 UI 和 Svelte 的编译时优化&#xff0c;同时采用细粒度响应式更新&#xff0c;避免了虚拟 DOM&#xff08;Virtual DOM&#xff0…...

基于Spring Boot + Vue的银行管理系统设计与实现

基于Spring Boot Vue的银行管理系统设计与实现 一、引言 随着金融数字化进程加速&#xff0c;传统银行业务向线上化转型成为必然趋势。本文设计并实现了一套基于Spring Boot Vue的银行管理系统&#xff0c;通过模块化架构满足用户、银行职员、管理员三类角色的核心业务需求…...

解决 Ubuntu/Debian 中 `apt-get` 报错 “无法获得锁 /var/lib/dpkg/lock“

问题描述 在 Ubuntu/Debian 系统中运行 sudo apt-get install 或 sudo apt update 时&#xff0c;遇到以下错误&#xff1a; E: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) E: 无法锁定管理目录(/var/lib/dpkg/)&#xff0c;是否有其他进程正占用它&#…...

OpenGL 着色器

一、‌着色器基础结构‌ ‌版本声明与入口函数‌ ‌首行版本声明‌&#xff1a;必须指定 GLSL 版本和模式&#xff08;如 #version 450 core&#xff09;‌。 #version 450 core // 声明使用 OpenGL 4.5 Core Profile ‌入口函数‌&#xff1a;所有着色器的入口均为 main() 函…...

代码随想录刷题day53|(二叉树篇)105.从前序与中序遍历序列构造二叉树(▲

目录 一、二叉树基础知识 二、构造二叉树思路 2.1 构造二叉树流程&#xff08;先序中序 2.2 递归思路 三、相关算法题目 四、易错点 一、二叉树基础知识 详见&#xff1a;代码随想录刷题day34|&#xff08;二叉树篇&#xff09;二叉树的递归遍历-CSDN博客 二、构造二叉…...

【leetcode刷题日记】lc.560-和为 K 的子数组

目录 1.题目 2.代码 1.题目 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2示例 2&#xff1a; 输入…...

计算机期刊推荐 | 计算机-人工智能、信息系统、理论和算法、软件工程、网络系统、图形学和多媒体, 工程技术-制造, 数学-数学跨学科应用

Computers, Materials & Continua 学科领域&#xff1a; 计算机-人工智能、信息系统、理论和算法、软件工程、网络系统、图形学和多媒体, 工程技术-制造, 数学-数学跨学科应用 期刊类型&#xff1a; SCI/SSCI/AHCI 收录数据库&#xff1a; SCI(SCIE),EI,Scopus,知网(CNK…...

K8S安装及部署calico(亲测有用[特殊字符])

一、 基础部署&#xff08;三台均部署&#xff09; 1. 关闭防火墙并修改网络为aliyun 要保证网络可以使用&#xff0c;可以将DNS的指向修改为114.114.114.114和8.8.8.8这两个。 systemctl stop firewalld && systemctl disable firewalld sed -i s/enforcing/disabl…...

etcd性能测试

etcd性能测试 本文参考官方文档完成etcd性能测试&#xff0c;提供etcd官方推荐的性能测试方案。 1. 理解性能&#xff1a;延迟与吞吐量 etcd 提供稳定、持续的高性能。有两个因素决定性能&#xff1a;延迟和吞吐量。延迟是完成一项操作所花费的时间。吞吐量是在某个时间段内…...