Este artigo é um artigo espelhado de tradução automática, por favor clique aqui para ir para o artigo original.

Vista: 9371|Resposta: 0

Zigbee Journey (9): Vários experimentos básicos importantes com CC2430 - sono sistemático e vigília interrompida

[Copiar link]
Publicado em 30/10/2014 23:24:30 | | | |
1. Conectando os níveis superior e inferior

Neste artigo, discutiremos a função do sono e o método de acordar do CC2430. No uso real, o nó CC2430 geralmente é alimentado por baterias, então o controle do consumo de energia é crucial.

A seguir, um trecho do manual chinês do CC2430 para a introdução dos 4 modos de consumo de energia do CC2430:

Como você pode ver na tabela acima, o CC2430 possui um total de 4 modos de energia:PM0(totalmente acordado),PM1(um pouco sonolento),PM2(meio acordado e meio dormindo),PM3(Dormindo muito pesado). Quanto mais atrás, mais funções são desativadas e o consumo de energia fica cada vez menor. A relação de conversão entre eles é a seguinte:

ColoquePM1、PM2AcordarPM0, existem três maneiras: reset, interrupção externa, interrupção do temporizador de sono; Mas coloquePM3AcordarPM0, existem apenas duas maneiras: reset, interrupção externa (isso porque emPM3Todos os osciladores pararam de funcionar, e claro que o temporizador de sono foi desligado~)

Vamos fazer um pequeno experimento para introduzir como entrar no modo de sono e como acordarPM0State.

2. Experimentos de sono sistemático e acordar interrompido(1) Introdução ao experimentoInicialização do sistema, emPM0
→ entrarPM1
→ Acordar pelo temporizador de sono após 1sPM0
→ entrarPM2
→ foi acordado pelo temporizador de sono após 2 segundosPM0
→ entrarPM3
→ Espere a tecla S1 ser pressionada, acionando uma interrupção externa e acordandoPM0
(2) Fluxograma de programas

(Nota: A caixa arredondada na imagem acima indica o estado de saúde do sistema)

(3) Código-fonte experimental e análise (As seguintes caixas podem ser clicadas~Definição de arquivo de cabeçalho e macro[url=] [/url]
/*
    Descrição experimental: Experimento de sono acordado interrompido, que introduz a vigília em três modos de sono
*/

#include
#define LED_ON 0
#define LED_OFF 1#defineliderou1 P1_0         
#defineLed2 P1_1         
#defineLed3 P1_2         
#defineliderou4 P1_3   [url=] [/url]

Subfunções[url=] [/url]
/*Inicialização do clock do sistema
-------------------------------------------------------
*/
vazioxtal_init(vazio)
{
  SONO &= ~0x04;            //Todos são movidos
  enquanto(! (SONO &0x40));     //O oscilador de cristal está ligado e estável
  CLKCON &= ~0x47;         //Escolha um oscilador de cristal de 32MHz
  SONO |=0x04;
}


/*Inicialização de LED
-------------------------------------------------------
*/
vazioled_init(vazio)
{
  P1SEL =0x00;         //P1 é a porta normal de E/S
  P1DIR |=0x0F;         //Saída P1.0 P1.1 P1.2 P1.3
  
  liderado1 = LED_OFF;         //Desligue todos os LEDs
  liderou2 = LED_OFF;
  liderado3 = LED_OFF;
  liderado4 = LED_OFF;
}


/*Inicialização de interrupção externa
-------------------------------------------------------
*/
vazioio_init(vazio)
{
    P0INP &= ~0X02;   //P0.1 tem pull-up e pull-down

    EA =1;           //Interrupção total permitida
   
    IEN1 |=  0X20;   //P0IE = 1, P0 interrupções ativadas
   
    PICTL |=  0X09;   //P0.1 permite interrupções, gatilhos de borda caída
   
    P0IFG &= ~0x02;   //P0.1 Marca de interrupção limpa0
}


/*Inicialização da interrupção do temporizador de sono
-------------------------------------------------------
*/
vaziosleepTimer_init(vazio)
{
  STIF=0;   //A marca de interrupção do temporizador de sono está limpa 0
   
  STIE=1;   //Ligue o temporizador de sono interrompido
   
  EA=1;     //Abra a interrupção total
}


/*Defina o intervalo programado para o temporizador de sono
-------------------------------------------------------
*/
vaziosetSleepTimer(unsignedintsec)
{
  sem assinaturaLongasSleepTimer =0;
  
  sleepTimeter |= ST0;                     //Obtenha o valor de contagem do temporizador de sono atual
  sleepTimer |= (sem sinalLongas)ST1 <<8;
  sleepTimer |= (sem sinalLongas)ST2 <<16;
  
  sleepTimer += ((sem sinalLongas)sec * (não assinadoLongas)32768);   //Além da duração do tempo exigido
  
  ST2 = (sem sinalChar(sleepTimer >>16);   //Defina o valor de comparação do temporizador de sono
  ST1 = (sem sinalChar(sleepTimer >>8);
  ST0 = (sem sinalChar)sleepTimer;
}


/*Selecionar Modo de Energia
-------------------------------------------------------
*/
vazioPowerMode(sem sinal)Charmodo)
{
  se(modo <4)
  {
    SONO &=0xfc;      //Limpar o MODO SLEEP para 0
    SLEEP |= modo;      //Selecionar Modo de Energia
    PCON |=0x01;        //Ative esse modo de energia
  }
}


/*Função de atraso
-------------------------------------------------------
*/
vazioAtraso (não assinadointn)
{
  sem assinaturainti,j;
  para(i=0; i<n; i++)
    para(j=0; j <1000; j++);
}
[url=] [/url]

Função principal[url=] [/url]
/*Função principal
-------------------------------------------------------
*/
vaziomain(vazio)
{
  xtal_init();         
  led_init();         
  
  //Status PM0, luz acesa e atraso
  liderou1 = LED_ON;         //LED1 de brilho indica que o sistema está funcionando em modo PM0
  Atraso(10);


  //Estado PM1, luzes apagadas
  setSleepTimer(1);      //Defina o intervalo de tempo do temporizador de sono para 1s
  sleepTimer_init();     //Ligue o temporizador de sono interrompido
  liderado1 = LED_OFF;
  PowerMode(1);         //Defina o modo de energia para PM1
  
  
//Depois de 1s, PM1 entra em PM0, acende-se e demora
  liderou1 = LED_ON;
  Atraso(50);
  
  //PM2, luzes apagadas
  setSleepTimer(2);      //Defina o intervalo de tempo do temporizador de sono para 2 segundos
  liderado1 = LED_OFF;
  PowerMode(2);         //Defina o modo de energia para PM2


  
//Após 2 segundos, o PM2 entra no PM0, acende-se e atrasa-se
  liderou1=0;
  Atraso(50);
  
  //PM3, apaguem as luzes  
  io_init();            //Inicializar interrupções externas
  liderado1 = LED_OFF;
  PowerMode(3);         //Defina o modo de energia para PM3
  
  
//Quando ocorre uma interrupção externa, o PM3 entra em PM0 e acende-se
  liderou1 = LED_ON;

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

Procedimentos de serviço de interrupção[url=] [/url]
/*Programa de serviço de interrupção externa
-------------------------------------------------------
*/
#pragmavetor = P0INT_VECTOR
__interruptvazioP0_ISR(vazio)
{
  EA =0;                        //O portão é interrompido
  
  Atraso(50);

  se((P0IFG &0x02) >0)         //As teclas são interrompidas
  {
    P0IFG &= ~0x02;               //P0.1 Marca de interrupção limpa0
  }
  P0SE =0;                       //Marca de interrupção P0 limpa0


  EA =1;                        //Interrupção aberta
}


/*Temporizador de sono interrompe programas de serviço
-------------------------------------------------------
*/
#pragmavetor= ST_VECTOR
__interruptvaziosleepTimer_IRQ(vazio)
{
  EA=0;     //O portão é interrompido
   
  STIF=0;   //A marca de interrupção do temporizador de sono está limpa 0
  
  EA=1;     //Interrupção aberta
}
[url=] [/url]

Como usar um temporizador de sono para acordar o sistema pode ser resumido da seguinte forma:Abrir a Interrupção do Timer de Sono → definir o intervalo de tempo do temporizador → definir o modo de energia

(Nota: O passo "Definir o Intervalo do Temporizador de Suspensão" deve ser antes de "Definir o Modo de Energia", porque o sistema não continuará executando o programa após entrar em suspensão)

Em seguida, vamos focar na subfunção que define o intervalo do temporizador de sono:setSleepTimer

Primeiramente, uma breve introdução ao temporizador de sono: ele funciona32,768kHzde24º lugarTemporizador, quando o sistema está rodandoAlém do PM3Em todos os modos de energia, o temporizador de suspensão seráOperação ininterrupta

Os registradores usados por temporizadores de sono são:ST0ST1ST2。 A seguir está uma introdução detalhada às suas funções a partir do manual chinês CC2430:

Pode-se ver que suas funções incluem dois aspectos:LeiaEscreva

  Leia: Usado para ler o valor de contagem do temporizador atual, a ordem em que as leituras devem ser seguidas:Leia ST0 → Leia ST1 → Leia ST2

  Escreva: Usado para definir o valor de comparação do temporizador (quando o valor de contagem = valor de comparação, ocorre uma interrupção), a ordem de escrita deve seguir:Escreva ST2 → escreva ST1 → escreva ST0

OK, vamos explicar isso em combinação com o código-fonte:

(1) Primeiro, defina um sleepTimer de variável longa sem sinal (32 bits) para receber o valor atual de contagem do timer de sono:

  sem assinaturaLongasSleepTimer =0;
  
  sleepTimeter |= ST0;                     //Obtenha o valor de contagem do temporizador de sono atual
  sleepTimer |= (sem sinalLongas)ST1 <<8;
  sleepTimer |= (sem sinalLongas)ST2 <<16;

(2) Então adicione o intervalo de tempo necessário:

  sleepTimer += ((sem sinalLongas)sec * (não assinadoLongas)32768);   //Além da duração do tempo exigido

Aqui vai uma pequena explicação:

Por que o 1s representa 32768? Como o temporizador está funcionando abaixo de 32,768kHz, leva 1/32768 s para cada 1 adicionado ao temporizador; Some 32768, e você vai precisar de 1s;

(3) Finalmente, o valor do sleepTimer é usado como valor de comparação do temporizador:

  ST2 = (sem sinalChar(sleepTimer >>16);   //Defina o valor de comparação do temporizador de sono
  ST1 = (sem sinalChar(sleepTimer >>8);
  ST0 = (sem sinalChar)sleepTimer;

Dessa forma, você pode definir com sucesso o período de tempo do temporizador~

(Nota: Quanto às outras partes do código-fonte, acredito que, combinadas com anotações detalhadas, você pode entender facilmente, e não vou repetir aqui)

(4) Resultados experimentais
Executando o programa, observando LED1, o fenômeno é:LED1 pisca (ou seja, ligado e > desligado 1 vez), pisca novamente após 1 segundo, pisca novamente após 2 segundos, permanece desligado e então pressiona S1, LED1 acende.
O fenômeno experimental é completamente consistente com a expectativa, Over~

3. Conclusão

Oh~ Depois de tirar 2 dias de tempo livre, finalmente consegui esse registro. Descobri que escrever um blog, especialmente um post "amigável para o leitor", é realmente um trabalho físico: rigor, estética, lógica... Tudo se resume à consideração.

Cada vez que posto o código, acho que está longo demais, mas fico relutante em usar a ferramenta dobrável que vem com o blog garden. Portanto, neste post do blog, o autor adicionou provisoriamente alguns elementos JQuery para conseguir uma dobra suave do código, e ainda há uma pequena sensação de realização, hehe (JQuery novato, não ria do mestre~). Mas não sei se isso realmente melhora a legibilidade do artigo, e leitores e amigos são bem-vindos para comentar :)

Neste mês, a autora realmente decidiu criar raízes no jardim do blog, então passei muito tempo livre escrevendo posts no blog. Quando escrevi um blog pela primeira vez, embora houvesse poucos comentários, a maioria dos registros tinha uma taxa de cliques superior a 500, o que foi um pequeno incentivo para mim! É preciso coragem para publicar conteúdo sobre microcontroladores no jardim do blog, mas vou me manter firme~

Os nove posts do blog desde o início até o presente focam no uso de módulos básicos de hardware no chip CC2430. Até agora, basicamente já passamos pela maioria dos periféricos do CC2430, mas ainda há coisas como acesso em flash, gerador de números aleatórios, coprocesador AES, comunicação RF, etc., que não foram abordadas. No entanto, a jornada do Zigbee não terminou, e o autor pretende preencher seletivamente essas omissões no próximo tópico (implementação do protocolo Z-Stack).

No próximo post do blog, pretendo encerrar a primeira viagem de Zigbee com um experimento um pouco mais abrangente e extenso – "sistema de monitoramento de temperatura" – e explicar como aplicar de forma abrangente os pontos de conhecimento aprendidos anteriormente.

Na verdade, não é qualificado para ser chamado de "ExplicaçãoComo iniciante, o autor só espera incentivar uns aos outros e progredir juntos no processo de escrever um doutorado!


</n; i++)




Anterior:Zigbee Journey (8): Vários experimentos básicos importantes do CC2430 - watchdogs
Próximo:Zigbee Journey (10): Experimento Abrangente - Sistema de Monitoramento de Temperatura Baseado no CC2430
Disclaimer:
Todo software, material de programação ou artigos publicados pela Code Farmer Network são apenas para fins de aprendizado e pesquisa; O conteúdo acima não deve ser usado para fins comerciais ou ilegais, caso contrário, os usuários terão todas as consequências. As informações deste site vêm da Internet, e disputas de direitos autorais não têm nada a ver com este site. Você deve deletar completamente o conteúdo acima do seu computador em até 24 horas após o download. Se você gosta do programa, por favor, apoie um software genuíno, compre o registro e obtenha serviços genuínos melhores. Se houver qualquer infração, por favor, entre em contato conosco por e-mail.

Mail To:help@itsvse.com