Olá Pessoal!
Neste artigo abordo o modo stop dos microcontroladores RL78. Assim como em outros microcontroladores, o modo stop paralisa a operação da CPU e da maioria dos periféricos, mas mantém o conteúdo da RAM e registradores, permitindo também que alguns periféricos (watchdog, timer de intervalo, RTC ou interrupção de pino) possam continuar operando e fazer com que a CPU retorne ao estado ativo. Vale ressaltar que além do modo stop, os RL78 possuem também o modo halt, onde apenas a CPU é paralisada, mas o restante dos periféricos pode continuar operando normalmente. Obviamente que o modo stop garante um consumo de energia substancialmente menor que o modo halt. Há também o modo snooze, uma variação do modo stop onde alguns periféricos (UART, CSI e ADC) podem continuar operando e provocar o retorno ao modo ativo.
Para ilustrar a diferença de consumo a tabela a seguir demonstra o consumo típico (em µA) para os modos ativo, halt e stop. É claro que o consumo no modo ativo e no modo halt irá variar conforme os periféricos operando.
Modo |
Consumo típico (µA) |
Ativo |
4600 |
Halt |
540 |
Stop |
0,23 |
O modo stop é executado pela instrução assembly STOP e o seu uso em linguagem C é feito através da macro __stop().
Quando em modo stop o clock da CPU e da maioria dos periféricos é parado, reduzindo o consumo de energia do chip. Uma interrupção de um periférico pode fazer com que o sistema retorna ao estado ativo (o controle global de interrupção EI não precisa estar habilitado, apenas a interrupção individual do periférico que será responsável pela saída do modo stop).
O exemplo a seguir demonstra a utilização deste modo. Ao ser ligada a alimentação o led D2 da placa de promoção do RL78/G13 irá piscar brevemente e em seguida a CPU irá entrar em modo stop, com o consumo reduzido para cerca de 230nA. A saída desde modo é realizada por meio do pino P5.0 que é configurado para operação como fonte de interrupção externa INTP1 com o seu resistor interno de pull-up ativado (uma tecla deve ser conectada entre este pino e o GND).
Uma transição negativa no pino (do nível “1” para nível “0”) provoca a saída do modo stop e o retorno ao modo normal de execução. Observe que o flag da interrupção é apagado por software (PIF1 = 0). Isto é necessário porque a aplicação não está com as interrupções habilitadas (EI = 0) e por isso não há uma ISR para o tratamento da mesma (o flag seria apagado automaticamente quando o programa fosse desviado para a ISR).
Para a correta operação do exemplo, alguns passos devem ser observados:
- A aplicação deve ser compilada com o depurador interno (OCD) desativado no byte de opção número 3;
- O projeto deve ser compilado no modo “Release” dentro do ambiente EWRL78. Lembre-se de configurar as opções de projeto da mesma forma que no modo “Debug”. O linker deve ser configurado para gerar um arquivo .hex, necessário para a gravação através da ferramenta RFP (Renesas Flash Programmer);
- Após a gravação do arquivo .hex gerado no passo 2, basta remover o jumper J9 para que o microcontrolador saia do reset e execute a aplicação. Para medição da corrente consumida, basta conectar um multímetro ou microamperímetro no local do jumper J3.
#include "ior5f100le.h" #include "ior5f100le_ext.h" #include "intrinsics.h" #include "myRL78.h" // Configura watchdog #pragma location = "OPTBYTE" __root __far const char opbyte0 = WDT_OFF; // Configura detector de baixa tensão #pragma location = "OPTBYTE" __root __far const char opbyte1 = LVD_OFF; // oscilador 4MHz flash low speed #pragma location = "OPTBYTE" __root __far const char opbyte2 = FLASH_HS | CLK_32MHZ; // debug ativado, com apagamento em casa de falha de autenticação #pragma location = "OPTBYTE" __root __far const char opbyte3 = DEBUG_OFF; /* Configura security ID */ #pragma location = "SECUID" __root __far const char senha[10] = {0,0,0,0,0,0,0,0,0,0}; #define LED_D2 P7_bit.no7 void pisca(void) { unsigned char cnt; unsigned long int temp; for (cnt=10;cnt;cnt--) { LED_D2 = 0; for (temp=100000;temp;temp--); LED_D2 = 1; for (temp=100000;temp;temp--); } } void main (void) { P0=P1=P2=P3=P4=P5=P6=P7=P12=P14=0; // configura todos os pinos como saídas PM0=PM1=PM2=PM3=PM4=PM5=PM6=PM7=PM12=PM14=0; // configura pinos analógicos para modo digital ADPC = 1; PMC0=PMC12=PMC14=0; CMC = 0; // desativa osciladores X1 e XT1 PM5_bit.no0 = 1; // pino P5.0 como entrada PU5_bit.no0 = 1; // liga pull-up do pino P5.0 EGN0 = BIT1; // interrupção INTP1 na borda de descida PIF1 = 0; // limpa o flag da interrupção INTP1 PMK1 = 0; // habilita a interrupção INTP1 while(1) { pisca(); // pisca 10 vezes o led __stop(); // entra em modo stop // ocorreu um sinal de wake-up PIF1 = 0; // limpa o flag da interrupção } }