第十一届蓝桥杯嵌入式设计与开发 (省赛)
分析
此次赛题围绕两个方向,结构如下:
代码:
1.主函数模块
main.c
#include <stm32f10x.h>
#include "lcd.h"
#include "adc.h"
#include "lcd_window.h"
#include "pwm.h"
#include "key.h"
#include "led.h"
float ADC_Value;
/******PWM********/
float CH1_duty=0.1,CH2_duty=0.1;
u8 channel_1_flag,channel_2_flag;
/*************************/
u8 setting_mode=0; //0 AUTO 1 MANU
u8 Data_Para=0; //0 Data 1 Para
int main(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);SysTick_Config(SystemCoreClock/1000);STM3210B_LCD_Init();LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);adc_Init();pwm_Init();KEY_Init();LED_Init();
while(1)
{lcd_window();KEY_Control();LED_Control();
}
}在这里插入代码片
2.ADC模块
adc.c
#include <stm32f10x.h>
#include "adc.h"void adc_Init(void)
{ADC_InitTypeDef ADC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;/* Enable ADC1 and GPIOC clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);/* Configure PC.04 (ADC Channel14) as analog input -------------------------*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);/* ADC1 configuration ------------------------------------------------------*/ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_ScanConvMode = DISABLE;ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_NbrOfChannel = 1;ADC_Init(ADC1, &ADC_InitStructure);/* ADC1 regular channel14 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_13Cycles5);/* Enable ADC1 */ADC_Cmd(ADC1, ENABLE);/* Enable ADC1 reset calibration register */ ADC_ResetCalibration(ADC1);/* Check the end of ADC1 reset calibration register */while(ADC_GetResetCalibrationStatus(ADC1));/* Start ADC1 calibration */ADC_StartCalibration(ADC1);/* Check the end of ADC1 calibration */while(ADC_GetCalibrationStatus(ADC1));/* Start ADC1 Software Conversion */ //ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}float ADC_GetValue(void)
{float ADC_V;ADC_SoftwareStartConvCmd(ADC1, ENABLE);while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);ADC_V=ADC_GetConversionValue(ADC1)*3.30/0xfff;return ADC_V;
}在这里插入代码片
ADC.h
#ifndef __ADC_H
#define __ADC_H
void adc_Init(void);
float ADC_GetValue(void);
#endif在这里插入代码片
3.按键模块
key.c
#include "stm32f10x.h"
#include "stm32f10x_it.h"
#include "key.h"
#include "lcd.h"
extern u8 setting_mode; //0锟斤拷示AUTO 1锟斤拷示MANU
extern u8 Data_Para; //0锟斤拷示Data页锟斤拷 1锟斤拷示Para页锟斤拷
extern float CH1_duty,CH2_duty;
float ch1_duty_1=0.1,ch2_duty_1=0.1;
u8 key1_sum,key2_sum,key3_sum,key4_sum;
void KEY_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;/* Enable GPIOA and GPIOB clock */RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;GPIO_Init(GPIOB, &GPIO_InitStructure);
}void KEY_Control(void)
{if(KEY1==0)
{delay_ms(10);if(KEY1==0){ key1_sum++;LCD_ClearLine(Line0);LCD_ClearLine(Line1);LCD_ClearLine(Line2);LCD_ClearLine(Line3);LCD_ClearLine(Line4);LCD_ClearLine(Line5);LCD_ClearLine(Line6);LCD_ClearLine(Line7);LCD_ClearLine(Line8);LCD_ClearLine(Line9);}if(key1_sum==1) {if(setting_mode==1){Data_Para^=1;}else{Data_Para=0;}}
}
else
{key1_sum=0;
}
if(KEY2==0)
{delay_ms(10);if(KEY2==0){ key2_sum++;if(key2_sum==1){if(setting_mode==1){ch1_duty_1+=0.1;if((ch1_duty_1-1.0)>=0){ch1_duty_1=0.1;} }}}
}
else
{key2_sum=0;
}
if(KEY3==0)
{delay_ms(10);if(KEY3==0){ key3_sum++;if(key3_sum==1){if(setting_mode==1){ch2_duty_1+=0.1;if((ch2_duty_1-1.0)>=0){ch2_duty_1=0.1;} }}}
}
else
{key3_sum=0;
}
if(KEY4==0)
{delay_ms(10);if(KEY4==0){key4_sum++;if(key4_sum==1){setting_mode^=1;}}}else{key4_sum=0;}
}
这里的按键模块我觉得是一个很好的按键消抖方法(是参照那些前辈们这样写的)。
key.h
#ifndef __KEY_H
#define __KEY_H
#include "stm32f10x.h"#define KEY1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
#define KEY2 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)
#define KEY3 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)
#define KEY4 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2)
void KEY_Init(void);
void KEY_Control(void);#endif在这里插入代码片
4.LED模块
#include "stm32f10x.h"
#include "led.h"
extern u8 setting_mode;
extern u8 Data_Para;void LED_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;/* Enable GPIOA and GPIOB clock */RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC, ENABLE);GPIO_InitStructure.GPIO_Pin = LED1|LED2|LED3|LED4|LED5|LED6|LED7|LED8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin =GPIO_Pin_2;GPIO_Init(GPIOD, &GPIO_InitStructure);
}void LED_Status(uint16_t LED,u8 state)
{// GPIO_Write(GPIOC,0Xff00); //全灭
// GPIO_SetBits(GPIOD,GPIO_Pin_2);//
// GPIO_ResetBits(GPIOD,GPIO_Pin_2);if(state) //on{GPIO_ResetBits(GPIOC,LED);GPIO_SetBits(GPIOD,GPIO_Pin_2);//GPIO_ResetBits(GPIOD,GPIO_Pin_2);}else{GPIO_SetBits(GPIOC,LED);GPIO_SetBits(GPIOD,GPIO_Pin_2);//GPIO_ResetBits(GPIOD,GPIO_Pin_2);}
}
void LED_Control(void)
{ GPIO_Write(GPIOC,0Xff00); //全灭GPIO_SetBits(GPIOD,GPIO_Pin_2);// 此处需要特别注意,应该在这里添加这三行代码GPIO_ResetBits(GPIOD,GPIO_Pin_2);if(setting_mode==1){LED_Status(LED1,0);}if(setting_mode==0){LED_Status(LED1,1);}if(Data_Para==0){LED_Status(LED2,1);} else{LED_Status(LED2,0);}}
LED.H
#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"
#define LED1 GPIO_Pin_8
#define LED2 GPIO_Pin_9
#define LED3 GPIO_Pin_10
#define LED4 GPIO_Pin_11
#define LED5 GPIO_Pin_12
#define LED6 GPIO_Pin_13
#define LED7 GPIO_Pin_14
#define LED8 GPIO_Pin_15
void LED_Init(void);
void LED_Status(uint16_t LED,u8 state);
void LED_Control(void);#endif
5.pwm模块
pwm.c
#include <stm32f10x.h>
#include "pwm.h"
/******功能介绍****/
/*
该PWM函数是在同一定时器下的不同通道可以产生不同的频率,同时产生不同的占空比;
可以配合按键进行占空比修改和频率进行修改。
*/
/******PWM参数设定********/
extern float CH1_duty,CH2_duty;
extern u8 channel_1_flag,channel_2_flag;
/*************************/
__IO uint16_t CCR1_Val =10000; //72000000/72/100 ---100HZ
__IO uint16_t CCR2_Val =5000; //72000000/72/200 ---200HZvoid pwm_Init(void)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;GPIO_InitTypeDef GPIO_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;/* TIM3 clock enable */RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);/* GPIOA and GPIOA clock enable */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); //注意要是能复用时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);/* Time base configuration */TIM_TimeBaseStructure.TIM_Period = 65535;TIM_TimeBaseStructure.TIM_Prescaler = 72-1;TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);/* Enable the TIM3 global Interrupt */NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);/* PWM1 Mode configuration: Channel1 */TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //记住TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse = CCR1_Val;TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;TIM_OC1Init(TIM3, &TIM_OCInitStructure);TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);/* PWM1 Mode configuration: Channel2 */TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse = CCR2_Val;TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;TIM_OC2Init(TIM3, &TIM_OCInitStructure);TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);/* TIM enable counter */TIM_Cmd(TIM3, ENABLE);/* Enable the CC2 Interrupt Request */TIM_ITConfig(TIM3, TIM_IT_CC2|TIM_IT_CC1, ENABLE);TIM_SetCounter(TIM3,0x0);TIM_SetCompare2(TIM3,0x0);TIM_SetCompare3(TIM3,0x0);
}void TIM3_IRQHandler(void)
{ u16 capture; //注意这里时u16,之前用得是u8不行。if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET){TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);capture = TIM_GetCapture1(TIM3);if(channel_1_flag){TIM_SetCompare1(TIM3, capture + (u16)CCR1_Val*CH1_duty);}else{TIM_SetCompare1(TIM3, capture + (u16)CCR1_Val*(1-CH1_duty));}channel_1_flag^=1;}if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET){TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);capture = TIM_GetCapture2(TIM3);if(channel_2_flag){TIM_SetCompare2(TIM3, (u16)(capture + CCR2_Val*CH2_duty));}else{TIM_SetCompare2(TIM3, (u16)(capture + CCR2_Val*(1-CH2_duty)));}channel_2_flag^=1;}
}
在这里插入代码片
该方法既可以调节占空比,也可以调节频率,题目要求只需调节占空比即可。同时有个地方注意一下: CH1_duty,CH2_duty这里我定义的是用float型来表示占空比,这样CH1_duty,CH2_duty直接就是小数,而当我把CH1_duty,CH2_duty,定义为u16时,用CH1_duty/100,CH2_duty/100来表示占空比时,PWM就无法正常输出。
pwm.h
#ifndef __PWM_H
#define __PWM_Hvoid pwm_Init(void);
#endif
lcd_window.c
#include <stm32f10x.h>
#include "lcd_window.h"
#include "adc.h"
#include "lcd.h"
#include "stdio.h"
extern float ADC_Value;
extern u8 setting_mode; //0锟斤拷示AUTO 1锟斤拷示MANU
extern u8 Data_Para; //0锟斤拷示Data页锟斤拷 1锟斤拷示Para页锟斤拷
extern float CH1_duty,CH2_duty;
extern float ch1_duty_1,ch2_duty_1;
void lcd_window(void)
{u8 str[20];ADC_Value=ADC_GetValue();if(Data_Para==0){ sprintf((char*)str," Data ");LCD_DisplayStringLine(Line1,str);sprintf((char*)str," V:%.2fV ",ADC_Value);LCD_DisplayStringLine(Line3,str);if(setting_mode==0){sprintf((char*)str," Mode:AUTO ");LCD_DisplayStringLine(Line5,str);CH1_duty=ADC_Value/3.30;CH2_duty=ADC_Value/3.30;}else{sprintf((char*)str," Mode:MANU ");LCD_DisplayStringLine(Line5,str);CH1_duty=ch1_duty_1;CH2_duty=ch2_duty_1;} }if(setting_mode==1&&Data_Para==1){CH1_duty=ch1_duty_1;CH2_duty=ch2_duty_1;sprintf((char*)str," Pata ");LCD_DisplayStringLine(Line1,str); sprintf((char*)str," PA6:%.f%% ",CH1_duty*100);LCD_DisplayStringLine(Line3,str); sprintf((char*)str," PA7:%.f%% ",CH2_duty*100);LCD_DisplayStringLine(Line5,str); }
}在这里插入代码片
lcd_window.h
在#ifndef __LCD_WINDOW_H
#define __LCD_WINDOW_Hvoid lcd_window(void);#endif这里插入代码片
结果
第十一届蓝桥杯嵌入式设计与开发 (省赛)相关推荐
- 第十一届蓝桥杯 单片机设计与开发省赛试题
第十一届蓝桥杯 单片机设计与开发 省赛 在昨天举办了第一波11届蓝桥杯比赛,第2波大概在10月份左右,看了看比赛题目,这次题目对于我来说,程序设计题简单,客观题全靠蒙! 本次比赛涉及: 1.数码管显示 ...
- 第十一届 蓝桥杯 单片机设计与开发项目 决赛
第十一届 蓝桥杯 单片机设计与开发项目 决赛 题目 源码 赛题总结 1.界面切换 2.参数生效 3.LED显示 题目 源码 #include <STC15F2K60S2.H> #inclu ...
- 蓝桥杯嵌入式设计与开发历届客观题答案
该页面由pdf转换而来,阅读效果不佳,你可以在这里下载pdf原件:https://download.csdn.net/download/dvs_dn/85085622 你也可以在百度文库免费下载该文档 ...
- 最新 2021年 第十二届 蓝桥杯 单片机设计与开发 省赛 客观试题 个人答案
第十二届蓝桥杯单片机设计与开发项目省赛 第一部分客观试题(30分) 不定项选择(3分/题) (1)MCS-51单片机外部中断1的中断请求标志是( B ). A.ET1 B.IE1 ...
- 第十一届 蓝桥杯 单片机设计与开发项目 省赛 程序设计试题及源码
一.试题 1. 基本要求 1.1 使用大赛组委会提供的国信长天单片机竞赛实训平台,完成本试题的程序设计 与调试. 1.2 选手在程序设计与调试过程中,可参考组委会提供的"资源数据包" ...
- 蓝桥杯单片机设计与开发_标准模板
蓝桥杯单片机设计与开发_标准模板 一.前言 首先,这篇文章是笔者第一次在 CSDN 上写博文,较为生疏,读者若有任何意见,欢迎大家在评论区交流! 笔者目前为一名大二学生,参加了2021年蓝桥杯单片机设 ...
- 蓝桥杯单片机设计与开发历届客观题答案
该页面由pdf转换而来,阅读效果不佳,你可以在这里下载pdf原件:https://download.csdn.net/download/dvs_dn/19373128 你也可以在百度文库免费下载该文档 ...
- 蓝桥杯——单片机设计与开发初学者必备资料
蓝桥杯--单片机设计与开发初学者必备资料 国信长天 大赛官方指定电子类比赛硬件提供方,可能大家只知道他们提供硬件,殊不知还有一些免费的视频讲解(只是老师可能说话带一点方言,嘻嘻),感兴趣的可以去看看, ...
- 蓝桥杯单片机设计与开发题目分析与源码(智能门锁)
蓝桥杯单片机设计与开发(智障门锁) 内附完整工程 代码仅供参考,如有建议疑问欢迎留言讨论 程序设计部分 智能门锁-任务指导书 开发环境 Keil5 Stc-isp 国兴天长开发板 任务分析 任务逻辑梳 ...
最新文章
- CalcBackProject函数
- VS报错:此项目需要缓解Spectre漏洞的库
- 区分Activity的四种加载模式
- 超炫jQuery测试答题功能
- Spring MVC 5 + Thymeleaf 基于Java配置和注解配置
- 云计算技术背后的那些天才程序员:KVM之父Avi Kivity
- 下了班----你干啥
- 【UE4+Vive】学习笔记1
- mysql json字段的使用与意义
- JQGrid 嵌套字表, json数据
- 巨佬就是巨佬,乔布斯 1973 年求职申请表,拍出22万美元高价!
- cannot allocate memory in static TLS block问题记录
- open连接MySQL超时_mysql5 超时链接
- STM32开发基础知识——定时器
- 【校招篇】招聘季来临,金三银四你准备好了吗?
- 854. Floyd求最短路
- Permissions 0777 for xxx are too open
- 2023电工杯数学建模A题思路模型代码
- halcon闭合轮廓线
- php浮点数取小数点两位小数,用小数点后两位数字打印PHP浮点数? - php