Страница 1 из 1

Помогите сделать генератор частоты на AVR.

Добавлено: Вс ноя 10, 2013 00:12:11
Aмstroн
Здравствуйте .
В сети есть пример такого генератора.
И исходник там имеется ,
Спойлер

Код: Выделить всё

$crystal = 20000000
$regfile = "attiny2313.dat"
$hwstack = 32
$swstack = 8
$framesize = 32

Dim F As Byte , F_input As Byte , Clkpr_prescale As Byte
Dim Ocr1a_value As Word , Ocr0a_value As Byte
Dim Clock_prescale As Word , Timer0_prescale As Byte

Config Pinb.2 = Output
Config Pinb.3 = Output
Config Portd = Input
Portd = &HFF

F = 255

Do
F_input = Pind And &H1F 'check switch combination
If F <> F_input Then 'if changed,
F = F_input
Gosub Set_f 'set new frequency
End If
Loop

Set_f:
Stop Timer0
Stop Timer1
Timer0 = 0
Timer1 = 0
Ocr0a_value = Lookup(f , Ocr0a_table)
Ocr1a_value = Lookup(f , Ocr1a_table)
Clock_prescale = Lookup(f , Clock_prescale_table)
Timer0_prescale = Lookup(f , Timer0_prescale_table)
Clkpr_prescale = 0
While Clock_prescale > 1
Shift Clock_prescale , Right
Incr Clkpr_prescale
Wend
Clkpr = &B10000000
Clkpr = Clkpr_prescale
If F < 31 Then 'f <= table_entries #
If Ocr0a_value = 0 Then
Gosub Set_high_f
Else
Gosub Set_low_f
End If
Else
Set Portb.3
End If
Return

Set_high_f: '10MHz-5Hz
Decr Ocr1a_value
Compare1a = Ocr1a_value
Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1 'start Timer1
Return

Set_low_f: '2Hz-0.001Hz
Decr Ocr0a_value
Ocr0a = Ocr0a_value
If Timer0_prescale = 1 Then
Config Timer0 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1 'start Timer0
Else
Config Timer0 = Timer , Prescale = 8 , Compare A = Toggle , Clear Timer = 1 'start Timer0
End If
Decr Ocr1a_value
Compare1a = Ocr1a_value
Config Timer1 = Counter , Edge = Falling , Compare A = Toggle , Clear Timer = 1 'start Timer1
Return

'for $crystal = 20MHz & table_entry 0-19:
'f = 20000000 / (2*clock_prescale*(1+ocr1a_value))

'for $crystal = 20MHz & table_entry 20-30:
'f = 20000000 / (2*clock_prescale*(1+ocr1a_value)) / (2*Timer0_clock_prescale*(1+ocr0a_value))

Clock_prescale_table: '[1-256]
Data 1% '0: 10 MHz
Data 2% '1: 5 MHz
Data 1% '2: 2 MHz
Data 2% '3: 1 MHz
Data 4% '4: 500 kHz
Data 2% '5: 200 kHz
Data 4% '6: 100 kHz
Data 8% '7: 50 kHz
Data 4% '8: 20 kHz
Data 8% '9: 10 kHz
Data 16% '10: 5 kHz
Data 8% '11: 2 kHz
Data 16% '12: 1 kHz
Data 32% '13: 500 Hz
Data 16% '14: 200 Hz
Data 32% '15: 100 Hz
Data 64% '16: 50 Hz
Data 32% '17: 20 Hz
Data 64% '18: 10 Hz
Data 64% '19: 5 Hz
Data 32% '20: 2 Hz
Data 64% '21: 1 Hz
Data 128% '22: 0.5 Hz
Data 64% '23: 0.2 Hz
Data 128% '24: 0.1 Hz
Data 256% '25: 0.05 Hz
Data 128% '26: 0.02 Hz
Data 256% '27: 0.01 Hz
Data 64% '28: 0.005 Hz
Data 256% '29: 0.002 Hz*
Data 256% '30: 0.001 Hz*
Data 256% '31: stop

Ocr1a_table: '[1-65535], Ocr1a = Ocr1a_table_entry - 1
Data 1% '0: 10 MHz
Data 1% '1: 5 MHz
Data 5% '2: 2 MHz
Data 5% '3: 1 MHz
Data 5% '4: 500 kHz
Data 25% '5: 200 kHz
Data 25% '6: 100 kHz
Data 25% '7: 50 kHz
Data 125% '8: 20 kHz
Data 125% '9: 10 kHz
Data 125% '10: 5 kHz
Data 625% '11: 2 kHz
Data 625% '12: 1 kHz
Data 625% '13: 500 Hz
Data 3125% '14: 200 Hz
Data 3125% '15: 100 Hz
Data 3125% '16: 50 Hz
Data 15625% '17: 20 Hz
Data 15625% '18: 10 Hz
Data 31250% '19: 5 Hz
Data 625% '20: 2 Hz
Data 625% '21: 1 Hz
Data 625% '22: 0.5 Hz
Data 3125% '23: 0.2 Hz
Data 3125% '24: 0.1 Hz
Data 3125% '25: 0.05 Hz
Data 15625% '26: 0.02 Hz
Data 15625% '27: 0.01 Hz
Data 15625% '28: 0.005 Hz
Data 5731% '29: 0.002 Hz*
Data 11462% '30: 0.001 Hz*
Data 0% '31: stop

Ocr0a_table: '[1-255, 0=not used], Ocr0a = Ocr0a_table_entry - 1
Data 0 '0: 10 MHz
Data 0 '1: 5 MHz
Data 0 '2: 2 MHz
Data 0 '3: 1 MHz
Data 0 '4: 500 kHz
Data 0 '5: 200 kHz
Data 0 '6: 100 kHz
Data 0 '7: 50 kHz
Data 0 '8: 20 kHz
Data 0 '9: 10 kHz
Data 0 '10: 5 kHz
Data 0 '11: 2 kHz
Data 0 '12: 1 kHz
Data 0 '13: 500 Hz
Data 0 '14: 200 Hz
Data 0 '15: 100 Hz
Data 0 '16: 50 Hz
Data 0 '17: 20 Hz
Data 0 '18: 10 Hz
Data 0 '19: 5 Hz
Data 125 '20: 2 Hz
Data 125 '21: 1 Hz
Data 125 '22: 0.5 Hz
Data 125 '23: 0.2 Hz
Data 125 '24: 0.1 Hz
Data 125 '25: 0.05 Hz
Data 125 '26: 0.02 Hz
Data 125 '27: 0.01 Hz
Data 125 '28: 0.005 Hz
Data 213 '29: 0.002 Hz*
Data 213 '30: 0.001 Hz*
Data 0 '31: stop

Timer0_prescale_table: '[1-8-64-256-1024, 0=not used]
Data 0 '0: 10 MHz
Data 0 '1: 5 MHz
Data 0 '2: 2 MHz
Data 0 '3: 1 MHz
Data 0 '4: 500 kHz
Data 0 '5: 200 kHz
Data 0 '6: 100 kHz
Data 0 '7: 50 kHz
Data 0 '8: 20 kHz
Data 0 '9: 10 kHz
Data 0 '10: 5 kHz
Data 0 '11: 2 kHz
Data 0 '12: 1 kHz
Data 0 '13: 500 Hz
Data 0 '14: 200 Hz
Data 0 '15: 100 Hz
Data 0 '16: 50 Hz
Data 0 '17: 20 Hz
Data 0 '18: 10 Hz
Data 0 '19: 5 Hz
Data 1 '20: 2 Hz
Data 1 '21: 1 Hz
Data 1 '22: 0.5 Hz
Data 1 '23: 0.2 Hz
Data 1 '24: 0.1 Hz
Data 1 '25: 0.05 Hz
Data 1 '26: 0.02 Hz
Data 1 '27: 0.01 Hz
Data 8 '28: 0.005 Hz
Data 8 '29: 0.002 Hz*
Data 8 '30: 0.001 Hz*
Data 0 '31: stop
но он на Bascom-AVR, а я только чуть юзаю CodeVisionAVR .
Пожалуйста помогите реализовать подобное на CodeVisionAVR .

Re: Помогите сделать генератор частоты на AVR.

Добавлено: Вс ноя 10, 2013 00:23:28
ANALOG
Так там ведь готовые хексы уже есть в архиве в статье - один скомпилен для 20 МГц, другой - для 8 МГц. Проивайте какой вам надо и все будет работать :)
Или я не так понял? Цель сборки устройства - получить устройство или это в качестве учебного примера делается?

Re: Помогите сделать генератор частоты на AVR.

Добавлено: Вс ноя 10, 2013 01:06:30
Aмstroн
Цель сделать это же, но на меге8. (это конечно если будет свой код для CodeVisionAVR).
Совсем не пойму, как это там задействован OCR1A + Timer0.

Re: Помогите сделать генератор частоты на AVR.

Добавлено: Вс ноя 10, 2013 15:16:09
uk8amk
Настраиваете таймер на CTC top = OCR1A.
Изменением значений предделителя счётчика и OCR1A будет меняться период выходного сигнала.

Upd.
Сетка частот будет иметь нерегулярный шаг из-за изменения коэф-та деления.
Чтобы получить сетку частот с одинаковым шагом, используют алгоритмы прямого цифрового синтеза( DDS ).

Re: Помогите сделать генератор частоты на AVR.

Добавлено: Вс ноя 10, 2013 17:14:43
Aмstroн
Пробовал , все организовать только на OCR1A
Вот таким образом

Код: Выделить всё

/*****************************************************
Chip type           : ATmega8
Program type        : Application
Clock frequency     : 8,000000 MHz
*****************************************************/
#include <mega8.h>
#include <delay.h>
#asm
   .equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <stdio.h>
#define Fclk      8000000.000
#define ReZ          64.000                 // предделитель таймера T1. Если предделитель равен 64,
unsigned char lcd_buffer[33];                           
unsigned int COUNT=4;   // 0...65535
float temp;
float ReZ1;

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here


}

void main(void)
{
// Declare your local variables here
                   PORTB=0b00000000;
                    DDRB=0b00000111;
                  PORTC=0b10111000;                                  
                    DDRC=0b00000000;
                  PORTD=0b00000000;                                   // 
                    DDRD=0b00000000;
// Timer/Counter 0 initialization

TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Toggle
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x40;
TCCR1B=0x0B;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
lcd_init(16);
#asm("sei")


while (1)
  {
                if (PINC.3==0  ) {          //
               COUNT++;               //Установка шага частоты
                 delay_ms(15);
                };   
                if (PINC.4==0  ) {         
               COUNT= COUNT+100;            
                 delay_ms(15);
                };
                if (PINC.5==0  ) {        
               COUNT--;           
                 delay_ms(15);
                };

        ReZ1 = (float)(2*ReZ*COUNT);
        temp = (float)((Fclk/ReZ1)-1);       
        OCR1A = temp;
                                           lcd_gotoxy(0,0);
                                           sprintf(lcd_buffer, "freq.= %uHz    ", COUNT);
                                           lcd_puts(lcd_buffer);                              
  };
}
Результат мне какой-то слабенький получается, до 20кГц , дальше "вода" ....

А та схема что в моем первом посте , проверял , реально выдает частоту от 1 гц до 10 мГц,
Вроде тот код "баскомский" и подсказку дает как оно там сделано, но я не могу увязать его в нужное русло. так сказать, пока это неразрешимая головоломка для меня.

Re: Помогите сделать генератор частоты на AVR.

Добавлено: Вс ноя 10, 2013 18:09:31
uk8amk
Не знаю что вы там намудрили, но этот код в симуляторе работает исправно.