题目
新建工程
编程框架
key3的功能较多,需要判定密码正确与否,所以key3设置一个标志位,进入标志位改变函数来控制其他模块,但是需要定时操作,所以使用systick来延时,延时结束后再次设置变量和标志位。
其中显示@和显示数字都要求,但是定义为uint8_t 类型的话@会存储为255,显示时需要用%d和%c不断切换显示@和数字,但是数字字符也是以编码形式存储,所以直接定义为char,统一显示格式为%c,而且字符加一也会是和数字加一是一样的效果。
主要代码
my_main.c
#include "my_main.h"
bool view=0;
char text[30];
uchar B1='@';
uchar B2='@';
uchar B3='@';
char mima[3]={'1','2','3'};
uint16_t frq=1000;
uint8_t duty=50;
typedef struct keys
{
bool status;
bool shortdown;
bool longdown;
uint8_t times;
}KEY;
KEY key[4];
uint8_t err=0;
bool key3_flag=0;
bool led_flag1=0;
bool led_flag2=0;
bool pwm_flag=0;
bool time5000_start_f=0;
bool time2000_start_f=0;
char uart_rx[30];
char uart_tx[30];
char text1[3];
char text2[3];
//
void setup(void)
{
LCD_Init();
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
HAL_TIM_Base_Start_IT(&htim4);
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
HAL_UARTEx_ReceiveToIdle_IT(&huart1,(uint8_t *)uart_rx,30);
}
lcd
void lcd_proce(void)
{
if(view==0)
{
sprintf(text," PSD ");
LCD_DisplayStringLine(Line1,(uint8_t*)text);
sprintf(text," B1:%c ",B1);
LCD_DisplayStringLine(Line3,(uint8_t*)text);
sprintf(text," B2:%c ",B2);
LCD_DisplayStringLine(Line4,(uint8_t*)text);
sprintf(text," B3:%c ",B3);
LCD_DisplayStringLine(Line5,(uint8_t*)text);
}
if(view==1)
{
sprintf(text," STA ");
LCD_DisplayStringLine(Line1,(uint8_t*)text);
sprintf(text," F:%dHz ",frq);
LCD_DisplayStringLine(Line3,(uint8_t*)text);
sprintf(text," D:%d%% ",duty);
LCD_DisplayStringLine(Line4,(uint8_t*)text);
}
}
///key
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM4)
{
key[0].status=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
key[1].status=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
key[2].status=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
key[3].status=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
}
for(int i=0;i<4;i++)
{
if(key[i].status==0)
{
key[i].times++;
}
if(key[i].status==1)
{
if(key[i].times>40)key[i].longdown=1;
else if((key[i].times>2)&&(key[i].times<40))key[i].shortdown=1;
key[i].times=0;
}
}
}
void key_proce(void)
{
if(key[0].shortdown==1)
{
key[0].shortdown=0;
if(view==0)
{
if((B1=='9')||(B1=='@'))
{
B1='0';
}
else B1++;
}
}
if(key[1].shortdown==1)
{
key[1].shortdown=0;
if(view==0)
{
if((B2=='9')|(B2=='@'))
{
B2='0';
}
else B2++;
}
}
if(key[2].shortdown==1)
{
key[2].shortdown=0;
if(view==0)
{
if((B3=='9')|(B3=='@'))
{
B3='0';
}
else B3++;
}
}
if(key[3].shortdown==1)
{
key[3].shortdown=0;
key3_flag=1;
}
}
///led
void LED_disp(uint lednumb,bool on_off)
{
static uint8_t mmry=0x00;
if(on_off==1) mmry|=lednumb;
if(on_off==0) mmry&=~lednumb;
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);//GPIO_PIN_All,只有A大写
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);//打开锁存器PD2
HAL_GPIO_WritePin(GPIOC,mmry<<8,GPIO_PIN_RESET);//mmry左移八位到要控制的高八位
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);//关闭锁存器PD2
}
void led_proce(void)
{
LED_disp(1,led_flag1);
LED_disp(2,led_flag2);
}
/flag_change
void flag_change_proce(void)
{
if(key3_flag==1)
{
key3_flag=0;
if(B1==mima[0]&&B2==mima[1]&&B3==mima[2])
{
err=0;
view=1;
LCD_Clear(Black);
led_flag1=1;
pwm_flag=1;
time5000_start_f=1;
}
else
{
B1='@';
B2='@';
B3='@';
err++;
if(err>=3)
{
time2000_start_f=1;
}
}
}
}
pwm
void pwm_proce(void)
{
if(pwm_flag==0)
{
frq=1000;
duty=50;
__HAL_TIM_SetAutoreload(&htim2,10000-1);
}
else if(pwm_flag==1)
{
frq=2000;
duty=10;
__HAL_TIM_SetAutoreload(&htim2,500-1);
__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,50);
}
}
//uart
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
sscanf(uart_rx,"%3s-%3s",text1,text2);
if(text1[0]==mima[0]&&text1[1]==mima[1]&&text1[2]==mima[2])
{
mima[0]=text2[0];
mima[1]=text2[1];
mima[2]=text2[2];
sprintf(uart_tx,"ok");
HAL_UART_Transmit(&huart1,(uint8_t *)uart_tx,strlen(uart_tx),50);
HAL_UARTEx_ReceiveToIdle_IT(&huart1,(uint8_t *)uart_rx,30);
}
}
/loop
void loop(void)
{
lcd_proce();
key_proce();
led_proce();
pwm_proce();
flag_change_proce();
}
my_main.h
#ifndef _MY_MAIN_H_
#define _MY_MAIN_H_
#include "main.h"
#include "lcd.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "stdbool.h"
#include "stdio.h"
#include "string.h"
void loop(void);
void setup(void);
void lcd_proce(void);
void led_proce(void);
void flag_change_proce(void);
void pwm_proce(void);
#endif
systick
#include "my_main.h"
extern bool time5000_start_f;
extern bool time2000_start_f;
extern bool view;
extern bool pwm_flag;
extern bool led_flag1;
extern bool led_flag2;
extern uchar B1;
extern uchar B2;
extern uchar B3;
uint32_t time5000=0;
uint32_t time2000=0;
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
if(time5000_start_f==1)
{
time5000++;
if(time5000>5000)
{
time5000_start_f=0;
time5000=0;
led_flag1=0;
view=0;
//pwm_flag=0;
B1='@';
B2='@';
B3='@';
}
}
if(time2000_start_f==1)
{
led_flag2=!led_flag2;
time2000++;
if(time2000>2000)
{
time2000_start_f=0;
led_flag2=0;
}
}
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}