蓝桥杯嵌入式模板(cubemxkeil5)

news2024/11/20 1:51:16

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闹钟的回调函数,在回调函数里进行对应的操作即可。

(可能不考,了解即可) 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1594011.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

五子棋:不会下五子棋也没关系,会用Java写五子棋就行

关注公号“微澜网络”获取完整源代码&#xff01; 效果展示&#xff1a; 目录 效果展示&#xff1a; 导语&#xff1a; 游戏介绍&#xff1a; 程序设计&#xff1a; 1.游戏规则和功能&#xff1a; 2.用户界面设计&#xff1a; 3.程序架构设计&#xff1a; 4.可扩展性和灵…

【IC验证】fork...join

1.fork...join 各线程并行执行&#xff0c;当耗时最长的线程执行完后&#xff0c;跳出该语句块。如果任何一个子线程无法结束&#xff0c;则整个fork...join将被挂起 2.fork...join_any 如果任何一个子线程完成&#xff0c;则程序允许执行fork...join_any块外面接下来的语句…

SVN的介绍

首先SVN是什么&#xff1a; Apache下的一个开源的项目Subversion&#xff0c;通常缩写为 SVN&#xff0c;是一个版本控制系统。 版本控制系统是一个软件&#xff0c;它可以伴随我们软件开发人员一起工作&#xff0c;让我们编写代码的完整的历史保存下来。 目前它的各个版本的…

华为ensp中aaa(3a)实现telnet远程连接认证配置命令

作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年4月14日18点49分 AAA认证的全称是Authentication、Authorization、Accounting&#xff0c;中文意思是认证、授权、计费。 以下是详细解释 认证&#xff08;Authentic…

Kylin-Server-V10-SP3-General-Release-2303-X86_64

Kylin-Server-V10-SP3-General-Release-2303-X86_64 银河麒麟V10 银河蓝色麒麟比红麒麟养眼多了 Kylin-CSDN博客 Kylin IPv4 setting-CSDN博客

安全加速SCDN带的态势感知能为网站安全带来哪些帮助

随着安全加速SCDN被越来越多的用户使用&#xff0c;很多用户都不知道安全加速SCDN的态势感知是用于做什么的&#xff0c;德迅云安全今天就带大家来了解下什么是态势感知&#xff0c;态势感知顾名思义就是对未发生的事件进行预知&#xff0c;并提前进行防范措施的布置&#xff0…

Android安卓开发 - 开发基础(二)

App的工程结构 本节介绍App工程的基本结构及其常用配置&#xff0c;首先描述项目和模块的区别&#xff0c;以及工程内部各目录与配置 文件的用途说明&#xff1b;其次阐述两种级别的编译配置文件build.gradle…

用于扩展Qt本身的插件(上)

Qt自身插件 引言示例插件与应用插件的程序作为整体插件和应用插件的程序单独存在实现插件编写测试插件的程序应用插件运行结果引言 用于扩展qt自身的插件按照我的理解分为两种: 1. 直接扩展Qt自身,无需在QtCreator的设计器中加载; 2. 扩展Qt自身,同时需要在QtCreator的设计…

【SpringBoot整合系列】SpringBoot 实现大文件分片上传、断点续传及秒传

目录 功能介绍文件上传分片上传秒传断点续传 相关概念相关方法大文件上传流程前端切片处理逻辑后端处理切片的逻辑流程解析 后端代码实现功能目标1.建表SQL2.引入依赖3.实体类4.响应模板5.枚举类6.自定义异常7.工具类8.Controller层9.FileService10.LocalStorageService11.File…

设计模式代码实战-工厂模式

1、问题描述 小明家有两个工厂&#xff0c;一个用于生产圆形积木&#xff0c;一个用于生产方形积木&#xff0c;请你帮他设计一个积木工厂系统&#xff0c;记录积木生产的信息。 输入案例 3 Circle 1 Square 2 Circle 1 2、工厂模式 将产品的创建过程封装在⼀个⼯⼚类中&am…

变换时光:用MagicTime生成落叶纷飞的视频

简介 MagicTime: https://huggingface.co/spaces/BestWishYsh/MagicTime 是一款基于时间延迟视频生成模型的变体人工智能工具&#xff0c;它可以让您将静止图像转换为动态视频&#xff0c;赋予图像生命。 今天&#xff0c;我们将利用MagicTime来生成一片落叶纷飞的景象&#…

【从浅学到熟知Linux】程序地址空间分布与进程地址空间详谈(含虚拟地址到物理地址的映射)

&#x1f3e0;关于专栏&#xff1a;Linux的浅学到熟知专栏用于记录Linux系统编程、网络编程等内容。 &#x1f3af;每天努力一点点&#xff0c;技术变化看得见 文章目录 程序地址空间概览进程地址空间 程序地址空间概览 我们在执行一个C语言程序时&#xff0c;它包含代码、变量…

配置DHCP服务器实现为动态客户端和静态客户端分配不同网络参数

相关学习推荐&#xff1a;什么是DHCP?为什么要使用DHCP&#xff1f; 华为HCIP课程【视频教程】&#xff1a;华为HCIP必考题&#xff1a;DHCP协议原理与配置 组网需求 如图1所示&#xff0c;Router作为企业出口网关&#xff0c;PC和IP Phone为某办公区办公设备。为了方便统一管…

记一次Oracle DG备库实例宕分析

一、问题现象 同事反馈国外点在国内的XXX备库实例宕&#xff0c;尝试将该实例重启&#xff0c;结果重启报如下错误&#xff0c;未能正常启动该数据库。 Standby crash recovery failed to bring standby database to a consistent point because needed redo hasnt arrived yet…

全国贫困县DID数据(2008-2022年)

数据来源&#xff1a;国W院扶贫开发领导小组办公室 时间跨度&#xff1a;2008-2022年 数据范围&#xff1a;各县域 数据指标 年份 县域名称 所属地市 所属省份 县域代码 是否贫困县(是为1&#xff0c;否为0) 参考文献&#xff1a; [1]马雯嘉,吴茂祯.从全面脱贫到乡村振兴…

ChatGPT在线网页版

ChatGPT镜像 今天在知乎看到一个问题&#xff1a;“平民不参与内测的话没有账号还有机会使用ChatGPT吗&#xff1f;” 从去年GPT大火到现在&#xff0c;关于GPT的消息铺天盖地&#xff0c;真要有心想要去用&#xff0c;途径很多&#xff0c;别的不说&#xff0c;国内GPT的镜像…

FL Studio808鼓音在哪 FL Studio怎么让音乐鼓点更有力 FL Studio教程

FL Studio808鼓音在哪&#xff1f;808是一款电鼓机的名称&#xff0c;它发出的声音也被称之为808鼓&#xff0c;通常我们可以安装鼓机插件来使用&#xff0c;但FL Studio中自带的也有808鼓的采样音频。FL Studio怎么让音乐鼓点更有力&#xff1f;让鼓点更有力要从EQ均衡器、压缩…

Pandas学习笔记——第二弹

在用正则表达式对数据进行filtering的时候&#xff0c;出现字符串和整数变量不匹配的问题&#xff0c;例如&#xff1a; 给3加上引号就好了&#xff1a;3 但是为什么10000不需要加引号&#xff0c;而3需要呢&#xff1f;这是因为他们的变量类型不一样的&#xff0c;于是总结一下…

分布式ID的方案和架构

超过并发&#xff0c;超高性能分布式ID生成系统的要求 在复杂的超高并发、分布式系统中&#xff0c;往往需要对大量的数据和消息进行唯一标识如在高并发、分布式的金融、支付、餐饮、酒店、电影等产品的系统中&#xff0c;数据日渐增长&#xff0c;对数据分库分表后需要有一个唯…

常见公开可用的数据集——对算法的鲁棒性和性能进行全面评估

提供了一组公开可用的数据集,这些数据集包含不同的图像变换,允许对算法的鲁棒性和性能进行全面评估。特征匹配实验中使用的数据集汇总信息如表2所示,图14为除YFCC100M外各数据集的样例图像。 Proj:202404 CMC-R.W Citavi (1) VGG [115]: This dataset comprises 40 pairs…