LED:
HAL_GPIO_WritePin(GPIOx, GPIO_Pin_x, GPIO_PIN_SET(RESET)) //引脚写
HAL_GPIO_TogglePin(GPIOx,GPIO_PIN_x); //引脚电平翻转
void LED_Disp(uint8_t led) //解决LCD引脚与LED引脚冲突的问题,该函数通常用在比赛题目中LED的编程
{
GPIOC->ODR = ~led<<8;
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
void LED_Proc(void) //该函数 其内的cnt在滴答定时器中计数,到达时间就会灭。
{
if(cnt1>0)
LED_Disp(0x05);
else if(cnt2>0)
LED_Disp(0x06);
else
LED_Disp(0x04);
}
//
KEY:
HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0); //按键读
#include "Key.h" //设置这么多标志位,是因为在比赛时需要通过按键实现不同的功能,这只是一个示例,不必多看。
uint8_t flag1 = 1;
uint8_t flag2_0 = 0;
uint8_t flag2_1 = 1;
uint8_t flag3_0 = 0;
uint8_t flag3_1 = 0;
uint8_t flag4_0 = 0;
uint8_t flag4_1 = 0;
void KEY_Scan(void)
{
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET)
{
HAL_Delay(15);
while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET);
flag1++;
if(flag1 == 4) flag1 = 1;
}
else if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET)
{
HAL_Delay(15);
while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET);
if(flag1 == 1) flag2_0 = 1;
else if(flag1 == 2) flag2_1++;
if(flag2_1 == 5) flag2_1 = 1;
}
else if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == GPIO_PIN_RESET)
{
HAL_Delay(15);
while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == GPIO_PIN_RESET);
if(flag1 == 1) flag3_0 = 1;
else if(flag1 == 2) flag3_1 = 1;
}
else if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET)
{
HAL_Delay(15);
while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET);
if(flag1 == 3) flag4_0 = 1; //
else if(flag1 == 2) flag4_1 = 1; //
}
}
#ifndef __KEY_H
#define __KEY_H
#include "gpio.h"
extern uint8_t flag1; //外部调用
extern uint8_t flag2_0;
extern uint8_t flag2_1;
extern uint8_t flag3_0;
extern uint8_t flag3_1;
extern uint8_t flag4_0;
extern uint8_t flag4_1;
void KEY_Scan(void);
#endif
///
USART:
1、串口接收回调函数,当需要接收PC端的数据时,需要使用
HAL_UART_Receive_IT(&huart1, rx, 3);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //示例不必多看
{
//printf("R37:%d,%d,%.1f", num_sum_R37,num_standard_R37,num_rate_R37);
if(rx[0] == 'R' && rx[1] == '3' && rx[2] == '7')
{
printf("R37:%d,%d,%.1f%%", num_sum_R37,num_standard_R37,num_rate_R37);
}
if(rx[0] == 'R' && rx[1] == '3' && rx[2] == '8')
{
printf("R38:%d,%d,%.1f%%", num_sum_R38,num_standard_R38,num_rate_R38);
}
HAL_UART_Receive_IT(&huart1, rx, 3);
}
//printf打印函数的实现过程, 首先点击keil5的魔术棒,打勾USE MicroLIB。
然后在usart.h文件中添加这两个文件
#include "stdio.h"
#include "stdarg.h"
//重新构造prinf函数
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 2);
return ch;
}
然后就能实现printf(“ ”); 发送数据给PC端
///
ADC:
//定义ADC值获取函数
uint16_t GetValue(ADC_HandleTypeDef hadc)
{
uint16_t adc = 0;
HAL_ADC_Start(&hadc);
adc = HAL_ADC_GetValue(&hadc);
return adc;
}
R37_V = GetValue(hadc2)*3.3/4095;
R38_V = GetValue(hadc1)*3.3/4095;
ADC连续读两次,对于那些用同一个ADC但不同通道的。比如MPC4017电阻分压的电压值与R37的电压值共用一个ADC。
///
Timer:
1、基础功能定时器:
HAL_TIM_Base_Start_IT(&htim1);//使用定时器,需要用此函数打开才能工作。
选择80MHZ的时钟频率:
80000000/80/1000=1ms,即1ms溢出,触发定时器中断。
在定时器回调函数中做相应事情,定时器只需打开一次,不需要在回调函数中再打开
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim == &htim1)
{
static uint8_t cnt = 0;
if(++cnt == 100)
{
cnt = 0;
Data++;
}
}
}
2、定时器其他功能: 输入捕获,(相应配置)
输入捕获需要用此函数才能工作:
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
回调函数: 此时回调函数计R38输入的脉冲周期, 上升沿触发。(进入一次回调函数就得打开一次定时器输入捕获功能)
if(htim == &htim3)
{
tim3_cnt1=__HAL_TIM_GetCounter(&htim3);
__HAL_TIM_SetCounter(&htim3,0);
f30=1000000/tim3_cnt1;
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
}
1us计一次, f30即计数的倒数即频率。
若要求占空比, 则需上升沿触发,下一次要下降沿触发,得到高电平的时间,再除以总时间*100%得占空比
要改变触发方式,即改变TIM2->CCER
TIM2->CCER |=0x02//上升沿触发 TIM2->CCER &=~0x02 //下降沿触发
I2C: //官方提供了i2c的时序代码,不需要自己写,但对应读写需要自己写。
首先mian函数中先初始化:void I2CInit(void)
AT24C02的读写:
注意: 写入后直接读出会导致错误。 写入后应加个延时,我也不知道为什么。可能写入过慢。
导致还没就写进去就读出来,导致错误。
MPC4017的读写:
MPC4017读写倒不会出现这种情况,但是以防万一。
写入和读出的数字是一样的, 要*0.78740才能得到相应电阻值
Res_Value,是电阻的分压
滴答定时器: 1ms计一次
可以在滴答定时器里做一些事情
//
c语言中重要的函数:sprintf()
#include "string.h"
#include "stdio.h"
//
DAC: 其实我不知道有什么用, 数转模,但在实际做题的时候没见过。
配置:
/
LCD: 底层代码过于复杂,所以主办方并没有为难我们。 直接复制过来自己的工程,然后配置相关引脚即可, 现在需要熟悉所给的函数的相关功能:
首先需要先在mian函数中初始化:LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue); //设置背景颜色
LCD_SetTextColor(White); //设置文字颜色
LCD_DisplayStringLine(Line0, (uint8_t *)" Anything "); 在第几行显示字符串
这就是蓝桥杯嵌入式的全部了!!