蓝桥杯STM32G431RBT6-各个外设的配置过程

news/发布时间2024/8/25 9:38:36

  LED,按键

  配置LED点亮,按键采集按键值

   

  前期准备:通过Cubemx生成一个源文件方便后续直接使用。

 

 

源文件准备完毕以后开始进行按键和LED的配置

LED  

  对比芯片引脚连接图可以知道8个LED分别连接在GPIOC的如下8个引脚中   

    

 

  Cubemx中对该8个引脚进行配置,分别配置为推挽输出模式,初始电平设置为高电平(保证初始化时LED是熄灭的),LE作为锁存器(由于部分引脚与LCD共用而引入的设计)

  

   将gpio.c中生成的代码拷贝到LED的初始化函数中

void BSP_LED_Init()
{GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOF_CLK_ENABLE();__HAL_RCC_GPIOD_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOC, LED6_Pin|LED7_Pin|LED8_Pin|LED1_Pin|LED2_Pin|LED3_Pin|LED4_Pin|LED5_Pin, GPIO_PIN_SET);/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(LED_Cmd_GPIO_Port, LED_Cmd_Pin, GPIO_PIN_RESET);/*Configure GPIO pins : PCPin PCPin PCPin PCPinPCPin PCPin PCPin PCPin */GPIO_InitStruct.Pin = LED6_Pin|LED7_Pin|LED8_Pin|LED1_Pin|LED2_Pin|LED3_Pin|LED4_Pin|LED5_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);/*Configure GPIO pin : PtPin */GPIO_InitStruct.Pin = LED_Cmd_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(LED_Cmd_GPIO_Port, &GPIO_InitStruct);}

 

  接下来写一个LED点亮函数来点亮LED(这里以点亮LED1,LED2为例子)  -  蠢方法,能用就行

 HAL_GPIO_WritePin(GPIOC, LED6_Pin|LED7_Pin|LED8_Pin|LED4_Pin|LED5_Pin, GPIO_PIN_SET);HAL_GPIO_WritePin(LED_Cmd_GPIO_Port, LED_Cmd_Pin, GPIO_PIN_SET);HAL_GPIO_WritePin(LED_Cmd_GPIO_Port, LED_Cmd_Pin, GPIO_PIN_RESET);if(LED == 1){if(Mode){HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);}else{HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);}}else if(LED == 2){if(Mode){HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);}else{HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);}}else if(LED == 3){if(Mode){HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_RESET);}else{HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_SET);}}HAL_GPIO_WritePin(LED_Cmd_GPIO_Port, LED_Cmd_Pin, GPIO_PIN_SET);HAL_GPIO_WritePin(LED_Cmd_GPIO_Port, LED_Cmd_Pin, GPIO_PIN_RESET);

 

按键KEY

  同LED去对比引脚情况得到Key的引脚如下

  

  

  利用Cubemx将对应引脚配置为输入模式  

  

  生成gpio中的代码,保留其中和按键有关的初始化配置到按键的初始化函数中

void BSP_Key_Init()
{GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();/*Configure GPIO pin : PtPin */GPIO_InitStruct.Pin = Key4_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(Key4_GPIO_Port, &GPIO_InitStruct);/*Configure GPIO pins : PBPin PBPin PBPin */GPIO_InitStruct.Pin = Key1_Pin|Key2_Pin|Key3_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);}

 

再写一个按键获取的函数(利用延时来消抖是一个贪图方便的做法,有更好的办法则代替它,顺便告诉我.......)

enum {Key1 = 1,Key2,Key3,Key4};
uint8_t Key_Get()
{uint8_t Temp = 0;    //声明一个临时变量用来获取后返回if(HAL_GPIO_ReadPin(GPIOB,Key1_Pin) == 0 ){Temp = Key1;HAL_Delay(100);}if(HAL_GPIO_ReadPin(GPIOB,Key2_Pin) == 0 ){Temp = Key2;HAL_Delay(100);}if(HAL_GPIO_ReadPin(GPIOB,Key3_Pin) == 0 ){Temp = Key3;HAL_Delay(100);}if(HAL_GPIO_ReadPin(Key4_GPIO_Port,Key4_Pin) == 0 ){Temp = Key4;HAL_Delay(100);}return Temp;}

 

 

 在h文件里声明以后去main函数中测试

int main(void)
{HAL_Init();SystemClock_Config();// MX_GPIO_Init();BSP_LED_Init();        //初始化LED
    BSP_Key_Init();#ifdef LED_DEBUGLED_On(1,1);    //点亮LED1LED_On(2,1);    //点亮LED2#endif while (1){#ifdef KEY_DEBUGuint8_t temp = Key_Get();if(temp == 1)LED_On(1,1);    //点亮LED1else if(temp == 2)LED_On(2,1);    //点亮LED2else if(temp == 0){LED_On(1,0); LED_On(2,0);    }#endif}/* USER CODE END 3 */
}

  现象应该是按下按键1之后点亮,松开则会熄灭,按键2同理。

 

2024.3.1更新  非阻塞延时以及按键消抖

  按键消抖:  --在Key_Get()中使用了HAL_DELAY()函数来作为按键消抖,但事实上这种效果并不好...,在此基础上新添加一个函数通过判断按键按下和按键松开两个状态解决问题

  先定义变量值Old_Key和Cur_Key来接收按键的状态。再定义Key_Down,Key_Up作为返回变量。

  1. Cur_Key 采集按键按下的值

CKey_Value = BSP_KEY_Getnum();

  2.将Cur_Key 和 (Cur_Key 与Old_Key异或后的结果)相与后将结果赋值给Key_Down

  3将Cur_Key取反后 和 (Cur_Key 与Old_Key异或后的结果)相与后将结果赋值给Key_Up

   Key_Down   = CKey_Value & (CKey_Value ^ OKey_Value);Key_Up     = ~CKey_Value & (CKey_Value ^ OKey_Value);

  4最后将Cur_Key 的值赋值给Old_Key

 OKey_Value = CKey_Value;

  5返回Key_Down/Key_Up作为判断依据

return Key_Up;

 

  非阻塞延时  -  为了实现非阻塞延时,我们利用uwTick和某个变量相减的值判断该轮回是否执行函数

  1.先定义一个32位的变量来接收uwTick的值

uint32_t Key_Tick;

  2判断(uwTick - 变量值)< 100(某个时间)是否成立 。 

  3如果成立,则直接返回,本论不执行代码

  4如果不成立,则将uwTick的值赋给变量以供下一个轮回使用

if( (uwTick - Key_Tick)<100 )    return 0;elseKey_Tick = uwTick;

  5结果就是前99ms不阻塞直接返回,不执行代码,直到第100ms条件不成立时后续代码才会执行。好处就是不会因为延时干扰到其它模块的运行

完整代码如下

uint8_t _Key_Get()
{//延时执行函数 每3s才能执行一次//如何利用uwTick实现部分函数的延时//首先定义一个32位的变量接收值//用(uwTick-变量值)<某个时间    成立则直接返回,本轮回不执行该代码。不成立则本次执行该代码并将uwTick的值赋给变量值if( (uwTick - Key_Tick)<100 )    return 0;elseKey_Tick = uwTick;//如何实现按键消抖//设立一个旧值和新值。首先,新值采集采集到的按键值//然后为了得到按下的命令,将新值和(新值与旧值异或处理后的结果)相与得到结果。//为了得到松开的命令,将新值取反以后和旧值和新值异或后的结果相与得到结果。
    CKey_Value = BSP_KEY_Getnum();Key_Down   = CKey_Value & (CKey_Value ^ OKey_Value);Key_Up     = ~CKey_Value & (CKey_Value ^ OKey_Value);OKey_Value = CKey_Value;return Key_Up;}

/************************************************************************************************************************/

  3.3日更新  关于长短按  ------这个破方法没法解决长按和短按分开的问题..............

由于在第14届中需要在DATA界面处理长按的需求,所以加入了一些代码

uint32_t Key_tick;uint8_t __Key_Get()
{if( (uwTick - Key_tick)<100 )  return 0;elseKey_tick =  uwTick ;uint8_t Temp= 0;if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin) == 0){Temp = KEY1;} if(HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin) == 0){Temp = KEY2;} if(HAL_GPIO_ReadPin(KEY3_GPIO_Port,KEY3_Pin) == 0){Temp = KEY3;} if(HAL_GPIO_ReadPin(KEY4_GPIO_Port,KEY4_Pin) == 0){Temp = KEY4;if(LCD_Mode == DATA){uint16_t Key_Tick=0;while(HAL_GPIO_ReadPin(KEY4_GPIO_Port,KEY4_Pin) == 0) {Key_Tick++;}  //判断长按时间if(Key_Tick >= 2000)  //时间超过2s{Temp = KEY4_1; Key_Tick = 0; }  //确定为长按}} return Temp;}

 

 综上,如果有长短按的需求/其它需求,就用第一种方法。如果没有的话两种方法都可以

 

/*********************************************************************************************************************/

接下来是串口配置

  模式我们选择异步(Asyno....)串口时钟模式,它适用于大多数情况,即UART。同步时钟(syno....)要求发送和接收处于同一个时钟下即时间同步,条件比较苛刻但传输速率似乎也更快

    

   配置好需要的各项参数如波特率,字长,校验位,停止位...........(其实这里根本不需要修改)

  

 

  打开串口中断,并在NVIC(中断管理)中设置优先级为3

  

 

  当然,如果此时对应引脚没有选择正确模式的话还需要自己去设置(这一点经常被忘记)  

       

   一切安排妥当后生成代码

  这时串口的初始化已经配置完毕了,剩下的就是串口接收中断的实现(针对不同的需要选择不同的中断方式,如接收中断,空闲中断等等)

  在红线标识都文件中找到串口的中断函数

  

  在红线标识都文件中找到串口的中断函数

void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 *//* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 *//* USER CODE END USART1_IRQn 1 */
}

在串口中断函数中我们去寻找中断回调函数HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart),我们将重写回调函数(注意不要找错了)

首先在usart.c中先声明4个全局变量来保存接收的数据和表示串口状态并将变量声明为外部变量(方便后续其它模块和串口数据联动)

uint8_t Rx_Str[255]={0};  //接收区
uint8_t Rx_Char=0;      //接收缓存区
uint8_t Rx_Count=0;      //接收数量
uint8_t Rx_Flag=0;      //接收完成标志位

 

然后在main.c中初始化串口之后打开串口接收中断

 

MX_USART1_UART_Init();    //串口初始化
HAL_UART_Receive_IT(&huart1,&Rx_Char,1);    //开启串口中断,接收数据保留在缓冲区中

  

在中断函数中处理接收到的串口数据

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance==USART1){Rx_Str[Rx_Count] = Rx_Char;  //如果Rx_Count在这里累加的话,到后面你会神奇的发现1234567890会输出0123456789,(因为最后一个字符没有接收到Rx_Count就已经在这里自增到10了。导致它成为了下一次的第一个数据)if(Rx_Count++ == 10)    //根据接收的不同选择不同的结束方式    ---这里接收10个字符后结束  //数据在判断前最好不要被更改,记住这条编程规范
         {Rx_Flag = 1;Rx_Count = 0;}}if(Rx_Flag == 1){    Rx_Flag = 0;printf("接收到的数据为%s\r\n",Rx_Str);        //这里对Printf进行了重定向,使其通向串口,后面会说明memset(Rx_Str,0,sizeof(Rx_Str)); }HAL_UART_Receive_IT(&huart1,&Rx_Char,1);    //再次开启接收中断
}//不定量接收void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){if(huart->Instance == USART1){Rec_Str[Rec_Count] = Rec_char;  if( Rec_Str[Rec_Count] == '\n')  //利用\r\n判断结束Rec_Flag = 1;     elseRec_Count++;HAL_UART_Receive_IT(&huart1,&Rec_char,1);}if(Rec_Flag == 1){Rec_Flag = 0;Rec_Count = 0;printf("%s\r\n",Rec_Str);}}

 

  关于printf的重定向

  在usart.c中补充该函数,记住要在配置中勾选如下选项才能使用

//printf重定向
//关于该函数:我推测该函数应该是printf用来向标准输出流输送字符的一个子函数。---没有看过源码.............
int fputc(int c,FILE* stream) {HAL_UART_Transmit(&huart1,(uint8_t *)&c,1,10);return c; }

 

 

  再来看IIC

 

  由于蓝桥杯比赛中IIC是用在驱动24c02闪存芯片的,且已经提供了IIC文件,所以这里不讲如何写IIC,只讲怎么在24c02中用。

 

  将赛方提供的IIC文件移植进来

    

  24c02的初始化直接用给的IIC_Init即可

void BSP_24c02_Init()
{I2CInit();
}

  24c02有写入/读取字节的操作,对应的函数如下

//向指定地址中读取字节
/*
Data_Addr:接收缓冲区
Target_Addr:要读取的目标地址
Count:读取总字节数
*/
void BSP_24c02_Read(uint8_t* Data_Addr,uint8_t Target_Addr,uint8_t Count)
{I2CStart();        //iic通信的基本操作,开始和结束....非常容易忘,后果也非常严重....(上次整整一个下午没找出这个DEBUG)
    I2CSendByte(0xa0);    //24c02写入操作码I2CWaitAck();        //这里我贪方便没有测试应答是否成功,正确做法应该是用状态机来执行这个过程I2CSendByte(Target_Addr);    //为了实现地址偏移
    I2CWaitAck();    I2CStart();        //重新开始I2CSendByte(0xa1);    //24c02读取操作码
    I2CWaitAck();while(Count){
    //先接收数据再应答
*Data_Addr++ =I2CReceiveByte(); //Count不为0接收字节if(--Count){ I2CSendAck();}elseI2CSendNotAck(); //非应答 }I2CStop();}

写入操作

void BSP_24c02_Write(uint8_t* Data_Addr,uint8_t Target_Addr,uint8_t Count)
{I2CStart();        //iic通信的基本操作,开始和结束....非常容易忘,后果也非常严重....(上次整整一个下午没找出这个DEBUG)
    I2CSendByte(0xa0);    //24c02写入操作码I2CWaitAck();        //这里我贪方便没有测试应答是否成功,正确做法应该是用状态机来执行这个过程I2CSendByte(Target_Addr);    //发送要写入的地址
    I2CWaitAck();while(--Count){
     //先接收/发送数据再应答I2CSendByte(
*Data_Addr++);I2CWaitAck();}I2CStop();HAL_Delay(500);}
//测试代码,测试结果
void
_24c02_Test() {BSP_24c02_Write(W_str_Test,0,5);BSP_24c02_Read(R_str_Test,0,5);//后面用LCD测试uint8_t LCD_str[255];sprintf((char *)LCD_str,"W_Str %x:%x:%x:%x:%x",W_str_Test[0],W_str_Test[1],W_str_Test[2],W_str_Test[3],W_str_Test[4]); //%x:显示16进制数 LCD_DisplayStringLine(Line2,LCD_str);sprintf((char *)LCD_str,"R_Str %x:%x:%x:%x:%x",R_str_Test[0],R_str_Test[1],R_str_Test[2],R_str_Test[3],R_str_Test[4]);LCD_DisplayStringLine(Line3,LCD_str);}

 

 

 

  LCD塞方也已经提供了需要的HAL文件,也只需要知道如何用就行

  将赛方提供的HAL文件移植进来

  

  初始化,并配置黑底白字

LCD_Init();LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);

  测试显示效果

  #ifdef LCD_DEBUGLCD_Clear(Black);uint8_t LCD_STR[255]="LCD test";LCD_DisplayStringLine(Line1,LCD_STR);#endif

  

 定时器相关

  RTC配置

  

  勾选这两个选项开启时钟源和日历

 

  选择二进制形式保存并将时间写入  

  

 

  生成代码文件rtc.c/h

  然后在rtc.c中定义两个结构体变量来保存时间和日期

RTC_DateTypeDef Date01;   //日期结构体
RTC_TimeTypeDef Time01;   //时间结构体

  调用库函数来获取时间并显示在LCD上效果如下 

void MyRTC_GetTime()
{HAL_RTC_GetTime(&hrtc,&Time01,RTC_FORMAT_BIN);HAL_RTC_GetDate(&hrtc,&Date01,RTC_FORMAT_BIN);uint8_t RTC_STR[255];sprintf((char *)RTC_STR,"cur Time:%02d:%02d:%02d",Time01.Hours,Time01.Minutes,Time01.Seconds);LCD_DisplayStringLine(Line4,RTC_STR);
}

 

  TIM  -  脉冲捕获

  根据蓝桥杯板子的引脚设计,信号发生器通过PA15输出脉冲信号。我们选用TIM2(PA15)来对输入脉冲进行捕获  

  

  

  先设置从模式为复位模式,触发信号为TF1FP1(即每次捕获到该通道信号时计数器会复位),时钟源选择内部时钟。两个通道一个直接捕获,一个间接捕获(....我不清楚是什么意思,求解答)

  

  关于TI1FP1  ---从我练习的情况来看这里是选择通道的意思,就比如上面,如果主要通道是通道1,就选择TI1FP1,如果主要通道是通道2,就选择TI2FP2。

  如果你只是需要一个通道来单独测量频率,那么选择对应的通道即可

  

 这里我选择了通道2来捕获,所以选择TI2FP2

 

 

  下面通道配置,一个通道捕获上升沿,一个通道捕获下降沿  

  

  开启中断并更改中断优先级  

  

  注意!!!一定要确保GPIO口已经配置好了,不然搞半天跟没搞一样。  

  

 

 

   生成tim.c/h文件后,去定时中断函数中找到输入捕获的回调函数

  

在中断函数中找输入捕获中断函数

 重写输入捕获回调函数

 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM2){if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){Cap_T_count =  HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1)+1;Duty =  (float)Cap_R_count/Cap_T_count;}if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2){Cap_R_count = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2)+1;}}}

main函数中执行初始化,开启时基单元,打开中断

    MX_TIM2_Init();HAL_TIM_Base_Start(&htim2);HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);

写测试代码

#ifdef TIM_IC_DEBUG    sprintf(IC_STR,"Cap count is:%d",Cap_T_count);LCD_DisplayStringLine(Line8,(uint8_t *)IC_STR);sprintf(IC_STR,"PWM1:%05dHz , %4.1f%%",(1000000/Cap_T_count),Duty * 100);  //频率和占空比LCD_DisplayStringLine(Line5,(uint8_t *)IC_STR);#endif

 

 

 

  TIM  -  PWM输出

  我这里选择PA7作为输出通道,即TIM17的通道1输出PWM(频率为2000HZ,占空比50%)  //80M/80/500 = 2khz 

        

 

生成tim.c后执行tim17初始化后开启PWM输出即可

    MX_TIM17_Init();HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);

 

这里利用了前面的脉冲捕获来确认波形

 

输出比较

  首先,先选择对应的引脚,设置为定时器输出比较

  

选择内部时钟,输出模式选择输出比较模式

 

 设置预分频值和比较值,模式选择Toggle on match 到达比较值时翻转电平来输出方波

 开启中断

 生成代码tim.c后前往中断函数里寻找TIM3输出比较的回调函数

void TIM3_IRQHandler(void)
{
HAL_TIM_IRQHandler(&htim3);

}

在输出回调函数里重新设置新的比较值

void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM3 ){if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){__HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1,  __HAL_TIM_GET_COMPARE(htim, TIM_CHANNEL_1)+200);  //1000000/(200*2)=2500hz的方波}}
}

main函数中初始化定时器并开启定时器的输出比较

MX_TIM3_Init();HAL_TIM_OC_Start_IT(&htim3,TIM_CHANNEL_1);

  

  

  ADC采集

  

  根据开发板的引脚图选择PB15作为ADC采集的端口

  对应ADC2的通道15  

  选择独立模式,异步时钟2分频  

  

 

  生成代码adc.c/h

  定义一个ADC采集函数,调用库函数启动ADC,然后获取ADC的值并显示在LCD屏幕上

 void MyADC_Get()   {HAL_ADC_Start(&hadc2);ADC_Value = HAL_ADC_GetValue(&hadc2);uint8_t ADC_STR[255];sprintf((char *)ADC_STR,"CUR ADC:%d",ADC_Value);LCD_DisplayStringLine(Line6,ADC_STR);}

 

 

 

 

 

 

 

   

 

  

 

 

 

 

 

 

 

 

 

  

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

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

相关文章

高级项目管理

4、六西格玛认为业务流程改进遵循5步循环改进法,即 DMAIC模式:定义、度量、分析、改进、控制。(1)定义(Define):识别需要改进的产品或过程,确定改进项目所需的资源。(2)度量(Measure):定义缺陷,收集产品或过程的表现作为工作基准,建立改进目标。(3)分析(Analy…

python爬虫—学习笔记-3

python爬虫—学习笔记-3 ps:因为本人近一个月住院,文章为队友所著。 此次学习内容为如何搭建服务器 1.打开pycharm,创建目录server在设置中的Python解释器中安装Flask2.在创建的server1中输入本节课所学代码在网页中输入ip 端口号 子目录 本机访问127.0.0.1:5000/子目录 外…

python 使用waitress替代flask自带的web服务器

首席引入依赖安装waitrss pip intsll waitress然后在flask程序内引入依赖 使用server()函数代替app.run()函数 启动时,直接python xxx.py即可from waitress import serve from flask import Flask app = Flask(__name__)@app.route(/) def hello_world(): return Hello Wo…

sy3

一、任务详情 密码引擎API的主要标准和规范包括: 1 微软的Crypto API 2 RAS公司的PKCS#11标准 3 中国商用密码标准:GMT 0016-2012 智能密码钥匙密码应用接口规范,GMT 0018-2012密码设备应用接口规范等 研究以上API接口,总结他们的异同,并以龙脉GM3000Key为例,写出调用不同…

发布一个自己的composer包

首先我们创建一个空的目录,并且运行以下命令初始化一个空白的composer包 composer init可以在命令窗口看到有返回提示; 需要输入包名 This command will guide you through creating your composer.json config.` Package name (<vendor>/<name>) :我这里写的是c…

读所罗门的密码笔记15_数据透明度

读所罗门的密码笔记15_数据透明度1. 数据透明度与控制权 1.1. 作为人类,我们会带有偏见,而且往往不知道自己在智力和情感上的盲区 1.2. 精心制作的人工智能机器,即使有自己的缺点,也能帮助我们做出更客观的决定,为提升我们的生活质量和改善社区的生态环境做出贡献 1.3. 美…

QAT量化感知训练

QAT量化感知训练 基本原理 相比训练后量化因为其不是全局最优而导致的精度损失,QAT量化感知训练能做到基于loss优化的全局最优,而尽可能的降低量化精度损失,其基本原理是:在fp32模型训练中就提前引入推理时量化导致的权重与激活的误差,用任务loss在训练集上来优化可学习的…

树状数组快速入门

树状数组、 Fenwick Tree 或 Binary Indexed Tree ,通常用缩写 BIT 代表。 是一种 “一种基于二进制 lowbit ,用于维护(加法、位运算、max、gcd 的)前缀和的树形数组” 。 可以叫做 一个树状数组 或 一棵 Fenwick Tree 。 重要性质:同时满足即是数组又是树的性质。针对定义…

蓝桥杯2020年C组-试题I-数字三角形(简化版-少一个左右路径差不大于1条件)

1. 题目介绍上图给出了一个数字三角形。 从三角形的顶部到底部有很多条不同的路径。 对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。 路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右边的那个数。 输入格式 输入的第一行包…

e/易语言 按钮界面弹出气泡提示

案例本文来自博客园,作者:__username,转载请注明原文链接:https://www.cnblogs.com/code3/p/18125232

Linux安装JDK详细教程

Linux安装JDK详细教程(图文教程) 这里介绍两种方式:yum安装方式和手动安装1、yum安装 1.1 查看JDK版本,找到你想要安装的JDK版本,这里以 JDK1.8 为例 输入命令:yum -y list java*1.2 安装JDK1.8 输入命令:yum install -y java-1.8.0-openjdk.x86_64 没权限执行这行:sud…

查询下属

win +R 键sqlplus1 用户名:scott密码 :tigerselect * from emp;select * from dept;select ename,sal,comm from emp;select ename,sal+nvl(comm,0) from emp;select ename,12*(sal+nvl(comm,0))年薪 from emp;1 select empno from emp where ename=upper(king);2 select …

PHP代码审计——Day7-Bells

漏洞解析 function getUser($id) {global $config, $db;if (!is_resource($db)) {$db = new MySQLi($config[dbhost],$config[dbuser],$config[dbpass],$config[dbname]);}$sql = "SELECT username FROM users WHERE id = ?";$stmt = $db->prepare($sql); // 调用…

【每周例题】蓝桥杯 C++ 多数

多数元素 题目 多数元素思路分析一 .第一个想法,暴力遍历,然后会发现容易超时,那么更进一步想:哈希表使用哈希表存储每个数出现的次数,即使用哈希映射(HashMap)来存储每个元素以及出现的次数。对于哈希映射中的每个键值对,键表示一个元素,值表示该元素出现的次数 加入…

Python函数

一、函数定义以及作用 函数/方法/function(功能):函数是组织好的,可重复使用的,用来实现单一或相关联功能的代码段(块)。函数能提高应用的模块性和代码的重复利用率。比如我们天天使用的函数print(),这个就是函数(一个Python内置的函数)。也可以自己创建函数,这类函数…

linux环境安装——kafka安装复习

需要安装jdk、zk;然后才是kafkakafka版本:kafka_2.13-3.2.3.tgz[root@iZf8zi6zcbssmm6c2nrhapZ /]# ls -alt total 84 drwxrwxrwt. 9 root root 4096 Apr 9 14:42 tmp drwxr-xr-x 7 root root 4096 Apr 9 14:38 soft drwxr-xr-x 7 root root 4096 Apr 9 14:38 …

中间件漏洞攻防学习总结

Apache(阿帕奇)是世界使用排名第一的Web服务器软件。它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一。 此漏洞的出现是由于 apache 在修复第一个后缀名解析漏洞时,用正则来匹配后缀。在解析 php 时 xxx.php\x0A…

若依RuoYi-Vue代码生成,新建一个增删改查模块

启动ruoyi-ui,登录前端后台 以cti_faq 问答对表 为例。首先在 mysql数据库 中建张 cti_faq 表CREATE TABLE `cti_faq` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 编号,`question` varchar(255) DEFAULT NULL COMMENT 问题内容,`answer` text COMMENT 答案内容,`category…

【攻防实操系列+域渗透】--安装域控(Windows-Server-2008-R2-x64)教程

1.创建windows 2008 R2 虚拟机选完全安装。 第一个是标准版功能很少。不建议选。 另外两个任意选。 我选的是Enterprse企业版。❗❗❗注意:需要提前了解域控的密码复杂度规则。 密码一定要自己记住!!! 密码①可以看到界面非常小,不方便操作。 ❗❗❗需要安装vm tools,详细…
推荐文章