Notas de estudio|Principio clave|Antirrebote|Cuatro modos de iluminación de botones|Tutorial de desarrollo de vídeo del microcontrolador STC32G (Brother Chong)|Episodio 7: Iluminación de botones

Respuestas a los ejercicios extraescolares del Episodio 6 (Parte 2): Recopilación de luces de socorro SOS

Principio de la señal de socorro

Fuente: Asking Knowledge: ¿Cómo se expresa SOS con luces?
Tres cortas, tres largas y tres cortas
SOS es una señal de socorro universal en el mundo. Si se representa con una señal luminosa, tres luces cortas representan la letra S, tres largas Las luces representan la letra O, y luego las siguientes tres luces cortas representan la S.
El tiempo de iluminación largo de la luz es tres veces el tiempo de iluminación corto, y el tiempo de iluminación corto es el mismo que el intervalo entre dos tiempos de iluminación del LED. También hay un intervalo de apagado de tres veces el tiempo de iluminación corto entre una letra. y la siguiente letra.

Código y análisis de Chongge.

Diseño modular:

matemáticas.h:

#ifndef __MATH_H  //if no define
#define __MATH_H

#include "stc.h"		//调用头文件,具体引用路径根据options选择的调用路径而定
#include "usb.h"

#define MAIN_Fosc 24000000UL		//定义一个IRC系统时钟

int  Add( int parm1,int parm2  );		//加法
int  Sub( int parm1,int parm2  );		//减法
int  Mul( int parm1,int parm2  );		//乘法


void SOS_Led(void);
void delay_ms(u16 ms);	//unsigned int


#endif

matemáticas.c:

Agregar definición de función:

#include "math.h"

int  Add( int parm1,int parm2  )
{
	return parm1 + parm2;
}


int  Sub( int parm1,int parm2  )
{
	return parm1 - parm2;
}

int  Mul( int parm1,int parm2  )
{
	return parm1 * parm2;
}



void SOS_Led(void)
{
	P60 = 0;			//点亮
	delay_ms(200);
	P60 = 1;			//熄灭
	delay_ms(200);
	P60 = 0;			//点亮
	delay_ms(200);
	P60 = 1;			//熄灭
	delay_ms(200);
	P60 = 0;			//点亮
	delay_ms(200);
	P60 = 1;			//熄灭
	delay_ms(200);

	P60 = 0;			//点亮
	delay_ms(500);
	P60 = 1;			//熄灭
	delay_ms(500);
	P60 = 0;			//点亮
	delay_ms(500);
	P60 = 1;			//熄灭
	delay_ms(500);
	P60 = 0;			//点亮
	delay_ms(500);
	P60 = 1;			//熄灭
	delay_ms(500);

	P60 = 0;			//点亮
	delay_ms(200);
	P60 = 1;			//熄灭
	delay_ms(200);
	P60 = 0;			//点亮
	delay_ms(200);
	P60 = 1;			//熄灭
	delay_ms(200);
	P60 = 0;			//点亮
	delay_ms(200);
	P60 = 1;			//熄灭
	delay_ms(200);

	delay_ms(3000);

}

void delay_ms(u16 ms)	//unsigned int
{
	u16 i;
	do
	{
		i = MAIN_Fosc/6000;
		while(--i);
	}while(--ms);
}

En el programa principal demo.c: #incluya "math.h" y llame directamente a: SOS_Led() en el cuerpo de la función principal función main() para implementar la función SOS.
Primero, coloque las declaraciones de función de void SOS_Led(void) y void delay_ms(u16 ms) en el archivo de encabezado math.h:

Luego, mueva las definiciones de funciones de void SOS_Led(void) y void delay_ms(u16 ms) a math.c:

MAIN_Fosc se usa en la función de retraso y debe agregarse. En principal.c:

#define MAIN_Fosc 24000000UL  //#define 名称 需要定义的内容

mientras que la parte principal del programa

while(1)		//死循环
	{
		if( DeviceState != DEVSTATE_CONFIGURED ) 	//
			continue;
		if( bUsbOutReady )
		{
			usb_OUT_done();


			printf("计算Add( 1,2 )结果为:%d\r\n",Add( 1,2 ));

			printf("计算Sub( 5,2 )结果为:%d\r\n",Sub( 5,2 ));

			printf("计算Mul( 5,3 )结果为:%d\r\n",Mul( 5,3 ));

		}
		P40 = 0;	//三极管引脚输出低电平

		SOS_Led();
	}

Compile normalmente y comience a flashear.

Iluminación de botones (abajo)

1.Principio del botón

Aunque los botones parecen extraños, son esencialmente la conexión entre dos pines.
Insertar descripción de la imagen aquí
En algunos casos, los dos pines se conectan después de presionar el botón;
en algunos casos, los dos pines se desconectan después de presionar el botón.
Diagrama esquemático:
Insertar descripción de la imagen aquí
hay una resistencia pull-up, si no se presiona el botón. Esta es una señal de desconexión completa.
El pin MCU 3.2 está conectado a un VCC. VCC fluye hacia el puerto IO de P3.2 INT0 a través de R10 y R82. Después de presionar el botón, la sección trasera de la resistencia se conecta a GND y
todas las posiciones del cable son 0 V. R10 es una resistencia limitadora de corriente para proteger el puerto IO. Después del análisis, es un nivel alto cuando no se presiona y un nivel bajo cuando se presiona.
Puede utilizar el método anterior para determinar si se presiona el botón.

Consejos: eliminación de pulsaciones de teclas

Supongamos: se suelta el botón SW17, P3.2 es de nivel alto y se presiona el botón, P3.2 es de nivel bajo.
Los botones son mecánicos. Cuando se presiona el interruptor mecánico y aparece, habrá una vibración. El tiempo de vibración se muestra en la siguiente figura:
Insertar descripción de la imagen aquí
después de que el nivel bajo sea de 10 ms, se detectará nuevamente. Si aún está bajo, Se considerará nivel bajo. 10 ms es el tiempo de rebote para procesarse.
Durante el proceso de presionar y soltar, el voltaje fluctuará hacia arriba y hacia abajo.

2. El proceso de implementación del código del botón.

Código de muestra 1:

if( KEY == 0 )
{
    Delay_ms(10);
    if( KEY == 0 )
        {
        执行功能
        }
}

Código de muestra 2:

if( KEY == 0 )
{
    Delay_ms(10);
    if( KEY == 0 )
        {
        while(KEY == 0);
        执行功能
        }
}

Ejemplo de proyecto

Copie la carpeta del proyecto de plantilla 1.C-Printf y cambie el nombre a: 3. LED de control de botones.
Según el diagrama esquemático, defina 2 CLAVES:

#define KEY1 P32  //定义一个按键引脚KEY1
#define KEY2 P33  //定义一个按键引脚KEY2

Copie la función Delay_ms y declarela.
Agregar código de control:

		if( KEY1 == 0 )
			{
				Delay_ms(10);
				if( KEY1 == 0 )
					{
						printf("按键P32已经按下!\r\n");

					}
			}
		if( KEY2 == 0 )
			{
				Delay_ms(10);
				if( KEY2 == 0 )
					{
						printf("按键P33已经按下!\r\n");

					}
			}

Impresión del puerto serie

Insertar descripción de la imagen aquí

3. Aplicación de botones

  • 3.1 El LED se enciende cuando se presiona el botón y se apaga cuando se suelta el botón.
    Agregue los códigos P22 = 0 y P23 = 0 para que se ilumine, pero no se apagará después de soltar el botón.
    También es necesario aumentar el juicio para realizar la liberación y extinción, y la luz indicadora original en el tablero se enciende y apaga en el mismo estado:
    código completo:
		if( KEY1 == 0 )
			{
				Delay_ms(10);
				if( KEY1 == 0 )
					{
						printf("按键P32已经按下!\r\n");
						P22 = 0;

					}
			}
		else //如果没有按下
			{
				P22 = 1;
			}

		if( KEY2 == 0 )
			{
				Delay_ms(10);
				if( KEY2 == 0 )
					{
						printf("按键P33已经按下!\r\n");
						P23 = 0;

					}
			}
		else //如果没有按下
			{
				P23 = 1;
			}
  • 3.2 Presione el botón y el LED se apagará, suéltelo y enciéndalo.
    Invierta el nivel de los puertos P22 y P23 (solo use la operación invertida ~), suéltelo y enciéndalo, que es opuesto al original encendido. Estado de la luz indicadora de la placa.
    Código de implementación:
		if( KEY1 == 0 )
			{
				Delay_ms(10);
				if( KEY1 == 0 )
					{
						printf("按键P32已经按下!\r\n");
						P22 =  0;  //实现按下点亮,抬起熄灭
						//P22 = !0;  //取反操作实现按下熄灭,抬起点亮

					}
			}
		else //如果没有按下
			{
				P22 =  1;
				//P22 = !1; //取反操作实现按下熄灭,抬起点亮
			}

		if( KEY2 == 0 )
			{
				Delay_ms(10);
				if( KEY2 == 0 )
					{
						printf("按键P33已经按下!\r\n");
						P23 =  0;  //实现按下点亮,抬起熄灭
						//P23 = !0;  //取反操作实现按下熄灭,抬起点亮

					}
			}
		else //如果没有按下
			{
				P22 =  1;
				//P23 = !1; //取反操作实现按下熄灭,抬起点亮
			}
  • 3.3 Cuando se presiona el botón una vez el LED cambia de estado una vez,
    la idea inicial es que al presionar el estado IO se invierte, P23 = !P23,
    después de presionar el estado de espera es incorrecto. Es necesario aumentar el retraso: Delay_ms(200); //Evita que la detección sea demasiado rápida.
    Pero mantenga presionado el botón (siga presionándolo) y el LED parpadea. Es necesario agregar un código de restricción que solo se ejecute una vez:
						printf("按键P33已经按下!\r\n");
						P23 =  !P23; //LED取反1次
						while( KEY2 == 0 ) //如果按键一直是按下,一直空循环,实现只执行1次
						{

						}

¿Se puede modificar para liberarlo y ejecutarlo nuevamente? Similar a la pulsación larga aplicada al costado del manual, consulte el código:

						while( KEY2 == 0 ) //如果按键松开,则结束空循环,则执行以下程序
						{

						}
						printf("按键P33已经松开!\r\n");
						P23 =  !P23; //LED取反1次
  • 3.4 Presione el botón una vez y el LED se moverá un paso hacia la izquierda (efecto de luz fluida).
    Para operar un grupo de luces tomamos como ejemplo P2:
    lo escribimos en hexadecimal: P2 = 0xFE; //1111 1110 Establece el estado inicial.
    Insertar descripción de la imagen aquí
    En el estado inicial, la luz más a la derecha se enciende primero, 1111 1101
    se desplaza 1 posición hacia la izquierda, la segunda luz se enciende y la derecha es el último dígito. Si se suma 0, la primera y la segunda luz se encienden. , 1111 1100, y los cambios son
    solo Si desea encender una luz, necesita una operación +1, que se convierte en: 1111 1101 Solo la segunda luz está encendida.
    Aquí, se usa una variable separada para calcular y el puerto P2 Se obtiene el estado después de presionar una determinada tecla y se asigna el valor:
u8 LED_Data = 0XFD; //8个2进制位的变量
P2 = LED_Data;  //1111 1110 设定初始状态

Código de control:

		if( KEY2 == 0  )	//判断按键有没有按下
		{
			Delay_ms(10);
			if( KEY2 == 0 )		//按键确实按下了
			{
				printf("按键P33已经按下,led左移一个\r\n");

				LED_Data = ( (LED_Data<<1) +1 );		//本来是直接输出P2,先计算,后输出


				if( LED_Data == 0xFF )
					LED_Data = 0xFD;

				P2 = LED_Data;
				while(KEY2 == 0);		//如果按键一直是按下的,一直执行while
										//while函数体如果无实际执行需要,即花括号内为空,可以直接跟;结束语句,
//				{
//
//				}

			}
		}

Nota : Si el cuerpo de la función while solo se usa para juzgar y no requiere la ejecución real del código, es decir, las llaves están vacías, puede finalizar la declaración directamente con ";".
Configuración de la herramienta del puerto serie STC-ISP
Para simplificar los datos de salida del puerto serie, se pueden realizar las configuraciones simplificadas de la herramienta del puerto serie para enviar caracteres al programa de visualización:
Insertar descripción de la imagen aquí

Tarea: Date cuenta de que después de presionar P32 (TECLA 1) una vez, la luz se moverá uno hacia la derecha.

  • 4. El uso de matrices
    El uso de matrices se divide en los dos pasos siguientes
    1. Definición
    Nombre del tipo [longitud] = {valor};
    Insertar descripción de la imagen aquí

Por ejemplo, para implementar una lámpara de agua corriente, varios estados son los siguientes:
1111 1110 0XFE
1111 1101 0XFD
1111 1011 0XFB
1111 0111 0XF7
1110 1111 0XEF 1101 1111 0XDF 1011 1111
0XBF 0111
1111
0 Si X7F
quiere implementar luces de marcha, puede genera directamente el estado anterior.
Por ejemplo, agregue código de prueba a la última línea del bucle while principal:

		P2 = 	0XFB;	Delay_ms(500);
		P2 = 	0XF7;	Delay_ms(500);
		P2 = 	0XEF;	Delay_ms(500);
		P2 = 	0XDF;	Delay_ms(500);
		P2 = 	0XBF;	Delay_ms(500);
		P2 = 	0X7F;	Delay_ms(500);

Efecto: la lámpara de agua corriente de derecha a izquierda se enciende durante 500 ms cada vez y se enciende en secuencia.
2. Utilice
la asignación: nombre [índice] = valor.Tome
la lámpara de agua corriente mencionada anteriormente como ejemplo, los datos son: 0XFB, 8 bits sin signo, el índice (cantidad total de datos) es 8 y los datos de definición son:

u8 LED_DataTab[8] = {0XFE,0XFD,0XFB,0XF7,0XEF,0XDF,0XBF,0X7F};

Texto de selección de columna vertical : seleccione el lado izquierdo del carácter que desea seleccionar con el cursor, mantenga presionada la tecla Alt + Shift y arrastre para seleccionar la fila o columna que desea seleccionar. Puede copiarlo después de invertirlo.
Utilice la variable num para realizar la lámpara de agua:

		P2 = 	LED_DataTab[num+1]; Delay_ms(500);//1111 0111  0XF7
		num++;

El código anterior implementa la lámpara de agua corriente una vez y luego se enciende por completo.
Solucione el problema, por qué: num ++ tiene un rango y necesita ser limitado: if (num > 7) num = 1; // num solo puede ser hasta 7. Después de llegar a 7, comienza desde 1 y regresa al extremo derecho .
El control de la iluminación se puede lograr modificando el valor de la matriz LED_DataTab. Por ejemplo, si se asigna el valor: LED_DataTab[3] = 0XFD;, la primera luz seguirá encendida por tercera vez.
Puede cambiar los datos a voluntad para lograr una iluminación elegante.

Resumir

1. Aprenda a usar las claves
2. Master arrays

Ejercicio después de clase: presione el botón para cambiar el LED y generar diferentes efectos.

4 luces y 4 luces están encendidas, o 3 luces y 3 luces están encendidas, 2 y 2 luces se mueven hacia la izquierda y así sucesivamente. Competencia en la escritura de códigos para realizar las funciones de los botones.

Supongo que te gusta

Origin blog.csdn.net/Medlar_CN/article/details/132360277
Recomendado
Clasificación