Reloj multifuncional 1 basado en stm32 - visualización del reloj
¡Hola lectores!
Siguiendo el contenido del capítulo anterior Reloj multifuncional (Introducción), en este capítulo presentaré la parte de visualización del reloj del reloj multifuncional. Sin más preámbulos, comencemos ~
Para un reloj multifunción, la función de visualización del reloj es esencial. Por lo tanto, utilizamos el temporizador stm32 para cronometrar. Originalmente planeé usar el reloj en tiempo real stm32 RTC, pero luego pensé que cuando comencé a hacerlo, debería tratar de ser lo más simple posible y no causarme problemas al principio. Hay muchas cosas que configurar para el reloj en tiempo real RTC. Si hace un buen trabajo esta vez, podrá agregar un reloj RTC en tiempo real más adelante.
stm32 es diferente de 51. Tiene 11 temporizadores, incluidos 2 temporizadores de control avanzado (TIM1 y TIM8), 4 temporizadores ordinarios (TIM2~TIM5) y 2 temporizadores básicos (TIM6 y TIM7). como 2 temporizadores de vigilancia y 1 temporizador de tic del sistema. Aquí, usamos el temporizador ordinario TIM2 y habilitamos la interrupción del temporizador. El tiempo de interrupción es 1 segundo, y en la función de interrupción, se simula la función de temporización del reloj.
(1) Configurar el controlador de interrupciones anidado NVIC
void tim2_nvic_config(void)
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;//La prioridad de preferencia es 2
NVIC_InitStruct .NVIC_IRQChannelSub Prioridad = 0; // La subprioridad es 0
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
Aquí Solo necesitamos asignar un valor a cada elemento de la estructura NVIC_InitStruct, donde TIM2_IRQn es la línea de interrupción del temporizador TIM2 y establecer el grupo de prioridad en 2, es decir, el grupo de prioridad de preferencia es el grupo 4, y la prioridad de preferencia aquí es 2. La subprioridad es 0 y luego se habilita NVIC (la prioridad no puede comprender la consulta en línea).
(2) Configuración de inicialización del temporizador
void tim2_config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
tim2_nvic_config(); //Configurar NVIC
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //Habilitar reloj
TIM_DeInit(TIM2); > TIM_TimeBaseInitStruct.TIM_Period = 2000-1; //Recargar automáticamente el valor del registro
TIM_TimeBaseInitStruct.TIM_Prescaler = 36000-1; /División de frecuencia de muestreo
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //Modo de conteo
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); //Inicializar TIM2
TIM_ClearFlag(TIM2, TIM_FLAG_Update); //Borrar el indicador de interrupción de desbordamiento
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE); //Habilitar reloj
<); p> }Para inicializar TIM2, primero configure el NVIC, encienda el reloj de TIM2 y reinicie TIM2. Luego asigne un valor a cada elemento de la estructura TIM_TimeBaseInitStruct. Aquí, explicamos principalmente cómo calcular el tiempo de interrupción programado. El tiempo de interrupción por desbordamiento del temporizador está determinado por TIM_Period y TIM_Prescaler. Aquí, doy directamente la fórmula: tiempo de interrupción = (TIM_Period+1) * (TIM_Prescaler+1)/FCLK, y FCLK es 72M, por lo que el tiempo es 1s, puede ser así: TIM_Period=2000-1, TIM_Prescaler= 36000-1; Finalmente, borre el indicador de interrupción de desbordamiento y permita que el reloj cuente.
(3) Escriba una función de sincronización de interrupción
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) ! =RESET)
{
seg++;
if(seg>=60)
{
seg = 0;
min++;
si(min>=60)
{
min = 0;
hora++;
if(hora>=24)
{
hora = 0;
}
}
}
}
TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);
}
Aquí Primero defina las tres variables de horas, minutos y segundos, y luego convierta la relación entre las variables de tiempo en la función de interrupción.
(4) Función de visualización del reloj de escritura
Aquí utilizamos LCD12864 para la visualización en tiempo real. El contenido relevante de LCD12864 se presentará específicamente en el capítulo de funciones de la biblioteca LCD más adelante. Aquí sólo se muestra la hora.
lcd_display_num_m(2, 16, hora/10);
lcd_display_num_m(2, 24, hora%10);
lcd_display_string(2,32," tiempo");
lcd_display_num_m(2, 48, min/10);
lcd_display_num_m(2, 56, min%10);
lcd_display_string(2 ,64,"minutos");
lcd_display_num_m(2, 80, seg/10);
lcd_display_num_m(2, 88, seg%10);
lcd_display_string(2,96,"segundos");
Escribí la función del controlador de LCD12864 siguiendo el video del profesor Huang, según las instrucciones del profesor, agregué una función de visualización de cadena de caracteres chinos. Aquí, puede considerarse como una función de biblioteca. Solo necesita una simple llamada para mostrar la hora.
(5) Presione el botón para ajustar la hora
Después de mostrar correctamente la hora, debemos presionar el botón para ajustar la hora. Necesitamos configurar la tecla de inicio/parada del reloj (K1), la tecla de selección de bit de tiempo (K2), la tecla de aumento de valor (K3) y la tecla de disminución de valor (K4).
1. Primero configuramos el GPIO del botón, activamos el reloj correspondiente, seleccionamos el pin correspondiente, configuramos el modo de entrada flotante, etc.
void key_gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*Habilitar el reloj RCC de GPIO*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
/*Configurar pines PB11~PB14*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
2. Después de configurar el puerto GPIO del botón, escriba la función de escaneo del botón para lograr la función de ajustar la hora.
u8 flag,mark;//flag es el indicador de inicio y parada del temporizador, mark es el indicador de selección de bits
//mark es 0, lo que significa que no está seleccionado, y la marca es 1, lo que significa que está seleccionado el bit de tiempo, la marca es 2 para seleccionar el bit de minutos, la marca es 3 para seleccionar el segundo bit
void keycan(void)
{
if(GPIO_ReadInputDataBit(GPIOB ,GPIO_Pin_11)==RESET)
{
delay_ms(10);
if(GPIO_ReadInputDataBit( GPIOB,GPIO_Pin_11)==RESET)
{
bandera = ~bandera;
if(!flag)
{ p>
TIM_Cmd(TIM2, HABILITAR);
}
más
{
TIM_Cmd(TIM2, DISABLE);
marca = 0;
}
}mientras(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==RESET);
} p>
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12 )==RESET)
{
delay_ms(10);
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)==RESET)
{
marca = marca>=3?0:marca+1;
}mientras(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12) ==RESET);
}
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)==RESET)
{
delay_ms(10 );
if(GPIO_ReadInputDataBit (GPIOB,GPIO_Pin_13)==RESET)
{
if(bandera)
{ p>
cambiar(marca)
{
caso 1:hora = hora<23?hora+1:0;descanso;
caso 2 :min = min<59?min+1:0 ;break;
caso 3:sec = seg<59?sec+1:0;break;
default:break;
}
}
}mientras(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)==RESET);
}
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==RESET)
{
delay_ms(10);
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==RESET)
{
if(bandera)
{
cambiar(marca)
{
caso 1:hora = hora>0? hora-1:23;descanso;
caso 2:min = min>0?min-1:59;descanso;
caso 3:seg = seg>0?sec- 1:59;romper;
predeterminado:romper;
}
}
}mientras(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)= =RESET);
}
}
En este punto, hemos completado la función de visualización del reloj. Por supuesto, si es posible más adelante, podemos usar el. RTC del recurso de reloj en tiempo real stm32, también puede configurar funciones de despertador y hora.
En este capítulo, presento principalmente cómo utilizar el temporizador TIM y los recursos GPIO de stm32 para realizar las funciones de visualización del reloj y ajuste de botones. En el próximo capítulo, presentaré cómo utilizar el módulo DHT11 para medir la temperatura y la humedad, a fin de lograr la adquisición de parámetros ambientales por parte del sistema.