基于STM32设计的自动刹车灯

一、项目介绍

随着科技的发展,人们对低碳环保的认知和需求不断提高。骑自行车既能够低碳环保,又能够锻炼身体,成为了很多人出行的首选。然而,由于自行车本身没有带指示灯,比如刹车指示灯等,所以自行车的安全性并不是很好,如果人们在骑自行车时紧急刹车,后车无法及时判断前方自行车的行为,容易造成交通事故。因此,设计一款自动刹车灯系统具有十分重要的意义。

本项目实现了通过安装ADXL345陀螺仪和四枚LED灯还有STM32F103C8T6主控芯片来实现自行车自动刹车灯的功能。当自行车上安装了该设备后,ADXL345通过IIC通信协议将X,Y,Z三轴的加速度实时值发送给SMT32F103C8T6主控芯片,并结合STM32高级定时器的PWM功能,输出不同占空比的脉冲,控制不同的LED灯输出多种亮度等级,从而控制不同的LED的开关以及明暗,并且通过不同亮度的红光和绿光混合,能够得到黄色的LED灯光。这样,在自行车急刹或者加速时,实时地控制LED灯的亮度和颜色,让后方车辆能够更清楚地了解前方自行车的行为,从而做出快速的反应,保障骑行者以及后车的安全。同时,该系统也能够提高自行车的可见性,并且对于追求低碳环保的人群来说,让自行车既能低碳环保,又能够锻炼身体。

image-20230618184936424

二、设计思路

如果需要下载项目工程,可以去这里:
https://blog.csdn.net/xiaolong1126626497/category_10192120.html

2.1 项目目标

本项目通过安装ADXL345陀螺仪和四枚LED灯还有STM32F103C8T6主控芯片来实现自行车自动刹车灯的功能,使得自行车在急刹或者加速时,实时地控制LED灯的亮度和颜色,提高其可见性,降低交通事故的风险。同时,该系统还能够使自行车既能低碳环保,又能够锻炼身体。

2.2 项目硬件构成

(1)自行车:作为安装系统的物体,需要有一个固定的位置来安装ADXL345陀螺仪和四枚LED灯。

(2)ADXL345陀螺仪:通过IIC通信协议与STM32F103C8T6主控芯片通信,并将X、Y、Z三轴的加速度实时值发送给SMT32F103C8T6主控芯片。

(3)四枚LED灯:使用不同亮度的红光和绿光混合,能够得到黄色的LED灯光。通过控制其亮度和颜色来提高自行车的可见性。

(4)STM32F103C8T6主控芯片:根据接收到的ADXL345数据,结合STN32的高级定时器的PWM功能,输出不同占空比的脉冲,控制不同的LED灯输出多种亮度等级。

2.3 项目功能实现

(1)自行车加速度监测:ADXL345陀螺仪通过IIC通信协议与STM32F103C8T6主控芯片通信,实时地感知自行车的加速度变化。

(2)LED灯亮度和颜色控制:STM32F103C8T6主控芯片运用高级定时器的PWM功能,能够输出不同占空比的脉冲,并控制不同的LED灯输出多种亮度等级,通过不同亮度的红光和绿光混合,能够得到黄色的LED灯光,提高自行车的可见性。

(3)系统安装和调试:需要将ADXL345陀螺仪和四枚LED灯与STM32F103C8T6主控芯片连接起来,并进行系统测试和调试。

三、系统测试

3.1 功能样机安装与焊接

绘制好电路原理图之后,按照原理图将自动刹车灯系统的各个模块安装在事先购买好的洞洞板上,然后用导线将他们连接在一起,最后再焊接在一起,做成完整的自动刹车灯电路板。

image-20230618184608787

3.2 ADXL345模块调试

当上电后,将自动刹车灯电路的串口2外设引脚连接至PC端,将加速度解算后的实际值发送至PC端,通过PC端串口调试助手显示出具体数值,再观察数值是否符合常理。

image-20230618184700297

通过显示的数据信息,可以推测出ADXL345陀螺仪能够正常工作。

3.3 实物调试

最后阶段,将对自行车自动刹车灯进行实物调试,确定其基本功能能够正常实现。

当系统上电后,左右各一枚LED发出低亮黄色灯光,如下图。

image-20230618184801135

静置30S后,所有LED均熄灭,如下图。

image-20230618184825767

当检测到震动后,重新亮起两盏黄色LED灯,如下图。

image-20230618184849795

当检测到刹车时,四枚LED灯均以高亮发出红色灯光,如下图。

image-20230618184910210

结合自行车自动刹车灯的功能需求和实物调试结果,可以发现,调试结果完全符合自动刹车灯的预期功能。

四、代码设计

4.1 主函数

#include "stm32f10x.h"
#include "usart.h"
#include "led.h"
#include "RTC_Time.h" 
#include <stdio.h>
#include "delay.h"
#include "sys.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "adxl345.h"
int main(void)
{u32 flag=0;short x, y, z;float accelerated;LED_GPIO_Config();//初始化LEDUSART2_Config();delay_init(); //延时函数初始化PWM_LED_INIT();   //PWM   PA8-9LED_Init();    //PB7 LED-RPBout(7) = 1;     ADXL345_Init(); //PB 10,11ADXL345_Read_Average(&x, &y, &z, 20);ADXL345_AUTO_Adjust((char *)&x, (char *)&y, (char *)&z);TIM_SetCompare1(TIM1, 50); //设置TIMx捕获比较1寄存器(通道1)值(脉冲宽度)   占空比%20TIM_SetCompare2(TIM1, 50); //设置TIMx捕获比较2寄存器(通道2)值(脉冲宽度)   占空比%20while (1){ADXL345_Read_Average(&x, &y, &z, 5);   //读加速度值accelerated=(x*3.9/1000*9.8);          //加速度实际值printf("X=%4.1f   Y=%4.1f  Z=%4.1f\r\n",accelerated,(y*3.9/1000*9.8),(z*3.9/1000*9.8));while(flag>425){TIM_SetCompare1(TIM1, 0);          //通道2 占空比%0                         TIM_SetCompare2(TIM1, 0);          //通道2 占空比%0 ADXL345_Read_Average(&x, &y, &z, 5);accelerated=(x*3.9/1000*9.8);if(accelerated<-5||accelerated>5) {break;}}flag++; if(accelerated<-4){//四个LED低电平导通		   TIM_SetCompare1(TIM1, 0);            //GREEN不亮                          TIM_SetCompare2(TIM1, 1000);         //RED高亮PBout(7) = 0;	flag=0;    }if(accelerated>0){PBout(7) = 1;TIM_SetCompare1(TIM1, 50);           //RED低亮  TIM_SetCompare2(TIM1, 50);           //GREEN低亮}if(accelerated>5){flag=0; }}	
}

4.2 LED灯控制

#include "led.h"
#include "delay.h"
void LED_GPIO_Config(void)
{	//定义一个GPIO_InitTypeDef 类型的结构体,名字叫GPIO_InitStructure GPIO_InitTypeDef  GPIO_InitStructure;//使能GPIOC的外设时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//选择要用的GPIO引脚		GPIO_InitStructure.GPIO_Pin =GPIO_Pin_13;///设置引脚模式为推免输出模式			 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //设置引脚速度为50MHZGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//调用库函数,初始化GPIOGPIO_Init(GPIOC, &GPIO_InitStructure);
}
void TIME_INIT()
{TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_OCInitTypeDef TIM_OCInitStructure; //根据TIM_OCInitStruct中指定的参数初始化外设TIMxRCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//TIM1定时器初始化  10msTIM_TimeBaseInitStructure.TIM_Period = 999; TIM_TimeBaseInitStructure.TIM_Prescaler = 719;TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);//TIM1的PWM配置	 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitStructure.TIM_Pulse = 0;//设置初始PWM脉冲宽度为0TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //PWM输出使能TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//当定时器计数值小于CCR_Val时为低电平//通道的使能TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //通道1TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC2Init(TIM1, &TIM_OCInitStructure);  //通道2TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);	TIM_ARRPreloadConfig(TIM1, ENABLE);	  //使能TIM1重载寄存器ARRTIM_Cmd(TIM1, ENABLE);                //使能TIM_CtrlPWMOutputs(TIM1, ENABLE);     //高级定时器必须加
}
void PWM_LED_INIT(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);  //GPIOA8,9,10是TIM1的通道1,2,3GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 ;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);TIME_INIT();
}
void LED_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);
}

4.3 adxl345.c

#include "adxl345.h"
#include "sys.h"
#include "delay.h"
#include "math.h"   
u8 ADXL345_Init(void)
{				  IIC_Init();							//初始化IIC总线	if(ADXL345_RD_Reg(DEVICE_ID)==0XE5)	//读取器件ID{  ADXL345_WR_Reg(0X31,0X2B);	//低电平中断输出,13位全分辨率,输出数据右对齐,16g量程 ADXL345_WR_Reg(0X2C,0x0A);		  //数据输出速度为100HzADXL345_WR_Reg(0X2D,0x28);	  //链接使能,测量模式ADXL345_WR_Reg(0X2E,0x00);	//不使用中断		 ADXL345_WR_Reg(0X1E,0x00);ADXL345_WR_Reg(0X1F,0x00);ADXL345_WR_Reg(0X20,0x00);	return 0;}			return 1;	   								  
}   
//写ADXL345寄存器
//addr:寄存器地址
//val:要写入的值
//返回值:无
void ADXL345_WR_Reg(u8 addr,u8 val) 
{IIC_Start();  				 IIC_Send_Byte(ADXL_WRITE);  //发送写器件指令	 IIC_Wait_Ack();	   IIC_Send_Byte(addr);   			//发送寄存器地址IIC_Wait_Ack(); 	 										  		   IIC_Send_Byte(val);     		//发送值					   IIC_Wait_Ack();  		    	   IIC_Stop();						      //产生一个停止条件 	   
}
//读ADXL345寄存器
//addr:寄存器地址
//返回值:读到的值
u8 ADXL345_RD_Reg(u8 addr) 		
{u8 temp=0;		 IIC_Start();  				 IIC_Send_Byte(ADXL_WRITE);	//发送写器件指令	 temp=IIC_Wait_Ack();	   IIC_Send_Byte(addr);   		//发送寄存器地址temp=IIC_Wait_Ack(); 	 										  		   IIC_Start();  	 	   		//重新启动IIC_Send_Byte(ADXL_READ);	//发送读器件指令	 temp=IIC_Wait_Ack();	   temp=IIC_Read_Byte(0);		//读取一个字节,不继续再读,发送NAK 	    	   IIC_Stop();					//产生一个停止条件 	    return temp;				//返回读到的值
}  
//读取ADXL的平均值
//x,y,z:读取10次后取平均值
void ADXL345_RD_Avval(short *x,short *y,short *z)
{short tx=0,ty=0,tz=0;	   u8 i;  for(i=0;i<10;i++){ADXL345_RD_XYZ(x,y,z);delay_ms(10);tx+=(short)*x;ty+=(short)*y;tz+=(short)*z;	   }*x=tx/10;*y=ty/10;*z=tz/10;
} 
//自动校准
//xval,yval,zval:x,y,z轴的校准值
void ADXL345_AUTO_Adjust(char *xval,char *yval,char *zval)
{short tx,ty,tz;u8 i;short offx=0,offy=0,offz=0;ADXL345_WR_Reg(POWER_CTL,0x00);	   	//先进入休眠模式.delay_ms(100);ADXL345_WR_Reg(DATA_FORMAT,0X2B);	//低电平中断输出,13位全分辨率,输出数据右对齐,16g量程 ADXL345_WR_Reg(BW_RATE,0x0A);		//数据输出速度为100HzADXL345_WR_Reg(POWER_CTL,0x28);	   	//链接使能,测量模式ADXL345_WR_Reg(INT_ENABLE,0x00);	//不使用中断		 ADXL345_WR_Reg(OFSX,0x00);ADXL345_WR_Reg(OFSY,0x00);ADXL345_WR_Reg(OFSZ,0x00);delay_ms(12);for(i=0;i<10;i++){ADXL345_RD_Avval(&tx,&ty,&tz);offx+=tx;offy+=ty;offz+=tz;}	 		offx/=10;offy/=10;offz/=10;*xval=-offx/4;*yval=-offy/4;*zval=-(offz-256)/4;	  ADXL345_WR_Reg(OFSX,*xval);ADXL345_WR_Reg(OFSY,*yval);ADXL345_WR_Reg(OFSZ,*zval);	
} 
//读取3个轴的数据
//x,y,z:读取到的数据
void ADXL345_RD_XYZ(short *x,short *y,short *z)
{u8 buf[6];u8 i;IIC_Start();  				 IIC_Send_Byte(0X3A);	//发送写器件指令	 IIC_Wait_Ack();	   IIC_Send_Byte(0x32);   		//发送寄存器地址(数据缓存的起始地址为0X32)IIC_Wait_Ack(); 	 		IIC_Start();  	 	   		//重新启动IIC_Send_Byte(0X3B);	//发送读器件指令IIC_Wait_Ack();for(i=0;i<6;i++){if(i==5)buf[i]=IIC_Read_Byte(0);//读取一个字节,不继续再读,发送NACK  else buf[i]=IIC_Read_Byte(1);	//读取一个字节,继续读,发送ACK delay_us(15);IIC_Start();  	 	   		//重新启动IIC_Send_Byte(0X3A);	//发送写器件指令IIC_Wait_Ack();	IIC_Send_Byte(0x33+i);   		//发送寄存器地址(数据缓存的起始地址为0X32)IIC_Wait_Ack(); 	 		IIC_Start();  	 	   		//重新启动IIC_Send_Byte(0X3B);	//发送读器件指令IIC_Wait_Ack();}	        	   IIC_Stop();					//产生一个停止条件*x=(short)(((u16)buf[1]<<8)+buf[0]); 	    *y=(short)(((u16)buf[3]<<8)+buf[2]); 	    *z=(short)(((u16)buf[5]<<8)+buf[4]); 	   
}
//读取ADXL345的数据times次,再取平均
//x,y,z:读到的数据
//times:读取多少次
void ADXL345_Read_Average(short *x,short *y,short *z,u8 times)
{u8 i;short tx,ty,tz;*x=0;*y=0;*z=0;if(times)//读取次数不为0{for(i=0;i<times;i++)//连续读取times次{ADXL345_RD_XYZ(&tx,&ty,&tz);*x+=tx;*y+=ty;*z+=tz;delay_ms(5);}*x/=times;*y/=times;*z/=times;}
}
//得到角度
//x,y,z:x,y,z方向的重力加速度分量(不需要单位,直接数值即可)
//dir:要获得的角度.0,与Z轴的角度;1,与X轴的角度;2,与Y轴的角度.
//返回值:角度值.单位0.1°.
short ADXL345_Get_Angle(float x,float y,float z,u8 dir)
{float temp;float res=0;switch(dir){case 0://与自然Z轴的角度temp=sqrt((x*x+y*y))/z;res=atan(temp);break;case 1://与自然X轴的角度temp=x/sqrt((y*y+z*z));res=atan(temp);break;case 2://与自然Y轴的角度temp=y/sqrt((x*x+z*z));res=atan(temp);break;}return res*1800/3.14;
}

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

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

相关文章

Scala编程语言入门教程

Scala教程 方便个人学习和查阅 学习目标 Scala介绍 简介 Scala创始人Martin Odersky马丁奥德斯基 再回到我们的scala语言&#xff0c;在Scala官网https://www.scala-lang.org/介绍了其六大特征。 Java和scala可以混编 类型推测(自动推测类型) 并发和分布式&#xff08;Ac…

AcWing 4310:树的DFS ← vector、auto、邻接表

【题目来源】https://www.acwing.com/problem/content/description/4313/【题目描述】 给定一棵 n 个节点的树。 节点的编号为 1∼n&#xff0c;其中 1 号节点为根节点&#xff0c;每个节点的编号都大于其父节点的编号。 现在&#xff0c;你需要回答 q 个询问。 每个询问给定两…

RabbitMQ(二)

二、高级特性、应用问题以及集群搭建 高级特性 1.消息的可靠性投递 在使用RabbitMQ的时候&#xff0c;作为消息发送方希望杜绝任何消息丢失或者投递失败场景。RabbitMQ 为我们提供了两种方式用来控制消息的投递可靠性模式。 rabbitMQ整个消息投递的路径为&#xff1a; produ…

springCache-缓存

SpringCache 简介&#xff1a;是一个框架&#xff0c;实现了基于注解的缓存功能&#xff0c;底层可以切换不同的cache的实现&#xff0c;具体是通过CacheManager接口实现 使用springcache,根据实现的缓存技术&#xff0c;如使用的redis,需要导入redis的依赖包 基于map缓存 …

简述静态网页和动态网页的区别。简述 Webl.0 和 Web2.0 的区别。安装tomcat8,配置服务启动脚本,部署jpress应用

静态网页和动态网页区别 静态网页和动态网页是两种常见的网页类型&#xff0c;它们在内容生成和交互方式上存在不同。 静态网页是在服务器上提前生成好的网页&#xff0c;它的内容在访问时不会发生变化。静态网页通常由HTML、CSS和JavaScript等静态文件组成&#xff0c;这些文…

无涯教程-Perl - bless函数

描述 此函数告诉REF引用的实体,它现在是CLASSNAME包中的对象,如果省略CLASSNAME,则为当前包中的对象。建议使用bless的两个参数形式。 语法 以下是此函数的简单语法- bless REF, CLASSNAMEbless REF返回值 该函数返回对祝福到CLASSNAME中的对象的引用。 例 以下是显示其…

Python web实战之 Django 的模板语言详解

关键词&#xff1a; Python、web开发、Django、模板语言 概要 作为 Python Web 开发的框架之一&#xff0c;Django 提供了一套完整的 MVC 模式&#xff0c;其中的模板语言为开发者提供了强大的渲染和控制前端的能力。本文介绍 Django 的模板语言。 1. Django 模板语言入门 Dj…

【Android】控件与布局入门 - 简易计算器

目录 1. 基础开发环境 2. 计算器的布局和相关按钮 3. 计算器的主要运算逻辑 4. APK 文件 5. 项目源码 1. 基础开发环境 JDK&#xff1a;JDK17 Android Studio&#xff1a;Android Studio Giraffe | 2022.3.1 Android SDK&#xff1a;Android API 34 Gradle: gradle-8.0-bi…

【Nginx基础】Nginx基础及安装

目录 Nginx出现背景Nginx 概念Nginx 作用Http 代理&#xff0c;反向代理负载均衡&#xff1a;内置策略和扩展策略内置策略&#xff1a;轮询内置策略&#xff1a;加权轮询内置策略&#xff1a;IP hash 动静分离 安装 NginxWindows下安装&#xff08;nginx-1.16.1&#xff09;Lin…

计算机毕设 深度学习实现行人重识别 - python opencv yolo Reid

文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉…

EtherCAT转Profinet网关连接西门子PLC与凯福科技总线步进驱动器通讯

西门子S7-1200/1500系列的PLC&#xff0c;采用Profinet实时以太网通讯协议&#xff0c;需要连接带EtherCAT的通讯功能的伺服驱动器等设备&#xff0c;就必须进行通讯协议转换。捷米特JM-EIP-RTU系列的网关提供了&#xff0c;快速可行的解决方案 捷米特JM-ECTM-PN在PROFINET一侧…

Linux下进程的特点与环境变量

目录 进程的特点 进程特点的介绍 进程时如何实现并发性的 进程间如何切换 概念铺设 PC指针 上下文 环境变量 PATH 修改PATH HOME SHELL env 命令行参数 什么是命令行参数&#xff1f; 打印命令行参数 通过函数获得环境变量 getenv 命令行参数 env 修改环境变…

Linux从安装到实战 常用命令 Bash常用功能 用户和组管理

1.0初识Linux 1.1虚拟机介绍 1.2VMware Workstation虚拟化软件 下载CentOS; 1.3远程链接Linux系统 &FinalShell 链接finalshell半天没连接进去 他说ip adress 看IP地址是在虚拟机上 win11主机是 终端输入&#xff1a; ifconfig VMware虚拟机的设置 & ssh连接_snge…

[Pytorch]卷积运算conv2d

文章目录 [Pytorch]卷积运算conv2d一.F.Conv2d二.nn.Conv2d三.nn.Conv2d的运算过程 [Pytorch]卷积运算conv2d 一.F.Conv2d torch.nn.functional.Conv2d()的详细参数&#xff1a; conv2d(input: Tensor, weight: Tensor, bias: Optional[Tensor]None, stride: Union[_int, _s…

如何在 Android 上恢复已删除的视频|快速找回丢失的记忆

想知道是否有任何成功的方法可以从 Android 手机中检索已删除的视频&#xff1f;好吧&#xff0c;本指南将向您展示分步说明&#xff0c;让您轻松从手机中找回丢失的视频文件&#xff01; 您是否不小心从 Android 智能手机中删除了珍贵的生日视频&#xff1f;难道是无处可寻吗…

【计算机视觉|语音分离】期望在嘈杂环境中聆听:一个用于语音分离的不依赖于讲话者的“音频-视觉模型”

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;Looking to Listen at the Cocktail Party: A Speaker-Independent Audio-Visual Model for Speech Separation 链接&#xff1a;Looking to listen at the cocktail party: a speaker-in…

驱动工作原理

驱动原理 在Linux操作系统中&#xff0c;硬件驱动程序中实现对硬件直接操作&#xff0c;而用户空间&#xff0c;通过通用的系统调用接口&#xff08;open() 打开相应的驱动设备,ioctl()控制相应的功能等&#xff09;&#xff0c;实现对硬件操作&#xff0c;应用程序没有直接操作…

MySQL事务管理

MySQL事务管理 MySQL增删查改时的问题一.什么是事务&#xff1f;二.为什么会出现事务&#xff1f;三.事务的其他属性1. 事务的版本支持2. 事务的提交方式 四.事务的准备工作五.事务的操作1. 事务的正常操作2. 事务的异常验证与产出结论 六.事务的隔离级别1. 事务隔离级别概念2.…

Linux-centos花生壳实现内网穿透

Linux-centos花生壳实现内网穿透 官网教程 1.安装花生壳 下载网址 点击复制就可以复制下载命令了 wget "https://dl.oray.com/hsk/linux/phddns_5.2.0_amd64.rpm" -O phddns_5.2.0_amd64.rpm# 下载完成之后会多一个rpm文件 [rootlocalhost HuaSheng]# ls phddns_…

ios_base::out和ios::out、ios_base::in和ios::in、ios_base::app和ios::app等之间有什么区别吗?

2023年8月2日&#xff0c;周三晚上 今天我看到了这样的两行代码&#xff1a; std::ofstream file("example.txt", std::ios_base::out);std::ofstream file("example.txt", std::ios::out);这让我产生了几个疑问&#xff1a; 为什么有时候用ios_base::o…