Funciona bien con 8 mhz interno, pero cuando se cambia a 32,7 khz, la pantalla led de multiplexación no funciona correctamente (parpadea de forma muy aleatoria). ¿Es este el límite de baja velocidad de reloj o hay un problema con mi código?
Timer0 es para multiplexar la pantalla de 7 segmentos; timer2 es para un conteo de reloj externo.
También he jugado con el TCNT0, es decir, para aumentar la velocidad de multiplexación, en la interrupción, pero sin suerte;
///////////////////////////////////////////////////
// B1, B2, D3, D5, D6, B3, D2, D4 (+) active HIGH
// B0, D7, B5, B4 (-) active LOW
///////////////////////////////////////////////////
#include <avr/io.h>
#include <avr/interrupt.h>
int8_t portA = 0b11011100;
int8_t pinA[8] = {1, 2, 3, 5, 6, 3, 2, 4};
uint8_t counter=0;
int8_t d1 = 0b00000110;
int8_t d2 = 0b01011011;
int8_t d3 = 0b01001111;
int8_t d4 = 0b01100110;
int8_t left=43;
int8_t right=21;
uint16_t one=9995;
uint8_t good;
uint8_t tsec;
uint8_t tmin;
uint8_t thr;
int8_t dig[] = //digit mapping
{
//HGFEDCBA
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111, // 9
0b00000000, // BLANK
0b10000000 }; //dot
//----------------------------------------------------
int main(void) {
//timer 0
TIMSK |= (1 << TOIE0);
TCCR0 |= (1<<CS01); // timer0 No prescaler
//timer 2
TIMSK |= (1 << TOIE2);
TCCR2 |= (1 << CS22) ; // 64 prescaler
//TCCR2 |= (1 << CS20) ; // no prescaler
//ASSR |= (1<<AS2);
sei();
//adc
ADCSRA |= (1<<ADPS2)|(1<<ADEN)|(1<<ADIE);
ADMUX |= (1<<REFS0) | (1<<MUX0)| (1<<MUX1);
ADCSRA |= 1<<ADSC;
// PORTs
DDRD = 0xff;
DDRB = 0xff;
while (1) {
if( one>=9999)one=0;
left=one/100;
right=one%100;
d1=dig[left/10];
d2=dig[left%10];
d3=dig[right/10];
d4=dig[right%10];
if(counter==0){
PORTB |=0b00110000;
PORTD |=0b10000000;
pinWrite(d1);
PORTB &= ~(1<<0);
}
if(counter==1){
PORTB |=0b00110001;
PORTD |=0b00000000;
pinWrite(d2);
PORTD &= ~(1<<7);
}
if(counter==2){
PORTB |=0b00010001;
PORTD |=0b10000000;
pinWrite(d3);
PORTB &= ~(1<<5);
}
if(counter==3){
PORTB |=0b00100001;
PORTD |=0b10000000;
pinWrite(d4);
PORTB &= ~(1<<4);
}
if(counter==4) counter=0;
}
}
//----------------------------------------------------
ISR (TIMER0_OVF_vect) // timer0 overflow interrupt
{
TCNT0=100;
counter++;
//19Khz @ 8Mhz/256/2=15Khz
}
//----------------------------------------------------
//2hz @ 32Khz/256/64=2hz
ISR (TIMER2_OVF_vect)
{
good=!good;
if(good==1)one++;
}
//----------------------------------------------------
ISR(ADC_vect) // adc interrupt
{
//one = ADC;
ADCSRA |= 1<<ADSC;
}
//----------------------------------------------------
// PortWrite
int pinWrite ( int8_t data){
for (int x = 0; x <8; x++) {
if (data & (1 << x)) {
if (portA & 1 << x) {
PORTD |= 1 << pinA[x];
}
else {
PORTB |= 1 << pinA[x];
}
}
else {
if (portA & 1 << x) {
PORTD &= ~(1 << pinA[x]);
}
else {
PORTB &= ~(1 << pinA[x]);
}
}
}
}