蓝桥各方面单片机使用心得
使定时器接近精确的重设
TIM2->CNT=0;
TIM2->SR=0;//https://blog.csdn.net/weixin_44788542/article/details/113111139
HAL_TIM_Base_Start_IT(&htim2);
该文章将记录蓝桥杯的模块使用方案
省赛
LCD
io:请使用LCD例程模板
为保证在LCD与灯状态的共存,需要做出如下修改
lcd.c
LCD_WriteReg函数
LCD_WriteRAM_Prepare函数
LCD_WriteRAM函数
一共三个函数每个函数前后两行供六行
u16 tmp=GPIOC->ODR;
//函数原本内容
GPIOC->ODR=tmp;
板载EEPROM
I2C软件模拟
io:PB6 PB7,GPIO OUTPUT不需要做额外配置

移植i2c.h后如下,默写如下函数
main.c
uint8_t IICRead(uint8_t address)
{
unsigned char val;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(address);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
val = I2CReceiveByte();
I2CWaitAck();
I2CStop();
HAL_Delay(10);//防止速度过快
return(val);
}
//
void IICWrite(unsigned char address,unsigned char info)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(address);
I2CWaitAck();
I2CSendByte(info);
I2CWaitAck();
I2CStop();
HAL_Delay(10);
}
启动->写入元器件写地址->写入写入地址->写入数据->结束
启动->写入元器件写地址->写入读取地址->启动->写入元器件读地址->读取->结束
板载ADC
ADC硬件
io:打开IN15即可,不需要额外配置

main.c
HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);
uint16_t getADC(void)
{
uint16_t adc = 0;
HAL_ADC_Start(&hadc2);
adc = HAL_ADC_GetValue(&hadc2);
return adc;
}
sprintf(tmp,"VR37:%.02fV",(float)getADC()/4096*3.3);
板载LED灯
锁存器,PD2高电平同步,低电平锁存
警告,例程默认不初始化PD2,记得开
使用:
main.c
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
//全关灯
RTC

国赛扩展板
国赛板子记得看跳线帽
数码管
跳线帽:SCK,RCK,RES
io:不需要配置,在SEG_Init会做
复制文件:seg.c
初始化函数:main.c
SEG_Init();
使用:
SEG_DisplayValue(1,1,1);//1,1,1
SEG_DisplayValue(10,10,10);//A,A,A
SEG_DisplayValue(16,16,16);//全灭,达到灭灯的效果!!!
BUTTON(ADC)
跳线帽:AKEY
io:需要配置ADC2,IN13 Single-ended
复制文件:button.c,其中getADC()函数需要自己写
使用:
u8 key_val = Scan_Btn();
温度传感器(DS18B20)
跳线帽:TDQ
io:不需要配置,在ds18b20_init_x会做
复制文件:ds18b20.c
使用:
ds18b20_init_x();
read = (ds18b20_read() & 0x07FF);
tem = read / 16.;
温湿度传感器(DHT11)
跳线帽:HDQ
io:不需要配置,在DHT11_Init会做
复制文件:dht11.c
使用:
u8 temper ;
u8 humi ;
DHT11_Init();
DHT11_Read_Data(&temper, & humi);
MEMS传感器(LIS302DL)
???
光敏电阻(DO)
跳线帽:TRDO
io:配置PA3为输入口
使用:低电平为亮,高电平为不亮
if(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) )
{
LCD_DisplayStringLine(Line7, (u8 *)" DO:High ");
}
else
{
LCD_DisplayStringLine(Line7, (u8 *)" DO:Low ");
}
光敏电阻(AO)
跳线帽:TRAO
io:配置ADC2 IN17 Single-end
使用:
tmp = getADC();
sprintf((char *)str, " R-P:%.2fK ", tmp / (4096. - tmp) * 10);
AD采集×2
跳线帽:AO1 AO2 RP5 RP6
io:配置ADC2 IN17 Single-end
使用:
(例程的写法多少有些暴力)
uint16_t getADC_RP5(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
uint16_t adc = 0;
sConfig.Channel = ADC_CHANNEL_13;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
Error_Handler();
}
HAL_ADC_Start(&hadc2);
adc = HAL_ADC_GetValue(&hadc2);
return adc;
}
uint16_t getADC_RP6(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
uint16_t adc = 0;
sConfig.Channel = ADC_CHANNEL_17;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
Error_Handler();
}
HAL_ADC_Start(&hadc2);
adc = HAL_ADC_GetValue(&hadc2);
return adc;
}
频率采集
跳线帽:PWM2 RP2
io:配置TIM3 CH2 上升沿 PSR:80 ARR:65535 自动重装关

使用:
main.c
//启动一次中断先
HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);
uint32_t cc1_value_2 = 0; // TIMx_CCR1 的值
uint32_t RP2 = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
cc1_value_2 = __HAL_TIM_GET_COUNTER(&htim3);
__HAL_TIM_SetCounter(&htim3, 0);
RP2 = 1000000 / cc1_value_2;
HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1);
}