A troca do microcontrolador afeta pouco o hardware, são os mesmos componentes ligados em pinos diferentes. Para simplificar a mexida do software, usei PB0 e PB1 para a geração de vídeo (no ATtiny44 usei PA0 e PA1, portanto os bits são os mesmos, só mudam os endereços das portas):
Para rodar o software do post anterior no ATmega328 basta:
- Alterar no Makefile o modelo do processador e o valor dos fuses.
- Trocar PORTA por PORTB e DDRA por DDRB. No código assembler, trocar OUT 0x1B,R30 por OUT 0x05,R30.
- Trocar TIM1_COMPA_vect por TIMER1_COMPA_vect (isto me custou um bom tempo, pois com TIM1_COMPA_vect compila sem erros mas não funciona).
Cada linha passa a ser mapeada em 12 bytes, o que é acertado na macro byteblast. O delay antes desta macro, na rotina de interrupção do timer, precisa ser aumentado para compensar os 24 pontos iniciais que não serão enviados (outra alternativa seria alterar byteblast para enviar bytes fixos). Na vertical, basta alterar as definições de primeiralinha e ultimalinha. Por último, pontLinha deve apontar para o byte correto. O código da rotina de interrupção fica assim:
- ISR (TIMER1_COMPA_vect)
- {
- static uint8_t syncON = VID_0V;
- static uint8_t syncOFF = VID_03V;
- // Gera o pulso de sync
- VID_PORT = syncON;
- linhaAtual++;
- if (linhaAtual == iniSyncV)
- {
- // Sync vertical é invertido
- syncON = VID_03V;
- syncOFF = VID_0V;
- }
- if (linhaAtual == fimSyncV)
- {
- // Voltar ao sync normal
- syncON = VID_0V;
- syncOFF = VID_03V;
- }
- if (linhaAtual == fimFrame)
- {
- // Fim do frame
- linhaAtual = 1;
- pontLinha = tela;
- }
- _delay_us(2); // Aguarda fim do tempo do pulso
- VID_PORT = syncOFF;
- // Gerar a imagem
- if ((linhaAtual <= ultLinha) && (linhaAtual >= primLinha))
- {
- _delay_us(18); // tempo para centrar a linha
- byteblast();
- pontLinha += nBytesLinha;
- }
- }
- uint8_t lePto (uint8_t x, uint8_t y)
- {
- return tela[y*nBytesLinha + (x >> 3)] & (0x80 >> (x & 7));
- }
- void acendePto (uint8_t x, uint8_t y)
- {
- tela[y*nBytesLinha + (x >> 3)] |= (0x80 >> (x & 7));
- }
- void apagaPto (uint8_t x, uint8_t y)
- {
- tela[y*nBytesLinha + (x >> 3)] &= ~(0x80 >> (x & 7));
- }
- for (i = 0; i < NCHUVA; i++)
- {
- chuva[i] = rand() & 0x1F;
- }
- O pingo é apagado na posição atual
- A linha é incrementada
- Se a nova posição estiver ocupada ou fora da tela, voltar o pingo para a primeira linha
- Se a nova posição estiver livre, desenhar o pingo nela
- for (j = 0; j < 6; j++)
- {
- apagaPto ((i << 1)+1, chuva[i]);
- chuva[i]++;
- if ((chuva[i] == nLinhas) || lePto ((i << 1)+1, chuva[i]))
- {
- chuva[i] = 0
- }
- acendePto ((i << 1)+1, chuva[i]);
- if (++i == NCHUVA)
- i = 0;
- }
O projeto completo pode ser baixado dos arquivos do blog (aquivo vidbpchuva.zip)
Nenhum comentário:
Postar um comentário