您现在的位置是:首页 >技术教程 >蓝桥杯国赛备赛(嵌入式组)网站首页技术教程
蓝桥杯国赛备赛(嵌入式组)
一、数码管(拓展板)(共阴接法)
引脚控制
PA3 :RCLK 串型存储时钟输入 (上升沿有效)
PA2 :SCK 串行移位时钟输入(上升沿有效)
PA1 :SER 串型数据输入
发送数据时先发高位:因为会通过移位寄存器将他移到最后一个位置。
1、程序设计
(1)拓展板跳线帽连接(如下图)
(2)配置PA1、PA2、PA3为推挽输出
(3)通过STC-ISP软件得到数码管显示“段选”
(4)根据595芯片工作原理,编写seg_display函数(先发送高位)
1.1、共阴数码管码表
1.2、程序
“seg.c”
#include "seg.h"
#define SER_H HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET)
#define SER_L HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET)
#define SCK_H HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET)
#define SCK_L HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_RESET)
#define RCK_H HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET)
#define RCK_L HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET)
u8 seg_buf[3]; // 数码管显示缓存数组
u8 seg_code[]={
// 0 1 2 3 4 5 6 7 8 9
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Seg_Display(void)
{
u8 i;
for(i=0;i<8;i++)
{
if(seg_buf[2] & 0x80) SER_H;
else SER_L;
SCK_L;
SCK_H;
seg_buf[2] <<= 1;
}
for(i=0;i<8;i++)
{
if(seg_buf[1] & 0x80) SER_H;
else SER_L;
SCK_L;
SCK_H;
seg_buf[1] <<= 1;
}
for(i=0;i<8;i++)
{
if(seg_buf[0] & 0x80) SER_H;
else SER_L;
SCK_L;
SCK_H;
seg_buf[0] <<= 1;
}
RCK_L;
RCK_H;
}
“seg.h”
#ifndef __SEG_H
#define __SEG_H
#include "main.h"
extern u8 seg_buf[3];
extern u8 seg_code[];
void Seg_Display(void);
#endif
main.c
void Seg_Process()
{
HAL_Delay(100);
seg_cnt++;
seg_buf[0] = seg_code[seg_cnt/100];
seg_buf[1] = seg_code[seg_cnt/10%10];
seg_buf[2] = seg_code[seg_cnt%10];
Seg_Display();
}
现象:数码管从0开始加
二、双路ADC采集(扩展板)
引脚:
PA4:RP5滑动变阻器
PA5:RP6滑动变阻器
2.1、程序设计步骤
(1)按上图接好线
(2)配置PA4、PA5为ADC采集模式,并设为单端模式
(3)配置ADC2的转换通道数为2
(4)测试HAL_ADC_Start的ADC启动函数和HAL_ADC_GetValue的ADC读取函数
代码
main.c
void ADC_Process()
{
//RANK1 - ADC2_IN17
HAL_ADC_Start(&hadc2);//开启adc
volt_rp5 = HAL_ADC_GetValue(&hadc2)/4095.0f*3.3f; //读取通道1
//RANK2 - ADC2_IN13
HAL_ADC_Start(&hadc2);
volt_rp6 = HAL_ADC_GetValue(&hadc2)/4095.0f*3.3f;//读取通道2
}
三、光敏电阻(扩展板)
1、接线
PA3:光敏电阻开关量信号
PA4:光敏电阻的分压模拟电压值
2、程序设计
(1)接线如上图
(2)配置PA4为ADC采集模式,并设置单端模式
(3)配置PA3为gpio输入模式
(4)测试ADC采集和GPIO读取功能
四、ADC按键(扩展板)
引脚:PA5
用法:每个按键按下去ad(pa5)采集到的电压不同,用以区分那个按键按下
u8 ADC_Key_Read()
{
u8 keyio = 0;
HAL_ADC_Start(&hadc2);
adc_keyval = HAL_ADC_GetValue(&hadc2);
if(adc_keyval < 100)
keyio = 1;
else if(adc_keyval < 400)
keyio = 2;
else if(adc_keyval < 800)
keyio = 3;
else if(adc_keyval < 1200)
keyio = 4;
else if(adc_keyval < 1600)
keyio = 5;
else if(adc_keyval < 2000)
keyio = 6;
else if(adc_keyval < 2400)
keyio = 7;
else if(adc_keyval < 3000)
keyio = 8;
return keyio;
}
五、DS18B20(扩展板)
引脚PA6连p3排针上tdq
比赛中底层驱动会给,我们只需编写读取DS18B20温度的程序
看手册18页参考编程
#define delay_us(X) delay((X)*100/5) //这儿之前是80要改成100
float DS18B20_Read(void)
{
float temp_return;
u8 low,high;
ow_reset();
ow_byte_wr(0xcc);
ow_byte_wr(0x44);
ow_reset();
ow_byte_wr(0xcc);
ow_byte_wr(0xbe);
low = ow_byte_rd();
high = ow_byte_rd();
temp_return = (high<<8 | low)*0.0625;
return temp_return;
}
ds18b20.h
#ifndef __DS18B20_HAL_H
#define __DS18B20_HAL_H
#include "main.h" //之前是stm32gxxx.h 换成main.h
#define OW_PIN_PORT GPIOA
#define OW_PIN GPIO_PIN_6
#define OW_DIR_OUT() mode_output1()
#define OW_DIR_IN() mode_input1()
#define OW_OUT_LOW() (HAL_GPIO_WritePin(OW_PIN_PORT, OW_PIN, GPIO_PIN_RESET))
#define OW_GET_IN() (HAL_GPIO_ReadPin(OW_PIN_PORT, OW_PIN))
#define OW_SKIP_ROM 0xCC
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xBE
void ds18b20_init_x(void);
float DS18B20_Read(void); //这个函数自己写
#endif
main.c
//温度
float temp_float;
u32 tempTick = 0;
void DS18B20_Process()
{
if(uwTick - tempTick < 500) return; //500ms执行一次
tempTick = uwTick;
temp_float = DS18B20_Read();
}
六、DHT11(扩展板)
引脚PA7连接 P3上的HDQ
代码设计
(1)修改头文件
(2)修改延时#define delay_us(X) delay(X*100/5);
(3)修改dht11.c中与GPIO操作相关的驱动文件
(4)调用dht11_read()函数解析数据
unsigned int dht11_read(void)
{
int i;
long long val;
int timeout;
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);
delay_us(18000); //pulldown for 18ms
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);
delay_us( 20 ); //pullup for 30us
mode_input();
//等待DHT11拉高,80us
timeout = 5000;
while( (! HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7)) && (timeout > 0) ) timeout--; //wait HIGH
//等待DHT11拉低,80us
timeout = 5000;
while( HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) && (timeout > 0) ) timeout-- ; //wait LOW
#define CHECK_TIME 28
for(i=0;i<40;i++)
{
timeout = 5000;
while( (! HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_7)) && (timeout > 0) ) timeout--; //wait HIGH
delay_us(CHECK_TIME);
if ( HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_7) )
{
val=(val<<1)+1;
} else {
val<<=1;
}
timeout = 5000;
while( HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_7) && (timeout > 0) ) timeout-- ; //wait LOW
}
mode_output();
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);
if (((val>>32)+(val>>24)+(val>>16)+(val>>8) -val ) & 0xff ) return 0;
else return val>>8;
}