为了减少篇幅,各模块的初始化均在模块配置中,可以随时去翻看博客,还有function里面的函数,将不再罗列出来,只是截图展示。
需要用的模块:LCD、IIC、四个按键、LED、USART2
LCD:显示-----》Display();
IIC:读取和存储信息到EEPROM-----》EEPROM_Write();EEPROM_Read();
按键:对参数进行调整-----》KEY_Handle();KEY_Scan();
LED:提示作用-----》LED();
USART2:与PC机交互
mode表示页面显示的三种状态
location表示设置某个位(时分秒),被选定为红色
void Dispaly(void)
{
if(mode == 0)
{
LCD_DisplayStringLine(Line1," MAIN ");
}else if(mode == 1)
{
LCD_DisplayStringLine(Line1," RTC-SETTING ");
}else if(mode == 2)
{
LCD_DisplayStringLine(Line1," ALARM-SETTING ");
}
if(mode == 0)
{
sprintf((char *)str," RTC:%.2d:%.2d:%.2d ",Time[0],Time[1],Time[2]);
LCD_DisplayStringLine(Line3,str);
}
else if(mode == 1)
{
if(location == 0)
{
LCD_SetTextColor(Black);
sprintf((char *)str," RTC: :%.2d:%.2d ",Time[1],Time[2]);
LCD_DisplayStringLine(Line3,str);
LCD_SetTextColor(Red);
LCD_DisplayChar(Line3,225, Time[0]/10 + '0');
LCD_DisplayChar(Line3,210, Time[0]%10 + '0');
}
else if(location == 1)
{
LCD_SetTextColor(Black);
sprintf((char *)str," RTC:%.2d: :%.2d ",Time[0],Time[2]);
LCD_DisplayStringLine(Line3,str);
LCD_SetTextColor(Red);
LCD_DisplayChar(Line3,180, Time[1]/10 + '0');
LCD_DisplayChar(Line3,165, Time[1]%10 + '0');
}
else if(location == 2)
{
LCD_SetTextColor(Black);
sprintf((char *)str," RTC:%.2d:%.2d: ",Time[0],Time[1]);
LCD_DisplayStringLine(Line3,str);
LCD_SetTextColor(Red);
LCD_DisplayChar(Line3,130, Time[2]/10 + '0');
LCD_DisplayChar(Line3,110, Time[2]%10 + '0');
}
}
else if(mode == 2)
{
if(location == 0)
{
LCD_SetTextColor(Black);
sprintf((char *)str,"Alarm: :%.2d:%.2d ",Alarm_Time[1],Alarm_Time[2]);
LCD_DisplayStringLine(Line3,str);
LCD_SetTextColor(Red);
LCD_DisplayChar(Line3,225, Alarm_Time[0]/10 + '0');
LCD_DisplayChar(Line3,210, Alarm_Time[0]%10 + '0');
}
else if(location == 1)
{
LCD_SetTextColor(Black);
sprintf((char *)str,"Alarm:%.2d: :%.2d ",Alarm_Time[0],Alarm_Time[2]);
LCD_DisplayStringLine(Line3,str);
LCD_SetTextColor(Red);
LCD_DisplayChar(Line3,180, Alarm_Time[1]/10 + '0');
LCD_DisplayChar(Line3,165, Alarm_Time[1]%10 + '0');
}
else if(location == 2)
{
LCD_SetTextColor(Black);
sprintf((char *)str,"Alarm:%.2d:%.2d: ",Alarm_Time[0],Alarm_Time[1]);
LCD_DisplayStringLine(Line3,str);
LCD_SetTextColor(Red);
LCD_DisplayChar(Line3,130, Alarm_Time[2]/10 + '0');
LCD_DisplayChar(Line3,110, Alarm_Time[2]%10 + '0');
}
}
LCD_SetTextColor(Black);
}
IIC的读写函数在模块配置iic那一小节
分别存储当前时间、设定时间、报警次数、设置次数
void EEPROM_Read(void)
{
Time[0] = IIC_Read(0x00);HAL_Delay(10);
Time[1] = IIC_Read(0x01);HAL_Delay(10);
Time[2] = IIC_Read(0x02);HAL_Delay(10);
Alarm_Time[0] = IIC_Read(0x03);HAL_Delay(10);
Alarm_Time[1] = IIC_Read(0x04);HAL_Delay(10);
Alarm_Time[2] = IIC_Read(0x05);HAL_Delay(10);
Alarm_num = IIC_Read(0x06);HAL_Delay(10);
Set_RTC = IIC_Read(0x07);HAL_Delay(10);
}
void EEPROM_Write(void)
{
IIC_Write(0x00,Time[0]);HAL_Delay(10);
IIC_Write(0x01,Time[1]);HAL_Delay(10);
IIC_Write(0x02,Time[2]);HAL_Delay(10);
IIC_Write(0x03,Alarm_Time[0]);HAL_Delay(10);
IIC_Write(0x04,Alarm_Time[1]);HAL_Delay(10);
IIC_Write(0x05,Alarm_Time[2]);HAL_Delay(10);
IIC_Write(0x06,Alarm_num);HAL_Delay(10);
IIC_Write(0x07,Set_RTC);HAL_Delay(10);
}
由于有长按和短按,所以对于长按有B3_B4函数进行操作(操作代码一样,调用函数更省空间)
uint8_t KEY_Scan(void)
{
uint8_t sum;//计数个数
static uint8_t flag = 1;
sum = 0;
if(flag &&(KEY_B1 == 0 || KEY_B2 == 0 || KEY_B3 == 0 || KEY_B4== 0 ))
{
flag = 0;
HAL_Delay(10);
if (KEY_B1 == 0) return B1_Press;
else if (KEY_B2 == 0) return B2_Press;
while(!KEY_B3)
{
HAL_Delay(200);
sum++;
if(sum > 5 )
{
B3_B4(B3_Press);
}
}
if (sum < 5 && sum != 0) return B3_Press;
while(!KEY_B4)
{
HAL_Delay(200);
sum++;
if(sum>5)
{
B3_B4(B3_Press);
}
}
if (sum < 5 && sum != 0) return B4_Press;
}else if(KEY_B1 == 1 && KEY_B2 == 1 && KEY_B3 == 1 && KEY_B4== 1) flag = 1;
return 0;
}
在B1按下时显示页面切换(mode变化)
在B2按下时切换参数选择的地址(location变化)
在B3按下时对应参数加1
在B4按下时对应参数减1
void KEY_Handle(uint8_t key)
{
if(key == B1_Press)
{
if(mode == 0)
{
run = 0;
mode = 1;
}
else if(mode == 1)
{
Set_RTC++;
run = 1;
mode = 0;
EEPROM_Write();
}
else if(mode == 2)
{
location++;
location = location % 3 ;
}
}
else if(key == B2_Press)
{
if(mode == 0)
{
run = 0;
mode = 2;
}
else if(mode == 2)
{
run = 1;
mode = 0;
EEPROM_Write();
}
else if(mode == 1)
{
location++;
location = location % 3 ;
}
}
else if(key == B3_Press) B3_B4(B3_Press);
else if(key == B4_Press) B3_B4(B4_Press);
}
void B3_B4(uint8_t key)
{
if(key == B3_Press)
{
if(mode == 1)
{
Time[location]++;
Time[location] = Time[location] % 60;
Time[0] = Time[0] % 24;
}
else if(mode == 2)
{
Alarm_Time[location]++;
Alarm_Time[location] = Alarm_Time[location] % 60;
Alarm_Time[0] = Alarm_Time[0] % 24;
}
}
else if(key == B4_Press)
{
if(location == 0)
{
if(mode == 1)
{
if(!Time[0]) Time[0] = 23;
Time[0]--;
}
else if(mode == 2)
{
if(!Alarm_Time[0]) Alarm_Time[0] = 23;
Alarm_Time[0]--;
}
}
else
{
if(mode == 1)
{
if(!Time[location]) Time[location] = 59;
Time[location]--;
}
else if(mode == 2)
{
if(!Alarm_Time[location]) Alarm_Time[location] = 59;
Alarm_Time[location]--;
}
}
}
}
I2CInit();
LCD_Init();
LCD_Clear(White);
LCD_SetTextColor(Black);
mode = 0;
IIC_Write(0x00,11);HAL_Delay(10);
IIC_Write(0x01,59);HAL_Delay(10);
IIC_Write(0x02,50);HAL_Delay(10);
IIC_Write(0x03,12);HAL_Delay(10);
IIC_Write(0x04,00);HAL_Delay(10);
IIC_Write(0x05,00);HAL_Delay(10);
IIC_Write(0x06,0);HAL_Delay(10);
IIC_Write(0x07,0);HAL_Delay(10);
EEPROM_Read();
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8|GPIO_PIN_10
|GPIO_PIN_9|GPIO_PIN_11|GPIO_PIN_12,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
Dispaly();//显示
key = KEY_Scan();
KEY_Handle(key);
if(count == 1 && run && mode == 0)//计数
{
Time[2]++;
if(Time[2] >= 60)
{
Time[2] = 0;
Time[1]++;
}
if(Time[1] >= 60)
{
Time[1] = 0;
Time[0]++;
}
if(Time[0] >= 24) Time[0] = 0;
count = 0;
// HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);
if(i++%2)
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_SET);
else
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15
|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
if(Alarm_Time[0] == Time[0] && Alarm_Time[1] == Time[1] && Alarm_Time[2] == Time[2])//报警
{
Alarm_num++;
IIC_Write(0x06,Alarm_num);HAL_Delay(10);
Dispaly();
HAL_Delay(3000);
num = 0;
EEPROM_Read();
printf("NEW RTC:%.2d:.%.2d:%.2d\r\n",Time[0],Time[1],Time[2]);
printf("NEW Alarm:%.2d:%.2d:%.2d\r\n",Alarm_Time[0],Alarm_Time[1],Alarm_Time[2]);
}
if(mode == 1)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
else if(mode == 2)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
|GPIO_PIN_9|GPIO_PIN_11|GPIO_PIN_12,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
上面的time和count在哪变了,在哪计时呢?
就在滴答定时器里面咯。
大家打开stm32g4xx_it.c
if(run) num++;
if(num >= 1000)
{
count = 1;
num = 0;
}
运行的时候才开始计数,一秒的计数。
以上就是本次模拟赛的程序设计部分(变量定义部分,本人没有罗列出来嗷),在代码简洁方面本人做的不是很好,如有更好的设计方法可以在评论区留言。互相学习。
还等什么,赶快自己写一下,测试一下代码。本人亲测有效、嘿嘿