Lição do Teach
Nios V na DE1-SoC (4/5): display HEX e temporizador
Compile e envie exemplos em C para o HEX0 e o temporizador de intervalo do Nios V e observe o comportamento de HEX0 e LEDR0 na DE1-SoC.
Entre com uma conta de professor para preparar uma sessão. Os estudantes entram com um código da turma.
Ainda não tem uma conta na LabsLand? Criar sua conta de professor
Objetivos de aprendizagem
Usar periféricos validados de display e temporizador mapeados em memória no sistema Nios V fixo.
Explicar por que displays de sete segmentos precisam de padrões de segmentos codificados.
Configurar e consultar o temporizador de intervalo da FPGA em
0xFF202000.Distinguir as entradas lógicas validadas
NB0..NB3via JP1/GPIO do caminho não compatível das teclas KEY da FPGAcademy no navegador.Coletar evidências ao vivo do comportamento dos periféricos em uma placa DE1-SoC real.
Visualização da atividade do estudante
Conteúdo da atividade
Apenas visualização. Em uma sessão de aula, os estudantes podem preencher respostas e entregar o trabalho ao professor.
De GPIO a periféricos
5 min
Nas lições anteriores, você usou E/S mapeada em memória com controles simples: entradas NSW do navegador, dados GPIO do JP1 e saídas LEDR. Esta lição mantém a mesma ideia, mas usa dois periféricos mais completos já incorporados ao sistema fixo da FPGA.
Um periférico é um bloco de hardware que o processador Nios V controla ao ler ou gravar um endereço específico. Você não modificará o projeto da FPGA nesta lição. Substituirá main.c por pequenos exemplos em C, compilará um arquivo ELF, enviará esse arquivo e verificará se o comportamento da placa corresponde à explicação no nível dos registradores.
Os dois exemplos obrigatórios são:
hex_counter, que grava padrões codificados em HEX0.timer_blink, que configura o temporizador de intervalo e alterna LEDR0.
Para consultar o mapa completo de registradores, use o manual FPGAcademy DE1-SoC Computer with Nios V. Esta atividade apresenta o subconjunto necessário: HEX3_HEX0 em 0xFF200020 e o temporizador de intervalo em 0xFF202000.
Esta lição usa dois caminhos de registradores validados do sistema Nios V fixo: a saída do display HEX e a temporização de LED controlada pelo temporizador de intervalo.
O navegador mostra controles de botões lógicos específicos do Nios V, com os rótulos NB0..NB3. Essas são entradas validadas via JP1/GPIO, e não o registrador KEY da FPGAcademy em 0xFF200050.
Para o trabalho obrigatório desta lição, use os exemplos de HEX e temporizador abaixo. A seção opcional de botões é independente caso seja atribuída: use NB0..NB3 como entradas lógicas do JP1 e evite a nomenclatura KEY0..KEY3.
Considere um periférico pronto para o curso somente quando houver evidência ao vivo no perfil atual do laboratório LabsLand. Um registrador pode existir no sistema de referência e ainda assim não servir para uma atividade remota se o caminho do controle no navegador não estiver conectado a ele.
Registrador de saída HEX
22 min
Os displays HEX são displays de sete segmentos. Um dígito não é gravado como o número 3; ele é gravado como um padrão de bits que acende ou apaga segmentos individuais.
O exemplo hex_counter grava padrões de segmentos em HEX3_HEX0, no endereço 0xFF200020.
Cada byte de HEX3_HEX0 controla um display. Neste programa inicial, somente o byte menos significativo é usado; portanto, apenas HEX0 muda. Um valor como 0x3F não é o número zero no sentido habitual: é o padrão de segmentos que acende os segmentos necessários para formar 0.
Exemplos:
- O dígito
0usa o padrão0x3F. - O dígito
1usa o padrão0x06. - O dígito
Ausa o padrão0x77.
Abra
Nios V C IDE for DE1-SoC.Substitua o código inicial pelo código de
hex_counterabaixo.Clique em
Build ELF(Compilar ELF) e envie o arquivo para a FPGA comUpload to FPGA.Observe HEX0 na visualização da placa por pelo menos dois dígitos diferentes.
Registre se HEX0 percorre valores hexadecimais.
Use este código para hex_counter:
Selecione todo o bloco de código antes de copiá-lo para main.c; substitua todo o código inicial.
/* Computador DE1-SoC com Nios V — E/S mapeada em memória */
volatile int *HEX3_HEX0 = (int *) 0xFF200020; /* 7 segmentos HEX3..HEX0 */
static const unsigned char HEX_CODE[16] = {
0x3F, 0x06, 0x5B, 0x4F,
0x66, 0x6D, 0x7D, 0x07,
0x7F, 0x67, 0x77, 0x7C,
0x39, 0x5E, 0x79, 0x71
};
static void delay(void)
{
volatile int i;
for (i = 0; i < 2000000; i++) {
}
}
int main(void)
{
int count = 0;
while (1) {
*HEX3_HEX0 = HEX_CODE[count & 0xF];
count++;
delay();
}
return 0;
}
Use a tabela para registrar o que você viu depois de enviar hex_counter. O comportamento esperado já está preenchido. Adicione dois dígitos ou padrões diferentes vistos em HEX0 e selecione passou, falhou ou incerto na coluna de resultado.
Registre uma verificação de HEX0 na placa ao vivo. Mantenha o comportamento esperado, a menos que o professor peça outro teste; anote dois dígitos ou padrões observados e selecione passou, falhou ou incerto.
| Comportamento esperado | Primeiro dígito ou padrão observado | Segundo dígito ou padrão observado | Resultado |
|---|---|---|---|
Por que o exemplo usa uma tabela de consulta de padrões de segmentos em vez de gravar os valores inteiros 0, 1, 2 e assim por diante diretamente no registrador HEX?
Temporizador de intervalo
22 min
O exemplo timer_blink programa o temporizador de intervalo da FPGA no endereço-base 0xFF202000. Ele define um período, inicia o temporizador, consulta o bit de fim de período, limpa esse bit e alterna LEDR0.
O clock do temporizador é de 100 MHz; portanto, 50.000.000 de pulsos correspondem a aproximadamente meio segundo. O período de 32 bits é dividido em dois registradores de 16 bits porque a interface do temporizador armazena separadamente as metades menos e mais significativas.
Registradores do temporizador usados aqui:
STATUSno deslocamento+0x0: o bit 0,TO, passa a 1 quando o período termina.CONTROLno deslocamento+0x4:STOP,STARTeCONTcontrolam se o temporizador funciona continuamente.PERIOD_LOno deslocamento+0x8: 16 bits menos significativos do período.PERIOD_HIno deslocamento+0xC: 16 bits mais significativos do período.
Substitua o código C pelo código de
timer_blinkabaixo.Clique em
Build ELF(Compilar ELF) e envie comUpload to FPGA.Observe
LEDR0por pelo menos 10 segundos.Registre pelo menos dois momentos em que o estado do LED muda.
Avalie se a alternância é estável o bastante para servir como fonte de temporização.
Use este código para timer_blink:
Selecione todo o bloco de código antes de copiá-lo para main.c; substitua todo o código anterior.
/* Computador DE1-SoC com Nios V — E/S mapeada em memória */
volatile int *LEDS = (int *) 0xFF200000; /* LEDs vermelhos */
#define TIMER_BASE 0xFF202000
#define TIMER_STATUS (*(volatile short *)(TIMER_BASE + 0x0))
#define TIMER_CONTROL (*(volatile short *)(TIMER_BASE + 0x4))
#define TIMER_PERIOD_LO (*(volatile short *)(TIMER_BASE + 0x8))
#define TIMER_PERIOD_HI (*(volatile short *)(TIMER_BASE + 0xC))
#define TIMER_TO 0x1
#define TIMER_CONT 0x2
#define TIMER_START 0x4
#define TIMER_STOP 0x8
int main(void)
{
const unsigned int half_second = 50000000u; /* clock do temporizador: 100 MHz */
int led = 0;
TIMER_CONTROL = TIMER_STOP;
TIMER_PERIOD_LO = (short)(half_second & 0xFFFFu);
TIMER_PERIOD_HI = (short)((half_second >> 16) & 0xFFFFu);
TIMER_STATUS = 0; /* limpar TO */
TIMER_CONTROL = TIMER_CONT | TIMER_START;
while (1) {
if ((TIMER_STATUS & TIMER_TO) != 0) {
TIMER_STATUS = 0; /* limpar TO */
led ^= 1;
*LEDS = led;
}
}
return 0;
}
Use a tabela para registrar a alternância controlada pelo temporizador. Mantenha a janela de 10 segundos, a menos que o professor solicite um teste mais longo. Na coluna de evidência, escreva o que mudou, por exemplo, apagado -> aceso -> apagado, e selecione passou, falhou ou incerto.
Registre uma observação do temporizador. Use uma janela de 10 segundos, descreva as mudanças de estado observadas em LEDR0 e selecione passou, falhou ou incerto.
| Janela de observação (s) | Mudanças de estado observadas em LEDR0 | Comportamento esperado | Resultado |
|---|---|---|---|
Qual é a diferença entre esta alternância controlada pelo temporizador e um laço de espera por software? Mencione os registradores de período, o bit de fim de período e uma razão pela qual um temporizador de hardware pode ser útil em software embarcado.
Uma pequena modificação no periférico
18 min
Escolha um dos exemplos validados e faça uma mudança pequena e observável.
Exemplos:
- Em
hex_counter, mude a sequência para contar somente valores hexadecimais pares. - Em
hex_counter, controle dois dígitos HEX em vez de apenas HEX0. - Em
timer_blink, mude o período para que LEDR0 alterne mais rápido ou mais devagar. - Em
timer_blink, alterne outro bit de LED. - Trabalho opcional com botões: leia os bits 0 a 3 do JP1 por meio de
NB0..NB3e mostre-os emLEDR0..LEDR3.
Escolha o exemplo de HEX ou de temporizador.
Faça uma pequena alteração no código.
Compile e envie o arquivo ELF.
Observe a placa e registre como o comportamento mudou.
Envie as linhas de código alteradas e identifique qual registrador mapeado em memória cada linha afeta.
Mantenha a modificação pequena o bastante para validá-la em uma única sessão da placa. Uma boa entrega altera um comportamento e pode ser verificada com uma ou duas observações.
Envie uma nota de observação concisa: o que mudou, o que você esperava ver e o que a placa ao vivo mostrou.
Opcional: botões lógicos NB
Os botões lógicos NB0..NB3 foram validados nos bits 0 a 3 do registrador de dados JP1. Eles servem para um exercício rápido de consulta, mas não correspondem à porta KEY3..KEY0 da FPGAcademy.
Padrão mínimo em C:
volatile int *LEDS = (int *) 0xFF200000;
volatile int *JP1 = (int *) 0xFF200060;
volatile int *JP1_DIR = (int *) 0xFF200064;
*JP1_DIR = 0;
while (1) {
*LEDS = (*JP1) & 0xF; // NB0..NB3 -> LEDR0..LEDR3
}Por que este exercício opcional lê os bits 0 a 3 do JP1 em vez de ler o registrador KEY da FPGAcademy em 0xFF200050?
Se você executar o exercício opcional, registre um botão NB que pressionou e o bit de LED que mudou.
Prepare o projeto final
8 min
O projeto final deve usar NSW0..NSW9 e LEDR0..LEDR9, além de pelo menos um periférico de extensão validado nesta lição.
Qual periférico de extensão você provavelmente usará no projeto final?
Descreva um comportamento do projeto final que combine NSW/LEDR com o periférico de extensão escolhido. Inclua o endereço ou os endereços de registradores que pretende usar.
Transforme esta visualização em uma sessão de aula
Continue para o LabsLand Teach para usar esta lição com seus estudantes e conferir o acesso disponível para sua conta.
Ainda não tem uma conta na LabsLand? Criar sua conta de professor