Здравствуйте! Есть плата синтезатора частоты на основе HMC769. Загрузка и перестройка которого выполняется с контроллера Attiny 2313V. С горем пополам насобирал код для его прошивки (программирвоанием не занимался никогда поэтмоу код частично из готовых примеров, частично помогли умные люди частично написан самостоятельно, поэтому несколько кривоват). Также в нем неисключены ошибки.Codevisionavr говорит что нехватает памяти контроллера (2646 байт у нас и 2048 в контроллере ). Можно ли как-то оптимизировать код?
Микросхема синтезатора частоты HMC769. Которая должна по сигналу перестраиваться на несколько частот с определенным шагом (скажем от 9350МГц с шагом 10МГц значений на 40 или меньше). Сигналы будут приходить с внешнего устрйоства МЦФОС. В виде:
[0][8 битный код][1].
Код пока произвольный.
Задача контроллера загрузить HMC769 на начальную частоту (и начальные настройки путем записи числе в регистры указаные ниже). И после этого ждать сигнала от МЦФОС. А при получениии преобразовать этот сигнал в вид понятный ФАПЧу, что бы он перестороился на нужную частоту. После перестройки сообщить МЦФОСУ о том что все прошло успешно послав ему единичку. Получать сигналы от МЦФОС он будет по COM-порту (RS-232).
Более подробное описание задания и алгоритма работы в прекрепленном документе...
Раздел: AVR
Микросхема синтезатора частоты HMC769. Которая должна по сигналу перестраиваться на несколько частот с определенным шагом (скажем от 9350МГц с шагом 10МГц значений на 40 или меньше). Сигналы будут приходить с внешнего устрйоства МЦФОС. В виде:
[0][8 битный код][1].
Код пока произвольный.
Задача контроллера загрузить HMC769 на начальную частоту (и начальные настройки путем записи числе в регистры указаные ниже). И после этого ждать сигнала от МЦФОС. А при получениии преобразовать этот сигнал в вид понятный ФАПЧу, что бы он перестороился на нужную частоту. После перестройки сообщить МЦФОСУ о том что все прошло успешно послав ему единичку. Получать сигналы от МЦФОС он будет по COM-порту (RS-232).
/*****************************************************
This program was produced by the
CodeWizardAVR V2.04.0a Evaluation
Automatic Program Generator
© Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 20.11.2012
Author : Freeware, for evaluation and non-commercial use only
Company :
Comments:
Chip type : ATtiny2313V
AVR Core Clock frequency: 8,000000 MHz
Memory model : Tiny
External RAM size : 0
Data Stack size : 32
*****************************************************/
#include <tiny2313.h> // библиотека с описанием регистров микроконтроллера - сопоставлены имена типа PORTB и физические адреса
#include <delay.h> // функции задержки
#include <stdio.h> // printf scanf для работы с UART
// Для функции send_spi определяем на какие выводы какие сигналы идут
#define SPI_SCK PORTB.1
#define SPI_SDI PORTB.2
#define SPI_SEN PORTB.3
// вход сигнала готовности ФАПЧ
#define LOCK_DETECT PORTB.0
// задаем физические адреса регистров в микросхеме ФАПЧ
#define REG1 0x1
#define REG2 0x2
#define REG3 0x3
#define REG4 0x4
#define REG5 0x5
#define REG6 0x6
#define REG7 0x7
#define REG8 0x8
#define REG9 0x9
#define REGA 0xA
#define REGB 0xB
#define REGC 0xC
#define REGD 0xD
#define REGE 0xE
#define REGF 0xF
// массив с частотами. номер элемента в массиве соответствует номеру частоты.
long int ch;
long int freq[10] = {13981013,0,2796202, 0,0,0,0,0,0,0};
// функция для записи по spi 24 бит data по адресу addr
// при необходимости функцию подкорректировать при отладке.
void send_spi(unsigned char addr, long int data)
{
unsigned int i;
unsigned long int d = addr & 0x3f; // осталяем только 7 младших разряда адреса
d <<= 24; // сдвигаем адрес в нужное место в посылке получаем 0АААААААхххххххххххххххххххххххх
d |= data & 0x00ffffff; // оставляем 24 младших разряда данных и собираем посылку целиком
i=(unsigned int) (1<<30); // формируем маску для отправки посылки. маска содержит 1 единичку из 30 разрядов, которая будет продвигаться от старших к младшим
delay_ms(1); // delay
do // рисуем временную диаграмму
{
SPI_SCK = 0; // перепад clk
delay_us(10);
if ( d & i ) SPI_SDI = 1; else SPI_SDI = 0; // при помощи маски проверяем каждый разряд и отправляем соответственно 0 или 1
delay_us(10);
SPI_SCK = 1; // перепад clk
i=i>>1; // сдвигаем маску на один разряд
}
while(i);
SPI_SCK = 1; // CLK HI
delay_us(10); // delay
SPI_SEN = 0; // SS = LO
delay_us(10); // delay
SPI_SEN = 1;
SPI_SCK = 0;
}
int set_freq(unsigned char ch)
{
int num = 10;
int time = 100; // время, за которое частота должна гарантированно установиться
while(num--) // пробуем за num посылок записать частоту
{
int Fvco = 0;
Fvco = 60*(156 + ch);
if(Fvco >= 9360)
{
send_spi(REG3, 156);
}
else {send_spi(REG3, 155);}
send_spi(REG4, freq[ch]); // из массива выбираем частоту, соответствующую номеру ch
while(time--) // time раз ищем на входе единицу
{
delay_us(1); // смотрим с интервалом 1us
if (LOCK_DETECT) return 0; // если увидели, выходим из функции, говорим, что все успешно
}
}
return 1; // долго пытались, не получилось, сообщаем о неудаче
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here unsign 23:44:21
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_ //
#pragma optsize+
#endif
// Input/Output Ports initialization
// Port A initialization
// Func2=In Func1=In Func0=In
// State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=In
// State7=T State6=T State5=T State4=T State3=0 State2=0 State1=0 State0=T
PORTB=0x01;
DDRB=0x0F;
// Port D initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// 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=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=0x00;
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 56000
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x06;
UBRRH=0x00;
UBRRL=0x08;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
send_spi(REG2, 1);
send_spi(REG5, 5304781);
send_spi(REG6, 1019392);
send_spi(REG7, 3666);
send_spi(REGC, 0);
send_spi(REGF, 2);
// записываем начальную частоту
while (set_freq(0)) {}; // устанавливаем начальную частоту, пока у нас это не получится
// основная работа
while (1)
{
// Place your code here
scanf("%u",ch); // ждем пока нам пришлют по UART значение. пока значение не пришло, дальше не идем.
if (!set_freq(ch)) printf("%c",1) ; // пробуем выставить частоту за num попыток
else printf("%c",0); // отправляем по UART отчет о выполнении
}; // и еще раз...
}
Более подробное описание задания и алгоритма работы в прекрепленном документе...
Прикрепленные файлы:
Раздел: AVR