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
}
}
