O primeiro passo é examinar o circuito e determinar onde estão conectados o controlador e as chaves. Para facilitar, gerei um arquivo .h com esta informação:
- #ifndef _JYMCU3208_H
- #define _JYMCU3208_H
- // Clock da CPU (clock internio de 8MHz dividido por 8)
- #define CLK_CPU 1000000 // 1.0 MHz
- // Conexões do controlador HT1632C
- // Três sinais: CS, RD, WR e DT(DATA)
- #define HT_CS_DDR DDRB
- #define HT_WR_DDR DDRB
- #define HT_DT_DDR DDRB
- #define HT_CS_PORT PORTB
- #define HT_WR_PORT PORTB
- #define HT_DT_PORT PORTB
- #define HT_CS_BIT _BV(PB3)
- #define HT_WR_BIT _BV(PB4)
- #define HT_DT_BIT _BV(PB5)
- // Conexão das Teclas
- #define TEC_DDR DDRD
- #define TEC_PIN PIND
- #define TEC_KEY1 _BV(PD7)
- #define TEC_KEY2 _BV(PD6)
- #define TEC_KEY3 _BV(PD5)
- #endif
- Em repouso os sinais CS e WR devem estar em nível 1
- O sinal CS é colocado em zero para sinalizar o início da comunicação
- Para cada bit enviado do microcontrolador para o controlador
- O sinal WR é colocado em zero
- O valor do bit é colocado no sinal DATA
- O sinal WR é retornado ao nível 1
- Ao final dos bits o sinal CS é retornado ao nível 1
Cada comando é composto por 9 bits: os primeiros 8 determinam o comando e o final é irrelevante. Logo após ligar o display é necessário enviar alguns comandos de configuração.
Na escrita na memória deve ser enviado o endereço inicial (7 bits) e os valores a escrever (cada posição da memória armazena 4 bits de dados).
O módulo abaixo implementa as operações básicas. Uma vez que não é possível ler a memória do controlador, ela é duplicada na memória do microcontrolador. Neste primeiro teste a escrita será feita sobre esta memória "shadow" que depois é copiada no controlador.
- #include <stdio.h>
- #include <stdlib.h>
- #include <inttypes.h>
- #include <avr/io.h>
- #include "jymcu3208.h"
- #include "ht1632c.h"
- // Comandos do controlador HT1632C
- // Os comandos possuem 8 bits e devem ser precedidos pelos 3 bits de ID e seguidos de
- // um bit adicional (0 ou 1, tanto faz)
- #define HT_ID_CMD 0b100
- #define HT_STARTSYS 0b00000001 // start system oscillator
- #define HT_STOPSYS 0b00000000 // stop sytem oscillator and LED duty
- #define HT_SETCLOCK 0b00011000 // set clock to master with internal RC
- #define HT_SETLAYOUT 0b00100000 // N-MOS open-drain output and 32 ROW * 8 COM
- #define HT_LEDON 0b00000011 // start LEDs
- #define HT_LEDOFF 0b00000010 // stop LEDs
- #define HT_SETBRIGHT 0b10100000 // set brightness 0b1010xxxx xxxx = brightness
- #define HT_BLINKON 0b00001001 // blinking on
- #define HT_BLINKOFF 0b00001000 // blinking off
- // Escrita de dado no controlador HT1632C
- // Enviar 3 bits de ID, 7 bits do endereço inicial e os 4 bits de dados
- // 101-aaaaaaa-dddd-dddd-dddd-dddd-dddd-...
- #define HT_ID_WRITE 0b101
- // Copia da Ram do controlador
- // Usa apenas os 4 bits menos significativos de cada byte
- //
- volatile uint8_t ht1632c_shadowram [(HT_COLS*HT_ROWS)/4];
- // Comandos de iniciacao do controlador
- static uint8_t cmd_init[] =
- {
- HT_STOPSYS, HT_SETLAYOUT, HT_SETCLOCK,
- HT_STARTSYS, HT_LEDON, HT_SETBRIGHT | 3,
- HT_BLINKOFF
- };
- // Rotinas internas
- static void ht1632c_send_commands (uint8_t *pCmds, int8_t nCmds);
- static void ht1632c_send_command (uint8_t cmd);
- static void ht1632c_send (uint8_t valor, int8_t nBits);
- // Inicia o controlador
- void ht1632c_init ()
- {
- // Inicia as direçoes dos pinos de conexão
- HT_CS_DDR |= HT_CS_BIT;
- HT_WR_DDR |= HT_WR_BIT;
- HT_DT_DDR |= HT_DT_BIT;
- // Default para o CS e WR é alto (inativo)
- HT_CS_PORT |= HT_CS_BIT;
- HT_WR_PORT |= HT_WR_BIT;
- HT_DT_PORT |= HT_DT_BIT;
- // Efetua a configuração
- ht1632c_send_commands (cmd_init, sizeof(cmd_init));
- }
- // Atualiza a memoria do controlador com o conteudo
- // da shadow mempory
- void ht1632c_send_screen ()
- {
- uint8_t addr;
- HT_CS_PORT &= ~HT_CS_BIT; // seleciona o controlador
- ht1632c_send (HT_ID_WRITE, 3);
- ht1632c_send (0, 7); // endereço inicial
- for(addr = 0; addr < (HT_COLS*HT_ROWS)/4; addr++)
- {
- ht1632c_send (ht1632c_shadowram[addr], 4);
- }
- HT_CS_PORT |= HT_CS_BIT; // libera o controlador
- }
- // Envia uma série de comandos ao controlador
- static void ht1632c_send_commands (uint8_t *pCmds, int8_t nCmds)
- {
- int8_t i;
- HT_CS_PORT &= ~HT_CS_BIT; // seleciona o controlador
- ht1632c_send (HT_ID_CMD, 3); // envia ID de comando
- for (i = 0; i < nCmds; i++)
- {
- ht1632c_send (pCmds[i], 8);
- ht1632c_send (0, 1);
- }
- HT_CS_PORT |= HT_CS_BIT; // libera o controlador
- }
- // Envia um comando ao controlador
- static void ht1632c_send_command (uint8_t cmd)
- {
- HT_CS_PORT &= ~HT_CS_BIT; // seleciona o controlador
- ht1632c_send (HT_ID_CMD, 3); // envia ID de comando
- ht1632c_send (cmd, 8);
- ht1632c_send (0, 1);
- HT_CS_PORT |= HT_CS_BIT; // libera o controlador
- }
- // Envia uma sequencia de bits ao controlador
- static void ht1632c_send (uint8_t valor, int8_t nBits)
- {
- int8_t i;
- uint8_t mask = 1 << (nBits-1); // enviar mais significativo primeiro
- for (i = nBits; i > 0; i--)
- {
- HT_WR_PORT &= ~HT_WR_BIT;
- if (valor & mask)
- HT_DT_PORT |= HT_DT_BIT;
- else
- HT_DT_PORT &= ~HT_DT_BIT;
- HT_WR_PORT |= HT_WR_BIT;
- mask = mask >> 1;
- }
- }
- #include <stdio.h>
- #include <stdlib.h>
- #include <inttypes.h>
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include "jymcu3208.h"
- #include "ht1632c.h"
- // Variaveis
- static volatile uint8_t cnt_delay;
- // Rotinas
- static void delay_seg (uint8_t seg);
- static void tempo_init (void);
- // Programa principal
- int main(void)
- {
- uint8_t addr, bit;
- ht1632c_init(); // inicia o controlador do display
- ht1632c_send_screen (); // limpa o display
- tempo_init(); // inicia a contagem de tempo
- // Acende um LED a cada segundo
- for (addr = 0; addr < (HT_COLS*HT_ROWS)/4; addr++)
- {
- for (bit = 0x01; bit < 0x10; bit = bit << 1)
- {
- ht1632c_shadowram [addr] |= bit;
- ht1632c_send_screen ();
- delay_seg (1);
- }
- }
- // nada mais a fazer
- for (;;)
- ;
- }
- // Aguarda um certo número de segundos (1 a 64)
- static void delay_seg (uint8_t seg)
- {
- cnt_delay = seg << 2;
- while (cnt_delay)
- ;
- }
- // Inicia a contagem de tempo
- static void tempo_init (void)
- {
- ASSR |= (1<<AS2); // timer2 async from external quartz
- TCCR2 = 0b00000011; // normal,off,/32; 32768Hz/256/32 = 4 Hz
- TIMSK |= (1<<TOIE2); // enable timer2 overflow int
- sei(); // enable interrupts
- }
- // Interrupção do Timer2
- ISR(TIMER2_OVF_vect)
- {
- if (cnt_delay)
- cnt_delay--;
- }
3 comentários:
Hola
Encontré este código que parece ser el original del JY-MCU 3608
https://code.google.com/p/buxiaoyang-project/source/browse/trunk/AVR/?r=23#AVR%2FLED3208V1
Logré cargarlo pero veo sólo caracteres chinos :-(
¿Me darían una mano tratando de adaptarlo para usar caracteres occidentales?
Saludos !
Não parece ser o software original, pois pega a data e hora de um DS1302 que não vem montado no display. Pretendo fazer um firmware de relógio para o display, mas ainda deve demorar algumas semanas.
Postar um comentário