蓝桥杯——嵌入式学习日记

因为lED和LCD共用PC8~PC15引脚,要通过锁存(LE)和(GPIOC->ODR)来避免LED和LCD引脚冲突

修改点:

  • main.c中,GPIO初始化引脚后,LE(PD2引脚低电平锁存,退出透明模式,LCD的输出就无法影响LED引脚的状态)
  • LCD_DisplayStringLine();

  • LCD_Clear()

定时器中断

定时器功能

定时器频率和周期公式

  • PSC(预分频系数): 1 / f == T, 乘上(PSC+1) 得到执行一次累加操作的实际周期,再乘上(ARR+1)等于中断周期
  • 预分频理解: 假设原本1ms执行一次累加, PSC == 2, 则当前变成2ms才执行一次累加(另外的1ms分给了别的任务)
  • 时钟配置
    - 通过STM32CubeMX,配置TIM2(通用定时器)的参数(Fsystem = 80MHz = 80 000 000)
    假设定时中断周期要求 1s , 则 ARR+1=8000 , PSC+1 = 10000

使能定时中断

c 复制代码
//定时中断需要使能
   HAL_TIM_Base_Start_IT(&htim2);  //HAL_TIM_Base_Start_IT函数用于以中断模式启动定时器

长按键、短按键(使用TIM3)



利用cnt计时

本质就是将计算 T 公式里的: ARR 代替为 CNT(计数值)------ T = 1 / f = CNT * (PSC + 1) / f

LCD高亮显示

c++ 复制代码
//按键4通过循环取余数,控制lcd某行高亮显示
static uint16_t temp_line = 0;
void Hight_light_lcd_line(){
     
	key_s4 = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);

	if(key_s4==RESET && k4_last_state==SET){  //按下B4
	    temp_line++;
		temp_line%=3;
		HAL_Delay(200);
	}
	
	//控制功能栏轮流高亮显示
	if(temp_line==0){
	   
       //sprintf();   用于写入字符串到字符数组
	   LCD_SetBackColor(Red);  //该行以下的背景颜色是红色
	   sprintf(text, "    Hello, Vodka!     ");
	   LCD_DisplayStringLine(Line3, (uint8_t*) text );
		
	   LCD_SetBackColor(Black);		//该行以下的背景颜色是黑色
	   sprintf(text, "      Count: %d        ", Count);
	   LCD_DisplayStringLine(Line4, (uint8_t*) text);
	   
		
	   sprintf(text, "   LightMode: %d        ", lightMode);
	   LCD_DisplayStringLine(Line5, (uint8_t*) text);

	}
	else if(temp_line==1){
	   //sprintf();   用于写入字符串到字符数组
	   sprintf(text, "    Hello, Vodka!     ");
	   LCD_DisplayStringLine(Line3, (uint8_t*) text );
		
	   LCD_SetBackColor(Red);	
	   sprintf(text, "      Count: %d        ", Count);
	   LCD_DisplayStringLine(Line4, (uint8_t*) text);
	   LCD_SetBackColor(Black);	
		
	   sprintf(text, "   LightMode: %d        ", lightMode);
	   LCD_DisplayStringLine(Line5, (uint8_t*) text);	
	}
    else if(temp_line==2){
	   //sprintf();   用于写入字符串到字符数组
	   sprintf(text, "    Hello, Vodka!     ");
	   LCD_DisplayStringLine(Line3, (uint8_t*) text );
		
	   sprintf(text, "      Count: %d        ", Count);
	   LCD_DisplayStringLine(Line4, (uint8_t*) text);
	   
	   LCD_SetBackColor(Red);	
	   sprintf(text, "   LightMode: %d        ", lightMode);
	   LCD_DisplayStringLine(Line5, (uint8_t*) text);
	   LCD_SetBackColor(Black);	
	}
	//LED闪烁,间隔两秒闪烁一次
	light_led(3,lightMode%2);
   
}

PWM波形

原理

占空比:高电平持续时间占整个周期时长的比值
PWM频率和占空比的概念:占空比由捕获比较寄存器(CCR)决定,而频率由ARR和PSC共同决定。不同的PSC和ARR组合可以得到相同的频率,只要它们的乘积相同。例如,PSC=1和ARR=1000,与PSC=2和ARR=500,得到的频率是一样的,但占空比的调节范围可能不同,因为ARR的值不同。

CubeMX配置

初始化

CCR(输出比较寄存器)

输入捕获测量引脚输出PWM波形

通过计算两个中断之间CNT差值(capture_value),得出中断周期(捕获周期)

捕获周期计算公式

信号发生器

PWM输出引脚和输入捕获引脚,板子上的引脚R37~R40分别是:电压采集1、电压采集2、频率输出1(PB4)、频率输出2(PA15)

例题


TIM17配置(记得配置NVIC)

pwm输入捕获代码

PA1、PA7需要杜邦线连接; PA1配置TIM2的通道2、PA7配置TIM17的通道1

输入捕获555定时器的频率

时钟通道配置

引脚PA15和引脚PB4测量频率输入1和频率输入2

代码

TIM2、TIM16输入捕获中断开启

TIM2、TIM16输入捕获展示

ADC测量

配置ADC1和ADC2

代码实现

USART通信(异步、全双工、字节传输)

配置

类型转换问题

c++ 复制代码
字符类型(char)在算术运算中会被转换为整数类型(int)。
short型会被转换为int型。
float型会被转换为double型以提高精度。
当有符号数与无符号数进行运算时,所有操作数自动转换为无符号类型

字符与字节

存储字符串 "bens in 2023/23/23" 的 char 数组需占用 19 字节,空格也算字符,包含'\0'作为终止符(转义字符\n,\t也算字符)

代码实现(向上位机发送数据)

c++ 复制代码
void UART_Tx_Test(void){
   
   sprintf((char*)uart_tx_text,"Hey~ Vodka~\r\n");	
   HAL_UART_Transmit(&huart1, (uint8_t *)uart_tx_text, strlen(uart_tx_text), 50);  //超时时间限制为50ms
   HAL_Delay(2000); //发送数据间隔时间: 0.1s	
	
}

代码实现(按字节循环接收uart串口数据)

主函数

c++ 复制代码
//util.h
#ifndef __util_h
#define __util_h
//串口接收变量
extern char uart_rx_text[22];
extern uint8_t Rx_Byte;
extern uint8_t Rx_Index;
extern uint8_t Rx_DoneFlag;

//车辆信息(串口接收)
extern char car_type[5];
extern char car_data[5];
extern char car_time[13];

//测试函数                                      
void lcd_test(void);                            
                                                                                            
//ADC测量                                       
void ADC_show(void);                            
	
//ADC测量电压
void ADC_Caculate_Volt(void);

//串口发送测试
void UART_Tx_Test(void);

//串口接收测试(只能通过中断接收)
void UART_Rx_Test(void);

//UART中断数据后续处理(放在主程序里循环)
void uart_data_process(void);
	
#endif


//util.c
//UART中断回调接收数据(第一次中断在主函数)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart){
    if(huart->Instance == USART1){
		uart_rx_text[Rx_Index++] = Rx_Byte;
		//判断接收的字节是否完成
   		if(Rx_Index==22||Rx_Byte=='\n'){
		    Rx_DoneFlag = 1;
		}
		//继续开启下一次中断
		HAL_UART_Receive_IT(&huart1,&Rx_Byte,sizeof(Rx_Byte));
	}
}

//UART中断数据后续处理(放在主程序里循环)
void uart_data_process(void){
   //判断中断接收完毕标志
   if(Rx_DoneFlag==1){
      if(Rx_Index <= 22){   //接收数组长度22字节,除去\0,实际只能存储21个字节
	     sscanf(uart_rx_text, "%4s %4s %10s", car_type, car_data, car_time);
		 //展示数据
		 LCD_SetBackColor(Yellow);
         LCD_SetTextColor(Black);		
		  
          sprintf(rx_display_text,"        UART_Rx           ");
		  LCD_DisplayStringLine(Line0,rx_display_text);		  
		  
		  sprintf(rx_display_text,"    car_type:%s       ",car_type);
		  LCD_DisplayStringLine(Line1,rx_display_text);
		  
		  sprintf(rx_display_text,"    car_data:%s         ",car_data);
		  LCD_DisplayStringLine(Line2,rx_display_text);
		  
		  sprintf(rx_display_text," car_time:%s        ",car_time);
		  LCD_DisplayStringLine(Line3,rx_display_text);		  
	  }
	  else{
	     sprintf(rx_display_text,"        Rx_Error\r\n          ");
		 HAL_UART_Transmit(&huart1, (uint8_t*)rx_display_text, strlen(rx_display_text), 50); 
	  }
	  //重置相应标志
	  Rx_DoneFlag = 0;
	  Rx_Index = 0;
	  memset(uart_rx_text,0,strlen(uart_rx_text));
   }
}

通过定时器,UART串口接收不定长的数据

原理

传送一个字节花费的时间,转化为CNT的值来判断

间隔指定时间读取一个数据

判断结束的标志:最后一个位的时间大于1.5ms

配置

TIM4:内部时钟、波特率:9600、 开启中断、 PSC: 8000-1

串口中断开启、时钟使能

中断处理、中断回调


自行编写




IIC

IIC原理图

非易失性存储器

从机地址

读写位:1是读、2是写

代码实现


RTC实时时钟

设置(读取)时间、日期,设置闹钟

RTC配置


代码实现


相关推荐
云上艺旅4 小时前
K8S学习之基础四十七:k8s中部署fluentd
学习·云原生·容器·kubernetes
网络安全指导员6 小时前
威胁驱动的网络安全方法论
开发语言·学习·安全·web安全·php
m0_735234606 小时前
蓝桥杯算法实战分享:算法进阶之路与实战技巧
算法·职场和发展·蓝桥杯
_GR7 小时前
2021年蓝桥杯第十二届C&C++大学B组真题及代码
c语言·数据结构·c++·算法·蓝桥杯
Leo来编程7 小时前
Python学习第二十三天
python·学习
咚咚轩7 小时前
蓝桥杯12届 货物摆放
蓝桥杯
郭逍遥8 小时前
GZCTF平台搭建及题目上传
笔记·学习·ubuntu·docker·容器
吱屋猪_9 小时前
MyBatis 学习经验分享
经验分享·学习·mybatis
落笔画忧愁e11 小时前
数据通信学习笔记之OSPF其他内容1
笔记·学习
遥感小萌新11 小时前
【蓝桥杯】真题 2386染色时间 (优先队列BFS)
职场和发展·蓝桥杯·宽度优先