Este artículo es un artículo espejo de traducción automática, por favor haga clic aquí para saltar al artículo original.

Vista: 9371|Respuesta: 0

Zigbee Journey (9): Varios experimentos básicos importantes con CC2430: sueño sistemático y vigilia interrumpida

[Copiar enlace]
Publicado en 30/10/2014 23:24:30 | | | |
1. Conexión entre los niveles superior e inferior

En este artículo, hablaremos sobre la función de sueño y el método de despertar de CC2430. En el uso real, el nodo CC2430 suele funcionar con baterías, por lo que el control de su consumo de energía es crucial.

A continuación se muestra un extracto del manual chino del CC2430 sobre la introducción de los 4 modos de consumo energético del CC2430:

Como puedes ver en la tabla anterior, el CC2430 tiene un total de 4 modos de potencia:PM0(completamente despierto),PM1(un poco somnolienta),PM2(medio despierto y medio dormido),PM3(Durmiendo muy profundamente). Cuanto más atrás, más funciones se desactivan y el consumo de energía es cada vez menor. La relación de conversión entre ellos es la siguiente:

putPM1、PM2DespiertaPM0, hay tres formas: reinicio, interrupción externa, interrupción del temporizador de sueño; Pero ponPM3DespiertaPM0, solo hay dos maneras: reinicio, interrupción externa (esto se debe a que enPM3Todos los osciladores dejaron de funcionar y, por supuesto, el temporizador de suspensión estaba apagado~)

Vamos a hacer un pequeño experimento para introducir cómo entrar en modo de suspensión y cómo despertarsePM0estado.

2. Experimentos sistemáticos de sueño y despertar interrumpida(1) Introducción al experimentoInicialización del sistema, enPM0
→ entrarPM1
→ Despierta con el temporizador de sueño después de 1 segundoPM0
→ entrarPM2
→ despertaba el contador de sueño tras 2 segundosPM0
→ entrarPM3
→ Esperar a que se pulse la tecla S1, activando una interrupción externa y despertandoPM0
(2) Diagrama de flujo del programa

(Nota: La casilla redondeada en la imagen anterior indica el estado de salud del sistema)

(3) Código fuente experimental y análisis (Se pueden hacer clic en las siguientes casillas~Encabezado y definición de macros[url=] [/url]
/*
    Descripción experimental: Experimento de sueño interrumpido y despertar, que introduce la vigilia en tres modos de sueño
*/

#include
#define LED_ON 0
#define LED_OFF 1#definelideró1 P1_0         
#defineled2 P1_1         
#defineLed3 P1_2         
#defineled4 P1_3   [url=] [/url]

Subfunciones[url=] [/url]
/*Inicialización del reloj del sistema
-------------------------------------------------------
*/
Vacíoxtal_init(Vacío)
{
  SUEÑO &= ~0x04;            //Todos son alimentados
  mientras(! (SUEÑO &0x40));     //El oscilador de cristal está encendido y estable
  CLKCON &= ~0x47;         //Elige un oscilador de cristal de 32MHz
  SUEÑO |=0x04;
}


/*Inicialización de LED
-------------------------------------------------------
*/
Vacíoled_init(Vacío)
{
  P1SEL =0x00;         //P1 es el puerto normal de E/S
  P1DIR |=0x0F;         //P1.0 P1.1 P1.2 P1.3 salida
  
  liderado1 = LED_OFF;         //Apaga todos los LEDs
  liderado2 = LED_OFF;
  liderado3 = LED_OFF;
  liderado4 = LED_OFF;
}


/*Inicialización de interrupciones externas
-------------------------------------------------------
*/
Vacíoio_init(Vacío)
{
    P0INP &= ~0X02;   //P0.1 tiene pull-up y pull-down

    EA =1;           //Interrupción total permitida
   
    IEN1 |=  0X20;   //P0IE = 1, P0 interrupciones habilitadas
   
    PICTL |=  0X09;   //P0.1 permite interrupciones, disparadores de borde descendente
   
    P0IFG &= ~0x02;   //P0.1 Marca de interrupción limpia0
}


/*Inicialización de interrupciones del temporizador de suspensión
-------------------------------------------------------
*/
VacíosleepTimer_init(Vacío)
{
  STIF=0;   //La marca de interrupción del temporizador de sueño está limpia 0
   
  STIE=1;   //Enciende el temporizador de suspensión interrumpido
   
  EA=1;     //Abre la interrupción total
}


/*Establece el intervalo programado para el temporizador de sueño
-------------------------------------------------------
*/
VacíosetSleepTimer(sin signarintsec)
{
  sin firmarlargosleepTimer =0;
  
  sleepTimer |= ST0;                     //Obtén el valor de conteo del cronómetro de sueño actual
  sleepTimer |= (sin signolargo)ST1 <<8;
  sleepTimer |= (sin signolargo)ST2 <<16;
  
  sleepTimer += ((sin signolargo)sec * (sin firmarlargo)32768);   //Además de la duración del tiempo requerido
  
  ST2 = (sin signochar(sleepTimer >>16);   //Establece el valor de comparación del tiempo de sueño
  ST1 = (sin signochar(sleepTimer >>8);
  ST0 = (sin signochar)sleepTimer;
}


/*Seleccionar Modo de Alimentación
-------------------------------------------------------
*/
VacíoPowerMode(sin signo)charmodo)
{
  si(modo <4)
  {
    SUEÑO &=0xfc;      //Borrar MODO SUSPENSIÓN a 0
    SUSPENSIÓN |= modo;      //Seleccionar Modo de Alimentación
    PCON |=0x01;        //Activa este modo de alimentación
  }
}


/*Función de retardo
-------------------------------------------------------
*/
VacíoRetraso (sin firmarintn)
{
  sin firmarinti,j;
  para(i=0; i<n; i++)
    para(j=0; j <1000; j++);
}
[url=] [/url]

Función principal[url=] [/url]
/*Función principal
-------------------------------------------------------
*/
Vacíomain(Vacío)
{
  xtal_init();         
  led_init();         
  
  //Estado PM0, luz encendida y retraso
  lideraba1 = LED_ON;         //El LED1 de brillo indica que el sistema funciona en modo PM0
  Retraso(10);


  //Estado PM1, luces apagadas
  setSleepTimer(1);      //Establece el intervalo de tiempo del tiempo de sueño a 1 s
  sleepTimer_init();     //Enciende el temporizador de suspensión interrumpido
  liderado1 = LED_OFF;
  PowerMode(1);         //Configura el modo de alimentación en PM1
  
  
//Después de 1s, PM1 entra en PM0, se ilumina y se retrasa
  lideraba1 = LED_ON;
  Retraso(50);
  
  //PM2, luces apagadas
  setSleepTimer(2);      //Pon el intervalo de tiempo del temporizador de sueño a 2 segundos
  liderado1 = LED_OFF;
  PowerMode(2);         //Configura el modo de alimentación en PM2


  
//Después de 2 segundos, PM2 entra en PM0, se ilumina y se retrasa
  lideró1=0;
  Retraso(50);
  
  //PM3, apaga las luces  
  io_init();            //Inicializar interrupciones externas
  liderado1 = LED_OFF;
  PowerMode(3);         //Configura el modo de alimentación en PM3
  
  
//Cuando ocurre una interrupción externa, PM3 entra en PM0 y se ilumina
  lideraba1 = LED_ON;

  mientras(1);
}
[url=] [/url]

Procedimientos de servicio de interrupción[url=] [/url]
/*Programa de servicio de interrupciones externas
-------------------------------------------------------
*/
#pragmavector = P0INT_VECTOR
__interruptVacíoP0_ISR(Vacío)
{
  EA =0;                        //La puerta se interrumpe
  
  Retraso(50);

  si((P0IFG &0x02) >0)         //Las teclas se interrumpen
  {
    P0IFG &= ~0x02;               //P0.1 Marca de interrupción limpia0
  }
  P0IF =0;                       //Marca de interrupción P0 clear0


  EA =1;                        //Interrupción abierta
}


/*El temporizador de suspensión interrumpe los programas de servicio
-------------------------------------------------------
*/
#pragmavector= ST_VECTOR
__interruptVacíosleepTimer_IRQ(Vacío)
{
  EA=0;     //La puerta se interrumpe
   
  STIF=0;   //La marca de interrupción del temporizador de sueño está limpia 0
  
  EA=1;     //Interrupción abierta
}
[url=] [/url]

Cómo usar un temporizador de sueño para despertar el sistema se puede resumir de la siguiente manera:Abrir la interrupción del temporizador de suspensión → configurar el intervalo de tiempo del temporizador de sueño → establecer el modo de encendido

(Nota: El paso "Establecer el intervalo del temporizador de suspensión" debe estar antes de "Establecer modo de encendido", porque el sistema no continuará ejecutando el programa tras entrar en suspensión)

A continuación, centrémonos en la subfunción que establece el intervalo temporizador de sueño:setSleepTimer

En primer lugar, una breve introducción al cronómetro de sueño: funciona32,768kHzde24º puestoTemporizador, cuando el sistema está en marchaAdemás de PM3En todos los modos de encendido, el temporizador de suspensión seráFuncionamiento ininterrumpido

Los registros utilizados por los temporizadores de sueño son:ST0ST1ST2。 A continuación se presenta una introducción detallada a sus funciones del manual chino CC2430:

Se puede ver que sus funciones incluyen dos aspectos:Leeescribe

  Lee: Usado para leer el valor de conteo del temporizador actual, el orden en que deben seguirse las lecturas:Lee ST0 → Lee ST1 → Lee ST2

  escribe: Usado para establecer el valor de comparación del temporizador (cuando el valor de conteo = valor de comparación, ocurre una interrupción), el orden de escritura debe seguir:Escribe ST2 → escribe ST1 → escribe ST0

Vale, vamos a explicarlo en combinación con el código fuente:

(1) Primero, definir un sleepTimer de variable larga sin signo (32 bits) para recibir el valor actual de conteo del temporizador de sueño:

  sin firmarlargosleepTimer =0;
  
  sleepTimer |= ST0;                     //Obtén el valor de conteo del cronómetro de sueño actual
  sleepTimer |= (sin signolargo)ST1 <<8;
  sleepTimer |= (sin signolargo)ST2 <<16;

(2) Luego añade el intervalo de tiempo requerido:

  sleepTimer += ((sin signolargo)sec * (sin firmarlargo)32768);   //Además de la duración del tiempo requerido

Aquí va una pequeña explicación:

¿Por qué el 1s representa 32768? Como el temporizador funciona por debajo de 32,768kHz, tarda 1/32768 s por cada 1 añadido al temporizador; Añade 32768 y necesitarás 1s;

(3) Finalmente, el valor de sleepTimer se utiliza como valor de comparación del temporizador:

  ST2 = (sin signochar(sleepTimer >>16);   //Establece el valor de comparación del tiempo de sueño
  ST1 = (sin signochar(sleepTimer >>8);
  ST0 = (sin signochar)sleepTimer;

De este modo, puedes establecer con éxito el periodo de tiempo del temporizador~

(Nota: En cuanto a las otras partes del código fuente, creo que combinadas con anotaciones detalladas se pueden entender fácilmente, y no lo repetiré aquí)

(4) Resultados experimentales
Ejecutando el programa, observando LED1, el fenómeno es:El LED1 parpadea (es decir, encendido-> apagado 1 vez), parpadea de nuevo tras 1 segundo, parpadea de nuevo tras 2 segundos, luego permanece apagado y después pulsa S1, LED1 se enciende.
El fenómeno experimental es completamente coherente con la expectativa, Over~

3. Conclusión

Oh~ Después de tomarme 2 días libres, por fin conseguí este registro. Realmente descubrí que escribir un blog, especialmente una entrada "amigable para el lector", es realmente un trabajo físico: rigor, estética, lógica... Todo se basa en la consideración.

Cada vez que publico el código, pienso que es demasiado largo, pero me da reparo usar la herramienta plegable que viene con el jardín del blog. Por eso, en esta entrada del blog, el autor añadió tentativamente algunos elementos de JQuery para lograr un plegado fluido del código, y aún así hay una pequeña sensación de logro, jeje (JQuery novato, no te rías del maestro~). Pero no sé si esto realmente mejora la legibilidad del artículo, y lectores y amigos están invitados a comentar :)

Este mes, la autora realmente decidió echar raíces en el jardín del blog, así que pasé mucho tiempo libre escribiendo entradas para el blog. Cuando escribí un blog por primera vez, aunque hubo pocos comentarios, la mayoría de los registros tenían una tasa de clics superior a 500, ¡lo cual fue un pequeño aliento para mí! Hace falta valor para publicar contenido sobre microcontroladores en el jardín de blogs, pero me mantendré firme~

Las nueve entradas del blog desde el principio hasta la actualidad se centran en el uso de módulos básicos de hardware en el chip CC2430. Hasta ahora, básicamente hemos revisado la mayoría de los periféricos del CC2430, pero aún hay cosas como el acceso Flash, el generador de números aleatorios, el coprocesador AES, la comunicación RF, etc., que no se han tocado. Sin embargo, el viaje con Zigbee no ha terminado, y el autor pretende cubrir selectivamente estas omisiones en el siguiente tema (implementación del protocolo Z-Stack).

En la próxima entrada del blog, planeo terminar el primer viaje de Zigbee con un experimento algo más completo y extenso: el "sistema de monitorización de temperatura", y explicar cómo aplicar de forma exhaustiva los puntos de conocimiento aprendidos anteriormente.

De hecho, no está calificado para llamarse "ExplicaciónComo principiante, el autor solo espera animarse mutuamente y avanzar juntos en el proceso de escribir un doctorado.


</n; i++)




Anterior:Zigbee Journey (8): Varios experimentos básicos importantes de CC2430 - watchdogs
Próximo:Zigbee Journey (10): Experimento integral - Sistema de monitorización de temperatura basado en CC2430
Renuncia:
Todo el software, materiales de programación o artículos publicados por Code Farmer Network son únicamente para fines de aprendizaje e investigación; El contenido anterior no se utilizará con fines comerciales o ilegales; de lo contrario, los usuarios asumirán todas las consecuencias. La información de este sitio proviene de Internet, y las disputas de derechos de autor no tienen nada que ver con este sitio. Debes eliminar completamente el contenido anterior de tu ordenador en un plazo de 24 horas desde la descarga. Si te gusta el programa, por favor apoya el software genuino, compra el registro y obtén mejores servicios genuinos. Si hay alguna infracción, por favor contáctanos por correo electrónico.

Mail To:help@itsvse.com