自用---

零、环境配置

keil代码补全

keil pack包

cubemx配置安装包

一、LED

cubemx配置PD2引脚为输出模式

cpp 复制代码
uint16_t led_value = 0x00;
void led_set(uint8_t led_dis)
{
    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOC,led_dis<<8,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);    
}
void led_single_on(uint8_t turn)
{
    led_value = led_value | (0x01<<(turn - 1));
    led_set(led_value);
}
void led_single_off(uint8_t turn)
{
    led_value = led_value & (~(0x01<<(turn - 1)));
    led_set(led_value);
}

void led_single_on(uint8_t turn);

void led_single_off(uint8_t turn);

通过位运算实现单独的led操作而不影响其他led灯的正常显示,便于实现led的同时闪烁和分别控制,成功解决和led灯冲突的问题

二、EPPEROM(I2C)

初始化

初始化函数【无需在cubemx配置引脚】,在while(1)前面初始化配置一下🆗,下面这个函数在提供的I2C函数里有

cpp 复制代码
void I2CInit(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};

    GPIO_InitStructure.Pin = GPIO_PIN_7 | GPIO_PIN_6;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.Pull = GPIO_PULLUP;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
}

EEPROM--AT24C02 只有对写操作有时间间隔要求,对读操作没有间隔要求

由上图可以得知,AT24C02读时间间隔为5ms

cpp 复制代码
HAL_Delay(5);    //延时5ms--AT24C02写时序要求

根据芯片手册时序图编写读写函数

cpp 复制代码
//字节写函数
void at24c02_Byte_Write(unsigned char addr,unsigned char cSendByte)
{
    I2CStart();
    I2CSendByte(0xa0);
    I2CWaitAck();
    I2CSendByte(addr);
    I2CWaitAck();
    I2CSendByte(cSendByte);
    I2CWaitAck();
    I2CStop();
}
cpp 复制代码
//随机读
unsigned char at24c02_Byte_read(unsigned char addr)
{
    unsigned char dat;
    I2CStart();
    I2CSendByte(0xa0);
    I2CWaitAck();
    I2CSendByte(addr);
    I2CWaitAck();
    I2CStart();
    I2CSendByte(0xa1);
    I2CWaitAck();
    dat = I2CReceiveByte();
    I2CSendNotAck();
    I2CStop();
    return dat;
}

三、LCD

1.LCD基本显示问题

cpp 复制代码
#include "stdio.h"  //进入sprintf函数的头文件

sprintf () 可以将格式化输出发送到一个字符串中

使用示例:

cpp 复制代码
        sprintf(text,"    Liquid Level     ");
        LCD_DisplayStringLine(Line1,(u8*)text);

2.高亮某一行

cpp 复制代码
        if(set_sel == Sel_3){
            LCD_SetBackColor(Yellow);
        }
        sprintf(text," Threshold_3:  %2dcm     ",Threshold_3);
        LCD_DisplayStringLine(Line7,(u8*)text);      
        LCD_SetBackColor(Black);    

设置set_sel用于选择高亮的某一行

在显示前设置高亮背景颜色

在显示后设置回默认的背景颜色

3.高亮某个字符

cpp 复制代码
void highlight(uint8_t *str,uint8_t pos)
{
	int i = 0;
	for(i = 0; i <= 20; i++)
	{
		if(i != pos && i!= (pos+1))
			LCD_DisplayChar(Line3,(320 - (16 * i)),str[i]);
	}
	LCD_SetBackColor(Yellow);
	LCD_DisplayChar(Line3,(320 - (16 * pos)),str[pos]);
    LCD_SetBackColor(Yellow);
    LCD_DisplayChar(Line3,(320 - (16 * (pos+1))),str[pos+1]);
	LCD_SetBackColor(Black);	
}

使用示例:

四、串口

1.串口重定向

cpp 复制代码
#include "stdio.h"
cpp 复制代码
int fputc(int ch,FILE *f)
{
    HAL_UART_Transmit(&huart1,(unsigned char*)&ch,1,50);
    return ch;
}

2.串口中断

3.串口DMA

4.不定长数据接收

5.指令解析

6.sscanf的使用

五、TIM

1.PWM输出(多通道脉冲输出/信号发生器)

cpp 复制代码
  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);  //PA6--PWM输出
  HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1); //PA7--PWM输出

2.PWM占空比

①初始化配置

②修改比较值

cpp 复制代码
__HAL_TIM_SetCompare(    );

3.PWM频率设置

cpp 复制代码
__HAL_TIM_SET_PRESCALER(&htim2,80-1);

4.输入捕获,双通道测量频率和占空比

cpp 复制代码
    HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
    HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_2);
cpp 复制代码
uint16_t cnt_rising=0, cnt_falling=0;
uint16_t freq=0;
float IC_duty;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim -> Instance == TIM3)
	{
		if(htim -> Channel == HAL_TIM_ACTIVE_CHANNEL_2)
		{
			cnt_rising = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2)+1;
			freq = (80000000/80) / cnt_rising;
			IC_duty = ((float)cnt_falling/cnt_rising)*100;
		}
		if(htim -> Channel == HAL_TIM_ACTIVE_CHANNEL_1)
		{
			cnt_falling = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1)+1;
		}
	}
}

5.RTC时钟

6.定时器实现闪烁/步进

六、按键

短按

长按+短按

按键处理函数

七、ADC(电位器)

ADC校准

cpp 复制代码
HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);        //ADC校准

ADC读取值

勾选ADC2 IN15 Single-ended,其他选项默认

cpp 复制代码
HAL_ADC_Start(&hadc2);
cpp 复制代码
HAL_ADC_GetValue(&hadc2);
cpp 复制代码
double getADCvalue(void)
{
    HAL_ADC_Start(&hadc2);
    HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);        //ADC校准
    uint32_t value = HAL_ADC_GetValue(&hadc2);
    ADC_get_flag = 0;
    return (value*3.3)/4095.0;
}

4095------>分辨率12bit

过采样(G4系列)

Oversampling Right Shift和Oversampling Ratio设置为对应的。

cpp 复制代码
double getADCvalue(void)
{
    HAL_ADC_Start(&hadc2);
    HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);        //ADC校准
    uint32_t value = HAL_ADC_GetValue(&hadc2);
    ADC_get_flag = 0;
    return (value*3.3)/4095.0;
}

硬件滤波

软件滤波(一阶互补滤波)

cpp 复制代码
double first_filter(double new_val,double old_val,float rate)
{
    return  (new_val*rate + old_val*(1-rate)); 
}

八、考试调试

①printf

②LCD

相关推荐
Asa31913 分钟前
STM32-按键扫描配置
stm32·单片机·嵌入式硬件
南城花随雪。32 分钟前
单片机:实现驱动超声波(附带源码)
单片机·嵌入式硬件
ThisIsClark1 小时前
【后端面试总结】MySQL主从复制逻辑的技术介绍
mysql·面试·职场和发展
LCG元9 小时前
【面试问题】JIT 是什么?和 JVM 什么关系?
面试·职场和发展
yutian06069 小时前
Keil MDK下载程序后MCU自动重启设置
单片机·嵌入式硬件·keil
不想当程序猿_11 小时前
【蓝桥杯每日一题】求和——前缀和
算法·前缀和·蓝桥杯
析木不会编程12 小时前
【小白51单片机专用教程】protues仿真独立按键控制LED
单片机·嵌入式硬件·51单片机
m0_7482455213 小时前
吉利前端、AI面试
前端·面试·职场和发展
枯无穷肉16 小时前
stm32制作CAN适配器4--WinUsb的使用
stm32·单片机·嵌入式硬件
不过四级不改名67716 小时前
基于HAL库的stm32的can收发实验
stm32·单片机·嵌入式硬件