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

Attiny2313V, Перестраиваемый Синтезатор Частоты, Оптимизация Кода.


gadge

Рекомендуемые сообщения

Здравствуйте! Есть плата синтезатора частоты на основе HMC769. Загрузка и перестройка которого выполняется с контроллера Attiny 2313V. С горем пополам насобирал код для его прошивки (программирвоанием не занимался никогда поэтмоу код частично из готовых примеров, частично помогли умные люди частично написан самостоятельно, поэтому несколько кривоват). Также в нем неисключены ошибки.Codevisionavr говорит что нехватает памяти контроллера (2646 байт у нас и 2048 в контроллере ). Можно ли как-то оптимизировать код?

Микросхема синтезатора частоты 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 отчет о выполнении
}; // и еще раз...
}

Более подробное описание задания и алгоритма работы в прекрепленном документе...

фапч.rar

Изменено пользователем gadge
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

а stdio.h точно нужен? Места он занимает порядочно а если нужна всего пара функций, так их проще реализовать вручную

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

а stdio.h точно нужен? Места он занимает порядочно а если нужна всего пара функций, так их проще реализовать вручную

Спасибо за ответ. Он ведь функцию scanf содержит? Слабо представляю как реализовать ее вручную. =(( Да и одной этой меры маловато. освободит это вроде около 100 байт. как еще 500 освободить ума не приложу =((

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Не проще ли взять проц "получше", например, Mega8?

Явно ведь, захотите добавить ещё какой-то функционал.

sscanf - тяжёлая функция ... Попробуйте ultoa, только не знаю, есть ли она в CvAVR, не пользовался. Сами попробуйте написать этот перевод строки в число. Готовых реализаций полно. По-любому проще будет. Или гоняйте через UART двоичные данные, а переводами пусть комп занимается. А кто у Вас сидит по другую сторону кабеля?

Да и printf из той же породы ... Один байт писать можно командой типа UDR='0'; :)

И ещё. Ваш CvAVR

CodeWizardAVR V2.04.0a Evaluation

сам по себе может накладывать ограничения на размер кода. Хоть ATMega128 поставьте ...

Изменено пользователем hd44780
Ссылка на комментарий
Поделиться на другие сайты

Слабо представляю как реализовать ее [scanf] вручную.
Реализовать UART вручную проще простого, главное не накосячить со скоростью.
Не проще ли взять проц "получше", например, Mega8?
Давайте вообще компьютер поставим. Для такой задачи, что-то мне подсказывает, и ATtiny13 хватит если по мощности, правда ног может не хватить. А аппаратный SPI вроде есть почти у всех контроллеров AVR.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Да мне то что? Пусть что хочет ставит, что хочет ....

Я по себе знаю, что при отладке надо то дисплей прикрутить, то ещё что-то. Поэтому отлаживаться лучше на чём-то более мощном, даже если для конечной задачи это не нужно ...

Ссылка на комментарий
Поделиться на другие сайты

Прошу прощения за долгие паузы в ответах. не было доступа к интернету.

Не проще ли взять проц "получше", например, Mega8?

Наверно так сделать и придется... =( Вот только контроллер нужен в таком же корпусе и с такой же распиновкой как у Attiny2313... Так как ПП уже готова....

И использовать аппаратный интерфейс, вместо неуклюжей эмуляции на Си.

Не совсем вас понял... =(( Не могли бы пояснить?

P.S. А если воспользоваться другим компилятором например подогнать код под winavr может ли это помочь уменьшить размер полученной прошивки?

Ссылка на комментарий
Поделиться на другие сайты

само по себе использование другого компилятора вряд ли. Геннадий имел в виду что во многих контроллерах AVR есть модуль аппаратного SPI. Для его использования нужно написать минимум кода и не требует столько ресурсов процессора. Как именно его запустить - см.даташит.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Да, это я по send_spi "проехался". А теперь еще и scanf в основном цикле увидел. По вашим сообщениям понял, что слишком наворочено в этой ф-ии. С UART надо работать через аппаратный интерфейс, используя его (UART) прерывания. Проще будет.

Ссылка на комментарий
Поделиться на другие сайты

Ну прерывания не обязательно, достаточно использования самого модуля а не программную эмуляцию, все равно в несколько раз меньше кода будет да и скорость существенно возрастет. Если МК используется только для преобразования интерфейсов, выигрыша от использования прерываний почти не будет.

Изменено пользователем COKPOWEHEU

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...