BASIC4MCU | 질문게시판 | 답변 : STM32F429ZIT6보드와 lcm1602 이용한 알람시계 질문 (사용자 지정 알람 값에 알람 인터럽트 반응)
페이지 정보
작성자 master 작성일2024-07-24 06:37 조회442회 댓글1건본문
void handle_buttons(){
ADC_MODULE();
if(adc_val!=last_adc_val &&(HAL_GetTick()-last_button_press_time)>200){
last_button_press_time=HAL_GetTick();
last_adc_val=adc_val;
if(adc_val<10){ // UP 버튼
if(mode==1){
if (set_step==0){ hour_now++; if(hour_now>23)hour_now=0; }
else if(set_step==1){ min_now++; if(min_now >59)min_now =0; }
else if(set_step==2){ sec_now++; if(sec_now >59)sec_now =0; }
update_lcd_set_time();
}
else if(mode==2){
if (set_step==0){ year_now++; if(year_now >99)year_now =0; }
else if(set_step==1){ month_now++; if(month_now >12)month_now =1; }
else if(set_step==2){ date_now++; if(date_now >31)date_now =1; }
else if(set_step==3){ weekday_now++; if(weekday_now> 7)weekday_now=1; }
update_lcd_set_date();
}
else if(mode==3){
if (set_step==0){ alarm_hour++; if(alarm_hour >23)alarm_hour =0; }
else if(set_step==1){ alarm_minute++; if(alarm_minute>59)alarm_minute=0; }
else if(set_step==2){ alarm_second++; if(alarm_second>59)alarm_second=0; }
update_lcd_set_alarm();
char debug_msg[50];
int debug_msg_len=sprintf(debug_msg,"Alarm Set to %02d:%02d:%02d\n",alarm_hour,alarm_minute,alarm_second);
HAL_UART_Transmit(&huart3,(uint8_t *)debug_msg,debug_msg_len,100);
set_rtc_alarm();
}
}
else if(adc_val>=800 && adc_val<900){ // DOWN 버튼
if(mode==1){
if (set_step==0){ if(hour_now==0)hour_now=23; else hour_now--; }
else if(set_step==1){ if(min_now ==0)min_now =59; else min_now--; }
else if(set_step==2){ if(sec_now ==0)sec_now =59; else sec_now--; }
update_lcd_set_time();
}
else if(mode==2){
if (set_step==0){ if(year_now ==0)year_now =99; else year_now--; }
else if(set_step==1){ if(month_now ==1)month_now =12; else month_now--; }
else if(set_step==2){ if(date_now ==1)date_now =31; else date_now--; }
else if(set_step==3){ if(weekday_now==1)weekday_now= 7; else weekday_now--; }
update_lcd_set_date();
}
else if(mode==3){
if (set_step==0){ if(alarm_hour ==0)alarm_hour =23; else alarm_hour--; }
else if(set_step==1){ if(alarm_minute==0)alarm_minute=59; else alarm_minute--; }
else if(set_step==2){ if(alarm_second==0)alarm_second=59; else alarm_second--; }
update_lcd_set_alarm();
char debug_msg[50];
int debug_msg_len=sprintf(debug_msg,"Alarm Set to %02d:%02d:%02d\n",alarm_hour,alarm_minute,alarm_second);
HAL_UART_Transmit(&huart3,(uint8_t *)debug_msg,debug_msg_len,100);
set_rtc_alarm();
}
}
else if(adc_val>=2600 && adc_val<3000){ // RIGHT 버튼
if(mode==1){
if(++set_step>2){ set_step=0; mode=0;
sTime.Hours=hour_now; sTime.Minutes=min_now; sTime.Seconds=sec_now;
HAL_RTC_SetTime(&hrtc,&sTime,RTC_FORMAT_BIN);
char buffer[50];
int buffer_len=sprintf(buffer,"Mode: 0,Time Set to %02d:%02d:%02d\n",hour_now,min_now,sec_now);
HAL_UART_Transmit(&huart3,(uint8_t *)buffer,buffer_len,100);
}
else{
char buffer[50];
int buffer_len=sprintf(buffer,"Set Step: %d\n",set_step);
HAL_UART_Transmit(&huart3,(uint8_t *)buffer,buffer_len,100);
}
update_lcd_set_time();
}
else if(mode==2){
if(++set_step>3){ set_step=0; mode=0;
sDate.Year=year_now; sDate.Month=month_now; sDate.Date=date_now; sDate.WeekDay=weekday_now;
HAL_RTC_SetDate(&hrtc,&sDate,RTC_FORMAT_BIN);
char buffer[50];
int buffer_len=sprintf(buffer,"Mode: 0,Date Set to %02d-%02d-%02d\n",year_now,month_now,date_now);
HAL_UART_Transmit(&huart3,(uint8_t *)buffer,buffer_len,100);
}
else{
char buffer[50];
int buffer_len=sprintf(buffer,"Set Step: %d\n",set_step);
HAL_UART_Transmit(&huart3,(uint8_t *)buffer,buffer_len,100);
}
update_lcd_set_date();
}
else if(mode==3){
if(++set_step>2){ set_step=0; mode=0; set_rtc_alarm(); }
else{
char buffer[50];
int buffer_len=sprintf(buffer,"Set Step: %d\n",set_step);
HAL_UART_Transmit(&huart3,(uint8_t *)buffer,buffer_len,100);
}
update_lcd_set_alarm();
}
}
}
}
int main(void){
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USB_OTG_FS_PCD_Init();
MX_USART3_UART_Init();
MX_ADC1_Init();
MX_DAC_Init();
MX_TIM3_Init();
MX_I2C1_Init();
MX_RTC_Init();
MX_TIM2_Init();
MX_NVIC_Init(); //기본 초기화 코드
HAL_TIM_Base_Start_IT(&htim2);
HAL_TIM_Base_Init(&htim3);
HAL_TIM_Base_Start_IT(&htim3);
time_LCM1602_init();
HAL_ADC_Start_IT(&hadc1);
sprintf(uart_buf,"System Initialized\n");
HAL_UART_Transmit(&huart3,(uint8_t *)&uart_buf,sizeof(uart_buf),100);
while(1){
if(mode==0){
if(update_lcd_flag){ update_lcd_flag=0; update_lcd_time(); }
}
else{ handle_buttons(); }
//
if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)){
if(++mode>3){ mode=0;
sTime.Hours=hour_now; sTime.Minutes=min_now; sTime.Seconds=sec_now; HAL_RTC_SetTime(&hrtc,&sTime,RTC_FORMAT_BIN);
sDate.Year=year_now; sDate.Month=month_now; sDate.Date=date_now; sDate.WeekDay=weekday_now; HAL_RTC_SetDate(&hrtc,&sDate,RTC_FORMAT_BIN);
}
if (mode==1){ set_step=0; update_lcd_set_time(); }
else if(mode==2){ set_step=0; update_lcd_set_date(); }
else if(mode==3){ set_step=0; update_lcd_set_alarm(); }
HAL_Delay(200);
}
if(alarm_triggered){ lcd_alarm(); alarm_triggered=0; }
}
}
메인함수 루프를 보면
GPIOC,GPIO_PIN_13 및 handle_buttons(); 함수 실행주기는 200ms로 짧습니다.
if(++set_step>3){ set_step=0;
따라서 정확히 1씩 증가시키지 못합니다.
GPIOC,GPIO_PIN_13 버튼 감지도 엣지 검출 방법을 공부해서 처리하고
else if(adc_val>=2600 && adc_val<3000){ // RIGHT 버튼
아나로그 값의 버튼도 엣지 검출 방법을 공부해서 처리 해보세요//아나로그 값의 버튼 엣지 검출은 어려워서 예제를 찾기 어려울테니 도움을 드리죠unsigned int btn13_stat=0,btnADC_stat=0; // 추가전역변수에 추가합니다.int main(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_DMA_Init();MX_USB_OTG_FS_PCD_Init();MX_USART3_UART_Init();MX_ADC1_Init();MX_DAC_Init();MX_TIM3_Init();MX_I2C1_Init();MX_RTC_Init();MX_TIM2_Init();MX_NVIC_Init(); //기본 초기화 코드HAL_TIM_Base_Start_IT(&htim2);HAL_TIM_Base_Init(&htim3);HAL_TIM_Base_Start_IT(&htim3);time_LCM1602_init();HAL_ADC_Start_IT(&hadc1);sprintf(uart_buf,"System Initialized\n");HAL_UART_Transmit(&huart3,(uint8_t *)&uart_buf,sizeof(uart_buf),100);while(1){if(mode==0){if(update_lcd_flag){ update_lcd_flag=0; update_lcd_time(); }}else{ handle_buttons(); }//if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)){if(btn13_stat==0){ btn13_stat=1;if(++mode>3){ mode=0;sTime.Hours=hour_now; sTime.Minutes=min_now; sTime.Seconds=sec_now; HAL_RTC_SetTime(&hrtc,&sTime,RTC_FORMAT_BIN);sDate.Year=year_now; sDate.Month=month_now; sDate.Date=date_now; sDate.WeekDay=weekday_now; HAL_RTC_SetDate(&hrtc,&sDate,RTC_FORMAT_BIN);}if (mode==1){ set_step=0; update_lcd_set_time(); }else if(mode==2){ set_step=0; update_lcd_set_date(); }else if(mode==3){ set_step=0; update_lcd_set_alarm(); }HAL_Delay(50);}}else{if(btn13_stat){ btn13_stat=0; HAL_Delay(50); }}//if(alarm_triggered){ lcd_alarm(); alarm_triggered=0; }}}
엣지를 검출하므로 버튼을 오래 누르고 있어도 1회만 실행합니다.채터링방지 딜레이는 50ms로 변경했습니다.void handle_buttons(){ADC_MODULE();if(adc_val!=last_adc_val &&(HAL_GetTick()-last_button_press_time)>200){last_button_press_time=HAL_GetTick();last_adc_val=adc_val;if(adc_val<10){ // UP 버튼if(btnADC_stat!=1){ btnADC_stat=1;if(mode==1){if (set_step==0){ hour_now++; if(hour_now>23)hour_now=0; }else if(set_step==1){ min_now++; if(min_now >59)min_now =0; }else if(set_step==2){ sec_now++; if(sec_now >59)sec_now =0; }update_lcd_set_time();}else if(mode==2){if (set_step==0){ year_now++; if(year_now >99)year_now =0; }else if(set_step==1){ month_now++; if(month_now >12)month_now =1; }else if(set_step==2){ date_now++; if(date_now >31)date_now =1; }else if(set_step==3){ weekday_now++; if(weekday_now> 7)weekday_now=1; }update_lcd_set_date();}else if(mode==3){if (set_step==0){ alarm_hour++; if(alarm_hour >23)alarm_hour =0; }else if(set_step==1){ alarm_minute++; if(alarm_minute>59)alarm_minute=0; }else if(set_step==2){ alarm_second++; if(alarm_second>59)alarm_second=0; }update_lcd_set_alarm();char debug_msg[50];int debug_msg_len=sprintf(debug_msg,"Alarm Set to %02d:%02d:%02d\n",alarm_hour,alarm_minute,alarm_second);HAL_UART_Transmit(&huart3,(uint8_t *)debug_msg,debug_msg_len,100);set_rtc_alarm();}}}else if(adc_val>=800 && adc_val<900){ // DOWN 버튼if(btnADC_stat!=2){ btnADC_stat=2;if(mode==1){if (set_step==0){ if(hour_now==0)hour_now=23; else hour_now--; }else if(set_step==1){ if(min_now ==0)min_now =59; else min_now--; }else if(set_step==2){ if(sec_now ==0)sec_now =59; else sec_now--; }update_lcd_set_time();}else if(mode==2){if (set_step==0){ if(year_now ==0)year_now =99; else year_now--; }else if(set_step==1){ if(month_now ==1)month_now =12; else month_now--; }else if(set_step==2){ if(date_now ==1)date_now =31; else date_now--; }else if(set_step==3){ if(weekday_now==1)weekday_now= 7; else weekday_now--; }update_lcd_set_date();}else if(mode==3){if (set_step==0){ if(alarm_hour ==0)alarm_hour =23; else alarm_hour--; }else if(set_step==1){ if(alarm_minute==0)alarm_minute=59; else alarm_minute--; }else if(set_step==2){ if(alarm_second==0)alarm_second=59; else alarm_second--; }update_lcd_set_alarm();char debug_msg[50];int debug_msg_len=sprintf(debug_msg,"Alarm Set to %02d:%02d:%02d\n",alarm_hour,alarm_minute,alarm_second);HAL_UART_Transmit(&huart3,(uint8_t *)debug_msg,debug_msg_len,100);set_rtc_alarm();}}}else if(adc_val>=2600 && adc_val<3000){ // RIGHT 버튼if(btnADC_stat!=3){ btnADC_stat=3;if(mode==1){if(++set_step>2){ set_step=0; mode=0;sTime.Hours=hour_now; sTime.Minutes=min_now; sTime.Seconds=sec_now;HAL_RTC_SetTime(&hrtc,&sTime,RTC_FORMAT_BIN);char buffer[50];int buffer_len=sprintf(buffer,"Mode: 0,Time Set to %02d:%02d:%02d\n",hour_now,min_now,sec_now);HAL_UART_Transmit(&huart3,(uint8_t *)buffer,buffer_len,100);}else{char buffer[50];int buffer_len=sprintf(buffer,"Set Step: %d\n",set_step);HAL_UART_Transmit(&huart3,(uint8_t *)buffer,buffer_len,100);}update_lcd_set_time();}else if(mode==2){if(++set_step>3){ set_step=0; mode=0;sDate.Year=year_now; sDate.Month=month_now; sDate.Date=date_now; sDate.WeekDay=weekday_now;HAL_RTC_SetDate(&hrtc,&sDate,RTC_FORMAT_BIN);char buffer[50];int buffer_len=sprintf(buffer,"Mode: 0,Date Set to %02d-%02d-%02d\n",year_now,month_now,date_now);HAL_UART_Transmit(&huart3,(uint8_t *)buffer,buffer_len,100);}else{char buffer[50];int buffer_len=sprintf(buffer,"Set Step: %d\n",set_step);HAL_UART_Transmit(&huart3,(uint8_t *)buffer,buffer_len,100);}update_lcd_set_date();}else if(mode==3){if(++set_step>2){ set_step=0; mode=0; set_rtc_alarm(); }else{char buffer[50];int buffer_len=sprintf(buffer,"Set Step: %d\n",set_step);HAL_UART_Transmit(&huart3,(uint8_t *)buffer,buffer_len,100);}update_lcd_set_alarm();}}}else if(adc_val>=3600){ // 버튼 해제if(btnADC_stat){ btnADC_stat=0; }}}}제일 마지막 버튼을 누르지 않았을 때의 ADC 값을 3600 이상으로 추정했는데맞지 않으면 값을 조정하세요
댓글 1
조회수 442aaahhhj님의 댓글
aaahhhj 작성일
버튼을 엣지로 인식하는 것도 한번 찾아봐야겠습니다
알람 트리거 부분은 뭐가 문제인지 잘 모르겠네요... 도대체 왜 임의지정값에 대해 알람이 안울리는건지..이것도 다시 찾아봐야겠습니다. ㅠ
답변 감사합니다~!