蓝桥杯嵌入式模板(cubemx&keil5)

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

(可能不考,了解即可) 

  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
### 回答1: 蓝桥杯嵌入式Keil的支持包是为了方便嵌入式软件开发而设计的。Keil作为一款常用的嵌入式开发工具,具有强大的功能和稳定的性能,可以帮助开发者快速而高效地进行嵌入式软件的编写和调试。 蓝桥杯嵌入式Keil的支持包提供了对多种嵌入式开发板的支持,包括常见的STM32、51系列单片机等。通过使用这些支持包,开发者可以直接在Keil的开发环境中进行项目配置和编写代码,无需额外的多余设置。 使用蓝桥杯嵌入式Keil的支持包,开发者可以充分发挥Keil的优势,如强大的调试功能、直观的界面设计等,提高开发效率和软件质量。同时,这些支持包还提供了丰富的示例代码和开发文档,帮助开发者更好地理解和使用嵌入式开发板的各种功能,快速上手。 蓝桥杯嵌入式Keil的支持包不仅支持单片机的基本功能,如GPIO控制、定时器、中断等,还支持各种外设模块的驱动,如UART、SPI、I2C等。这些支持包对于参加蓝桥杯嵌入式竞赛的选手来说尤为重要,因为它们能够大大简化开发过程,降低学习和开发的门槛。 总之,蓝桥杯嵌入式Keil的支持包是一个为嵌入式软件开发者提供便利的工具,它充分发挥了Keil的优势,提供了对多种嵌入式开发板的支持,使得软件开发更加高效和简便。通过使用这些支持包,开发者可以更好地应对蓝桥杯嵌入式竞赛的挑战,提升自己的技能水平。 ### 回答2: 蓝桥杯嵌入式keil的支持包是蓝桥杯竞赛扩展嵌入式开发环境和工具的一项重要功能。蓝桥杯是中国IT领域的一项重要竞赛,旨在培养和选拔优秀的计算机人才。而嵌入式开发则是计算机领域的一个重要分支,专门用于设计和开发嵌入式系统。 Keil是一款广泛应用于ARM嵌入式系统开发的集成开发环境(IDE),它提供了丰富的开发工具和支持包来简化嵌入式软件的开发过程。蓝桥杯嵌入式keil支持包是为了配合蓝桥杯嵌入式竞赛而开发的一套针对特定开发需求的支持工具。 蓝桥杯嵌入式keil的支持包主要有以下几个特点和功能:首先,它提供了完整的开发环境,包括Keil MDK集成开发环境、编译器、调试器等。这些工具能够帮助参赛选手更高效地进行软件开发和调试。 其次,蓝桥杯嵌入式keil的支持包还包含了一些专门为竞赛设计的特殊功能。例如,它提供了一套完整的蓝桥杯嵌入式竞赛项目模板,该模板包含了常用的功能代码和设置,可以极大地简化竞赛项目的初始化工作。 此外,蓝桥杯嵌入式keil的支持包还提供了一些与竞赛相关的实用工具和示例代码,这些工具和示例代码可以帮助选手更好地理解竞赛规则和要求,提高编程能力和竞赛成绩。 总之,蓝桥杯嵌入式keil的支持包为参加蓝桥杯嵌入式竞赛的选手提供了一套高效、全面的开发环境和工具,帮助他们更好地完成竞赛项目,培养和选拔优秀的嵌入式系统开发人才。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sakabu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值