Lab 8 - TC - RTC - RTT
Neste laboratório iremos trabalhar com os periféricos de contagem de tempo do nosso microcontrolador.
Lab 5 |
---|
Data limite para entrega: 01/12/2023 |
Entregue o código pelo repositório do Classroom |
Preencha para entregar Google forms |
Os periféricos apresentados neste laboratório são:
- Real Time Clock - RTC
- Timer Counter - TC
O laboratório é formado por duas partes:
-
Parte 1 (mínimo):
- Entender os exemplos (TC/RTC)
- Incorporar todos os exemplos em um único projeto
- Pisca pisca
-
Parte 2:
- C+: fazer outro LED piscar com TC
- B : Exibir a hora atual no OLED
- A : Usar IRQ do segundos do RTC
Exemplos
Nesse lab iremos trabalhar com três periféricos que lidam com "tempo": o TimerCounter (TC) que temos no total de quatro unidades TC (TC0 ~ TC3) e cada um com três contadores; o Real-time Timer (RTT) que só temos um e o Real-time Clock (RTC) que também só temos um e funciona como um relógio/calendário.
Um pouco mais sobre os periféricos:
- TC: Faz várias coisas, mas na disciplina iremos utilizá-lo para gerar interrupções de tempo maiores que 2Hz (ele não consegue gerar tempos muito lentos!)
- RTT: É um contador que consegue gerar praticamente qualquer frequência (vamos usar para gerar frequências lentas)
- RTC: É um como um calendário com relógio, ele conta anos, meses, dias, horas, minutos e segundos. E possui um alarme que pode ser configurado para gerar uma interrupção em um determinado momento.
Nós fornecemos para cada periférico um exemplo diferente:
Periférico exemplos |
---|
Perifericos/TC-IRQ |
Perifericos/RTC-IRQ |
Cada exemplo possui o seu próprio README
que explica de forma ampla os periféricos. Note que todos esses exemplos estão operando por interrupção! Onde cada periférico possui o seu handler
para resolver a interrupção.
Exercise
Exercise
Answer
- O TC pode ser configurado para gerar uma frequência de 10s
O tempo mínimo que ele pode contar é 1s.
- O RTC tem resolucão de ms
O RTC conta segundos!
- O nosso microcontrolador possui até 3 RTT
Não só possui um. Quem tem 3 é o TC
- Cada RTT possui três canais
Não! Quem possui três canais é o TC
- O RTT pode gerar duas interrupcões: incremento e alarme.
Sim!! Podemos configurar no RTT dois modos de IRQ
Exercise
Exercise
Answer
O handler a ser usado tem realacão com o ID do canal, no caso do canal 0 do TC1 o ID é o ID_TC3 e o handler o TC3_Handler
.
Exercise
Answer
Aqui tem uma pegadinha! Para o TC contar "tempo" ele precisa usar como base um clock gerado pelo PMC, o TC não consegue usar mais de uma base de tempo por periférico (a mesma base se aplica a todos os canais que ele controla). Para as frequências 1Hz e 2Hz pode ser que funcione usar o mesmo TC pois a base de tempo que a função tc_init vai encontrar deve ser a mesma, mas já para a frequência de 44200Hz a base deve ser outra (é ordens de grandeza maior que as outras frequências) e usar o mesmo TC não vai funcionar!
A melhor solução aqui seria, usar um TC para as frequências mais baixas e outro apenas para a maior frequência:
TC0
/ID_TC0
@ 1HzTC0
/ID_TC1
@ 2HzTC1
/ID_TC3
@ 44200Hz
Essa parte da escolha da frequência é realizado dentro da função TC_init
nas linhas:
/** Configura o TC para operar em freq hz e interrupçcão no RC compare */
tc_find_mck_divisor(freq, ul_sysclk, &ul_div, &ul_tcclks, ul_sysclk);
tc_init(TC, TC_CHANNEL, ul_tcclks | TC_CMR_CPCTRG);
Exercise
Answer
Vamos recapitular o que a função RTT_init
recebe de argumentos:
- arg0: define a frequência na qual o contador interno do RTT irá operar.
- arg1: se configurado a interrupção de alarme, qual o seu valor
- arg2: quais modos de IRQ vão estar ativados.
Agora vamos analisar as respostas:
-
RTT_init(4, 13, RTT_MR_ALMIEN)
Configura o RTT para operar a 4hz (0.25s) e configuramos o alarme para quando o contador chegar em 13, ou seja: 13*0.25 = 3.25s*
. Poderíamos ter colocado 52 no lugar de 13, assim o alarme estaria certo: 0.25*52 = 13s*
.
-
RTT_init(13, 1, RTT_MR_ALMIEN);
Configura o RTT para operar com 13 incrementos por segundo, mas o alarme foi configurado para 1
, ou seja: 1/13 * 1 = 0.078s
.
-
RTT_init(10, 130, RTT_MR_ALMIEN);
Essa aqui é uma opção de resposta correta. Incremento de 10x por segundo e alarme configurado para 130, ou seja: 130/10 = 13s
-
RTT_init(1, 13, RTT_MR_ALMIEN);
Outra opção de resposta correta. Incremento de 1x por segundo e alarme configurado para 13, ou seja: 13/1= 13s
Notem que temos duas respostas corretas, mas elas possuem uma sutil e importante diferença: O valor que o contador do RTT atinge antes do alarme.
Exercise
Answer
Bom.... não tem uma única resposta para essas perguntas, tudo vai depender um pouco de como é o sistema embarcado que você está desenvolvendo/ projetando, mas vamos analisar algumas alternativas aqui.
Fazer com que o RTC sincronize com o horário/ calendário real?
O sistema embarcado tem conexão com a internet? Se tiver facilita um pouco a solução. Com a internet podemos consutlar um dos servidor de relógio disponível, existe até um protocolo chamado de Network Time Protocol (NTP) criado para esse fim de sincronizacão de relógios e vários servidores são públicos e estão espalhados pelo globo:
Alguns servidores, fonte: http://www.pi-time.ca/
Se não tiver conexão com a internet, a solucão é configurar o relógio no próprio dispositivo (via botões e displays) ou conectar o dispositivo em algum outro device via bluetooth/usb/... e fazer a configuracão por um programa/aplicativo próprio.
O que acontece se acabar a bateria do equipamento? Vamos perder a configuracão do RTC?
Muitas vezes o RTC usa uma bateria auxiliar para que ele não se desconfigure quando o sistema principal fica sem energia. Pegue como exemplo o seu notebook, mesmo quando acaba a bateria ele volta com a hora correta. A vida útil dessa bateria depende de vários fatores, mas é comum durar anos.
Anti tamper RTC
O RTC é um dos itens de um sistema embarcado que os hackers gostam de atacar, deem uma olhada nisso:
Lab
Info
Lembre de sempre utilizar fila ou semáforo para comunicar IRQ e TASK
Use o código fornecido no repositório: RTOS-OLED-Xplained-Pro
.
Conceito C
No código do RTOS-OLED
, vocês devem configurar os botões e os LEDs da placa OLED e então utilizando os periféricos fazer:
- Que o
LED1
pisque na frequência de 4Hz, para isso utilize o TC; - Fazer com que o
LED2
pisque a uma frequência de 0.25Hz, para isso utilize o RTT; - Piscar o
LED3
depois de 20 segundos do botão 1 da placa OLED ter sido pressionado, para isso utilize o alarme do RTC.
Tip
Abrir o código atual e o exemplo e ir trazendo as funções e defines que precisa usar, não esqueça de chamar as funções no main
.
Tip
Você vai precisar incluir no ASF WIZARD
os drivers do: RTT e RTT
O TC já foi adicionado no código exemplo, não adicone o outro que vai dar problema!!!!
Tip
O RTC tem uma função que você consegue buscar no periférico a hora atual: rtc_get_time()
, você pode então configurar um alarme para daqui 20s.
- Leia a função e entenda os seus parâmetros!!
Exercise
Exercise
Tip
Para executar isso você deverá ser capaz de saber quando que o segundo mudou, duas são as opções:
- Usar um novo TC configurado com 1hz
- Pedir para o RTC gerar uma IRQ a cada mudança de segundo
A segunda opção você faz modificando a função de init_rtc:
RTC_init(RTC, ID_RTC, rtc_initial, RTC_IER_ALREN | RTC_IER_SECEN);
E agora você consegue dentro do RTC_handler
saber quando você entrou
na IRQ pelo segundo:
/* Verifica por qual motivo entrou
* na interrupcao, se foi por segundo
* ou Alarm
*/
if ((ul_status & RTC_SR_SEC) == RTC_SR_SEC) {
//
// Entrou por segundo!
//
rtc_clear_status(RTC, RTC_SCCR_SECCLR);
}
Warning
Você nunca deve atualizar display dentro de interrupção (handler)! Sempre na task!.
Conceito B: Melhorando
Exercise
Conceito A:
Exercise