http://www.count-zero.ru/2015/timer2/
CodeVision AVR в вопросах и ответах
может про таймеры почитать надо?
http://www.count-zero.ru/2015/timer2/
http://www.count-zero.ru/2015/timer2/
- Реклама
- Сообщения: 120
- Зарегистрирован: Пт мар 19, 2021 08:58:45
Добрый весенний вечер! Нашёл в просторах интернета урок по меню для 1602 LCD Keypad Shield For Arduino, где кнопки опрашиваются по средством ацп, напсиан в AVR Studio. Решим перемахнуть сей проект для ознакомления собственного в CodevisionAVR под atmega328p вместо atmega8.
Так вот у меня не получается нормальной работы таймера по совпадению канала А. Что не так делаю:
код проекта изначально:
мой код перепевка, правда таймер немного не так настроил, мне так надо:
Так вот у меня не получается нормальной работы таймера по совпадению канала А. Что не так делаю:
код проекта изначально:
Код: Выделить всё
//----------------------------------------
ISR(ADC_vect)
{
low_adc = ADCL;
high_adc = ADCH;//Старшая часть регистра ADC должна быть считана последней, иначе не продолжится преобразование
if(adc_counter<20) {adc_tmp+=high_adc;adc_counter++;}
else {adc_value=adc_tmp/20;adc_counter=0;adc_tmp=0;}
}
//----------------------------------------
void ADC_Init(void)
{
ADCSRA |= (1<<ADEN) // Разрешение использования АЦП
|(1<<ADSC)//Запуск преобразования
|(1<<ADFR)//Непрерывный режим работы АЦП
|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)//Делитель 128 = 128 кГц
|(1<<ADIE);//Разрешение прерывания от АЦП
ADMUX |= (1<<ADLAR)|(0<<REFS1)|(1<<REFS0); //Внутренний Источник ОН 5в, вход ADC0
}
//-----------------------------------------
void init_button_timer(void)
{
TIMSK |= (1<<TOIE0); //устанавливаем бит разрешения прерывания 0-ого счетчика по переполнению
TCCR0 |= (0<<CS02)|(1<<CS01)|(1<<CS00); // устанавливаем предделитель 64
//тем самым получаем - частота тактирования / предделитель / 256 = 976,5625 (около милисекунды)
//делим на 256, так как таймер нулевой всегда считает от 0x00 до 0xFF и это не регулируется никак
}
//-----------------------------------------
ISR (TIMER0_OVF_vect)
{
Read_Button_State(Button_Right);
Read_Button_State(Button_Up);
Read_Button_State(Button_Down);
Read_Button_State(Button_Left);
Read_Button_State(Button_Select);
tim_cnt++;
if(tim_cnt>=1000) tim_cnt=0;
}
//-----------------------------------------
Код: Выделить всё
// Voltage Reference: AVCC pin
#define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (0<<ADLAR))
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | ADC_VREF_TYPE;
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=(1<<ADSC);
// Wait for the AD conversion to complete
while ((ADCSRA & (1<<ADIF))==0);
ADCSRA|=(1<<ADIF);
return ADCW;
}
// Timer 0 output compare A interrupt service routine
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
Read_Button_State(Button_Right); //читаем состояние кнопки вправо
Read_Button_State(Button_Up); //читаем состояние кнопки вверх
Read_Button_State(Button_Down); //читаем состояние кнопки вниз
Read_Button_State(Button_Left); //читаем состояние кнопки влево
Read_Button_State(Button_Select); //читаем состояние кнопки выбор
tim_cnt++;
if(tim_cnt>=1000) {tim_cnt=0;}
}
....
// Clock value: 125,000 kHz
// Mode: Fast PWM top=OCR0A
// OC0B output: Non-Inverted PWM
// Timer Period: 1 ms
// OC0B Period: 1 ms Width: 0 us
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (1<<COM0B0) | (1<<WGM01) | (1<<WGM00);
TCCR0B=(1<<WGM02) | (0<<CS02) | (1<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A=0x7C;
OCR0B=0x00;
TIMSK0=(0<<OCIE0B) | (1<<OCIE0A) | (0<<TOIE0);
// ADC Clock frequency: 125,000 kHz
// ADC Voltage Reference: AVCC pin
// ADC Auto Trigger Source: Free Running
// Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On, ADC4: On, ADC5: On
DIDR0=(0<<ADC5D) | (0<<ADC4D) | (0<<ADC3D) | (0<<ADC2D) | (0<<ADC1D) | (0<<ADC0D);
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (1<<ADATE) | (0<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0); //(1<<ADATE) - используется в режиме по событию
ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
- Сообщения: 430
- Зарегистрирован: Вс апр 18, 2021 15:43:55
Почему так получается останавливать таймер:
А так нет:
?
Код под Atmega8. Таймер в ШИМ режиме.
Код: Выделить всё
TCCR2 = 0x00;Код: Выделить всё
TCCR2=(1<<PWM2) | (1<<COM21) | (0<<COM20) | (1<<CTC2) | (0<<CS22) | (0<<CS21) | (0<<CS20);Код под Atmega8. Таймер в ШИМ режиме.
Конкретно в битах я разбираться не стал, но чисто по логике разница очевидна. Первый оператор сбрасывает все биты, второй - формирует константу, устанавливающую единицы в PWM2, COM21, CTC2, остальные остаются нулями , потому что конструкция вида (0<<CS20) бессмыслена по своей сути, она ничего не добавляет в константу - нули остались на всех позициях, не "затронутых" единицей . Так что второй оператор мог выглядеть и так:
и он должен был остановить таймер ?
Код: Выделить всё
TCCR2=(1<<PWM2) | (1<<COM21) | (1<<CTC2) ;- Сообщения: 430
- Зарегистрирован: Вс апр 18, 2021 15:43:55
Вот табличка из даташита:

Вроде написано что если эти биты "по-нулям", то таймер остановлен. Кстати... может таймер останавливается и высокий уровень на ноге зависает (т.е. импульсов нет, просто висит высокий уровень)? Это я думал, что если таймер остановлен, то должен быть низкий уровень. Атмега ведь может думать иначе
Вроде написано что если эти биты "по-нулям", то таймер остановлен. Кстати... может таймер останавливается и высокий уровень на ноге зависает (т.е. импульсов нет, просто висит высокий уровень)? Это я думал, что если таймер остановлен, то должен быть низкий уровень. Атмега ведь может думать иначе
- Реклама
режим формирования ШИМ вы не выключили, поэтому тот факт, что счетчик таймера больше не считает, на все остальные его части никак не влияет. и, если в момент остановки формирователь ШИМ-а выдавал высокий уровень - с чего бы ему меняться? триггер потерял тактирование, но он сохраняет своё последнее состояние...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 430
- Зарегистрирован: Вс апр 18, 2021 15:43:55
- Сообщения: 120
- Зарегистрирован: Пт мар 19, 2021 08:58:45
Как правильно считать регистр TCNT1 для atmega328 в CodeVisionAVR. Не определенные целиком 16 битные регистры(((
или может так?
Подскажите новичку))
Код: Выделить всё
TCNT1 = TCNT1H<<8; //с начало старший
TCNT1 = TCNT1 + TCNT1L; //потом младшийКод: Выделить всё
TCNT1 = TCNT1H<<8 | TCNT1L;разве в CVAVR нет предопределенной unsigned int переменной TCNT1?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
kote52, сначала читаем младший байт, потом старший. Пишем старший, потом младший.
Из даташита - Assembly Code Example:
Читаются данные из таймера в момент чтения младшего байта, пишутся - при записи младшего.
Из даташита - Assembly Code Example:
Код: Выделить всё
; Set TCNT1 to 0x01FF
ldi r17,0x01
ldi r16,0xFF
out TCNT1H,r17
out TCNT1L,r16
; Read TCNT1 into r17:r16
in r16,TCNT1L
in r17,TCNT1H- Сообщения: 120
- Зарегистрирован: Пт мар 19, 2021 08:58:45
[uquote="ARV",url="/forum/viewtopic.php?p=4079895#p4079895"]разве в CVAVR нет предопределенной unsigned int переменной TCNT1?[/uquote]
нету(((
вот так возможно ли дописать в файле mega328p.h?
Добавлено after 4 minutes 27 seconds:
[uquote="GoldenAndy",url="/forum/viewtopic.php?p=4079907#p4079907"]Читаются данные из таймера в момент чтения младшего байта, пишутся - при записи младшего.[/uquote]
т.е. на Си это будет
нету(((
вот так возможно ли дописать в файле mega328p.h?
Код: Выделить всё
...
#define TCCR1A (*(unsigned char *) 0x80)
#define TCCR1B (*(unsigned char *) 0x81)
#define TCCR1C (*(unsigned char *) 0x82)
#define TCNT1L (*(unsigned char *) 0x84)
#define TCNT1H (*(unsigned char *) 0x85)
#define TCNT1 (*(unsigned char *) 0x84) // мое творчество
...[uquote="GoldenAndy",url="/forum/viewtopic.php?p=4079907#p4079907"]Читаются данные из таймера в момент чтения младшего байта, пишутся - при записи младшего.[/uquote]
т.е. на Си это будет
Код: Выделить всё
TCNT1 = TCNT1L; //младший
TCNT1 |= (unsigned int) TCNT1H<<8; //потом старшийправильно должно быть так:
Код: Выделить всё
#define TCNT1L (*(volatile unsigned char *) 0x84)
#define TCNT1H (*(volatile unsigned char *) 0x85)
#define TCNT1 (*(volatile unsigned int *) 0x84) // мое творчествоесли рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Я бы приводил к uint не результат сдвига, а TCNT1H:kote52 писал(а):TCNT1 = TCNT1L; //младший
TCNT1 |= (unsigned int) TCNT1H<<8; //потом старший
Код: Выделить всё
TCNT1 |= ( (unsigned int)TCNT1H ) << 8; - Сообщения: 120
- Зарегистрирован: Пт мар 19, 2021 08:58:45
[uquote="ARV",url="/forum/viewtopic.php?p=4079909#p4079909"]правильно должно быть так:[/uquote]
ну да unsigned char я дал маху)))
Код: Выделить всё
#define TCNT1L (*(volatile unsigned char *) 0x84)
#define TCNT1H (*(volatile unsigned char *) 0x85)
#define TCNT1 (*(volatile unsigned int *) 0x84) // мое творчествону да unsigned char я дал маху)))
- Сообщения: 1
- Зарегистрирован: Пт окт 29, 2021 16:42:55
Получается в CVAVR нет переменной TCNT1, а в Atmel Studio есть? Там можно напрямяю прочитать да? Без Hi и Low
я у себя эту проблему решил так:
взял конфигурационный файл применённого в данный момент камня и дописал.
работает до меги328 = до тех пор, пока адресное пространство периферии на адресное пространство ОЗУ не начнёт налезать...
дописывать несложно - там уже есть регистры с 16 битовым доступом - делаешь по аналогии.
взял конфигурационный файл применённого в данный момент камня и дописал.
работает до меги328 = до тех пор, пока адресное пространство периферии на адресное пространство ОЗУ не начнёт налезать...
дописывать несложно - там уже есть регистры с 16 битовым доступом - делаешь по аналогии.
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
как в данной среде указать исходную папку которая будет являться рабочим пространством чтобы в нее складывались все последующии новые проэкты автоматически при создании ?
Tell Me The Truth
- Сообщения: 430
- Зарегистрирован: Вс апр 18, 2021 15:43:55
Объявление переменной i в условии цикла for не поддерживается?
На такой код ругается...
На такой код ругается...
Код: Выделить всё
for(int i=0;i<3;i++){
}и у меня ругается
если прям локальный счётчик нужен, то напиши примерно так
{чар и;
фор (и=0;и<3;и++)
{тело цикла};
};
если прям локальный счётчик нужен, то напиши примерно так
{чар и;
фор (и=0;и<3;и++)
{тело цикла};
};
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Сообщения: 120
- Зарегистрирован: Пт мар 19, 2021 08:58:45
Котаны и котики, как посредством CVAVR и стандартной библиотеки alcd.h вывести свой символ созданный к примеру в LCDVision на экран LCD1602?






