STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组

ops/2024/11/19 19:05:26/

eventgroup_0">STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组

STM32CUBE开发环境集成了STM32 HAL库进行FreeRTOS配置和开发的组件,不需要用户自己进行FreeRTOS的移植。这里介绍最简化的用户操作类应用教程。以STM32F401RCT6开发板为例,只用到USB,USART1极少的接口,体现FreeRTOS的各种操作过程。
在这里插入图片描述
操作教程(九)配置FreeRTOS及相关环境,实现LED闪灯功能及基于eventgroup事件标志组的USB虚拟串口发收环回。从电脑端连接USB虚拟串口后,发送出去的串口数据,会被保存且一个事件标志位被设置,在任务中发现该事件标志位有效,则将数据通过USB虚拟串口返回电脑端。本例程也设置了一个timer软件定时器,定时设置一个事件标志位,任务发现定时器设置的事件标志位有效,通过虚拟串口向外打印出固定信息。

FreeRTOS的教程较多,推荐参考正点原子所出的《STM32F407 FreeRTOS开发手册》了解相关知识。
在这里插入图片描述
在这里插入图片描述

STM32CUBEIDE工程配置

选择TIM1(也可以是其它TIM)作为FreeRTOS操作系统占用的时钟源:
在这里插入图片描述

在这里插入图片描述

配置时钟树包括USB的48MHz时钟:
在这里插入图片描述
配置PC13为低电平点灯的管脚:
在这里插入图片描述
配置USB串口:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
配置UART1串口(但本例中不用到UART1):
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

FreeRTOS配置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
保存并生成基础工程代码:
在这里插入图片描述
在生成代码的这个部分可以看到FreeRTOS代码部分:
在这里插入图片描述

任务实现

基于前述的配置,main.c代码里会加载Free-RTOS的配置,并启动几个任务的调度,当然,此时的任务都是什么也不干。实现LED闪灯,就在LED闪灯任务里加入代码即可:

void StartTask_TASK_LED_FLASH(void *argument)
{/* USER CODE BEGIN StartTask_TASK_LED_FLASH *//* Infinite loop */for(;;){osDelay(1000);HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);}/* USER CODE END StartTask_TASK_LED_FLASH */
}

也就实现了LED闪灯功能,其中osDelay(1000);实现1秒时间的操作系统调度延时,也就是1秒执行一次LED灯的亮灭。osDelay(1);是最小的调度延时,为1毫秒。要实现更小的延时,则可以用微秒延时函数实现,参考《STM32 HAL us delay(微秒延时)的指令延时实现方式及优化》。

在USB的接收中断里,保存接收到的数据和数据长度,并设置事件标志位:
在这里插入图片描述

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{/* USER CODE BEGIN 6 */extern uint8_t USB_VCOM_BUFF[1024];extern uint32_t USB_VCOM_INDEX;extern osEventFlagsId_t USB_VCOM_Event01Handle;extern BaseType_t USB_VCOM_pxHigherPriorityTaskWaken;memcpy(USB_VCOM_BUFF, Buf, *Len);USB_VCOM_INDEX = *Len;xEventGroupSetBitsFromISR( USB_VCOM_Event01Handle, 0x01, USB_VCOM_pxHigherPriorityTaskWaken);USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);USBD_CDC_ReceivePacket(&hUsbDeviceFS);return (USBD_OK);/* USER CODE END 6 */
}

main.c文件里软件定时器设置事件标志位

void USB_VCOM_Timer01_Callback01(void *argument)
{/* USER CODE BEGIN USB_VCOM_Timer01_Callback01 */xEventGroupSetBitsFromISR( USB_VCOM_Event01Handle, 0x02, USB_VCOM_pxHigherPriorityTaskWaken);/* USER CODE END USB_VCOM_Timer01_Callback01 */
}

main.c文件里任务处理

void StartTask_TASK_USB_VCOM(void *argument)
{/* USER CODE BEGIN StartTask_TASK_USB_VCOM */EventBits_t Flags = 0;/* Infinite loop */for(;;){osDelay(10);Flags = xEventGroupGetBits( USB_VCOM_Event01Handle );if(Flags&0x01){usbprintarray(USB_VCOM_BUFF, USB_VCOM_INDEX);xEventGroupClearBits( USB_VCOM_Event01Handle, 0x01);}if(Flags&0x02){usbprintstring("\r\nSoftware Timer Outputs\r\n");xEventGroupClearBits( USB_VCOM_Event01Handle, 0x02);}}/* USER CODE END StartTask_TASK_USB_VCOM */
}

完整的main.c文件:

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2023 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
//Example 9: LED flash + USB VCOM loop back with event-group & timer
//Written by Pegasus Yu
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "cmsis_os.h"
#include "usb_device.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "event_groups.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
__IO float usDelayBase = 7.63238716; //For STM32F401RCT6 working in 84MHz main clockvoid PY_Delay_us_t(uint32_t Delay)
{__IO uint32_t delayReg;__IO uint32_t usNum = (uint32_t)(Delay*usDelayBase);delayReg = 0;while(delayReg!=usNum) delayReg++;
}
/* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {.name = "defaultTask",.stack_size = 128 * 4,.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for TASK_LED_FLASH */
osThreadId_t TASK_LED_FLASHHandle;
const osThreadAttr_t TASK_LED_FLASH_attributes = {.name = "TASK_LED_FLASH",.stack_size = 128 * 4,.priority = (osPriority_t) osPriorityLow,
};
/* Definitions for TASK_UART1 */
osThreadId_t TASK_UART1Handle;
const osThreadAttr_t TASK_UART1_attributes = {.name = "TASK_UART1",.stack_size = 128 * 4,.priority = (osPriority_t) osPriorityLow,
};
/* Definitions for TASK_USB_VCOM */
osThreadId_t TASK_USB_VCOMHandle;
const osThreadAttr_t TASK_USB_VCOM_attributes = {.name = "TASK_USB_VCOM",.stack_size = 128 * 4,.priority = (osPriority_t) osPriorityLow,
};
/* Definitions for USB_VCOM_Timer01 */
osTimerId_t USB_VCOM_Timer01Handle;
const osTimerAttr_t USB_VCOM_Timer01_attributes = {.name = "USB_VCOM_Timer01"
};
/* Definitions for USB_VCOM_Event01 */
osEventFlagsId_t USB_VCOM_Event01Handle;
const osEventFlagsAttr_t USB_VCOM_Event01_attributes = {.name = "USB_VCOM_Event01"
};
/* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
void StartDefaultTask(void *argument);
void StartTask_TASK_LED_FLASH(void *argument);
void StartTask_TASK_UART1(void *argument);
void StartTask_TASK_USB_VCOM(void *argument);
void USB_VCOM_Timer01_Callback01(void *argument);/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
void usbprintstring(char * data)
{if(CDC_Transmit_FS((uint8_t *)data, strlen(data))==USBD_BUSY){PY_Delay_us_t(1000000);CDC_Transmit_FS((uint8_t *)data, strlen(data));}
}void usbprintarray(uint8_t * data, uint16_t len)
{if(CDC_Transmit_FS(data, len)==USBD_BUSY){PY_Delay_us_t(1000000);CDC_Transmit_FS(data, len);}
}uint8_t USB_VCOM_BUFF[1024];
uint32_t USB_VCOM_INDEX = 0;BaseType_t USB_VCOM_pxHigherPriorityTaskWaken = 0;
TickType_t USB_VCOM_xBlockTime = 0;
uint32_t Timer_Period_ms = 10;
/* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Init scheduler */osKernelInitialize();/* USER CODE BEGIN RTOS_MUTEX *//* add mutexes, ... *//* USER CODE END RTOS_MUTEX *//* USER CODE BEGIN RTOS_SEMAPHORES *//* add semaphores, ... *//* USER CODE END RTOS_SEMAPHORES *//* Create the timer(s) *//* creation of USB_VCOM_Timer01 */USB_VCOM_Timer01Handle = osTimerNew(USB_VCOM_Timer01_Callback01, osTimerPeriodic, NULL, &USB_VCOM_Timer01_attributes);/* USER CODE BEGIN RTOS_TIMERS *//* start timers, add new ones, ... *//* USER CODE END RTOS_TIMERS *//* USER CODE BEGIN RTOS_QUEUES *//* add queues, ... *//* USER CODE END RTOS_QUEUES *//* Create the thread(s) *//* creation of defaultTask */defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);/* creation of TASK_LED_FLASH */TASK_LED_FLASHHandle = osThreadNew(StartTask_TASK_LED_FLASH, NULL, &TASK_LED_FLASH_attributes);/* creation of TASK_UART1 */TASK_UART1Handle = osThreadNew(StartTask_TASK_UART1, NULL, &TASK_UART1_attributes);/* creation of TASK_USB_VCOM */TASK_USB_VCOMHandle = osThreadNew(StartTask_TASK_USB_VCOM, NULL, &TASK_USB_VCOM_attributes);/* USER CODE BEGIN RTOS_THREADS *//* add threads, ... *//* USER CODE END RTOS_THREADS *//* Create the event(s) *//* creation of USB_VCOM_Event01 */USB_VCOM_Event01Handle = osEventFlagsNew(&USB_VCOM_Event01_attributes);/* USER CODE BEGIN RTOS_EVENTS *//* add events, ... *//* USER CODE END RTOS_EVENTS *//* Start scheduler */osKernelStart();/* We should never get here as control is now taken by the scheduler *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 25;RCC_OscInitStruct.PLL.PLLN = 336;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;RCC_OscInitStruct.PLL.PLLQ = 7;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/*** @brief USART1 Initialization Function* @param None* @retval None*/
static void MX_USART1_UART_Init(void)
{/* USER CODE BEGIN USART1_Init 0 *//* USER CODE END USART1_Init 0 *//* USER CODE BEGIN USART1_Init 1 *//* USER CODE END USART1_Init 1 */huart1.Instance = USART1;huart1.Init.BaudRate = 115200;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;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN USART1_Init 2 *//* USER CODE END USART1_Init 2 */}/*** Enable DMA controller clock*/
static void MX_DMA_Init(void)
{/* DMA controller clock enable */__HAL_RCC_DMA2_CLK_ENABLE();/* DMA interrupt init *//* DMA2_Stream2_IRQn interrupt configuration */HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 5, 0);HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);}/*** @brief GPIO Initialization Function* @param None* @retval None*/
static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 *//* GPIO Ports Clock Enable */__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOH_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);/*Configure GPIO pin : LED_Pin */GPIO_InitStruct.Pin = LED_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//* USER CODE BEGIN Header_StartDefaultTask */
/*** @brief  Function implementing the defaultTask thread.* @param  argument: Not used* @retval None*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{/* init code for USB_DEVICE */MX_USB_DEVICE_Init();/* USER CODE BEGIN 5 */Timer_Period_ms = 2000;xTimerChangePeriodFromISR( USB_VCOM_Timer01Handle, Timer_Period_ms, &USB_VCOM_pxHigherPriorityTaskWaken );xTimerStartFromISR( USB_VCOM_Timer01Handle, &USB_VCOM_pxHigherPriorityTaskWaken );  //Start Timer/* Infinite loop */for(;;){osDelay(1);}/* USER CODE END 5 */
}/* USER CODE BEGIN Header_StartTask_TASK_LED_FLASH */
/**
* @brief Function implementing the TASK_LED_FLASH thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask_TASK_LED_FLASH */
void StartTask_TASK_LED_FLASH(void *argument)
{/* USER CODE BEGIN StartTask_TASK_LED_FLASH *//* Infinite loop */for(;;){osDelay(1000);HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);}/* USER CODE END StartTask_TASK_LED_FLASH */
}/* USER CODE BEGIN Header_StartTask_TASK_UART1 */
/**
* @brief Function implementing the TASK_UART1 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask_TASK_UART1 */
void StartTask_TASK_UART1(void *argument)
{/* USER CODE BEGIN StartTask_TASK_UART1 *//* Infinite loop */for(;;){osDelay(1);}/* USER CODE END StartTask_TASK_UART1 */
}/* USER CODE BEGIN Header_StartTask_TASK_USB_VCOM */
/**
* @brief Function implementing the TASK_USB_VCOM thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask_TASK_USB_VCOM */
void StartTask_TASK_USB_VCOM(void *argument)
{/* USER CODE BEGIN StartTask_TASK_USB_VCOM */EventBits_t Flags = 0;/* Infinite loop */for(;;){osDelay(10);Flags = xEventGroupGetBits( USB_VCOM_Event01Handle );if(Flags&0x01){usbprintarray(USB_VCOM_BUFF, USB_VCOM_INDEX);xEventGroupClearBits( USB_VCOM_Event01Handle, 0x01);}if(Flags&0x02){usbprintstring("\r\nSoftware Timer Outputs\r\n");xEventGroupClearBits( USB_VCOM_Event01Handle, 0x02);}}/* USER CODE END StartTask_TASK_USB_VCOM */
}/* USB_VCOM_Timer01_Callback01 function */
void USB_VCOM_Timer01_Callback01(void *argument)
{/* USER CODE BEGIN USB_VCOM_Timer01_Callback01 */xEventGroupSetBitsFromISR( USB_VCOM_Event01Handle, 0x02, USB_VCOM_pxHigherPriorityTaskWaken);/* USER CODE END USB_VCOM_Timer01_Callback01 */
}/*** @brief  Period elapsed callback in non blocking mode* @note   This function is called  when TIM1 interrupt took place, inside* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment* a global variable "uwTick" used as application time base.* @param  htim : TIM handle* @retval None*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{/* USER CODE BEGIN Callback 0 *//* USER CODE END Callback 0 */if (htim->Instance == TIM1) {HAL_IncTick();}/* USER CODE BEGIN Callback 1 *//* USER CODE END Callback 1 */
}/*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

例程下载

STM32 STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组 例程

例程测试

例程测试效果如下:

在这里插入图片描述

–End–


http://www.ppmy.cn/ops/135046.html

相关文章

未来汽车新变革,智能表面浮出水面

摘要: 智能表面技术的应用,不仅提升了内饰的美观度,还增强了用户交互的直观性和便捷性。 近年来,智能表面技术在汽车内饰领域的应用标志着智能座舱设计的重大进步。这种技术整合了功能性与智能化,使得座舱内部设计得以…

图像处理学习笔记20241115

文章目录 饱和度1. 饱和度的定义2. 在颜色模型中的表示3. 饱和度的计算假设图像像素矩阵如下饱和度计算步骤 引导滤波1. 引导滤波的原理2. 公式推导3. 引导滤波的参数4. 代码示例 孪生网络1. 孪生网络的基本结构2. 工作原理 双边滤波(Bilateral Filter)双…

MQ集群

目录 MQ集群 集群分类 普通集群 集群结构和特征 集群的部署 获取cookie 准备集群配置 启动集群 镜像模式 镜像模式的特征 镜像模式的配置 exactly模式 仲裁队列 集群特征仲裁队列:仲裁队列是3.8版本以后才有的新功能,用来替代镜像队列&#…

界面控件DevExpress Blazor UI v24.1新版亮点 - 全新PDF Viewer等组件

DevExpress Blazor UI组件使用了C#为Blazor Server和Blazor WebAssembly创建高影响力的用户体验,这个UI自建库提供了一套全面的原生Blazor UI组件(包括Pivot Grid、调度程序、图表、数据编辑器和报表等)。 DevExpress Blazor控件目前已经升级…

蓝队知识浅谈(中)

声明:学习视频来自b站up主 泷羽sec,如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址:蓝队基础之网络七层杀伤链_哔哩哔哩_bilibili 本文主要分享一些蓝队相关的知识。 一、网络杀伤链 网络杀伤链(Cyber Kill Chain&…

【开源免费】基于Vue和SpringBoot的实习管理系统(附论文)

本文项目编号 T 623 ,文末自助获取源码 \color{red}{T623,文末自助获取源码} T623,文末自助获取源码 随着信息化时代的到来,管理系统都趋向于智能化、系统化,实习管理也不例外,但目前国内仍都使用人工管理…

OpenCV基础(2)

1.图像像素与通道操作 1.1.像素算术操作 //加法操作 void cv::add(InputArray src1,InputArray src2,OutputArray dst,InputArray masknoArray(),int dtype-1);//减法操作 void cv::subtract(InputArray src1,InputArray src2,OutputArray dst,InputArray masknoArray(),int …

thinkphp增删查改例子

以下是一个简单的示例,演示如何使用ThinkPHP操作数据库进行增删查改: 增加数据: public function addData(){$data [name > John,age > 25,email > johnexample.com];$result Db::name(user)->insert($data);if($result){ech…