з.ы. Да что там прошивку, лучше весь проект сразу
Генератор на Atmega8 (микросекунды) большие погрешности
Прошивку можно?, проверю у меня как будет работать, просто у меня все нормально работает.
з.ы. Да что там прошивку, лучше весь проект сразу
з.ы. Да что там прошивку, лучше весь проект сразу
- Реклама
- Сообщения: 141
- Зарегистрирован: Ср окт 26, 2011 13:38:13
Ок
- Вложения
-
- Gener.dsn.zip
- Проект
- (19.83 КБ) 185 скачиваний
-
- timer.c
- Исходники
- (419 байт) 288 скачиваний
-
- firmware.hex
- Прошивка
- (480 байт) 281 скачивание
Это не хвост, это антенна
Нашел проблему, дело в том, что в режиме СТС оба канала сравниваются по OCR1A, у себя то, Я проверял через канал А, поэтому у меня все работало.
Спойлер
Код: Выделить всё
#define F_CPU 10000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
void SetupTIMER1(void)
{
OCR1A = 499;
TCCR1A = (0b01<<COM1B0);
TCCR1B = (0b01<<WGM12)|(0b001<<CS10); //режим таймера СТС, аппаратный прескалер 1:1
}
int main(void)
{
DDRB = (1 << PB2);
SetupTIMER1();
sei();
while(1)
{
}
}
Мне интересно нафига они дергают Нулевой таймер если Т2 сам по себе адаптирован под работу в асенхроне.zero648 писал(а):ИнтересноJeysonRou писал(а):Не тугодумте народ нафига вы юзаете OSC T1![]()
, где это видно, причем тут OSC T1?
И не придерайся умник ну опечатался. Бывает...
При чем здесь опечатка, с чего ты взял, что нужно внешнее тактирование и работа в ассинхр режиме?JeysonRou писал(а):Мне интересно нафига они дергают Нулевой таймер если Т2 сам по себе адаптирован под работу в асенхроне.
И не придерайся умник ну опечатался. Бывает...
- Реклама
Похоже опечатки вас просто преследуютJeysonRou писал(а):в асИнхроне.
И не придИрайся... ну опечатался
- Сообщения: 141
- Зарегистрирован: Ср окт 26, 2011 13:38:13
И опять вернулись к тому с чего начинали. Сигнал генерится на лапе PB2, 10Khz. А толку? Помните какую я хочу получить осцилограмму?

Обясняю, сейчас в вашем варианте кода получается работает только канал A, так как есть только регистр OCR1A, соответсвенно и приведенной мной осцилограммы получается только первая часть.
Нужно или еще запустить и канал B, выставить ему свою частоту и чтоб в результате чтоб получилась третья часть из преведенного мной рисунка, тоисть то где написано "Результат сложения".
Как этого достичь?
Делать чтоб все это было уже на одной лапе и сложение реализовывалось программно, или на две лапы и потом складывать сигнал какой то внешней логикой, например по той схеме что я показывал выше.
Скважность будет 50% а вот частоты будут менятся, тоесть частота первого канала не может зависеть от частоты второго и наоборот
Обясняю, сейчас в вашем варианте кода получается работает только канал A, так как есть только регистр OCR1A, соответсвенно и приведенной мной осцилограммы получается только первая часть.
Нужно или еще запустить и канал B, выставить ему свою частоту и чтоб в результате чтоб получилась третья часть из преведенного мной рисунка, тоисть то где написано "Результат сложения".
Как этого достичь?
Делать чтоб все это было уже на одной лапе и сложение реализовывалось программно, или на две лапы и потом складывать сигнал какой то внешней логикой, например по той схеме что я показывал выше.
Скважность будет 50% а вот частоты будут менятся, тоесть частота первого канала не может зависеть от частоты второго и наоборот
- Вложения
-
- oscil.jpg
- (19.63 КБ) 654 скачивания
Последний раз редактировалось dem66 Сб фев 02, 2013 18:21:33, всего редактировалось 2 раза.
Это не хвост, это антенна
Частота 2 будет кратная частоте 1, чтобы полупериоды были полные или не важно?
- Сообщения: 141
- Зарегистрирован: Ср окт 26, 2011 13:38:13
Не важно, сколько впихнет столько впихнет
Это не хвост, это антенна
Так во втором таймере по прерыванию делитель первого(тот что генерит частоту) переключаем в 0 или в 1 и все, таймер останавливается, если на ноге 1, ставим ноль. три команды буквально.
- Сообщения: 141
- Зарегистрирован: Ср окт 26, 2011 13:38:13
както непонятно 
Это не хвост, это антенна
Вам только готовый код подходит, чтобы понять?
- Сообщения: 141
- Зарегистрирован: Ср окт 26, 2011 13:38:13
Ну я в этом деле вобще недавно, в основном на PHP пишу, а вы тут о каких то трех командах говорите.
Тут явно не три команды надо
Тут явно не три команды надо
Это не хвост, это антенна
Алгоритм
Таймер, который вы уже настроили работает так как есть.
Прерывание переполнения другого таймера
загрузили новое значение, чтобы нужная частота поддерживалась в этом таймере.
flag^=1
если флаг,( то TCCR1B = (0b01<<WGM12)|(0b001<<CS10); //режим таймера СТС, аппаратный прескалер 1:1
если не флаг то( TCCR1B =x;<<смотрим сколько тут нужно для аппаратный прескалер 0
Таймер, который вы уже настроили работает так как есть.
Прерывание переполнения другого таймера
загрузили новое значение, чтобы нужная частота поддерживалась в этом таймере.
flag^=1
если флаг,( то TCCR1B = (0b01<<WGM12)|(0b001<<CS10); //режим таймера СТС, аппаратный прескалер 1:1
если не флаг то( TCCR1B =x;<<смотрим сколько тут нужно для аппаратный прескалер 0
- PORTB &=~(1 << PB2);//Очистили сигнал с порта.Можно и без проверок.)
- Сообщения: 141
- Зарегистрирован: Ср окт 26, 2011 13:38:13
Чтото про флаг не понятно, зачем оно вобще надо. И зачем там здался делитель 0?
Ладно оставим пока это дело, сейчас пытаюсь запустить таймер0 и генерить на другую лапу, а оно ноль эмоций, только при запуске устанавливает на лапе высокий уровень и все.
Ладно оставим пока это дело, сейчас пытаюсь запустить таймер0 и генерить на другую лапу, а оно ноль эмоций, только при запуске устанавливает на лапе высокий уровень и все.
Код: Выделить всё
#define F_CPU 10000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(TIMER0_OVF_vect)
{
TCNT0 = 195;
PORTB ^= (1 << PB1);
}
void SetupTIMER1(void)
{
// Prescaler = FCPU/1024
TCCR0|=(1<<CS02)|(1<<CS00);
//Enable Overflow Interrupt Enable
TIMSK|=(1<<TOIE0);
TCNT0 = 0;
}
int main(void)
{
DDRB = (1 << PB1);
DDRB = (1 << PB2);
SetupTIMER1();
sei();
while(1)
{
}
}
Это не хвост, это антенна
Строчку подправьdem66 писал(а):Ладно оставим пока это дело, сейчас пытаюсь запустить таймер0 и генерить на другую лапу, а оно ноль эмоций, только при запуске устанавливает на лапе высокий уровень и все.
DDRB |= (1 << PB2);
Код с наложеной частотой, выход РВ1.
Спойлер
Код: Выделить всё
#define F_CPU 10000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(TIMER0_OVF_vect)
{
TCNT0 = 195;
TCCR1A ^= (1<<COM1A0);
// TCCR1B ^= (1<<CS10);
// PORTB ^= (1<<PB1);
}
void SetupTIMERs(void)
{
TCNT0 = 195;
TCCR0 = (0b101<<CS00); // Prescaler = FCPU/1024
TIMSK = (1<<TOIE0); // Enable Overflow Interrupt Enable
OCR1A = 499;
TCCR1A = (0b01<<COM1A0);
TCCR1B = (0b01<<WGM12)|(0b001<<CS10); //режим таймера СТС, аппаратный прескалер 1:1
}
int main(void)
{
DDRB = (1 << PB1);
SetupTIMERs();
sei();
while(1)
{}
}
- Сообщения: 141
- Зарегистрирован: Ср окт 26, 2011 13:38:13
Спасибо за помощь, я уже какраз тоже разобрался))
Скажите а можно ли менять TCCR0 в зависимости от диапазона частот?
Это нужно будет перезапускать таймер или как?
Допустим для одного диапазона частот лучше прескалер 64 для других 8 и т.д.
Скажите а можно ли менять TCCR0 в зависимости от диапазона частот?
Это нужно будет перезапускать таймер или как?
Допустим для одного диапазона частот лучше прескалер 64 для других 8 и т.д.
Это не хвост, это антенна
Да, без проблем, какой надо, тот и ставишь прескалер, если ноль таймер остановлен.
- Сообщения: 141
- Зарегистрирован: Ср окт 26, 2011 13:38:13
Ну имею ввиду типа этого
Сам прескаллер получаем по юарту, вот только не придумал как
Код: Выделить всё
int SetPrescaller(char prescaller){
switch(prescaller){
case('256'):
TIMSK|=(0<<TOIE0);
TCCR0 |= (1 << CS02)|(0 << CS01)|(0 << CS00); // 256
TIMSK|=(1<<TOIE0);
break;
case('64'):
TIMSK|=(0<<TOIE0);
TCCR0 |= (0 << CS02)|(1 << CS01)|(1 << CS00); // 64
TIMSK|=(1<<TOIE0);
break;
case('8'):
break;
}
}
int main(void)
{
DDRB = (1 << PB1);
DDRB |= (1 << PB2);
SetupTIMER1();
sei();
while(1)
{
if(prescaller!=''){
SetPrescaller(prescaller);
}
}
}
Это не хвост, это антенна
TIMSK|=(0<<TOIE0);
Бесполезный оператор, он ничего не делает.
если нужно сбрасывать бит TOIE0, тогда вроде так:
TIMSK&=~(1<<TOIE0);
p.s. И зачем везде ставить логическое "или - | "
берем например строку:
TCCR0 |= (1 << CS02)|(0 << CS01)|(0 << CS00); // 256
из нее следует, что TCCR0 = 0x04;
потом меняем прескалер и выполняется эта строка:
TCCR0 |= (0 << CS02)|(1 << CS01)|(1 << CS00); // 64
и получается, что TCCR0 = TCCR0 | 0x03 = 0x07;
и после этого прескалер больше никогда не изменится.
Бесполезный оператор, он ничего не делает.
если нужно сбрасывать бит TOIE0, тогда вроде так:
TIMSK&=~(1<<TOIE0);
p.s. И зачем везде ставить логическое "или - | "
берем например строку:
TCCR0 |= (1 << CS02)|(0 << CS01)|(0 << CS00); // 256
из нее следует, что TCCR0 = 0x04;
потом меняем прескалер и выполняется эта строка:
TCCR0 |= (0 << CS02)|(1 << CS01)|(1 << CS00); // 64
и получается, что TCCR0 = TCCR0 | 0x03 = 0x07;
и после этого прескалер больше никогда не изменится.


