首页 > 其他分享 >蓝桥杯STM32G431RBT6-各个外设的配置过程

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

时间:2024-04-10 18:55:39浏览次数:19  
标签:HAL Pin STM32G431RBT6 蓝桥 TIM Key GPIO LED 外设

  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 PCPin
                           PCPin 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_DEBUG
          LED_On(1,1);    //点亮LED1
          LED_On(2,1);    //点亮LED2
    #endif 
    
  while (1)
  {
    #ifdef KEY_DEBUG
        uint8_t temp = Key_Get();
        if(temp == 1)
          LED_On(1,1);    //点亮LED1
        else if(temp == 2)
          LED_On(2,1);    //点亮LED2
        else 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;
    else
        Key_Tick = uwTick;

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

完整代码如下

uint8_t _Key_Get()
{
    //延时执行函数 每3s才能执行一次
    //如何利用uwTick实现部分函数的延时
    //首先定义一个32位的变量接收值
    //用(uwTick-变量值)<某个时间    成立则直接返回,本轮回不执行该代码。不成立则本次执行该代码并将uwTick的值赋给变量值
    if( (uwTick - Key_Tick)<100 )    return 0;
    else
        Key_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;
    else
        Key_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;     
        else
            Rec_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(); } else I2CSendNotAck(); //非应答 } 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_DEBUG
            LCD_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);
 
 }

 

 

 

 

 

 

 

   

 

  

 

 

 

 

 

 

 

 

 

  

标签:HAL,Pin,STM32G431RBT6,蓝桥,TIM,Key,GPIO,LED,外设
From: https://www.cnblogs.com/sujian4412/p/18026320

相关文章

  • 蓝桥杯-N皇后
    0.题目【题目描述】有一个N*N的矩阵棋盘和N个棋子,现在需要将N个棋子按要求放置在矩阵方格中。要求:1、任意两颗棋子不能在同一行2、任意两个棋子不能在同一列3、任意两个棋子不能在同一对角线上(下面的红线都是对角线)根据以上要求,问N个棋子放置到N*N矩阵中有多少种放置方案......
  • P8661 [蓝桥杯 2018 省 B] 日志统计 题解
    好久没写题解了,水一篇。这里主要想讲的是不同的处理方法,在阅读本篇题解前请确保读完题。详解一,排序这很好理解,题目要求将热帖从小到大输出,同时题目中还有相对的时间这一概念,因此将输入的\(id\)与\(ts\)按照优先\(id\)其次\(ts\)的排序方式从小到大,排序,这样输出时就没......
  • 蓝桥杯真题代码记录(最优清零方案
    目录1.题目:2.我的代码:小结:1.题目:给定一个长度为N的数列41,42,…,AN。现在小蓝想通过若干次操作将这个数列中每个数字清零。每次操作小蓝可以选择以下两种之一:1.选择一个大于0的整数,将它减去1;2.选择连续区个大于0的整数,将它们各减去1。小蓝最少经......
  • 第十一届蓝桥杯C/C++组C组决赛之思维风暴 快速解题
    十五届蓝桥杯即将开赛,十一届的蓝桥杯国赛的一些巧妙解法。美丽的2 题目描述本题为填空题,只需要算出结果后,在代码中使用输出语包将所填结果输出即可。小蓝特别喜欢2,今年是公元2020年,他特别高兴。他很好奇,在公元1年到公元2020年(包含)中,有多少个年份的数位中包含数字2?......
  • Acwing2024蓝桥杯DFS
    模板:AcWing826.单链表利用数组创建单链表:#include<iostream>usingnamespacestd;constintN=100005;inthead,value[N],nextt[N],id;voidInit(){head=-1,id=0;}voidHead_Insert_x(intx){value[id]=x;nextt[id]=head;head=id++;}voidD......
  • 杨辉三角形(蓝桥杯,acwing)
    题目描述:下面的图形是著名的杨辉三角形:如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列:1,1,1,1,2,1,1,3,3,1,1,4,6,4,1,...给定一个正整数 N,请你输出数列中第一次出现 N 是在第几个数?输入格式:输入一个整数 N。输出格式:输......
  • 蓝桥杯-公平抽签
    0.题目题目描述小A的学校,蓝桥杯的参赛名额非常有限,只有m个名额,但是共有n个人报名。作为老师非常苦恼,他不知道该让谁去,他在寻求一个绝对公平的方式。于是他准备让大家抽签决定,即m个签是去,剩下的是不去。小A非常想弄明白最后的抽签结果会有多少种不同到情况,请你设计一......
  • 蓝桥杯 强者挑战赛9
    标算无理数位数查询LL没开全,WA想不太清楚细节,写了半个多小时。。。预处理而不是现算会好写一点赛时做法先确定第\(n\)位所属的数的位数,再确定该位数中第\(k\)大的数标算设\(g(x)\)表示\(m\)进制下\(1\simx\)的位数和,二分第\(n\)位所属的数贝贝的集合先不......
  • 蓝桥杯之初等数论
    在蓝桥杯竞赛中,初等数论部分涉及多个关键知识点。以下是对这些知识点的详细列出、基本概念解释、应用实例以及解题策略和步骤的说明:1.质数与合数基本概念:质数(素数):大于1的自然数中,只能被1和它本身整除的数。合数:除了1和它本身以外还有其他因数的自然数。应用实例:题目:......
  • 蓝桥杯-外卖店优先级
     代码及其解析#include<bits/stdc++.h>usingnamespacestd;constintN=100010;intorder[N];//order[id]第id号店上一次的订单,记录的是时间intprior[N];//prior[id]第id号店的优先级intflag[N];//flag[id]第id号店在不在优先缓存中structnode{......