第十一届蓝桥杯嵌入式设计与开发 (省赛)

   日期:2021-03-06     浏览:119    评论:0    
核心提示:第十一届蓝桥杯嵌入式设计与开发 (省赛)分析此次赛题围绕两个方向,结构如下:代码: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;floa

分析

此次赛题围绕两个方向,结构如下:

代码:

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;

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;
   
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);
  
  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);
  
  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);

   
  ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_13Cycles5);
 
  
  ADC_Cmd(ADC1, ENABLE);

     
  ADC_ResetCalibration(ADC1);
  
  while(ADC_GetResetCalibrationStatus(ADC1));

  
  ADC_StartCalibration(ADC1);
  
  while(ADC_GetCalibrationStatus(ADC1));
     
   
  //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;
   
  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;
  
  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"



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 ---200HZ

void  pwm_Init(void)
{ 
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef  NVIC_InitStructure;
  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, 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);

  
  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);

   
  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);
  
  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);
  
  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_Cmd(TIM3, ENABLE);

  
  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_H
 void  pwm_Init(void);
#endif


结果




 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服