蓝桥杯嵌入式第十三届省赛——“没有名字的一届我叫它可设置密码并且能输出PWM波的系统”旧版标准库

6 篇文章 0 订阅
6 篇文章 0 订阅
本文介绍了蓝桥杯嵌入式竞赛中关于PWM输出和USART通信的简化处理。通过修改PWM配置实现不同频率和占空比,以及调整USART中断处理函数以接收密码。同时,提供了关键代码段,包括PWM初始化、USART中断服务函数以及主函数中的关键逻辑。程序还包括错误提示和LCD显示功能。
摘要由CSDN通过智能技术生成

一、赛题分析

        这届赛题相较于上一届,只能用一个词来形容--“简单”。只需要改一下PWM输出,改一下USART然后再组合一下就可以了。

二、程序设计

往届链接:此处没有的.c.h文件均可在往期博客中找到。蓝桥杯嵌入式第八届省赛——“模拟升降控制器”旧板标准库_对愁眠后霜满天的博客-CSDN博客

1、PA1的PWM输出

#ifndef _PWM_H_
#define _PWM_H_

#include "stm32f10x.h"

void TIM2_CH2_PWM(u16 Per,u16 CCR2_Val);

#endif
/*********************************************

PA1--TIM2--CH2   PA2--TIM2--CH3   PA3--TIM2--CH4 
PA6--TIM3--CH1   PA7--TIM3--CH2

*********************************************/
#include "pwm.h"
#include "stm32f10x_tim.h"

void TIM2_CH2_PWM(u16 Per,u16 CCR2_Val)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;	
	
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
	
  TIM_TimeBaseStructure.TIM_Period = Per;
  TIM_TimeBaseStructure.TIM_Prescaler = 71;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
	
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC2Init(TIM2, &TIM_OCInitStructure);

  TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);

  TIM_ARRPreloadConfig(TIM2, ENABLE);

  TIM_Cmd(TIM2, ENABLE);
}

2、USART稍微改动

void USART2_IRQHandler(void)
{
  if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
  {
    USART_ClearITPendingBit(USART2,USART_IT_RXNE);		
    USART_RXBUF[RXCUNT++] = USART_ReceiveData(USART2);
    if(USART_RXBUF[6] != '\0')
    {
      USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
      RXOVER = 1;  
    }
  }
}

3、main.c

#include "stm32f10x.h"
#include "lcd.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "pwm.h"
#include "timer.h"
#include "usart.h"
#include "stdio.h"
#include "string.h"

u8 p_w[3] = {1,2,3},e_pw[3] = {0,0,0};
u8 key_flag = 0,ke1=0,ke2=0,ke3=0;
u8 show_flag = 0,error_flag = 0;
u8 led_flag = 0;
u8 string[20];

void key_in(void);	
void show_psd(void);
void pwm_change(void);
void usart_pre(void);

//Main Body
int main(void)
{
  STM3210B_LCD_Init();      
  LCD_Clear(Black);          
  LCD_SetBackColor(Black);   
  LCD_SetTextColor(White);  
  SysTick_Config(SystemCoreClock/1000);
	
  TIM4_Init();
  LED_Init();
  KEY_Init();
  TIM2_CH2_PWM(1000-1,500-1);
  USART2_Init(9600);
  while(1)
  {
    key_in();
    show_psd();
    pwm_change();
    usart_pre();
    LED_Control(LED1,show_flag);
    LED_Control(LED2,led_flag);
  }
}

void key_in(void)	
{
  if(show_flag == 0)key_flag = key_scan();
	
  if(key_flag == 1)
  {
    e_pw[0] = (e_pw[0] + 1) % 10;
    ke1 = 1;
  }
	
  if(key_flag == 2)
  {
    e_pw[1] = (e_pw[1] + 1) % 10;
    ke2 = 1;
  }
	
  if(key_flag == 3)
  {
    e_pw[2] = (e_pw[2] + 1) % 10;
    ke3 = 1;
  }
	
  if(key_flag == 4)
  {
    if(e_pw[0]==p_w[0]&&e_pw[1]==p_w[1]&p_w[2]==e_pw[2])
    {
      show_flag = 1;
      ke1=0;ke2=0;ke3=0;
      e_pw[0]=0;e_pw[1]=0;e_pw[2]=0;
    }else
    {
      ke1=0;ke2=0;ke3=0;
      e_pw[0]=0;e_pw[1]=0;e_pw[2]=0;
      error_flag++;
    }
  }
}

void show_psd(void)
{
  if(show_flag == 0)
  {
    LCD_DisplayStringLine(Line1,(u8*)"       PSD          ");
		
    if(ke1 == 0)
      LCD_DisplayStringLine(Line3,(u8*)"    B1:@            ");
    else
    {
      memset(string,0,sizeof(string));
      sprintf((char*)string,"    B1:%d            ",e_pw[0]);
      LCD_DisplayStringLine(Line3,string);			
    }
    if(ke2 == 0)
      LCD_DisplayStringLine(Line4,(u8*)"    B2:@            ");
    else
    {
      memset(string,0,sizeof(string));
      sprintf((char*)string,"    B2:%d            ",e_pw[1]);
      LCD_DisplayStringLine(Line4,string);			
    }
    if(ke3 == 0)
      LCD_DisplayStringLine(Line5,(u8*)"    B3:@            ");
    else
    {
      memset(string,0,sizeof(string));
      sprintf((char*)string,"    B3:%d            ",e_pw[2]);
      LCD_DisplayStringLine(Line5,string);			
    }
  }
  if(show_flag == 1)
  {
    LCD_DisplayStringLine(Line1,(u8*)"       STA          ");
		
    LCD_DisplayStringLine(Line3,(u8*)"    F:2000HZ        ");
		
    LCD_DisplayStringLine(Line4,(u8*)"    D:10%            ");
  }
}

//这个程序可以保证,每次show_flag改变都会重新写入一此PWM输出频率及占空比。
void pwm_change(void)
{
  static u8 pwm_flag = 0;
  if(show_flag != pwm_flag)
  {
    LCD_Clear(Black);
    if(show_flag == 1)
      TIM2_CH2_PWM(500-1,50-1);
    if(show_flag == 0)
      TIM2_CH2_PWM(1000-1,500-1);
    pwm_flag = show_flag;
  }
}

void usart_pre(void)
{
  if(RXOVER == 1)
  {
    RXOVER = 0;
    RXCUNT = 0;
		if(USART_RXBUF[0]-48==p_w[0]&&USART_RXBUF[1]-48==p_w[1]&&USART_RXBUF[2]-48==p_w[2])
    {
      p_w[0]=USART_RXBUF[4]-48;
      p_w[1]=USART_RXBUF[5]-48;
      p_w[2]=USART_RXBUF[6]-48;
		
      memset(string,0,sizeof(string));
      sprintf((char*)string,"ok\r\n");
      USART_SendString(USART2,string);
    }
    memset(USART_RXBUF,0,sizeof(USART_RXBUF));
  }
}

void TIM4_IRQHandler(void)
{
  static u16 led_cnt = 0,correct_cnt = 0;
  if(TIM_GetITStatus(TIM4,TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
    if(error_flag>3&&led_cnt<=5000)
    {
      if(++led_cnt%100==0)
      {
        led_flag =! led_flag;
      }
      if(led_cnt == 5000)
      {
        led_flag = 0;
        led_cnt = 0;
        error_flag = 0;
      }
    }
    if(show_flag == 1)
    {
      if(++correct_cnt>=5000)
      {
        show_flag = 0;
        correct_cnt = 0;
      }
    }
  }
}

三、附上工程

链接:https://pan.baidu.com/s/1kNmAYWSjMBiqqe9ANlOKCg 
提取码:yinc

有不对的地方,请多指教...

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

对愁眠后霜满天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值