Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн май 17, 2021 22:45:35
Встал на лапы
Зарегистрирован: Пт мар 19, 2021 08:58:45 Сообщений: 103
Рейтинг сообщения: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) бессмыслена по своей сути, она ничего не добавляет в константу - нули остались на всех позициях, не "затронутых" единицей . Так что второй оператор мог выглядеть и так:
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Вот табличка из даташита: Вроде написано что если эти биты "по-нулям", то таймер остановлен. Кстати... может таймер останавливается и высокий уровень на ноге зависает (т.е. импульсов нет, просто висит высокий уровень)? Это я думал, что если таймер остановлен, то должен быть низкий уровень. Атмега ведь может думать иначе
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
режим формирования ШИМ вы не выключили, поэтому тот факт, что счетчик таймера больше не считает, на все остальные его части никак не влияет. и, если в момент остановки формирователь ШИМ-а выдавал высокий уровень - с чего бы ему меняться? триггер потерял тактирование, но он сохраняет своё последнее состояние...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
я у себя эту проблему решил так: взял конфигурационный файл применённого в данный момент камня и дописал. работает до меги328 = до тех пор, пока адресное пространство периферии на адресное пространство ОЗУ не начнёт налезать... дописывать несложно - там уже есть регистры с 16 битовым доступом - делаешь по аналогии.
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
как в данной среде указать исходную папку которая будет являться рабочим пространством чтобы в нее складывались все последующии новые проэкты автоматически при создании ?
и у меня ругается если прям локальный счётчик нужен, то напиши примерно так {чар и; фор (и=0;и<3;и++) {тело цикла}; };
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 44
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения