Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн май 17, 2021 22:45:35
Встал на лапы
Зарегистрирован: Пт мар 19, 2021 08:58:45 Сообщений: 118
Рейтинг сообщения:0
Добрый весенний вечер! Нашёл в просторах интернета урок по меню для 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; } //----------
мой код перепевка, правда таймер немного не так настроил, мне так надо:
// 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);
Конкретно в битах я разбираться не стал, но чисто по логике разница очевидна. Первый оператор сбрасывает все биты, второй - формирует константу, устанавливающую единицы в PWM2, COM21, CTC2, остальные остаются нулями , потому что конструкция вида (0<<CS20) бессмыслена по своей сути, она ничего не добавляет в константу - нули остались на всех позициях, не "затронутых" единицей . Так что второй оператор мог выглядеть и так:
Вот табличка из даташита: Вроде написано что если эти биты "по-нулям", то таймер остановлен. Кстати... может таймер останавливается и высокий уровень на ноге зависает (т.е. импульсов нет, просто висит высокий уровень)? Это я думал, что если таймер остановлен, то должен быть низкий уровень. Атмега ведь может думать иначе
режим формирования ШИМ вы не выключили, поэтому тот факт, что счетчик таймера больше не считает, на все остальные его части никак не влияет. и, если в момент остановки формирователь ШИМ-а выдавал высокий уровень - с чего бы ему меняться? триггер потерял тактирование, но он сохраняет своё последнее состояние...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
я у себя эту проблему решил так: взял конфигурационный файл применённого в данный момент камня и дописал. работает до меги328 = до тех пор, пока адресное пространство периферии на адресное пространство ОЗУ не начнёт налезать... дописывать несложно - там уже есть регистры с 16 битовым доступом - делаешь по аналогии.
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
как в данной среде указать исходную папку которая будет являться рабочим пространством чтобы в нее складывались все последующии новые проэкты автоматически при создании ?
и у меня ругается если прям локальный счётчик нужен, то напиши примерно так {чар и; фор (и=0;и<3;и++) {тело цикла}; };
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения