工训赛驱动代码

前言

本次工训赛时间太紧没有及时完成吗,但是在解决问题的过程中,自己创建了很多的算法代码,用于调试,本篇文章用于保存这些代码。


基本中断配置

定时器中断以及串口中断的代码定义函数

其中定时器为5ms执行一次

HAL_TIM_Base_Start_IT(&htim2);

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    static uint32_t time=0;
    time++;
    if(time%5000==0)
    led1_toggle();
    if (htim->Instance == TIM2)
    {   
        usart1_time(1);
        uart3_time(1);
        uart5_time(1);
    }

    if (htim->Instance == TIM4)
    {
   
    }
}

串口中断配置

因为进中断后都要进入中断回调函数,但是中断回调函数只有一个,所以要分串口进入

int fputc(int ch, FILE *f)
    {
		//HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
	 HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,1000);//锟斤拷锟酵达拷锟斤拷
    return ch;
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)
    {
        USART1_HANDLE();
    }
    if(huart->Instance == UART4)
    {
      UART4_HANDLE();
    }
   if (huart->Instance == USART2)
   {
       UART2_HANDLE();
   }
    if (huart->Instance == USART3)
    {
        USART3_HANDLE();
    }
    if (huart->Instance == UART5)
    {
        USART5_HANDLE();
    }
}

串口接收不定时长框架代码

下面的.c和.h文件,是我的串口1,主要是用来调试的,我装了个串口蓝牙,然后使用printf()在上位机来观察并且调试

interaction.c

#include "interaction.h"
#include "string.h"
#include "stdio.h"
#include "led.h"
#include "k210ewm.h"
#include "lift.h"
uint8_t ineraction_buffer[1];
char ineraction_OUT[100],send_buff[100];

void ineraction_str_change()
{
    uint16_t count = 0;
    char *p;
    p=ineraction_OUT;
    while (*p!='\0')
    {
        count=count*10+(*p-'0');
        p++;
    }
    debug_counrt(1,count);
   printf("count=%d\r\n",count);
}

uint16_t debug_counrt(uint16_t cmd,uint16_t num)
{
    static uint16_t count=0;
    switch (cmd)
    {
    case 0:
       {
            return count; 
           break;
        }
    case 1:
        count=num;
        break;
    }
}

void interaction_init(void)
{
    HAL_UART_Receive_IT(&huart1, (uint8_t *)ineraction_buffer, 1);
}

void USART1_HANDLE()
{
   ineraction_OUT[uart1_length_chang(0)]=ineraction_buffer[0];
    uart1_length_chang(1);
    ineraction_change_flag(1);
    HAL_UART_Receive_IT(&huart1, (uint8_t *)ineraction_buffer, 1);
} 

uint16_t usart1_time(uint8_t cmd)
{
    static uint16_t time=0;
    switch (cmd)
    {
    case 0:
        return time;
        break;
    case 1:
        time++;
        if ((time>10)&&ineraction_change_flag(0))
        {   
        usart1_time(2);
        ineraction_change_flag(2);
        ineraction_str_change();
        memset(ineraction_OUT, '\0', sizeof(ineraction_OUT));
        uart1_length_chang(2);   
        }
        break;
    case 2:
        time=0;
        break;
    }
}

uint8_t ineraction_change_flag(uint8_t cmd)
{
    static uint8_t flag=0;
    switch (cmd)
    {
    case 0:
        return flag;
        break;
    case 1:
        flag=1;
        break;
    case 2:
        flag=0;
        break;
    }
}

uint16_t uart1_length_chang(uint8_t cmd)
{
    static uint16_t length=0;
    switch (cmd)
    {
    case 0:
        return length;
        break;
    case 1:
        length++;
        break;
    case 2:
        length=0;
        break;
    }
}


interaction.h

#ifndef INTERACTION_H
#define INTERACTION_H
#include "usart.h"
uint16_t usart1_time(uint8_t cmd);
uint8_t ineraction_change_flag(uint8_t cmd);
uint16_t uart1_length_chang(uint8_t cmd);
uint16_t debug_counrt(uint16_t cmd,uint16_t num);
void USART1_HANDLE();
void interaction_init(void);
#endif

按键模块

按键直接用阻塞式就好了,按键主要也是用于调试

key.c

#include "key.h"

uint8_t key_return()
{
    uint8_t k = 0;
    // 检测 PD8 引脚
    if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_8) == GPIO_PIN_RESET)
    {
        HAL_Delay(20);
        if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_8) == GPIO_PIN_RESET)
        {
            while (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_8) == GPIO_PIN_RESET);
            k = 1;
        }
        HAL_Delay(20);
    }
    // 检测 PD9 引脚
    else if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_9) == GPIO_PIN_RESET)
    {
        HAL_Delay(20);
        if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_9) == GPIO_PIN_RESET)
        {
            while (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_9) == GPIO_PIN_RESET);
            k = 2;
        }
        HAL_Delay(20);
    }
    // 检测 PD10 引脚
    else if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_10) == GPIO_PIN_RESET)
    {
        HAL_Delay(20);
        if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_10) == GPIO_PIN_RESET)
        {
            while (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_10) == GPIO_PIN_RESET);
            k = 3;
        }
        HAL_Delay(20);
    }
    // 检测 PD11 引脚
    else if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_11) == GPIO_PIN_RESET)
    {
        HAL_Delay(20);
        if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_11) == GPIO_PIN_RESET)
        {
            while (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_11) == GPIO_PIN_RESET);
            k = 4;
        }
        HAL_Delay(20);
    }

    return k;
}

key.h

#ifndef KEY
#define KEY
#include "gpio.h"

uint8_t key_return();

#endif

舵机

舵机我单独封装

其中psc=主频*10

arr=2000

Servo.c

#include "Servo.h"

void Servo_Init()
{
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
    Servo_SetAngle(100);
}

void Servo_SetAngle( uint16_t angle)
{
    
    uint32_t pulse_width;
    if (angle > 120)
    {
        angle = 120;
    }
    else if (angle < 20)
    {
        angle = 20;
    }
    
    pulse_width = 50 + (angle * (250 - 50) / 180);
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, pulse_width);
}

void clip_open()
{
    Servo_SetAngle(125);
}

void clip_close()
{
    Servo_SetAngle(20);
}

void clip_wait()
{
    Servo_SetAngle(60);
}

void clip_release()
{
    Servo_SetAngle(20);
    uint8_t i=20;
    while (i++!=80)
    {
        Servo_SetAngle(i);
        HAL_Delay(5);
    }
}

Servo.h

#ifndef SERVO_H
#define SERVO_H
#include "tim.h"

void Servo_Init(void);
void Servo_SetAngle(uint16_t angle);
void clip_open();
void clip_close();
void clip_wait();
void clip_release();
#endif

存储芯片

还以为是跟电赛一样不能带电脑去调,于是自己编写调试程序,调试代码,结果可以带电脑调,嘤嘤嘤...

是使用w25k64,我前面的文章也有

int32_t save_digital(uint8_t flag, uint16_t address, int32_t num);

主要是使用这个函数实现读写,具体自己看.c文件

w25q64_soft_spi.c

#include "w25q64_soft_spi.h"
#include <string.h>

// 每个扇区大小为4KB
#define SECTOR_SIZE 4096

// 软件SPI初始化
void W25Q64_SoftSPI_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();

    // 配置CS引脚
    GPIO_InitStruct.Pin = W25Q64_CS_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(W25Q64_CS_PORT, &GPIO_InitStruct);

    // 配置CLK引脚
    GPIO_InitStruct.Pin = W25Q64_CLK_PIN;
    HAL_GPIO_Init(W25Q64_CLK_PORT, &GPIO_InitStruct);

    // 配置MOSI引脚
    GPIO_InitStruct.Pin = W25Q64_MOSI_PIN;
    HAL_GPIO_Init(W25Q64_MOSI_PORT, &GPIO_InitStruct);

    // 配置MISO引脚
    GPIO_InitStruct.Pin = W25Q64_MISO_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    HAL_GPIO_Init(W25Q64_MISO_PORT, &GPIO_InitStruct);

    // 片选信号初始化为高电平
    W25Q64_CS_HIGH();
}

// 软件SPI读写一个字节
uint8_t W25Q64_SoftSPI_ReadWriteByte(uint8_t byte)
{
    uint8_t receivedByte = 0;
    for (int i = 7; i >= 0; i--)
    {
        if (byte & (1 << i))
        {
            W25Q64_MOSI_HIGH();
        }
        else
        {
            W25Q64_MOSI_LOW();
        }

        W25Q64_CLK_LOW();
        HAL_Delay(1); // 适当延时,确保时钟信号稳定
        receivedByte <<= 1;
        if (W25Q64_READ_MISO())
        {
            receivedByte |= 0x01;
        }
        W25Q64_CLK_HIGH();
        HAL_Delay(1);
    }
    return receivedByte;
}

// 读取设备ID
void W25Q64_ReadID(uint8_t * ManufacturerID, uint16_t * DeviceID)
{
    W25Q64_CS_LOW();
    uint8_t temp = W25Q64_SoftSPI_ReadWriteByte(0x90);  // 发送读ID指令
    temp = W25Q64_SoftSPI_ReadWriteByte(0x00);
    temp = W25Q64_SoftSPI_ReadWriteByte(0x00);
    temp = W25Q64_SoftSPI_ReadWriteByte(0x00);
    *ManufacturerID = W25Q64_SoftSPI_ReadWriteByte(0xFF);
    *DeviceID = W25Q64_SoftSPI_ReadWriteByte(0xFF) << 8;
    *DeviceID |= W25Q64_SoftSPI_ReadWriteByte(0xFF);
    W25Q64_CS_HIGH();
}

// 写使能
void W25Q64_WriteEnable(void)
{
    W25Q64_CS_LOW();
    W25Q64_SoftSPI_ReadWriteByte(0x06);  // 发送写使能指令
    W25Q64_CS_HIGH();
}

// 等待写操作结束
void W25Q64_WaitForWriteEnd(void)
{
    uint8_t status;
    W25Q64_CS_LOW();
    W25Q64_SoftSPI_ReadWriteByte(0x05);  // 发送读状态寄存器指令
    do
    {
        status = W25Q64_SoftSPI_ReadWriteByte(0xFF);
    } while (status & 0x01);
    W25Q64_CS_HIGH();
}

// 扇区擦除
void W25Q64_SectorErase(uint32_t SectorAddr)
{
    W25Q64_WriteEnable();
    W25Q64_CS_LOW();
    W25Q64_SoftSPI_ReadWriteByte(0x20);  // 发送扇区擦除指令
    W25Q64_SoftSPI_ReadWriteByte((SectorAddr >> 16) & 0xFF);
    W25Q64_SoftSPI_ReadWriteByte((SectorAddr >> 8) & 0xFF);
    W25Q64_SoftSPI_ReadWriteByte(SectorAddr & 0xFF);
    W25Q64_CS_HIGH();
    W25Q64_WaitForWriteEnd();
}

// 页编程
void W25Q64_PageProgram(uint32_t Address, uint8_t * pBuffer, uint16_t NumByteToWrite)
{
    W25Q64_WriteEnable();
    W25Q64_CS_LOW();
    W25Q64_SoftSPI_ReadWriteByte(0x02);  // 发送页编程指令
    W25Q64_SoftSPI_ReadWriteByte((Address >> 16) & 0xFF);
    W25Q64_SoftSPI_ReadWriteByte((Address >> 8) & 0xFF);
    W25Q64_SoftSPI_ReadWriteByte(Address & 0xFF);
    for (uint16_t i = 0; i < NumByteToWrite; i++)
    {
        W25Q64_SoftSPI_ReadWriteByte(pBuffer[i]);
    }
    W25Q64_CS_HIGH();
    W25Q64_WaitForWriteEnd();
}

// 缓冲区读取
void W25Q64_BufferRead(uint32_t Address, uint8_t * pBuffer, uint16_t NumByteToRead)
{
    W25Q64_CS_LOW();
    W25Q64_SoftSPI_ReadWriteByte(0x03);  // 发送读数据指令
    W25Q64_SoftSPI_ReadWriteByte((Address >> 16) & 0xFF);
    W25Q64_SoftSPI_ReadWriteByte((Address >> 8) & 0xFF);
    W25Q64_SoftSPI_ReadWriteByte(Address & 0xFF);
    for (uint16_t i = 0; i < NumByteToRead; i++)
    {
        pBuffer[i] = W25Q64_SoftSPI_ReadWriteByte(0xFF);
    }
    W25Q64_CS_HIGH();
}

#include "w25q64_soft_spi.h"
// 假设SECTOR_SIZE在头文件或者其他地方已经定义
#define SECTOR_SIZE 4096

int32_t save_digital(uint8_t flag, uint16_t address, int32_t num)
{
    // 定义一个错误返回值,这里用 -1 作为错误标识
    const int32_t ERROR_RETURN = -1;

    if (address > 2047) {
        return ERROR_RETURN; // 地址超出范围,返回错误值
    }
    uint32_t sectorAddr = address * SECTOR_SIZE;
    uint8_t buffer[4]; // 用于存储32位数据的字节数组
    int32_t result = 0;

    switch (flag) {
        case 0: // 写入
            buffer[0] = (num >> 24) & 0xFF;
            buffer[1] = (num >> 16) & 0xFF;
            buffer[2] = (num >> 8) & 0xFF;
            buffer[3] = num & 0xFF;

            W25Q64_SectorErase(sectorAddr); // 先擦除扇区
            W25Q64_PageProgram(sectorAddr, buffer, 4); // 写入数据
            break;
        case 1: // 读取
            W25Q64_BufferRead(sectorAddr, buffer, 4);
            result = ((int32_t)buffer[0] << 24) | ((int32_t)buffer[1] << 16) | ((int32_t)buffer[2] << 8) | buffer[3];
            break;
        case 2: // 清除
            W25Q64_SectorErase(sectorAddr);
            break;
        default:
            result = ERROR_RETURN; // 无效的标志位,返回错误值
            break;
    }
    return result;
}

Servo.h

#ifndef __W25Q64_SOFT_SPI_H
#define __W25Q64_SOFT_SPI_H

#include "gpio.h"

// 定义软件SPI引脚
#define W25Q64_CS_PIN    GPIO_PIN_14
#define W25Q64_CS_PORT   GPIOC
#define W25Q64_CLK_PIN   GPIO_PIN_13
#define W25Q64_CLK_PORT  GPIOC
#define W25Q64_MISO_PIN  GPIO_PIN_15
#define W25Q64_MISO_PORT GPIOC
#define W25Q64_MOSI_PIN  GPIO_PIN_4
#define W25Q64_MOSI_PORT GPIOA

// 片选操作宏定义
#define W25Q64_CS_LOW()  HAL_GPIO_WritePin(W25Q64_CS_PORT, W25Q64_CS_PIN, GPIO_PIN_RESET)
#define W25Q64_CS_HIGH() HAL_GPIO_WritePin(W25Q64_CS_PORT, W25Q64_CS_PIN, GPIO_PIN_SET)

// 时钟操作宏定义
#define W25Q64_CLK_LOW() HAL_GPIO_WritePin(W25Q64_CLK_PORT, W25Q64_CLK_PIN, GPIO_PIN_RESET)
#define W25Q64_CLK_HIGH() HAL_GPIO_WritePin(W25Q64_CLK_PORT, W25Q64_CLK_PIN, GPIO_PIN_SET)

// MOSI操作宏定义
#define W25Q64_MOSI_LOW() HAL_GPIO_WritePin(W25Q64_MOSI_PORT, W25Q64_MOSI_PIN, GPIO_PIN_RESET)
#define W25Q64_MOSI_HIGH() HAL_GPIO_WritePin(W25Q64_MOSI_PORT, W25Q64_MOSI_PIN, GPIO_PIN_SET)

// 读取MISO引脚电平
#define W25Q64_READ_MISO() HAL_GPIO_ReadPin(W25Q64_MISO_PORT, W25Q64_MISO_PIN)

// 函数声明
void W25Q64_SoftSPI_Init(void);
uint8_t W25Q64_SoftSPI_ReadWriteByte(uint8_t byte);
void W25Q64_ReadID(uint8_t * ManufacturerID, uint16_t * DeviceID);
void W25Q64_WriteEnable(void);
void W25Q64_WaitForWriteEnd(void);
void W25Q64_SectorErase(uint32_t SectorAddr);
void W25Q64_PageProgram(uint32_t Address, uint8_t * pBuffer, uint16_t NumByteToWrite);
void W25Q64_BufferRead(uint32_t Address, uint8_t * pBuffer, uint16_t NumByteToRead);
int32_t save_digital(uint8_t flag, uint16_t address, int32_t num);

#endif

灯两灭调试

这个没什么好说的,就是测试而已

led.c

#include "led.h"
#include "gpio.h"

void led1_on(void)
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);
}
void led1_off(void)
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET);
}

void led2_on(void)
{
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET);
}

void led2_off(void)
{
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET);	
}

void led3_on(void)
{
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET);
}

void led3_off(void)
{
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET);	
}

void led1_toggle(void)
{
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_0);
}
void led2_toggle(void)
{
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_1);
}

void led3_toggle(void)
{
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_2);
}

led.h

#ifndef LED_H
#define LED_H

void led1_on(void);
void led1_off(void);
void led2_on(void);
void led2_off(void);
void led3_on(void);
void led3_off(void);
void led1_toggle(void);
void led2_toggle(void);

#endif

维特科技陀螺仪

初始化后直接获取就好

在前面的文章中我有讲的

wtkj.c

#include "wtkj.h"
#include "stdio.h"


uint8_t buffer[1];
float xyz_return(uint8_t number,float count)
{
    static float xyz[3]={0};
    if(number>2)
    {
        xyz[number-3]=count;
        return 0;
    }
    else
    {
    return xyz[number];
    }
}

void xyz_init(void)
{
    // 修改为串口2
    HAL_UART_Receive_IT(&huart2, (uint8_t *)buffer, 1);
}
 
void UART2_HANDLE(void)
{
    static uint8_t i = 0;
    static int16_t buff[8]; 
 
        buff[i++] = buffer[0];
        if((i == 1) && (buff[0] != 0x55))
        {
            i = 0;
        }

        if((i == 2) && (buff[1] != 0x53))
        {
            i = 0;
        }
        
        if(i == 8)
        {
                int16_t value_x = (buff[3] << 8) | buff[2];
                int16_t value_y = (buff[5] << 8) | buff[4];
                int16_t value_z = (buff[7] << 8) | buff[6];
                xyz_return(3,(float)value_x / 32768* 180) ;
                xyz_return(4,(float)value_y / 32768* 180) ;
                xyz_return(5,(float)value_z / 32768* 180) ;
            for(int j = 0; j < 8; j++)
            {
                buff[j] = 0;
            }
            i = 0;
        }
        // 修改为串口2
        HAL_UART_Receive_IT(&huart2, (uint8_t *)buffer, 1);
}

wtkj.h

#ifndef WTKJ
#define WTKJ
#include "usart.h"

float xyz_return(uint8_t number,float count);
void xyz_init(void);
// 修改为串口2的处理函数名,假设是UART2_HANDLE
void UART2_HANDLE(void);

#endif

串口屏的使用

我这里使用的是3.5寸淘晶驰T1系列无铁框串口屏,在串口屏设置好后,发送什么就显示什么

lcd.c

#include "lcd.h"
#include "usart.h"
#include "string.h"
#include "stdio.h"

// 定义缓冲区和输出数组
uint8_t lcd_buffer[1];
char lcd_OUT[100], lcd_buff[100];

// 字符串处理函数
void lcd_str_change()
{
    uart4_send_data(lcd_OUT, strlen(lcd_OUT));
    memset(lcd_OUT, '\0', sizeof(lcd_OUT));
    uart4_length_chang(2);
}

// 标志位处理函数
uint8_t lcd_change_flag(uint8_t cmd)
{
    static uint8_t flag = 0;
    switch (cmd)
    {
    case 0:
        return flag;
    case 1:
        flag = 1;
        break;
    case 2:
        flag = 0;
        break;
    }
    return 0;
}

// 串口4中断处理函数
void UART4_HANDLE(void)
{
    lcd_OUT[uart4_length_chang(0)] = lcd_buffer[0];
    uart4_length_chang(1);
    lcd_change_flag(1);
    uart4_time(2);
    HAL_UART_Receive_IT(&huart4, (uint8_t *)lcd_buffer, 1);
}

// 串口长度处理函数
uint16_t uart4_length_chang(uint8_t cmd)
{
    static uint16_t length = 0;
    switch (cmd)
    {
    case 0:
        return length;
    case 1:
        length++;
        break;
    case 2:
        length = 0;
        break;
    }
    return 0;
}

// 初始化函数
void lcd_init(void)
{
    HAL_UART_Receive_IT(&huart4, (uint8_t *)lcd_buffer, 1);
}

// 串口发送函数
void uart4_send_data(const char *data, int length)
{
    HAL_UART_Transmit(&huart4, (uint8_t *)data, length, HAL_MAX_DELAY);
}

// 时间处理函数
uint16_t uart4_time(uint8_t cmd)
{
    static uint16_t time = 0;
    switch (cmd)
    {
    case 0:
        return time;
    case 1:
        time++;
        if ((time > 10) && lcd_change_flag(0))
        {
            uart4_time(2);
            lcd_change_flag(2);
            lcd_str_change();
        }
        break;
    case 2:
        time = 0;
        break;
    }
    return 0;
}

lcd.h

#ifndef LCD_H
#define LCD_H

#include <stdint.h>

// 定义缓冲区和输出数组
extern uint8_t lcd_buffer[1];
extern char lcd_OUT[100], lcd_buff[100];

// 函数声明
void lcd_str_change();
uint8_t lcd_change_flag(uint8_t cmd);
void UART4_HANDLE(void);
uint16_t uart4_length_chang(uint8_t cmd);
void lcd_init(void);
void uart4_send_data(const char *data, int length);
uint16_t uart4_time(uint8_t cmd);

#endif

传入多少就会变成多少的算法

这个是步进电机的算法,因为步进电机加上编码器闭环,所以输入多少就会指定多少,那么就根据这个原理来写函数,用来调试要升到多高

void lift_chassis_H_direction(uint16_t targe)//1上升  0下降
{
    static uint16_t high=0;
    if(targe>1200)
    return;
    if(targe>high)
    {
         HAL_GPIO_WritePin(GPIOE, GPIO_PIN_6, GPIO_PIN_SET);
        while (high!=targe)
        {
        HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_7);
        HAL_Delay(1);
        high++;
        }
          printf("hight=%d\r\n",high);
    }
    else if (targe<high)
    {
        HAL_GPIO_WritePin(GPIOE, GPIO_PIN_6, GPIO_PIN_RESET);
        while (high!=targe)
        {  

        HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_7);
        HAL_Delay(1);
        high--;
           
        }
            printf("hight=%d\r\n",high);
    }
}