蓝桥杯嵌入式个人笔记(自用)持续更新

以蓝桥杯嵌入式开发版G431

下载失败可尝试更改下载速率。

工程创建

CubeMx配置

选择芯片

进去之后点击SystemCore

时钟配置

LCD

#include "lcd.h"
#include "stdio.h"

//界面相关参数
float volt_r37;//电压
u16 freq_pa7 = 1000;//初始值1Khz 输出频率1000Hz
u16 duty_pa7 = 40;//占空比,初始值为40%

//1.LCD
void LCD_Process()
{
  u8 display_buf[20];
  LCD_DisplayStringLine(Line1,(unsigned char *)"         DATA   ");
  
  sprintf((char*)display_buf,"   Volt:%4.2fV",volt_r37);
  LCD_DisplayStringLine(Line3, (unsigned char *)display_buf);
  
  sprintf((char*)display_buf,"   D:%2d%%",duty_pa7);
  LCD_DisplayStringLine(Line5, (unsigned char *)display_buf);
  
  sprintf((char*)display_buf,"   F:%-5dHz",freq_pa7);
  LCD_DisplayStringLine(Line7, (unsigned char *)display_buf);
}

注意:display_buf数组最好不要设置为全局变量。

按键

CubeMX配置

1.每次按下按键需要单次触发!

2.需要有松手检测!

3.不阻塞程序!不要有Delay!更不有vhile(!P30):等待按键弹起!

4.最好有长按功能!

无需配置上拉电阻

程序设计

#incldue "key.h"

#define KB1  HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)
#define KB2  HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)
#define KB3  HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)
#define KB4  HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)
#define KEYPORT  KB1 | (KB2<<1) | (KB3<<2) | (KB4<<3) | 0xf0

u8 Trg;	 	 
u8 Cont; 	 
void Key_Read(void)
{
    u8 ReadData = (KEYPORT)^0xff;   		  
    Trg = ReadData & (ReadData ^ Cont);        
    Cont = ReadData;                           
}
#ifndef __KEY_H
#define __KEY_H
#include "main.h"

extern u8 Trg;
extern u8 Cont;

#endif

//按键
u32 keyTick;
void Key_Process()
{
  if(uwTick - keyTick < 20) return;//每20ms执行一次
  keyTick = uwTick;
  Key_Read();
  if(Trg & 0x01)  //B1
  {
    
  }
  
  if(Trg & 0x02)  //B2
  {
    
  }
  
  if(Trg & 0x04)  //B3
  {
    
  }
  
  if(Trg & 0x08)  //B4
  {
    
  }
}

LED

CubeMX配置

配置PD2(锁存器),为GPIO_output模式

程序思路:

  1. 上电先让PC8-15输出高电平,关闭全部LED。
  2. 然后打开锁存器,让PC8-15的数据进去,再关闭锁存器。
  3. 根据题意点亮对应的LED。设置控制变量led_ctrl。
#ifndef __LED_H
#define __LED_H

#include "main.h"
void LED_Control(u8 led_ctrl);

#endif
#include "led.h"

void LED_Control(u8 led_ctrl)
{
  HAL_GPIO_WritePin(GPIOC,0xff00,GPIO_PIN_SET);      //让PC8-15输出高电平,熄灭LED
  HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);  //打开锁存器
  HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);//关闭锁存器
  
  //根据led_ctrl点亮对应的LED
  HAL_GPIO_WritePin(GPIOC,led_ctrl<<8,GPIO_PIN_RESET);//点亮对应的LED
  HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);   //打开锁存器
  HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET); //关闭锁存器
}

利用中断精确定时

举例:LED亮3S后熄灭。

1.main函数中

//5.LED 
u8 led_ctrl = 0x00;
u32 ledTick = 0;
u16 cnt_led = 0;

void LED_Process()
{
 
  //方法2
  if(uart_right_flag == 1)
  {
    led_ctrl |= 0x01;
  }
  else
  {
    led_ctrl &= ~0x01;
  }
  
  if(uart_error_flag == 1)
  {
    led_ctrl |=  0x02;
  }
  else
  {
    led_ctrl &= ~0x02;
  }
  
  LED_Control(led_ctrl);
   
}

2.在stm32g4xx_it.c中声明

3.找到SysTick_Handler函数,在内部编写所需要的逻辑

ADC(模拟电压输入)

CubeMX配置

以配置R37(PB15为例)

ADC,模拟电压输入。

最高12位。2^12 = 4096,0-4095

实际电压 = X/4096*3.3。➗4096运行速度比较快。

ADC:显示电压。模拟转数字

DAC:输出电压。数字转模拟

单端模式,差分模式(两个电压做差值)

代码部分

MX_ADC2_Init();//ADCX,X=1,2。CubeMX自动生成

HAL_ADC_Start(&hadc1);//启动

HAL_ADC_GetValue(&hadc1);//获取值

r37单通道采集代码部分:

//ADC
u16 adc2_val;
void ADC_Process()
{
  HAL_ADC_Start(&hadc2);
  adc2_val = HAL_ADC_GetValue(&hadc2);
  volt_r37 = adc2_val / 4096.0f*3.3f;
}

r37,r38双通道采集代码部分:

//ADC
u16 adc1_val,adc2_val;
u32 adcTick;
void ADC_Process()
{
  if(uwTick - adcTick < 100) return;//每100ms采集一次
  adcTick = uwTick;
  HAL_ADC_Start(&hadc1);
  adc1_val = HAL_ADC_GetValue(&hadc1);
  volt_r38 = adc1_val/4095.0f * 3.3f;

  HAL_ADC_Start(&hadc2);
  adc2_val = HAL_ADC_GetValue(&hadc2);
  volt_r37 = adc2_val/4095.0f * 3.3f;;  
}

数字滤波(均值求和)

在ADC中的应用

代码部分

/* ADC */
u16 adc_val;
float volt_r37_prev;
u32 adc_sum;
u8 adc_cnt;
void ADC_Process()
{
    HAL_ADC_Start(&hadc2);
    adc_val = HAL_ADC_GetValue(&hadc2);
    
    adc_sum = adc_sum + adc_val;
    adc_cnt++;
    
    if(adc_cnt == 10)//计算十次平均值
    {
        
        volt_r37_prev = volt_r37;//保存上一个时刻的电压
        volt_r37  = (adc_sum / 10.0f) / 4095.0f * 3.30f;//获取当前电压值
        adc_cnt = 0;
        adc_sum = 0;
    }
}

DAC输出

CubeMX的配置

选择Connected 同external pin only 模式

其他不用改。

代码部分:

/* DAC */
float dac_volt1,dac_volt2;
void DAC_Process()
{
  dac_volt1 = 3.30f;
  HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_1,DAC_ALIGN_12B_R,4095/(3.3/dac_volt1));//0-0V,4096-3.3V。默认12位右对齐
  HAL_DAC_Start(&hdac1,DAC1_CHANNEL_1);
  
  dac_volt2 = 1.11f;
  HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_2,DAC_ALIGN_12B_R,4095/(3.3/dac_volt2));//0-0V,4096-3.3V。默认12位右对齐
  HAL_DAC_Start(&hdac1,DAC1_CHANNEL_2);
  
}


RTC

CubeMX配置

Activate Clock Source使能时钟源 Activate Calendar 使能日历

在时钟为 32KHz的情况下,Asynchronous Predivider value 设置为32-1。Synchronous Predivider value 设置为1000-1 。因为是从0开始计时,0-999为1000。 

代码部分

RTC_TimeTypeDef rtc_time;//包含时分秒
RTC_DateTypeDef rtc_date;//包含年月日星期

/* RTC实时时钟 */

void RTC_Process()
{
  HAL_RTC_GetTime(&hrtc,&rtc_time,RTC_FORMAT_BIN);
  HAL_RTC_GetDate(&hrtc,&rtc_date,RTC_FORMAT_BIN);
}


void LCD_Process()
{
  u8 display_buf[20];
  switch(display_mode)
  {
    case 0://界面1
    {
      sprintf((char*)display_buf,"     %02d-%02d-%02d  ",
      rtc_time.Hours,rtc_time.Minutes,rtc_time.Seconds);

      LCD_DisplayStringLine(Line9, (uint8_t *)display_buf);
      break;
    }
}


PWM输出

PWM输出 = 频率输出 = 信号输出

CubeMX配置

其他管脚大同小异,重点掌握PA6PA7的PWM输出。

PA7的PWM输出

中断不需要配置

参数设置

Prescaler 分频值设置为79(80-1),Counter Period 对应周期(us)。这里设置上电后默认PA7输出1KHz,占空比为20%。对应1000us.(0-999)。

Pulse(us):高电平时间。占空比20%对应为1000us * 20% = 200us

while(1)前

//PWM输出
  HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
 

完成。编译后下载到板子上,经测试PA7成功输出1000Hz,占空比为20%波形。

PA6的PWM输出

CubeMX的配置

PWM输出不需要开启中断

这里我们目标设置PA6输出10KHz,占空比50%,一般情况下只需修改三个参数。

 HAL_TIM_PWM_Start(&htim16,TIM_CHANNEL_1);


自定义函数控制

HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);//开启TIM2_CH2的PWM输出
//6.PWM输出。输出方波(占空比为50%)
void PWM_Process()
{
  
  if(volt_r37 > volt_r38)
  {
    TIM2->ARR = 100-1;//周期为100us(0-99)。10Khz 对应100us.
    TIM2->CCR2 = 50;//CCR对应占空比
  }
  else
  {
    TIM2->ARR = 5000-1;//周期为5000us(0-4999)。对应200hz
    TIM2->CCR2 = 2500;//高电平时间。5000us中2500us为高电平
  }
  
}

CNT为定时器中的计数器,(自动重装载寄存器)ARR寄存器存放的是周期(us),CCR寄存器存放的是高电平时间(us)

举例:要设置输出1KHz的PWM方波信号(占空比50%),则ARR = 1000-1 = 999.

因为0-999us则为1000ms,对应的频率为1KHz。CCR = 500。1000ms * 50% = 500ms。


PWM捕获

R40对应PA15,R39对应PB4

测量1路频率(PA15 R40)

CubeMX配置

开启中断

参数设置

Prescaler设置为79(0-79 则为80)。时钟80MHz,分频后为1MHz,即1us计时一次。

Counter Period 设置成最大,尽量防止溢出。

代码部分

while(1)前初始化

//PWM捕获
  HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);//开启TIM2_CH1的输入捕获中断

u32 tim2_cnt1 = 0;
u32 f40 = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  tim2_cnt1 = __HAL_TIM_GetCounter(&htim2);//获取CNT,单位us
  __HAL_TIM_SetCounter(&htim2,0);//设置CNT为0,重新开始计时
  
  f40 = 1e6 / tim2_cnt1;//R40调制的555定时器频率
  
  HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);//每次都需要重新开启TIM2_CH1的输入捕获中断
  
}

测量2路频率 (PA15 R40 +  PB4 R39)

开启中断

周期最大为65535us。可测量范围为:15Hz-1MHz

参数设置

这里的Counter Period 最大为0xFFFF(65535)

代码部分:

while(1)前:

HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);//开启TIM3_CH1的输入捕获中断

/* PWM捕获 */
u32 tim2_cnt1 = 0;
u32 f40 = 0;
u32 tim3_cnt1 = 0;
u32 f39 = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  //因为2路PWM捕获利用的是同一个中断函数,所以需要if进行判断
  
  if(htim == &htim2)
  {
    tim2_cnt1 = __HAL_TIM_GetCounter(&htim2);//获取CNT,单位us
    __HAL_TIM_SetCounter(&htim2,0);//设置CNT为0,重新开始计时
    
    f40 = 1e6 / tim2_cnt1;//R40调制的555定时器频率
    
    HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);//每次都需要重新开启TIM2_CH1的输入捕获中断
  }
  
  if(htim == &htim3)
  {
    tim3_cnt1 = __HAL_TIM_GetCounter(&htim3);//获取CNT,单位us
    __HAL_TIM_SetCounter(&htim3,0);//设置CNT为0,重新开始计时
    
    f39 = 1e6 / tim3_cnt1;//R39调制的555定时器频率
    
    HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);//每次都需要重新开启TIM3_CH1的输入捕获中断
  }
}

如果碰到同一个定时器不同通道,还需对通道进行判断。

测量频率和占空比

基本思路:cnt1为高电平时间,cnt为周期  占空比= cnt1/cnt2。

代码部分:

/* PWM捕获 */
u32 tim2_cnt1 = 0, tim2_cnt2 = 0;//cnt1 为高电平时间 cnt2为周期
u32 f40 = 0;
float d40;
u32 tim3_cnt1 = 0,tim3_cnt2 = 0;//cnt1 为高电平时间 cnt2为周期
u32 f39 = 0;
float d39;
u8 tim2_state = 0;//0-开始计时 1-获取T1 2-获取T2 
u8 tim3_state = 0;//0-开始计时 1-获取T1 2-获取T2 
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  //因为2路PWM捕获利用的是同一个中断函数,所以需要if进行判断
  //tim2_channel 1
  if(htim == &htim2)
  {
    if(tim2_state == 0)//第一个上升沿产生,开始计时
    {
      __HAL_TIM_SetCounter(&htim2,0);//设置CNT为0,重新开始计时
      TIM2->CCER |= 0x02;//CC1P置为1,改为下降沿中断
      tim2_state = 1;
    }
    else if(tim2_state == 1)//获取T1(高电平时间),并改为上升沿中断
    {
      tim2_cnt1 = __HAL_TIM_GetCounter(&htim2);//获取T1(us)高电平时间
      TIM2->CCER &= ~0x02;//CC1P置为0,改为上升沿中断
      tim2_state = 2;
    }
    else if(tim2_state == 2)//第二个上升沿中断,获取T2(us)周期
    {
      tim2_cnt2 = __HAL_TIM_GetCounter(&htim2);//获取T1,单位us
      f40 = 1e6 / tim2_cnt2;//R40调整的555定时器频率
      d40 = tim2_cnt1*100.0f/tim2_cnt2;
      tim2_state = 0;
    }
    HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);//每次都需要重新开启TIM2_CH1的输入捕获中断
  }
  
  //tim3_channel 1
  if(htim == &htim3)
  {
    if(tim3_state == 0)//第一个上升沿产生,开始计时
    {
      __HAL_TIM_SetCounter(&htim3,0);//设置CNT为0,重新开始计时
      TIM3->CCER |= 0x02;//CC1P置为1,改为下降沿中断
      tim3_state = 1;
    }
    else if(tim3_state == 1)//获取T1(高电平时间),并改为上升沿中断
    {
      tim3_cnt1 = __HAL_TIM_GetCounter(&htim3);//获取T1(us)高电平时间
      TIM3->CCER &= ~0x02;//CC1P置为0,改为上升沿中断
      tim3_state = 2;
    }
    else if(tim3_state == 2)//第二个上升沿中断,获取T2(us)周期
    {
      tim3_cnt2 = __HAL_TIM_GetCounter(&htim3);//获取T1,单位us
      f39 = 1e6 / tim3_cnt2;//R40调整的555定时器频率
      d39 = tim3_cnt1*100.0f/tim3_cnt2;
      tim3_state = 0;
    }
    HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);//每次都需要重新开启TIM2_CH1的输入捕获中断
  }
  
}


串口通信

串口配置:

CubeMX配置 PA10和PA9管脚

设置为Asynchronous异步模式,开启串口接收中断。

一般只需将波特率Baud Rate设置为9600 Bits/s。其他保持默认

串口发送:

串口发送方法1:

上电自动发送

//串口发送
  //sizeof后面-1,不然只能发送一次。50ms为超时时间
  HAL_UART_Transmit(&huart1,(unsigned char *)"Hello DNF!\r\n",sizeof("Hello DNF!\r\n")-1,50);
  
  u8 tx_buf[] = {"DNF,启动!\r\n"};
  HAL_UART_Transmit(&huart1,(unsigned char *)tx_buf,sizeof(tx_buf)-1,50);
  
  u8 tx2_buf[] = {"今天又是充满希望的一天。\r\n"};
  HAL_UART_Transmit(&huart1,(unsigned char *)tx2_buf,sizeof(tx2_buf)-1,50);
  //以上内容上电后自动发送一次

串口发送方法2:

需要重定向printf函数

//串口发送
int fputc(int ch, FILE *f) 
{
  HAL_UART_Transmit(&huart1,(unsigned char*)&ch,1,50);
  /* Your implementation of fputc(). */
  return ch;
}
printf("勇士记得早点起,每日6点更新疲劳值\r\n");

串口成功发送

注意一定要勾选上使用Use MicroLIB,否则printf函数会卡死。

串口接收:

串口接收数据进行实现特定功能程序的基本思路

  1. 开启中断,定义串口闲时判断函数
  2. 定义字符串数据检查函数
  3. 定义串口中断回调函数

开启串口接收中断(  while(1)前  )

HAL_UART_Receive_IT(&huart1,uart_buf,1);//开启串口中断

定义串口闲时判断函数,接收数组以及相关变量。

RxIdle_Process():每50ms对串口数据接收数组进行一次清零。

/* 串口 */
u8 uart_buf[2];
u8 rx_buf[10];//串口数据缓存数组
u8 rx_cnt = 0;
u32 uartTick;
u8 rx_cnt_flag = 0;
_Bool rx_cmd_error_flag;//串口接收到错误数据,置1。正确则置0


//每50ms对接收数组进行一次清零
void RxIdle_Process()//串口闲时处理
{
    if(uwTick - uartTick < 50) return;//50ms执行一次
    uartTick = uwTick;
    
    //--这里根据题目需要修改
    if(rx_cnt > 0 && rx_cnt_flag == 0)//接收到数据,但字节数据不足7个
    {
        printf("Cmd Cnt Error\r\n");
        rx_cmd_error_flag = 1;
    }
    //-------分隔符-------

    rx_cnt = 0;
    rx_cnt_flag = 0;
    memset(rx_buf,'\0',sizeof(rx_buf));
}

定义字符串

判断数据是否符合格式,符合返回1,不符合返回0。

//判断数据是否符合格式,符合返回1,不符合返回0
_Bool Check_String(u8* str)
{
    //根据题目需要自行编写
    //3.2,1.4
    u8 i;
    if(str[3] != ',')
        return 0;
    
    if(str[1] != '.' || str[5] != '.')
        return 0;
    
    for(i=0;i<7;)
    {
        if(str[i] > '9' || str[i] < '0')
            return 0;
        i = i + 2;
    }
    return 1;
}

编写串口接收中断回调函数

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    uartTick = uwTick;
    rx_buf[rx_cnt++] = uart_buf[0];//接收数据
    HAL_UART_Receive_IT(&huart1,uart_buf,1);//开启下一次串口接收中断

    if(rx_cnt == 7)
    {
        rx_cnt = 0;
        rx_cnt_flag = 1;
        printf("Cmd Cnt Right\r\n");
        if( Check_String(rx_buf) == 1)//数据符合要求
        { 
            /* 根据题目需要自行编写 */
        }
        else
        {
            printf("数据格式不符合\r\n");
            rx_cmd_error_flag = 1;
        }
    }
}

同时在while(1)调用RxIdle_Process()函数

while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    LCD_Process();
    Key_Process();
    LED_Process();
    ADC_Process();
    DAC_Process();
    RTC_Process();
    RxIdle_Process();
  }

数据判断:
串口助手发送数据到单片机

例如发送数字9,发送的是字符9(阿斯康码值57).

所以如果串口助手发送数据到单片机,发送6,想让单片机中的a变量赋值为6,则需要对应接收到的数据进行转换; a = str[0] - '0' 或者 a = str[0] - 48。str[]为串口接收数据数组。

串口DMA模式

CubeMX配置

代码

//串口接收
u8 uart_buf[20];
u8 rx_buf[10];
u8 rx_cnt;
u32 uartTick;

void RxIdle_Process()//串口接收延时判断函数
{
  if(uwTick - uartTick < 50) return;//50ms清空一次
  uartTick = uwTick;
  
  rx_cnt = 0;
  memset(rx_buf,'\0',sizeof(rx_buf));//清空缓存数组
}


/* 串口DMA不定长数据收发 */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if(huart == &huart1)
    {
        HAL_UART_Transmit_DMA(&huart1,uart_buf,Size);
        
        rx_buf[rx_cnt++] = uart_buf[0];
          if(rx_cnt > 0)
          {
              printf("%s",rx_buf);
          }
        
        /* 这里使用HAL_UARTEx)ReceiveToldle 或者 HAL_UARTEx_ReceiveToIdle_IT 也可以*/
        HAL_UARTEx_ReceiveToIdle_DMA(&huart1,uart_buf,sizeof(uart_buf));//启动接收
        __HAL_DMA_DISABLE_IT(&hdma_usart1_rx,DMA_IT_HT);//关闭DMA传输过半中断
    }
      
}

 while(1)前初始化

 //串口接收DMA

  HAL_UARTEx_ReceiveToIdle_DMA(&huart1,uart_buf,sizeof(uart_buf));
  __HAL_DMA_DISABLE_IT(&hdma_usart1_rx,DMA_IT_HT);//关闭DMA传输过半中断
  
  //这里填参数之前,要在main.h 里添加extern DMA_HandleTypeDef hdma_usart1_rx;

EEPROM

代码部分

比赛时需要自己编写的两个函数

//写24C02
void EEPROM_Write(u8 add,u8 dat)
{
	I2CStart(); 
	I2CSendByte(0xa0); 
	I2CWaitAck(); 
	
	I2CSendByte(add);	
	I2CWaitAck(); 
	I2CSendByte(dat); 
	I2CWaitAck(); 
	I2CStop();
	HAL_Delay(5);
}
//读24C02
u8 EEPROM_Read(u8 add)
{
	u8 dat;
	
	I2CStart(); 
	I2CSendByte(0xa0);
	I2CWaitAck(); 	
	I2CSendByte(add);
	I2CWaitAck(); 
	
	I2CStart();
	I2CSendByte(0xa1); 
	I2CWaitAck();
	dat = I2CReceiveByte(); 
	I2CSendNotAck();
	I2CStop();
	
	return(dat);
}

可读写的地址,0x01,0x02,0x03......

while(1)前

I2CInit();

注意事项

全新的EEPROM中的值为255,使用时要进行上电检测。如果EEPROM中读取的参数值超出目标范围,说明是第一次使用,不是我们存储的数据。我们则需要对参数进行初值设置。

简单应用:上电后记录开机次数

//EEPROM,上电后统计开机次数
  I2CInit();
  startup_times = EEPROM_Read(0x20);
  EEPROM_Write(0x20,++startup_times);

关于debug

黄色箭头表示当前所在位置。


蓝色表示光标所在位置。

断点只能打在左侧深灰色处,白色的地方无效。

被优化的变量无法通过watch窗口查看。
局部变量只有运行到所在块内才能查看。

一般程序默认开始位置在main的起始处。
 


1.跳转到函数里面
2.跳过当前行
3.跳出这行
4.执行到光标所在位置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值