primera publicación aquí, lo siento por cualquier mal estilo.
Estoy trabajando en un proyecto grupal y usando un Atmega328, sin entrar en detalles, necesito controlar dos ventiladores, dos servos y 1 función basada en CTC de 3 temporizadores. A mi pregunta entonces; hay registros OCRx A y B que estoy usando para impulsar los ventiladores a velocidades variables y usando un método similar para los servos. Al configurar un script PWM muy básico, noté que ambos registros impulsarán un ventilador, sin embargo, cuando intento usar cualquiera de los registros de forma independiente (ventilador 1 encendido, 2 apagado, luego cambio), OCRxB no producirá una salida.
Aquí hay un recorte de mi código de configuración:
void setup_timers () {
// Set Timer0 to Fast PWM mode
TCCR0A |= (1 << WGM01) | (1 << WGM00);
// Set Timer0 to clear OCR0 A/B on match
TCCR0A |= (1 << COM0A1) | (1 << COM0A0) | (1 << COM0B1) | (1 << COM0B0);
TCCR0B |= (1 << CS01);
TCNT0 = 0;
// Set OCR0 A/B
DDRD = 0xFF;}
Ahora, idealmente, esto configurará ambos registros en el temporizador 0 para las salidas. Estoy enviando esta señal a un transistor, que luego alimenta los ventiladores según lo determinado por el siguiente bit:
int main () {
setup_timers();
while (1) {
/* Timer 0; OCR0A (i = 0, L), OCR0B (i = 1, R), i = 2 denotes both fans */
for (uint8_t i = 0; i <= 3; i++) {
// Cycle Fans Left/Right/Both
for (uint8_t j = 1; j <= 4; j++) {
// Cycle Speed
if (i == 2) {
// Check motor; run timer 0 A/B as required
OCR0A = 0xFF * j / 4;
OCR0B = 0xFF * j / 4;
_delay_ms(2000);
}
else if (i == 1) {
OCR0A = 0xFF * j / 4;
OCR0B = 0;
_delay_ms(2000);
}
else if (i == 0) {
OCR0A = 0;
OCR0B = 0xFF * j / 4;
_delay_ms(2000);
}
}
}
}
return 1; }
Ahora sé que esto podría hacerse mejor, este segmento tiene un montón de otras pruebas recortadas. El problema principal aquí es que el ventilador 1 se ejecutará (dirigido por OCR0A), pero el ventilador 2 se ignora por completo. He leído la hoja de datos varias veces, pero no estaba un poco claro si esto es realmente posible, decía algo sobre que OCRxB no se almacenaba, y he visto otras publicaciones preguntando sobre eso. Por lo que entiendo son registros independientes, pero es posible que se conserve OCRxA, pero despues de escribir OCRxB es imposible ejecutar?
O tal vez estoy completamente equivocado, ciertamente no sería la primera vez.
Parece que hubo algún problema con los valores predeterminados, al configurar COM1A0 y COM1B0, el temporizador 1 se puede configurar para dar señales independientes. Este es el código de instalación que funciona:
void setup_timers () {
TCCR1A |= (1 << WGM11) | (1 << WGM10);
TCCR1A |= (1 << COM1A1) | (1 << COM1A0) | (1 << COM1B1) | (1 << COM1B0);
TCCR1B |= (1 << CS11);
TCNT1 = 0;
DDRB = 0xFF;}
Todavía tengo problemas para que controle correctamente los motores, pero los servos funcionan bien y se puede hacer.
Nota: el temporizador 1 en realidad tiene dos salidas separadas, pero el temporizador 0/2 no. Para obtener salidas duales, debe alternar los registros WGMx2 y COMxB 0/1, cuando WGMx2 está configurado, OCRxA no emitirá correctamente, pero OCRxB sí, con algunos cambios. Cuando WGMx2 no está configurado, deshabilita OCRxB, y OCRxA funcionará normalmente, para obtener salidas independientes, deberá tener esto en cuenta.
KyranF
TMa
miguel karas
TMa
Omán
KyranF
Omán
KyranF
Omán
KyranF
KyranF
Omán
Omán