Перейти к содержанию

Deicide

Members
  • Постов

    3
  • Зарегистрирован

  • Посещение

Весь контент Deicide

  1. ARV приветствую, шаг не предусмотрел, максимальная частота 100кГц. Чем ниже значение регистра OCR, тем лучше. Перестройка устраивает, вопрос по программной части, а именно не понимание, как выводить частоту на жк, а не посчитанное по формуле значение OCR. Да и в коде ошибка где функция wave_adj(), конечно же temp, а не freq увеличивается/уменьшается.
  2. Здравствуйте. Потребовался генератор прямоугольных импульсов (меандра) с регулировкой частоты в диапазоне от 1Гц до 100кГц (T = 1s...10us) задание частоты и вывод на дисплей 16х2. Регулировка осуществляется кнопками. В общем для этой цели использую режим CTC (Clear-To-Compare) таймер 1 (16 бит, 65535 тактов) при частоте ядра 8МГц и при двух установочных коэффициентах деления (1:1) и (1:256) можно варьировать в данном диапазоне. Вопрос состоит в следующем: как перейти из значения регистра OCR1A к частоте сигнала? На данном этапе хотелось бы видеть реальную частоту на жки + как-то переключаться между коэффициентами деления (switch?), функция (set_freq()). В общем прошу помочь программно и отнестись с пониманием. Программирование со скрипом идёт. Код прилагаю. Спасибо. #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <stdlib.h> #include <stdio.h> #include "main.h" #include "lcd.h" #define F_CPU 8000000UL char lcd_buffer[16]; float freq = 1000000; // max desired freq (Hz) unsigned int prescaler = 1; // divider unsigned int temp; void tc1_init() { TCCR1A |= (1<<COM1A0) | (1<<COM1B0); // toggle OC1A on compare match TCCR1B |= (1<<WGM12) | (1<<CS10); // clk/1 TIMSK |= (1<<TOIE1); // enable interrupt overflow TCNT1 = 0; // init counter } void io_init() { DDRB = 0x00; // PB input buttons DDRD = 0x20; // PD5 output gen } void set_freq() { temp = (F_CPU/(2*prescaler*freq)-1); OCR1A = temp; } // if (..) // // switch (prescaler) // { // case 1: TCCR1B |= (1<<WGM12) | (1<<CS10); break; // 1:1 // case 256: TCCR1B |= (1<<WGM12) | (1<<CS12); break; // 1:256 // } void wave_adj() // frequency adjusting { if(~PINB & (1<<0)) // PB0 log 0 increase freq { freq +=10; _delay_ms(250); } if(~PINB & (1<<1)) // PB1 log 0 decrease freq { freq -=10; _delay_ms(250); } } ISR(TIMER1_OVF_vect) { PORTD ^= (1<<5); // toggle log level } int main(void) { port_init(); io_init(); tc1_init(); lcd_init(); lcd_load(); lcd_clear(); set_freq(); sei(); // enable global interrupts while (1) { set_pos(0,0); string_lcd("SETTING FREQ = "); set_pos(0,1); sprintf(lcd_buffer, "= %u Hz", temp); string_lcd(lcd_buffer); wave_adj(); } }
  3. Потребовался генератор прямоугольных импульсов (меандра) с регулировкой частоты в диапазоне от 1Гц до 100кГц (T = 1s...10us) задание частоты и вывод на дисплей 16х2. Регулировка осуществляется кнопками. В общем для этой цели использую режим CTC (Clear-To-Compare) таймер 1 (16 бит, 65535 тактов) при частоте ядра 8МГц и при двух установочных коэффициентах деления (1:1) и (1:256) можно варьировать в данном диапазоне. Вопрос состоит в следующем: как перейти из значения регистра OCR1A к частоте сигнала? На данном этапе хотелось бы видеть реальную частоту на жки + как-то переключаться между коэффициентами деления (switch?), функция (set_freq()). В общем прошу помочь и отнестись с пониманием). Программирование со скрипом идёт. Код прилагаю. Спасибо. #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <stdlib.h> #include <stdio.h> #include "main.h" #include "lcd.h" #define F_CPU 8000000UL char lcd_buffer[16]; // массив для вывода на жк unsigned int freq = 50000; // значение частоты unsigned int prescaler; // делитель void tc1_init() { TCCR1A |= (1<<COM1A0) | (1<<COM1B0); // переключение OC1A TIMSK |= (1<<TOIE1); // разрешить прерывание по переполнению TCNT1 = 0; // инициализация счётчика } void io_init() { DDRB = 0x00; // кнопки на PB с внешней подтяжкой DDRD = 0x20; // генерация сигнала на PD5 } void set_freq() // настройка частоты { freq = (F_CPU/(2*prescaler*freq))-1; OCR1A = freq; if (..) switch (prescaler) { case 1: TCCR1B |= (1<<WGM12) | (1<<CS10); break; // 1:1 case 256: TCCR1B |= (1<<WGM12) | (1<<CS12); break; // 1:256 } } void wave_adj() // регулировка частоты { if(~PINB & (1<<0)) // PB0 log 0 уменьшение частоты { freq +=10; _delay_ms(250); //if (temp >= 65534) temp = 20000; } if(~PINB & (1<<1)) // PB1 log 0 увеличение частоты { freq -=10; _delay_ms(250); //if (temp == 0) temp = 20000; } } ISR(TIMER1_OVF_vect) { PORTD ^= (1<<5); // переключение логического уровня } int main(void) { port_init(); io_init(); tc1_init(); lcd_init(); // инициализация жки lcd_load(); // полоса загрузки black-bar lcd_clear(); // очистка экрана set_freq(); sei(); // разрешить прерывание глобально while (1) { set_pos(0,0); string_lcd("SETTING FREQ = "); set_pos(0,1); sprintf(lcd_buffer, "= %u Hz", freq); string_lcd(lcd_buffer); wave_adj(); } }
×
×
  • Создать...