蓝桥杯国赛备赛(嵌入式组)
(4)测试HAL_ADC_Start的ADC启动函数和HAL_ADC_GetValue的ADC读取函数。(4)根据595芯片工作原理,编写seg_display函数(先发送高位)PA3:RCLK串型存储时钟输入(上升沿有效)PA2:SCK串行移位时钟输入(上升沿有效)(2)配置PA4为ADC采集模式,并设置单端模式。(2)配置PA1、PA2、PA3为推挽输出。(4)测试ADC采集和GPIO读取功能
一、数码管(拓展板)(共阴接法)
引脚控制
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 < 200)
keyio = 1;
else if(adc_keyval < 800)
keyio = 2;
else if(adc_keyval < 1400)
keyio = 3;
else if(adc_keyval < 2000)
keyio = 4;
else if(adc_keyval < 2600)
keyio = 5;
else if(adc_keyval < 3200)
keyio = 6;
else if(adc_keyval < 3800)
keyio = 7;
else if(adc_keyval < 3950)
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;
}
void lcd_diaplay()
{
sprintf((char*)display_buf,"T:%d.%dC H:%d%%",(dht11_val>>8 & 0xff),(dht11_val & 0xff),(dht11_val>>24 & 0xff));
LCD_DisplayStringLine(Line6 ,(unsigned char *)display_buf);
}
七、一个定时器通道捕获两路pwm频率(扩展板)
1、cube配置
2、代码
// 输入捕获
/* Captured Values */
uint32_t uwIC3Value1 = 0;
uint32_t uwIC3Value2 = 0;
uint32_t uwDiffCapture_ch3 = 0;
/* Capture index */
uint16_t uhCaptureIndex_ch3 = 0;
/* Frequency Value */
uint32_t uwFrequency_ch3 = 0;
/* Captured Values */
uint32_t uwIC2Value1 = 0;
uint32_t uwIC2Value2 = 0;
uint32_t uwDiffCapture = 0;
/* Capture index */
uint16_t uhCaptureIndex = 0;
/* Frequency Value */
uint32_t uwFrequency = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
{
//TIM2_CH3频率捕获
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
{
if(uhCaptureIndex_ch3 == 0)
{
/* Get the 1st Input Capture value */
uwIC3Value1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3);
uhCaptureIndex_ch3 = 1;
}
else if(uhCaptureIndex_ch3 == 1)
{
/* Get the 2nd Input Capture value */
uwIC3Value2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3);
/* Capture computation */
if (uwIC3Value2 > uwIC3Value1)
{
uwDiffCapture_ch3 = (uwIC3Value2 - uwIC3Value1);
}
else if (uwIC3Value2 < uwIC3Value1)
{
/* 0xFFFFFFFF is max TIM2_CCRx value */
uwDiffCapture_ch3 = ((0xFFFFFFFF - uwIC3Value1) + uwIC3Value2) + 1;
}
else
{
/* If capture values are equal, we have reached the limit of frequency
measures */
Error_Handler();
}
/* Frequency computation: for this example TIMx (TIM1) is clocked by
APB2Clk */
uwFrequency_ch3 = 1e6 / uwDiffCapture_ch3;
uhCaptureIndex_ch3 = 0;
}
}
//TIM2_CH2频率捕获
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
if(uhCaptureIndex == 0)
{
/* Get the 1st Input Capture value */
uwIC2Value1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
uhCaptureIndex = 1;
}
else if(uhCaptureIndex == 1)
{
/* Get the 2nd Input Capture value */
uwIC2Value2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
/* Capture computation */
if (uwIC2Value2 > uwIC2Value1)
{
uwDiffCapture = (uwIC2Value2 - uwIC2Value1);
}
else if (uwIC2Value2 < uwIC2Value1)
{
/* 0xFFFFFFFF is max TIM2_CCRx value */
uwDiffCapture = ((0xFFFFFFFF - uwIC2Value1) + uwIC2Value2) + 1;
}
else
{
/* If capture values are equal, we have reached the limit of frequency
measures */
Error_Handler();
}
/* Frequency computation: for this example TIMx (TIM1) is clocked by
APB2Clk */
uwFrequency = 1e6 / uwDiffCapture;
uhCaptureIndex = 0;
}
}
}
}
void main()
{
//...
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2); //开启TIM2_CH2的输入捕获中断
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_3);
while(1)
{
}
}
八、一个定时器通道捕获两路pwm占空比(扩展板)
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM3)
{
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
if(uhCaptureIndex_T3CH2 == 0) //第一次中断:上升沿中断,CCR
{
/* Get the 1st Input Capture value */
uwIC2Value1_T3CH2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_2,TIM_INPUTCHANNELPOLARITY_FALLING);
uhCaptureIndex_T3CH2 = 1;
}
else if(uhCaptureIndex_T3CH2 == 1) //第二次中断:下沿中断,CCR
{
/* Get the 2nd Input Capture value */
uwIC2Value2_T3CH2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_2,TIM_INPUTCHANNELPOLARITY_RISING);
/* Capture computation */
if (uwIC2Value2_T3CH2 > uwIC2Value1_T3CH2)
{
uwHigh_T3CH2 = (uwIC2Value2_T3CH2 - uwIC2Value1_T3CH2);
}
else if (uwIC2Value2_T3CH2 < uwIC2Value1_T3CH2)
{
/* 0xFFFF is max TIM1_CCRx value */
uwHigh_T3CH2 = ((0xFFFF - uwIC2Value1_T3CH2) + uwIC2Value2_T3CH2) + 1;
}
uwIC2Value1_T3CH2 = uwIC2Value2_T3CH2;
uhCaptureIndex_T3CH2 = 2;
}
else if(uhCaptureIndex_T3CH2 == 2) //第三次中断,上升沿中断,CCR
{
uwIC2Value2_T3CH2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
/* Capture computation */
if (uwIC2Value2_T3CH2 > uwIC2Value1_T3CH2)
{
uwLow_T3CH2 = (uwIC2Value2_T3CH2 - uwIC2Value1_T3CH2);
}
else if (uwIC2Value2_T3CH2 < uwIC2Value1_T3CH2)
{
/* 0xFFFF is max TIM1_CCRx value */
uwLow_T3CH2 = ((0xFFFF - uwIC2Value1_T3CH2) + uwIC2Value2_T3CH2) + 1;
}
/* Frequency computation */
uwFrequency_T3CH2 = 1e6 / (uwLow_T3CH2 + uwHigh_T3CH2);
duty_T3CH2 = uwHigh_T3CH2 * 100.0f / (uwLow_T3CH2 + uwHigh_T3CH2); //单位是%
uhCaptureIndex_T3CH2 = 0;
}
}
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
if(uhCaptureIndex_T3CH1 == 0) //第一次中断:上升沿中断,CCR
{
/* Get the 1st Input Capture value */
uwIC1Value1_T3CH1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING);
uhCaptureIndex_T3CH1 = 1;
}
else if(uhCaptureIndex_T3CH1 == 1) //第二次中断:下沿中断,CCR
{
/* Get the 2nd Input Capture value */
uwIC1Value2_T3CH1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);
/* Capture computation */
if (uwIC1Value2_T3CH1 > uwIC1Value1_T3CH1)
{
uwHigh_T3CH1 = (uwIC1Value2_T3CH1 - uwIC1Value1_T3CH1);
}
else if (uwIC1Value2_T3CH1 < uwIC1Value1_T3CH1)
{
/* 0xFFFF is max TIM1_CCRx value */
uwHigh_T3CH1 = ((0xFFFF - uwIC1Value1_T3CH1) + uwIC1Value2_T3CH1) + 1;
}
uwIC1Value1_T3CH1 = uwIC1Value2_T3CH1;
uhCaptureIndex_T3CH1 = 2;
}
else if(uhCaptureIndex_T3CH1 == 2) //第三次中断,上升沿中断,CCR
{
uwIC1Value2_T3CH1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
/* Capture computation */
if (uwIC1Value2_T3CH1 > uwIC1Value1_T3CH1)
{
uwLow_T3CH1 = (uwIC1Value2_T3CH1 - uwIC1Value1_T3CH1);
}
else if (uwIC1Value2_T3CH1 < uwIC1Value1_T3CH1)
{
/* 0xFFFF is max TIM1_CCRx value */
uwLow_T3CH1 = ((0xFFFF - uwIC1Value1_T3CH1) + uwIC1Value2_T3CH1) + 1;
}
/* Frequency computation */
uwFrequency_T3CH1 = 1e6 / (uwLow_T3CH1 + uwHigh_T3CH1);
duty_T3CH1 = uwHigh_T3CH1 * 100.0f / (uwLow_T3CH1 + uwHigh_T3CH1); //单位是%
uhCaptureIndex_T3CH1 = 0;
}
}
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)