Alkaitu:STM32串口定时器延时接收不定数组和串口发送

该代码实现了一个基于STM32的串口接收和发送框架,包括串口初始化、中断服务函数、延时处理和数据接收完成标志。代码支持多个串口,并提供了数据接收缓冲区和发送功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include "user_uart.h"
#include "stm32f10x.h"
#include <stdio.h>


/******************************************************************************************/
/*串口接收部分代码移植需要改动3处*/
/******************************************************************************************/


/******************************************************************************************/
/********************************串口接收部分代码*******************************************/
/******************************************************************************************/


/******************************************************************************************/
/*此结构体类型无需改动*/
/******************************************************************************************/
typedef struct
{
	volatile unsigned int uart_delay_flag;    //串口进入中断后,定时器开启标志位
	volatile unsigned int uart_delay_count;   //串口进入中断后,定时器计数变量,自加
	volatile unsigned char uart_array_num;    //接受数据的数组的序号
  volatile unsigned char uart_receive_flag; //串口接收数据完成标志位
}User_Uart_InitTypeDef;
/*******************************************************************************************/

  
/******************************************************************************************************/
/*串口结构体数组,预设5个串口,如增加新串口,可按格式增加,如不需要增加串口,此结构体无需改动*/
/******************************************************************************************************/
User_Uart_InitTypeDef uart_array[UART_NUM_ALL] =  
{
 {0,0,0,0,},
 
 #if UART_NUM_ALL > 1 
 {0,0,0,0,},
 #endif
 
  #if UART_NUM_ALL > 2 
 {0,0,0,0,},
 #endif
 
  #if UART_NUM_ALL > 3 
 {0,0,0,0,},
 #endif
 
  #if UART_NUM_ALL > 4 
 {0,0,0,0,},
 #endif
};
/***************************************************************************************************/


/***************************************************************************************************/
/*串口接收数组声明,预设5个串口,如增加新串口,可按格式增加,如不需要增加串口,此结构体无需改动*/
/***************************************************************************************************/
volatile unsigned char uart1_array_receive_buff[N1_UART];

#if UART_NUM_ALL > 1
volatile unsigned char uart2_array_receive_buff[N2_UART];
#endif

#if UART_NUM_ALL > 2
volatile unsigned char uart3_array_receive_buff[N3_UART];
#endif

#if UART_NUM_ALL > 3
volatile unsigned char uart4_array_receive_buff[N4_UART];
#endif

#if UART_NUM_ALL > 4
volatile unsigned char uart5_array_receive_buff[N5_UART];
#endif
/***************************************************************************************************/


/**********************************移植需改动的第1处***********************************/
/*串口初始化代码*/
/*************************************************************************************/
void user_uart_init(void)
{
   GPIO_InitTypeDef GPIO_InitStruct; 
	 USART_InitTypeDef USART_InitStruct;
   NVIC_InitTypeDef NVIC_InitStruct;
	 
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	 
	 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;	
   GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	 GPIO_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);
	
	 USART_InitStruct.USART_BaudRate = 115200;
	 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_Rx | USART_Mode_Tx;
	 USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	 USART_Init(USART1, &USART_InitStruct);
	 
	 NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
	 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	 NVIC_Init(&NVIC_InitStruct);
	 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	 
	 USART_Cmd(USART1, ENABLE);
}	
/******************************************************************************************/


/***********************************移植需改动的第2处*******************************************************/
/*此函数放置到串口中断服务函数,移植需改动: 1串口清除中断标志位的函数 2串口接收数据函数*/
/*********************************************************************************************************/
void user_uart_intterrupt(unsigned char uart_id)
{
	switch(uart_id)
	{
	  case 1: USART_ClearITPendingBit(USART1, USART_IT_RXNE);break;
		
		#if UART_NUM_ALL > 1
  	case 2: USART_ClearITPendingBit(USART2, USART_IT_RXNE);break;
    #endif
		
		#if UART_NUM_ALL > 2
  	case 3: USART_ClearITPendingBit(USART3, USART_IT_RXNE);break;
    #endif
		
		#if UART_NUM_ALL > 3
  	case 4: USART_ClearITPendingBit(USART4, USART_IT_RXNE);break;
    #endif
		
		#if UART_NUM_ALL > 4
  	case 4: USART_ClearITPendingBit(USART5, USART_IT_RXNE);break;
    #endif
	}
	uart_array[uart_id - 1].uart_delay_flag = 1; //进入中断后开启定时
  uart_array[uart_id - 1].uart_delay_count = 0; //清零定时器计数
	if(uart_array[uart_id - 1].uart_array_num < N1_UART)
	{
	  switch(uart_id)
		{
		  case 1:uart1_array_receive_buff[uart_array[uart_id - 1].uart_array_num] = USART_ReceiveData(USART1);break;
			
			#if UART_NUM_ALL > 1
      case 2:uart2_array_receive_buff[uart_array[uart_id - 1].uart_array_num] = USART_ReceiveData(USART2);break;
      #endif
			
			#if UART_NUM_ALL > 2
  	  case 3:uart3_array_receive_buff[uart_array[uart_id - 1].uart_array_num] = USART_ReceiveData(USART3);break;
      #endif
			
			#if UART_NUM_ALL > 3
  	  case 4:uart4_array_receive_buff[uart_array[uart_id - 1].uart_array_num] = USART_ReceiveData(USART4);break;
      #endif
			
			#if UART_NUM_ALL > 4
  	  case 4:uart4_array_receive_buff[uart_array[uart_id - 1].uart_array_num] = USART_ReceiveData(USART5);break;
      #endif
  	}
    uart_array[uart_id - 1].uart_array_num++;	
	}
	else
	{
	  uart_array[uart_id - 1].uart_array_num = N1_UART;  //不再接收接收数据
	}
}
/*********************************************************************************************************/


/*********************************************************************************************************/
/*此函数放置到systick或者定时器中断函数去,此结构体无需改动*/
/*********************************************************************************************************/
void user_uart_scan(void)
{
  unsigned char uart_index;
	for(uart_index =0;uart_index < UART_NUM_ALL;uart_index++)
	{	
		if(uart_array[uart_index].uart_delay_flag == 1)     //判断标志位,串口启动定时延时
		{
			uart_array[uart_index].uart_delay_count++;        //延时计数
			if(uart_array[uart_index].uart_delay_count > UART_DELAY_TIME) //延时计数超过设定值
			{
				uart_array[uart_index].uart_delay_count = 0;   //延时计数清零
				uart_array[uart_index].uart_delay_flag = 0;    //延时计数的标志位清零,关串口计数定时器
				uart_array[uart_index].uart_array_num = 0;     //串口数组的下标归零,以便下次串口接收数据从0下标开始
				uart_array[uart_index].uart_receive_flag = 1;  //接收完成,标志位赋值
			}
		}
	}	
}
/**********************************************************************************************************/


/***********************************************************************************/
/*判断串口数据是否接收完成,一般在主函数使用,并处理串口接收到的数据,此结构体无需改动*/
/***********************************************************************************/
unsigned char user_uart_get_flag(unsigned char uart_id)
{
  unsigned char uart_local_param = 0;
	if(uart_array[uart_id - 1].uart_receive_flag == 1)
	{
	  uart_array[uart_id - 1].uart_receive_flag = 0;
		uart_local_param = 1;
  }
	else
	{
	  uart_local_param = 0;
	}
	return uart_local_param;
}
/*****************************************************************************/


/******************************移植需要改动的第3处*******************************/
/*串口中断服务函数,如移植需重写串口对应的中断服务函数*/
/*****************************************************************************/
void USART1_IRQHandler()
{
  user_uart_intterrupt(1);
}


#if UART_NUM_ALL > 1
void USART2_IRQHandler()
{
  user_uart_intterrupt(2);
}
#endif
/*****************************************************************************/


/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/分界线/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
/******************************************************************************************/


/******************************************************************************************/
/*串口发送部分代码移植需要改动2处*/
/******************************************************************************************/


/****************************************************************************/
/***************************串口发送部分代码*********************************/
/****************************************************************************/


/****************************************************************************/
/*不用勾选使用keil的Use MicroLIB,不需要改动*/
/****************************************************************************/
#if 1
#pragma import(__use_no_semihosting)
void _sys_exit(int x){x = x;}   //定义_sys_exit()以避免使用半主机模式 
struct __FILE{int handle;};     //标准库需要的支持函数 
FILE __stdout;
#endif
/*****************************************************************************/


/**************************移植需要改动的第1处********************************/
/*重定义print函数,如移植需重写串口发送单个字节函数,和获取标志位函数*/
/****************************************************************************/
int fputc(int ch, FILE *f)
{
  USART_SendData(USART1,(uint8_t)ch);   //发送一字节数据
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); //等待发送完成
	return ch;
}
/*****************************************************************************/


/******************************************移植需要改动的第2处********************************************/
/*串口发送函数,如移植需重写串口发送单个字节函数,和获取标志位函数*/
/****************************************************************************/
void user_uart_send(unsigned char uart_id,unsigned char *uart_p,unsigned char uart_array_member_total)
{
  unsigned char uart_local_param;
	switch(uart_id)
	{
	  case 1: for(uart_local_param = 0;uart_local_param < uart_array_member_total;uart_local_param++)
		        {
						  USART_SendData(USART1,(uint8_t)uart_p[uart_local_param]);   //发送一字节数据
	            while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); //等待发送完成
							USART_ClearFlag(USART1,USART_FLAG_TC);                      //清除发送标志位
						};break;
		
		#if UART_NUM_ALL > 1
		case 2: for(uart_local_param = 0;uart_local_param < uart_array_member_total;uart_local_param++)
		        {
						  USART_SendData(USART2,(uint8_t)uart_p[uart_local_param]);   //发送一字节数据
	            while(USART_GetFlagStatus(USART2,USART_FLAG_TXE) == RESET); //等待发送完成
							USART_ClearFlag(USART2,USART_FLAG_TC);                      //清除发送标志位
						};break;
	  #endif					
	  
		#if UART_NUM_ALL > 2
		case 3: for(uart_local_param = 0;uart_local_param < uart_array_member_total;uart_local_param++)
		        {
						  USART_SendData(USART3,(uint8_t)uart_p[uart_local_param]);   //发送一字节数据
	            while(USART_GetFlagStatus(USART3,USART_FLAG_TXE) == RESET); //等待发送完成
							USART_ClearFlag(USART3,USART_FLAG_TC);                      //清除发送标志位
						};break;
		#endif				
	  
		#if UART_NUM_ALL > 3
		case 4: for(uart_local_param = 0;uart_local_param < uart_array_member_total;uart_local_param++)
		        {
						  USART_SendData(USART4,(uint8_t)uart_p[uart_local_param]);   //发送一字节数据
	            while(USART_GetFlagStatus(USART4,USART_FLAG_TXE) == RESET); //等待发送完成
							USART_ClearFlag(USART4,USART_FLAG_TC);                      //清除发送标志位
						};break;
						
		#endif

    #if UART_NUM_ALL > 4		
	  case 5: for(uart_local_param = 0;uart_local_param < uart_array_member_total;uart_local_param++)
		        {
						  USART_SendData(USART5,(uint8_t)uart_p[uart_local_param]);   //发送一字节数据
	            while(USART_GetFlagStatus(USART5,USART_FLAG_TXE) == RESET); //等待发送完成
							USART_ClearFlag(USART5,USART_FLAG_TC);                      //清除发送标志位
						};break;
    #endif						
	}
}
/**********************************************************************************************************/


/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/分界线/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
/******************************************************************************************/


/****************************************************************************/
/*串口数组数据清除,适用于所有数组*/
/****************************************************************************/
 void array_clear(unsigned char *array_p,unsigned char array_num)
 {
   unsigned char array_local_param;
	 for(array_local_param = 0;array_local_param < array_num;array_local_param++)
	 {
	   array_p[array_local_param] = 0;
	 }
 }
 /****************************************************************************/
 
  
#ifndef _user_uart_h_
#define _user_uart_h_


/******************************************************************************************/
/*串口接收部分代码移植需要改动3处*/
/******************************************************************************************/


/***************移植需改动的第1处*********************/
/*宏定义串口的总个数*/
/****************************************************/
#define UART_NUM_ALL 1
/****************************************************/


/****************移植需改动的第2处********************/
/*宏定义串口延时接收时间设置*/
/****************************************************/
#define UART_DELAY_TIME 10
/****************************************************/


/****************移植需改动的第3处*******************/
/*宏定义串口接收数组的大小*/
/****************************************************/
#define N1_UART 10 

#if UART_NUM_ALL > 1
N2_UART 10
#endif

#if UART_NUM_ALL > 2
N3_UART 10
#endif

#if UART_NUM_ALL > 3
N4_UART 10
#endif

#if UART_NUM_ALL > 4
N5_UART 10
#endif
/****************************************************/


/******************************************************************/
/*声明串口数据接收数组外部调用,无需改动*/
/******************************************************************/
extern volatile unsigned char uart1_array_receive_buff[N1_UART];

#if UART_NUM_ALL > 1
extern volatile unsigned char uart2_array_receive_buff[N2_UART];
#endif

#if UART_NUM_ALL > 2
extern volatile unsigned char uart3_array_receive_buff[N3_UART];
#endif

#if UART_NUM_ALL > 3
extern volatile unsigned char uart4_array_receive_buff[N4_UART];
#endif

#if UART_NUM_ALL > 4
extern volatile unsigned char uart5_array_receive_buff[N5_UART];
#endif
/*******************************************************************/


/****************************************************/
/*串口初始化*/
void user_uart_init(void);
/****************************************************/



/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/分界线/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
/******************************************************************************************/


/*与串口发送有关的函数*/
/****************************************************/
/*此函数放置到串口中断服务函数*/
void user_uart_intterrupt(unsigned char uart_id);
/****************************************************/


/****************************************************************/
/*此函数放置到systick或者定时器中断函数去*/
void user_uart_scan(void);
/****************************************************************/


/******************************************************************/
/*判断串口数据是否接收完成,一般在主函数使用,并处理串口接收到的数据*/
unsigned char user_uart_get_flag(unsigned char uart_id);
/******************************************************************/



/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/分界线/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
/******************************************************************************************/


/******************************************************************************************************/
/*串口发送函数*/
void user_uart_send(unsigned char uart_id,unsigned char *uart_p,unsigned char uart_array_member_total);
/******************************************************************************************************/

  
/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/分界线/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
/******************************************************************************************/

 
/*****************************************************************/
/*串口数组数据清除,适用于所有数组*/
void array_clear(unsigned char *array_p,unsigned char array_num);
/*****************************************************************/


#endif




### 部署 Stable Diffusion 的准备工作 为了成功部署 Stable Diffusion,在本地环境中需完成几个关键准备事项。确保安装了 Python 和 Git 工具,因为这些对于获取源码和管理依赖项至关重要。 #### 安装必要的软件包和支持库 建议创建一个新的虚拟环境来隔离项目的依赖关系。这可以通过 Anaconda 或者 venv 实现: ```bash conda create -n sd python=3.9 conda activate sd ``` 或者使用 `venv`: ```bash python -m venv sd-env source sd-env/bin/activate # Unix or macOS sd-env\Scripts\activate # Windows ``` ### 下载预训练模型 Stable Diffusion 要求有预先训练好的模型权重文件以便能够正常工作。可以从官方资源或者其他可信赖的地方获得这些权重文件[^2]。 ### 获取并配置项目代码 接着要做的就是把最新的 Stable Diffusion WebUI 版本拉取下来。在命令行工具里执行如下指令可以实现这一点;这里假设目标路径为桌面下的特定位置[^3]: ```bash git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git ~/Desktop/stable-diffusion-webui cd ~/Desktop/stable-diffusion-webui ``` ### 设置 GPU 支持 (如果适用) 当打算利用 NVIDIA 显卡加速推理速度时,则需要确认 PyTorch 及 CUDA 是否已经正确设置好。下面这段简单的测试脚本可以帮助验证这一情况[^4]: ```python import torch print(f"Torch version: {torch.__version__}") if torch.cuda.is_available(): print("CUDA is available!") else: print("No CUDA detected.") ``` 一旦上述步骤都顺利完成之后,就可以按照具体文档中的指导进一步操作,比如调整参数、启动服务端口等等。整个过程中遇到任何疑问都可以查阅相关资料或社区支持寻求帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值