赛前准备

今天来复习一下赛前要准备的东西,以及注意事项。这里我根据考纲的内容来准备一点点来。

LED操作

LED一共有八个,但是他和LCD是复用的,所以加入了锁存器PD2,需要led的时候,将PD2拉高,然后led配置,不需要进行进一步的配置只需要打开就行,下面就是LED的IO口。 alt text 主要用到两个函数,然后需要初始化一共变量,已经完全背在脑子里了

u8 led_sta=0x00;
void led_pro(u8 dsLED)
{
    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC,dsLED<<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);
}
void led_change(u8 led_num,u8 led_dat)
{
    u8 pos=0x01<<(led_num-1);
    led_sta=(led_sta&~pos)|(pos*led_dat);
    led_pro(led_sta);
}

ADC

这个内容基本上也是必考的,然后要考虑一个校准,还有过采样可以让电压变得更精准。 alt text alt text

HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);//ADC校准
float adc_get(ADC_HandleTypeDef *hadc)
{
	u16 adc_value;
	HAL_ADC_Start(hadc);
	adc_value=HAL_ADC_GetValue(hadc);
	return adc_value*3.3f/65535.0f;
}

IIC

这里将IIC主要是和EEPROM一起使用,这里需要导入.c .h文件。 然后这里主要讲下,数据读取和写入和一些细节,这部分考的概率也有 首先需要注意的是,IIC需要初始化I2CInit(); 然后接下来就是IIC的写入和读取 alt text

u8 eeprom_read(u8 addr)
{
    u8 dat;
    I2CStart();
    I2CSendByte(0xa0);//写入
    I2CWaitAck();
    I2CSendByte(addr);
    I2CWaitAck();
    I2CStop();

    I2CStart();
    I2CSendByte(0xa1);//读取
    I2CWaitAck();
    dat=I2CReceiveByte();
    I2CWaitAck();
    I2CStop();
    return dat;
}

alt text

void eeprom_write(u8 addr,u8 dat)
{
   I2CStart();
   I2CSendByte(0xa1);
   I2CWaitAck();
   I2CSendByte(addr);
   I2CWaitAck();
   I2CSendByte(dat);
   I2CWaitAck();
   I2CStop();
}

alt text

定时器输入捕获

这部分内容其实有两种方法,up的那个方法很好用这里也介绍一下。 alt text 这里主要就是两个引脚PA15和PB14对应两个定时器。 然后讲下cube的配置 alt text 然后代码部分就十分的简单,两个分别对应的是占空比和频率

	fre1=1000000.0f/(HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1)+1);
	duty1=(HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2)+1)*100.0f/(HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1)+1);

输入捕获中断另外在写吧

PWM波输出

这部分考的内容还是比较简单的,这里就不作分析了,用的频率太多了。

串口

这部分也是每年必考的,去年都没考,注意的一个点就是波特率设置成9600 记得要开启中断 然后这里也写两种方式,因为这部分不确定cube的包里面有没有


HAL_UARTEx_ReceiveToIdle_IT(&huart1,(u8 *)uart_rx,30);
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if(huart->Instance==USART1)
	{
        memset(uart_rx,0,30);
	    HAL_UARTEx_ReceiveToIdle_IT(&huart1,(u8 *)uart_rx,30);
    }
}
char uart_rx[30];
uint8_t point;
uint8_t uart_r;
HAL_UART_Receive_IT(&huart3,&uart_r,1);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART3)
	{
		uart_rx[point++]=uart_r;
		HAL_UART_Receive_IT(&huart3,&uart_r,1);
	}
}
void uart_rpo()
{
    if(point>0)
    {
        if(point==4)
        {
        }
        point=0;
        memset(uart_rx,0,30);
    }
}
while(1)
{
    if(point>0)
	{
		uint8_t temp=point;
		HAL_Delay(1);
		if(temp==point)
			uart_rpo();
	}
}

DMA

key

按键这部分内容是最重要的,其中涉及单击双击和长按 首先是单击

单击

struct keys{
    u16 age;
    u8 short;
}
u8 key_scan()
{
    if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0) return 1;
    else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0) return 2;
    else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0) return 3;
    else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0) return 4;
    else retun 0;
}
key_prc()
{
    u8 sta=key_scan();
    if(sta!=0)
    {
        key[sta].age++;
        if(key[sta].age==2) key[sta].short=1;
    }
    else
    {
        for(int i=0;i<5;i++)
        {
            key[i].age=0;
        }
    }
}

长按

长按分两种

struct keys
{
    age;
    press;
    short;
    long;
}key[5];
u8 key_scan()
{
    if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0) return 1;
    else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0) return 2;
    else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0) return 3;
    else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0) return 4;
    else retun 0;
}
key_proc()
{
    u8 sta=key_scan();
    if(sta!=0)
    {
        key[sta].age++;
        if(key[sta].age>1)key[sta].press=1;
    }
    else
    {
        for(int i=0;i<5;i++)
        {
            if(key[i].long==0&&key[i].press==1)
            {
                key[i].short=1;
            }
            key[i].age=0;
            key[i].press=0;
            key[i].long=0;
        }
    }
    if(key.[sta].age>200)
    {
        key[sta].long=1;
    }
}
key_proc()
{
    u8 sta=key_scan();
    if(sta!=0)
    {
        key[sta].age++;
        if(key[sta].age>1)key[sta].press=1;
    }
    else
    {
        for(int i=0;i<5;i++)
        {
            if(key.[sta].age>200)
            {
                key[sta].long=1;
            } 
            if(key[i].long==0&&key[i].press==1)
            {
                key[i].short=1;
            }
            key[i].age=0;
            key[i].press=0;
        }
    }
}

双击

struct keys
{
    u16 age;
    u8 press;
    u8 double_en;
    u16 double_age;
    u8 key_short;
    u8 key_long;
    u8 key_double;
}key[5];
void key_proc()
{
    u8 sta=key_scan();
    if(sta!=0)
    {
        key[sta].age++;
        if(key[sta].age>1)key[sta].press=1;
    }
    else
    {
        for(int i=0;i<5;i++)
        {
            if(key[i].age>200&&key[i].press==1)
                key[i].key_long=1;
			if(key[i].double_en==1&&key[i].press==1)
            {
                key[i].key_double=1;
                key[i].double_en=0;
                key[i].double_age=0;
            }
            if(key[i].press==1&&key[i].key_long==0&&key[i].key_double==0)
                key[i].double_en=1;
            if(key[i].double_en==1)
                key[i].double_age++;
            if(key[i].double_en==1&&key[i].double_age>20)
            {
                key[i].key_short=1;
                key[i].double_en=0;
                key[i].double_age=0;
            }
            key[i].press=0;
            key[i].age=0;
        }
    }
}

本文章使用limfx的vscode插件快速发布