当前位置: 首页 > news >正文

蓝桥杯嵌入式学习(cubemxkeil5)

目录

一、LED

二、KEY

三、ADC

四、PWM

五、IC

六、IC(测量占空比) 

七、UART

八、I2C

九、RTC

十、 RTC闹钟


一、LED

引脚PC8~PC15,默认高电平(灭)。

此外还要配置PD2为输出引脚(控制LED锁存) ,默认低电平(锁住)!!!

#include "led.h"void led_disp(unsigned char disp_led)
{HAL_GPIO_WritePin(GPIOC,GPIO_PIN_ALL,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOC,disp_led<<8,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}/*使用方法*/
unsigned char ledon=0x00;
led_disp(ledon|=0x01);//第一个led亮
led_disp(ledon|=0x04);//第三个led亮led_disp(ledon&=~(0x01))//第一个led灭
led_disp(ledon&=~(0x08))//第四个led灭

二、KEY

选择PB0~PB2,PA0为输入模式,配置成上拉输入。 我们按键用的是定时器轮询检测按键状态(还能实现长按短按的功能)。

时钟源选择内部时钟,设置成100Hz,也就是10ms进一次中断,别忘了在NVIC Settings打勾 

#include "intterrupt.h"struct keys
{unsigned char sta;//引脚电平unsigned char flag;//是否按下unsigned char longflag;//是否长按unsigned char judge;//进度标志位unsigned int time;//长按时要用到
};
struct keys key[4]={0,0,0};void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIMX){key[0].sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);key[1].sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);key[2].sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);key[3].sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);for(int i=0;i<4;i++){switch(key[i].judge){case 0:{if(key[i].sta==0){key[i].judge=1;key[i].time=0;}}break;case 1:{if(key[i].sta==0){key[i].judge=2;}else{key[i].judge=0;}}break;case 2:{if(key[i].sta==1)//松手的时候根据time来判断长短按{key[i].judge=0;if(key[i].time<200)//小于2s{key[i].flag=1;}}else//没松手{key[i].time++;if(key[i].time>200)//大于2s{key[i].longflag=1;}}}break;}}}
}/*使用方法*/void key_proc(void)
{if(key[0].flag==1)//按键1短按{//处理数据key[0].flag=0;}if(key[3].longflag==1)//按键4长按{//处理数据key[3].longflag=0;}
}

key_proc()丢while里。


三、ADC

板子从左往右数第一个是PB15引脚(对应ADC2的通道15),第二个是PB12引脚(对应ADC1的通道11),采样周期选到最大,一定程度上能防止adc一直抖动。

#include "myadc.h"double adc_get(ADC_HandleTypeDef *pin)
{unsigned int adc;HAL_ADC_Start(pin);adc=HAL_ADC_GetValue(pin);//HAL_Delay(1);可不加return adc*3.3/4096;                                                                                                                                                                           
}/*使用方法*/
adc_get(&hadc2);//获取第一个电压
adc_get(&hadc1);//获取第二个电压

四、PWM

假设题目要求我们在PA7引脚输出频率为1000Hz,占空比为50%的PWM波

注意所选定时器最好不要和按键中断的定时器共用 !

frq=80000000/800/100;duty=50/100;

//在while之前启动PWM
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);/*设置占空比和频率*/
__HAL_TIM_SET_PRESCALER(&htim17,80000000/100/PWM_frq);//设置频率__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,duty);//设置占空比

五、IC

PB4和PA15引脚用于输入捕获,测量频率。最好用TIM2和TIM3! 按键定时器等所有外设都设置好了再设置。

#include "intterrupt.h"unsigned int ccrl_val=0;
unsigned int frq=0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM2){ccrl_val=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);__HAL_TIM_SetCounter(htim,0);frq=(80000000/80)/ccrl_val;HAL_TIM_IC_Start_IT(htim,TIM_CHANNEL_1);}//if(htim->Instance==TIM3)//{//  //}//同上 再定义一个变量即可 注意在main里extern frq
}/*使用方法*/
//在while之前启动IC 就可以在while里读frq
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);//启动第一个IC
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);//启动第二个IC

六、IC(测量占空比) 

假设题目要求我们检测PA7引脚输入的信号的占空比

cubemx如上配置,PA7对应TIM3的通道二,那么把通道二设置成直接模式,另外选一个通道设置成间接模式,让直接模式测量上升沿,间接模式测量下降沿。

#include "intterrupt.h"unsigned int ccrl_vala=0,ccrl_valb=0;
unsigned int frq=0;
double duty=0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM3){ccrl_vala=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2);//直接ccrl_valb=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);//间接__HAL_TIM_SetCounter(htim,0);frq=(80000000/80)/ccrl_vala;duty=(double)(ccrl_valb/ccrl_vala)*100;HAL_TIM_IC_Start_IT(htim,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(htim,TIM_CHANNEL_2);}
}

 这个看看就好 考的几率不大。


七、UART

记得手动选择PA9和PA10,波特率按题目要求,一般是9600。记得开中断!!! 

#include "interrupt.h"
#include "usart.h"char rxdata[22];
unsigned char rxbit;
unsigned char rx_p;void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{rxdata[rx_p++]=rxbit;HAL_UART_Receive_IT(&huart1,&rxbit,1);
}/*使用方法*/
include "string.h"//使用memset函数
//在while之前初始化 调用HAL_UART_Receive_IT(&huart1,&rxbit,1);void uart_proc(void)
{if(rx_p>0){if(rx_p==x)//实际要接收的位数{//处理}else{//报错}rx_p=0;memset(rxdata,0,22);//22要和你设置的rxdata长度一样}
}/*注意事项*/
//在while循环里这样写 防止接收不完整
while(1)
{if(rx_p!=0){uint8_t temp=rx_p;HAL_Delay(1);if(rx_p==temp){uart_proc();}}
}

八、I2C

直接在官方给的i2c_hal.c里写,cubemxPB6和PB7直接选择输出模式。

#include "i2c_hal.h"//官方的.c函数void eeprom_write(unsigned char addr,unsigned char dat)
{I2CStart();I2CSendByte(0xa0);//0表示写I2CWaitAck();I2CSendByte(addr);I2CWaitAck();I2CSendByte(dat);I2CWaitAck();I2CStop();
}unsigned char eeprom_read(unsigned char addr)
{unsigned char dat;I2CStart();I2CSendByte(0xa0);//0表示写I2CWaitAck();I2CSendByte(addr);I2CWaitAck();I2CStop();I2CStart();I2CSendByte(0xa1);//1是读I2CWaitAck();dat=I2CReceiveByte();I2CSendNotAck();//读出来之后发送非应答I2CStop();return dat;
}/*使用方法*/
eeprom_write(0,data);//地址从0开始,存八位的数据。data=eeprom(0);//读地址

八位无符号整型数据可以直接写和读,double类型的参考下图;

注意:每次写入都要延时5ms!!!  


九、RTC

近几年基本不考,但要会最基本的rtc时钟。参数填125和6000。

#include "stdio.h"RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;while(1)
{HAL_RTC_GetTime(&hrtc,&sTime,RTC_FORMAT_BIN);//一定要先获取时间再获取日期!!!HAL_RTC_GetDate(&hrtc,&sDate,RTC_FORMAT_BIN);char text[50];sprintf(text,"%02d:%02d:%02d--%02d:%02d:%02d",sDate.Year,sDate.Month,sDate.Date,sTime.Hours,sTime.Minutes,sTime.Seconds);//再用官方提供的lcd显示函数显示年月日时分秒即可
}

RTC暂停:__HAL_RCC_RTC_DISABLE(); 

RTC恢复:__HAL_RCC_RTC_ENABLE(); 


十、 RTC闹钟

记得开中断,闹钟先设置成3s后

RTC_AlarmTypeDef sAlarm;void GET_Time(void)
{HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
}void SET_alarm(void)
{sAlarm.AlarmTime.Hours = 0x00;sAlarm.AlarmTime.Minutes = 0x0;
/**/sAlarm.AlarmTime.Seconds = sTime.Seconds+1;sAlarm.AlarmTime.SubSeconds = 0x0;sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS|RTC_ALARMMASK_MINUTES;sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;sAlarm.AlarmDateWeekDay = 0x1;sAlarm.Alarm = RTC_ALARM_A;
/**/if(sAlarm.AlarmTime.Seconds==60)sAlarm.AlarmTime.Seconds=0;
/**/HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN);//这里要注意,我们选择的是十进制
}//中断服务函数
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{GET_Time();SET_Alarm();//操作
}

 SET_alarm里加了多行注释的是自己添加的东西,其余从rtc.c复制

每一秒进一次rtc闹钟的回调函数,在回调函数里进行对应的操作即可。

(可能不考,了解即可) 

相关文章:

  • 网络销售应该注册什么公司温州seo公司
  • 做代收的网站有哪些网络销售平台排名
  • 网站建设 开发工具 python韶关新闻最新今日头条
  • 镇江百度网站排名百度搜不干净的东西
  • seo关键词优化软件排名赣州seo优化
  • 广东一站式网站建设报价百度客服24小时电话人工服务
  • 记一次 Kafka 磁盘被写满的排查经历
  • HarmonyOS Next的HiLog日志系统完全指南:从入门到精通
  • 图的拓扑排序管理 Go 服务启动时的组件初始化顺序
  • Flink内存配置
  • GPU常见规格及算力
  • Langchain实战指南:从入门到精通AI链式编程!
  • 使用 ttrpc 实现高效的进程间通信(附 Go Demo)
  • 从零到一训练一个 0.6B 的 MoE 大语言模型
  • 6月24日星期二今日早报简报微语报早读微语早读
  • 代码随想录|图论|02深度优先搜索理论基础
  • JVM(11)——详解CMS垃圾回收器
  • Excel学习04
  • IAR平台全面升级,提升瑞萨MCU架构的嵌入式软件开发效率
  • 从零开始学习 Go 语言:快速入门指南(完整版)
  • 左神算法之数字字符串解码方案计数算法
  • 开篇-认识Gin——Go语言Web框架的性能王者
  • Redis 哨兵模式学习笔记
  • 华为云Flexus+DeepSeek征文 | DeepSeek-V3/R1 商用服务华为云开通指南及使用体验全解析
  • python果蔬种植销售一体化服务系统
  • 对于高考边界的理解以及未来就业层级的学习与思考