期末大作业-增加了显示时间、设置时间的功能,已基本完成功能。

设置时间的功能使用Cursor生成。

为了减少误差,专门调整了时钟周期。
This commit is contained in:
423A35C7 2025-01-07 21:01:38 +08:00
parent 324328bd25
commit 2fb33e955c
7 changed files with 1470 additions and 28 deletions

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,8 @@ typedef struct {
uint8_t bTenMilSecOk; // 10毫秒标志位
uint8_t mTimeCount; // 秒计数
uint8_t bTimeOk; // 秒标志位
uint8_t mHundredMilSecCount; // 百微秒计数
uint8_t bHundredMilSecOk; // 百微秒标志位
} stSysTickTimer;
typedef struct {
@ -23,6 +25,16 @@ typedef struct {
uint8_t bTenMilIsOk;
} structTime;
typedef enum {
SET_HOUR_TENS, // 小时十位
SET_HOUR_ONES, // 小时个位
SET_MIN_TENS, // 分钟十位
SET_MIN_ONES, // 分钟个位
SET_SEC_TENS, // 秒十位
SET_SEC_ONES, // 秒个位
SET_DONE // 设置完成
} TIME_STATE;
#ifdef __cplusplus
}
#endif

View File

@ -1,7 +1,9 @@
#include "main.h"
#include "variable.h"
extern uint8_t is_setting_time;
extern TIME_STATE set_time_state;
extern uint8_t show_digit;
uint16_t display_tab[] = {
0x3f,
@ -20,7 +22,8 @@ uint16_t display_tab[] = {
0x5e,
0x79,
0x71,
0x40
0x40,
0x00
};
uint8_t DispBuff[8];
uint16_t PosSel = 0;
@ -28,6 +31,31 @@ uint16_t PosSel = 0;
static void DisplayOneLed(uint8_t dat, uint8_t pos, uint8_t dot) {
uint16_t temp;
if (is_setting_time && !show_digit) {
switch (set_time_state) {
case SET_HOUR_TENS:
if (pos == 0) dat = 17;
break;
case SET_HOUR_ONES:
if (pos == 1) dat = 17;
break;
case SET_MIN_TENS:
if (pos == 3) dat = 17;
break;
case SET_MIN_ONES:
if (pos == 4) dat = 17;
break;
case SET_SEC_TENS:
if (pos == 6) dat = 17;
break;
case SET_SEC_ONES:
if (pos == 7) dat = 17;
break;
default:
break;
}
}
temp = display_tab[dat];
if (dot)
temp |= 0x80;

View File

@ -30,6 +30,7 @@
#include "SegLed.h"
#include "MatrixKey.h"
#include "gui.h"
#include <stdio.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@ -57,7 +58,7 @@ uint16_t mNum=15;
stSysTickTimer sSysTickTimer = {
0, 0, 0, 0
};
uint8_t tempValue;
uint8_t tempValue = 255;
structTime stTime = {
.mSecond = 50,
.mMinute = 45,
@ -69,8 +70,20 @@ structTime stTime = {
};
uint8_t KeyValue = 0;
extern uint8_t is_setting_time;
extern TIME_STATE set_time_state;
extern uint32_t blink_counter;
extern uint8_t show_digit;
enum picture_index {
NEURO_SAMA_SMALL,
EVIL_NEURO_SMALL
} pic_index = 0;
extern const unsigned char gImage_qq[3200];
extern const unsigned char gImage_Neuro_Sama[40704];
extern const unsigned char gImage_Neuro_Sama_small[10112];
extern const unsigned char gImage_Evil_Neuro_small[10240];
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
@ -81,30 +94,57 @@ void SystemClock_Config(void);
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void Gui_Drawbmp_full(uint16_t x,uint16_t y,const unsigned char *p) //显示159*128 图片
void Gui_Drawbmp_full(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const unsigned char *p)
{
int i;
unsigned char picH,picL;
LCD_SetWindows(x,y,x+159-1,y+128-1);//窗口设置
for(i=0;i<159*128;i++)
LCD_SetWindows(x,y,x+width-1,y+height-1);
for(i=0;i<width*height;i++)
{
picL=*(p+i*2); //数据低位在前
picL=*(p+i*2);
picH=*(p+i*2+1);
Lcd_WriteData_16Bit(picH<<8|picL);
}
LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复显示窗口为全屏
LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);
}
void my_test(void)
{
void my_init(void) {
LCD_direction(1);
// LCD_Clear(WHITE);
// DrawTestPage("图片显示测试");
//LCD_Fill(0,20,lcddev.width,lcddev.height-20,WHITE);
Gui_Drawbmp_full(0,0,gImage_Neuro_Sama);
// Show_Str(20+12,75,BLUE,YELLOW,"QQ",16,1);
// Gui_Drawbmp16(70,30,gImage_qq);
// Show_Str(70+12,75,BLUE,YELLOW,"QQ",16,1);
Gui_Drawbmp_full(0,0,159,128,gImage_Neuro_Sama);
HAL_Delay(1200);
LCD_Clear(WHITE);
}
void refresh_picture() {
switch (pic_index) {
case NEURO_SAMA_SMALL:
Gui_Drawbmp_full(40,50,79,64,gImage_Neuro_Sama_small);
break;
case EVIL_NEURO_SMALL:
Gui_Drawbmp_full(40,50,80,64,gImage_Evil_Neuro_small);
break;
default:
break;
}
pic_index = (pic_index + 1) % 2;
}
void my_show_time(void) {
char timeStr[20];
sprintf(timeStr, "%02d:%02d:%02d", stTime.mHour, stTime.mMinute, stTime.mSecond);
if (is_setting_time && show_digit) {
// 在设置模式下,根据当前设置的位置显示闪烁
char mask[6] = {':', ':', '\0'}; // 用于保持冒号显示
switch (set_time_state) {
case SET_HOUR_TENS: timeStr[0] = ' '; break;
case SET_HOUR_ONES: timeStr[1] = ' '; break;
case SET_MIN_TENS: timeStr[3] = ' '; break;
case SET_MIN_ONES: timeStr[4] = ' '; break;
case SET_SEC_TENS: timeStr[6] = ' '; break;
case SET_SEC_ONES: timeStr[7] = ' '; break;
case SET_DONE: break;
}
}
Show_Str(50, 10, BLUE, YELLOW, timeStr, 16, 0);
}
/* USER CODE END 0 */
@ -143,6 +183,8 @@ int main(void)
HAL_TIM_Base_Start_IT(&htim3);
TimeToBuff(&stTime);
LCD_Init();
my_init();
refresh_picture();
/* USER CODE END 2 */
/* Infinite loop */
@ -167,10 +209,17 @@ int main(void)
// Chinese_Font_test();
// Pic_test();
// Rotate_Test();
if (sSysTickTimer.bHundredMilSecOk) {
sSysTickTimer.bHundredMilSecOk = 0;
my_show_time();
}
if (sSysTickTimer.bTimeOk) {
sSysTickTimer.bTimeOk = 0;
HAL_GPIO_TogglePin(TickLed_GPIO_Port, TickLed_Pin);
my_test();
}
if (tempValue == 10) {
refresh_picture();
tempValue = 255;
}
}
/* USER CODE END 3 */

View File

@ -46,6 +46,14 @@
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
TIME_STATE set_time_state = SET_DONE;
uint8_t is_setting_time = 0; // 是否在设置时间模式
uint32_t blink_counter = 0; // 用于闪烁效果的计数器
uint8_t show_digit = 1; // 用于闪烁效果
extern uint8_t tempValue;
extern structTime stTime;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
@ -56,6 +64,63 @@
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void process_time_setting() {
if (tempValue == 11) { // 按键11用于进入/退出设置模式
if (!is_setting_time) {
is_setting_time = 1;
set_time_state = SET_HOUR_TENS;
show_digit = 1;
blink_counter = 0;
} else {
is_setting_time = 0;
set_time_state = SET_DONE;
}
tempValue = 255;
return;
}
if (!is_setting_time || tempValue > 9) return; // 只处理0-9的按键输入
switch (set_time_state) {
case SET_HOUR_TENS:
if (tempValue > 2) tempValue = 2; // 限制小时十位最大为2
stTime.mHour = tempValue * 10;
set_time_state = SET_HOUR_ONES;
break;
case SET_HOUR_ONES:
if (stTime.mHour == 20 && tempValue > 3) tempValue = 3; // 如果十位是2个位最大为3
stTime.mHour = (stTime.mHour / 10) * 10 + tempValue;
set_time_state = SET_MIN_TENS;
break;
case SET_MIN_TENS:
if (tempValue > 5) tempValue = 5; // 限制分钟十位最大为5
stTime.mMinute = tempValue * 10;
set_time_state = SET_MIN_ONES;
break;
case SET_MIN_ONES:
stTime.mMinute = (stTime.mMinute / 10) * 10 + tempValue;
set_time_state = SET_SEC_TENS;
break;
case SET_SEC_TENS:
if (tempValue > 5) tempValue = 5; // 限制秒十位最大为5
stTime.mSecond = tempValue * 10;
set_time_state = SET_SEC_ONES;
break;
case SET_SEC_ONES:
stTime.mSecond = (stTime.mSecond / 10) * 10 + tempValue;
is_setting_time = 0;
set_time_state = SET_DONE;
break;
case SET_DONE:
break;
}
}
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
@ -207,17 +272,26 @@ void SysTick_Handler(void)
for (int i = 0; i < 16; i++) {
if (KeyValue == KeyTable[i]) {
tempValue = i;
break;
}
}
DispToBuff(tempValue);
process_time_setting();
// DispToBuff(tempValue);
}
if (++sSysTickTimer.mTimeCount >= 100) {
if (++sSysTickTimer.mHundredMilSecCount >= 10) {
sSysTickTimer.mHundredMilSecCount = 0;
sSysTickTimer.bHundredMilSecOk = 1;
if (is_setting_time) {
show_digit = !show_digit;
}
if (++sSysTickTimer.mTimeCount >= 10) {
sSysTickTimer.mTimeCount = 0;
sSysTickTimer.bTimeOk = 1;
if(++mNum>=19)
mNum=15;
}
}
}
/* USER CODE END SysTick_IRQn 1 */
}

View File

@ -43,7 +43,7 @@ void MX_TIM3_Init(void)
htim3.Instance = TIM3;
htim3.Init.Prescaler = 170-1;
htim3.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
htim3.Init.Period = 999;
htim3.Init.Period = 1015;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)

View File

@ -315,7 +315,7 @@ SPI2.Mode=SPI_MODE_MASTER
SPI2.VirtualType=VM_MASTER
TIM3.CounterMode=TIM_COUNTERMODE_CENTERALIGNED1
TIM3.IPParameters=Prescaler,CounterMode,PeriodNoDither
TIM3.PeriodNoDither=1000-1
TIM3.PeriodNoDither=1016-1
TIM3.Prescaler=170-1
VP_SYS_VS_DBSignals.Mode=DisableDeadBatterySignals
VP_SYS_VS_DBSignals.Signal=SYS_VS_DBSignals