|
Как выделить область памяти? |
|
|
|
May 17 2011, 04:42
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 8-02-11
Пользователь №: 62 788

|
Как выделить область памяти во flash,чтобы компилятор не занимал ее и чтобы во время работы контроллера была возможность записи на нее?
--------------------
Глупых вопросов не бывает, бывают глупые ответы!
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 18)
|
May 17 2011, 05:49
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 8-02-11
Пользователь №: 62 788

|
AT32UC3B0256, AVR32Studio, C ?
И еще такой вопрос, чтобы на ассемблере писать для этого контроллера в какой среде программирования лучше всего?
--------------------
Глупых вопросов не бывает, бывают глупые ответы!
|
|
|
|
|
May 17 2011, 09:41
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 8-02-11
Пользователь №: 62 788

|
А как-нибудь в программе контроллера это реализовать нельзя?
--------------------
Глупых вопросов не бывает, бывают глупые ответы!
|
|
|
|
|
May 18 2011, 02:14
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 8-02-11
Пользователь №: 62 788

|
Выделить, т.е. задать некоторое количество ячеек памяти во flash так,чтобы потом при выполнении программы контроллера можно было попрограммой записать в эти ячейки данные.
--------------------
Глупых вопросов не бывает, бывают глупые ответы!
|
|
|
|
|
May 18 2011, 05:19
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 8-02-11
Пользователь №: 62 788

|
Цитата(dinar21 @ May 18 2011, 05:14)  Выделить, т.е. задать некоторое количество ячеек памяти во flash так,чтобы потом при выполнении программы контроллера можно было попрограммой записать в эти ячейки данные. Нашел для этого Flash User Page. Осталось разобраться как в него записывать и как обращаться. Ни у кого нет примера раоты с пользовательской страницей ( Flash User Page) ???
--------------------
Глупых вопросов не бывает, бывают глупые ответы!
|
|
|
|
|
May 18 2011, 06:54
|
Группа: Участник
Сообщений: 12
Регистрация: 17-03-11
Пользователь №: 63 666

|
Как раз недавно писал кое-что в user page. Сам наковырял что смог из примеров. На идельность не претендую, но если надо могу выложить код.
|
|
|
|
|
May 18 2011, 08:38
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 8-02-11
Пользователь №: 62 788

|
Цитата(Storejet @ May 18 2011, 09:54)  Как раз недавно писал кое-что в user page. Сам наковырял что смог из примеров. На идельность не претендую, но если надо могу выложить код. Буду благодарен
--------------------
Глупых вопросов не бывает, бывают глупые ответы!
|
|
|
|
|
May 18 2011, 09:51
|
Группа: Участник
Сообщений: 12
Регистрация: 17-03-11
Пользователь №: 63 666

|
для начала создаем структуру, которая будет размещаться во flash памяти. Я привожу кусок из свое программы, а вообще структура может быть любая. typedef const struct { char Part_number[32];// шифр прибора (ASCII) char Mnem[4];//мнемоника прибора (ASCII) char Add_Mnem[4];// дополнительная мнемоника (ASCII) char Making_Year[4]; //календарный год изготовления прибора (ASCII) char Defis_1; //Дефис (ASCII) char Making_Month[2]; //календарный месяц изготовления прибора (ASCII) char Defis_2; //Дефис (ASCII) char Making_Day[2];//календарный день изготовления прибора(ASCII) U8 UIN_Number[2];//Уникальный нмер прибора (HEX) U8 Sch_Version; //Схемотехническая верся контроллера (HEX) U8 Soft_Version; //Программная версия контроллера (HEX) U8 Calibr_Size[4]; //Размер калибровочной записи (HEX) char Calibr_Name[12]; // Имя калибровочной записи (ASCII) U8 BLK_Size[4]; // Длина BUF, байт (HEX) U8 TTO[2]; //TTO , ms (HEX) U8 FRAM_Size[4]; //длина FRAM, байт (HEX) U8 SRAM_Size[4]; //Длина SRAM, байт (HEX U8 Reserved[44]; //Резерв } nvram_data_t;
//Размещаем структуру идентификатора () в пользовательской странице Flash памяти __attribute__((__section__(".userpage"))) //".userpage" static nvram_data_t user_nvram_data; ;
Далее для работы с данными из flash памяти объявляю указатель nvram_data_t *user_page=&user_nvram_data; // объявляем указатель
Вот некоторые константы, которые будут прописываться в пользовательскую страницу
const char Part_number[32]={'x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'};// шифр прибора (ASCII) const char Mnem[4]={'B','K','3','5'};//мнемоника прибора (ASCII) const char Add_Mnem[4]={' ',' ',' ',' '};// дополнительная мнемоника (ASCII) const char Making_Year[4]={'2','0','1','1'}; //календарный год изготовления прибора (ASCII)
Функция, которая пропишет константы в пользовательскую страницу:
void ID_write_init (void){ //Смотрим, записано ли что нибудь в пользовательской странице Flash (она будет пуста в новом контроллере) if (flashc_quick_user_page_read()){ //Записываем во Flash изначальные данные //Записываем новые данные во flash flashc_memcpy((void*)&user_page->Part_number,&Part_number,sizeof(user_page->Part_number),TRUE); flashc_memcpy((void*)&user_page->Mnem,&Mnem,sizeof(user_page->Mnem),TRUE); flashc_memcpy((void*)&user_page->Add_Mnem,&Add_Mnem,sizeof(user_page->Add_Mnem),TRUE); flashc_memcpy((void*)&user_page->Making_Year,&Making_Year,sizeof(user_page->Making_Year),TRUE); }
Если нужно обратиться к данным, размещенным нами в памяти, делаем так: usart_putchar(USART_ADDR, user_page->Part_number[0]); usart_putchar(USART_ADDR, user_page->Part_number[1]); ну и так далее
Если что-то не понятно или неправильно, пишите...
|
|
|
|
|
May 19 2011, 02:55
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 8-02-11
Пользователь №: 62 788

|
Цитата(Storejet @ May 18 2011, 12:51)  U8 UIN_Number[2];//Уникальный нмер прибора (HEX) U8 Sch_Version; //Схемотехническая верся контроллера (HEX) U8 Soft_Version; //Программная версия контроллера (HEX) U8 Calibr_Size[4]; //Размер калибровочной записи (HEX) U8 TTO[2]; //TTO , ms (HEX) U8 FRAM_Size[4]; //длина FRAM, байт (HEX) U8 SRAM_Size[4]; //Длина SRAM, байт (HEX U8 Reserved[44]; //Резерв } nvram_data_t; Что значит U8 ?
--------------------
Глупых вопросов не бывает, бывают глупые ответы!
|
|
|
|
|
May 19 2011, 05:37
|
Группа: Участник
Сообщений: 12
Регистрация: 17-03-11
Пользователь №: 63 666

|
typedef unsigned char U8 -тип данных unsigned char, длина 8 бит
|
|
|
|
|
May 19 2011, 08:23
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 8-02-11
Пользователь №: 62 788

|
Цитата(Storejet @ May 19 2011, 08:37)  typedef unsigned char U8 -тип данных unsigned char, длина 8 бит Точно. Туплю. А нет примера программы прерывания от PWM ?
--------------------
Глупых вопросов не бывает, бывают глупые ответы!
|
|
|
|
|
May 19 2011, 09:36
|
Группа: Участник
Сообщений: 12
Регистрация: 17-03-11
Пользователь №: 63 666

|
Нет, а в чем там проблема? Приведитете код
|
|
|
|
|
May 19 2011, 10:35
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 8-02-11
Пользователь №: 62 788

|
Цитата(Storejet @ May 19 2011, 12:36)  Нет, а в чем там проблема? Приведитете код CODE #include <avr32/io.h> #include "compiler.h" #include "board.h" #include "intc.h" #include "power_clocks_lib.h" #include "gpio.h" #include "usart.h" #include "pwm.h" #include "pm.h"
# define EXAMPLE_PWM_PIN AVR32_PWM_0_0_PIN # define EXAMPLE_PWM_FUNCTION AVR32_PWM_0_0_FUNCTION # define EXAMPLE_PWM_CHANNEL_ID 0
# define EXAMPLE_GCLK_ID 0 # define EXAMPLE_GCLK_PIN AVR32_PM_GCLK_0_PIN # define EXAMPLE_GCLK_FUNCTION AVR32_PM_GCLK_0_FUNCTION
# define EXAMPLE_PWM (&AVR32_PWM) # define EXAMPLE_PWM_IRQ AVR32_PWM_IRQ
bool front; int shet;
/*! \ краткое USART обработчик прерывания. * * \ к сведению `__attribute__ ((__interrupt__)) '(под GNU GCC для AVR32) и * `__interrupt" (под IAR Embedded Workbench для Atmel AVR32) с функцией * атрибуты используются для управления `Rete 'инструкции. */ #if defined (__GNUC__) __attribute__((__interrupt__)) #elif defined(__ICCAVR32__) __interrupt #endif
static void pwm_int_handler(void) // п/п формирования пилы { if (front==true) // признак спадающего фронта {if (shet!=0x00000000) AVR32_GPIO.port[1].ovr = shet-- ; // уменьшаем с на 1 до тех пор пока оно не 0 else {front=false; AVR32_GPIO.port[1].ovr = shet; } } else // иначе признак возрастающего фронта {if (shet!=0x00000200) AVR32_GPIO.port[1].ovr = shet++ ; // увеличиваем с на 1 до тех пор пока оно не 512 else {front=true; AVR32_GPIO.port[1].ovr = shet; } } }
static void local_start_highfreq_clock(void) // п/п задания частоты процессора 60 МГц { volatile avr32_pm_t* pm = &AVR32_PM; /* \Примечание во всех расчетах предположить, что Osc0 частота 12 МГц. */
pm_switch_to_osc0(pm, FOSC0, OSC0_STARTUP); // переключение тактирования на Osc0.
/* Установка ФАПЧ0 на Osc0, Mul = 9, делитель на 1, lockcount = , то есть. 12Mhzx10 = 120MHz/2=60МГц выходной */
pm_pll_setup(pm, 0, // разрешение использования ФАПЧ0 9, // MUL=10 умножение частоты кварца на 10 1, // DIV=1 деление частоты на 1 0, // Выбираем Osc0/PLL0 или Osc1/PLL1 16); // lockcount in main clock for the PLL wait lock
/* Эта функция устанавливает опции ФАПЧ. *pm Base address of the Power Manager (i.e. &AVR32_PM) pll PLL number 0 pll_freq Set to 1 for VCO frequency range 80-180MHz, set to 0 for VCO frequency range 160-240Mhz. pll_div2 Divide the PLL output frequency by 2 (this settings does not change the FVCO value) pll_wbwdisable 1 Disable the Wide-Bandith Mode (Wide-Bandwith mode allow a faster startup time and out-of-lock time). 0 to enable the Wide-Bandith Mode. */ /* Выходная VCO частта ФАПЧ 120 MHz. Мы делим ее на 2 с pll_div2=1. Это позволяет разрешить дальше тактировать CPU на 60 MHz */ pm_pll_set_option(pm, 0, 1, 1, 0);
/* Enable PLL0 */ /* void pm_pll_enable(volatile avr32_pm_t* pm, unsigned int pll) { */ pm_pll_enable(pm,0);
/* Wait for PLL0 locked */ pm_wait_for_pll0_locked(pm) ;
/* Деление тактовой частоты PBA на 2 пурем деления тактовой частоты CPU (PBA clock = 60MHz/2 = 30 MHz). Pheripheral Bus A clock divisor enable = 1 Pheripheral Bus A select = 0 Pheripheral Bus B clock divisor enable = 0 Pheripheral Bus B select = 0 High Speed Bus clock divisor enable = 0 High Speed Bus select = 0 */ pm_cksel(pm, 1, 1, 0, 0, 0, 0);// тактирование внешней периферии от CPU / 4=60 Мгц/4=15МГц
pm_switch_to_clock(pm, AVR32_PM_MCSEL_PLL0); /* Переключение тактовой частоты процессора на 60 MHz */
}
static void local_enable_gclk_on_gpio(volatile avr32_pm_t* pm) { int gc = EXAMPLE_GCLK_ID;
/* установка на gc (вданном случае PA30) на прием от ФАПЧ и деление на 2^3=8 */ pm_gc_setup(pm, gc, 1, 0, 1, 3);
/* разрешение gc */ pm_gc_enable(pm,gc); /* Назначение gc на выход GPIO */ gpio_enable_module_pin(EXAMPLE_GCLK_PIN, EXAMPLE_GCLK_FUNCTION); // Note that gclk0_1 is GPIO pin 51 pb19 on AT32UC3A0512 QFP144. // Note that gclk2 is GPIO pin 30 pa30 on AT32UC3B0256 QFP64. // Note that gclk1 is GPIO pin 43 pb11 on AT32UC3A3256 QFP144. // Note that gclk1 is GPIO pin 6 pa06 on AT32UC3L064 pin 10 on QFP48. // Note that gclk0 is GPIO pin 54 pb22 on AT32UC3C0512C QFP144. }
int main(void) // основное тело программы { volatile avr32_pm_t* pm = &AVR32_PM;
// Настройка Osc0 в кристалле режиме (т.е. использование внешнего источника кристалла, с // частота FOSC0) с соответствующим время запуска затем переключиться Главные часы // источник Osc0. //pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP);
// Отключить все прерывания Disable_global_interrupt();
pwm_opt_t pwm_opt; // PWM option config. avr32_pwm_channel_t pwm_channel = { .ccnt = 0 }; // к. // номер канала и, например, используется в ряде функций. // Это определяется как локальная переменная для простоты использования. unsigned int channel_id;
channel_id = EXAMPLE_PWM_CHANNEL_ID; gpio_enable_module_pin(EXAMPLE_PWM_PIN, EXAMPLE_PWM_FUNCTION);
// конфигурация PWM controller . pwm_opt.diva = AVR32_PWM_DIVA_CLK_OFF; pwm_opt.divb = AVR32_PWM_DIVB_CLK_OFF; pwm_opt.prea = AVR32_PWM_PREA_MCK; pwm_opt.preb = AVR32_PWM_PREB_MCK;
pwm_init(&pwm_opt);
pwm_channel.CMR.calg = PWM_MODE_LEFT_ALIGNED; // режим канала. pwm_channel.CMR.cpol = PWM_POLARITY_LOW; // полярность канала. pwm_channel.CMR.cpd = PWM_UPDATE_DUTY; // не используется в начальное время. pwm_channel.CMR.cpre = AVR32_PWM_CPRE_MCK_DIV_32; // канальный предделитель. pwm_channel.cdty = 6; // рабочий цикл канала, должен быть < CPRD. pwm_channel.cprd = 12; // период канала. pwm_channel.cupd = 0; // обновление канала здесь не используется. // С такими настройками, период выходного сигнала будет : // (12000000/32)/12 == 31250 Hz ==32 мкс // prescaler == 32, period == 12.
// Инициализация векторов прерываний. INTC_init_interrupts(); // Регистрация USART обработчик прерывания на контроллер прерываний. // usart_int_handler является обработчик прерывания для регистров // EXAMPLE_USART_IRQ является IRQ из обработчика прерывания для регистров // AVR32_INTC_INT0 является прерывание уровень приоритета назначить группу // это IRQ. // недействительными INTC_register_interrupt (__int_handler обработчик, неподписанные IRQ Int, неподписанные int_level Int); INTC_register_interrupt(&pwm_int_handler, EXAMPLE_PWM_IRQ, AVR32_INTC_INT0);
// Включить USART Rx прерывания. EXAMPLE_PWM->ier = 1;
AVR32_GPIO.port[1].oders =0x000003FE; // Конфигурируем соответствующие ножки на выход AVR32_GPIO.port[1].gpers =0x000003FE; // Включаем эти ножки порта
/* Начало высокой тактовой частоте и переключаться Main Clock с этой высокой тактовой частоты */ local_start_highfreq_clock();
/* Настройка общих часы с высокой тактовой частотой и выхода его на GPIO PIN */ // local_start_gc(); local_enable_gclk_on_gpio(pm);// включение внешнего тактирования 7,5 МГц на ножку // Включить все прерывания. Enable_global_interrupt();
pwm_channel_init(channel_id, &pwm_channel); // Установить конфигурацию каналов 0.
pwm_start_channels(1 << channel_id); // стартовать канал 0.
// У нас ничего не осталось делать в основной, так что мы можем перейти к устройству сна // Режим работы: мы просто должны быть уверены, что модуль USART будет по-прежнему быть активным // в выбранном режиме ожидания. спящий режим для использования режима МЕРЗЛЫХ сна: // в этом режиме РВ часы все еще активны (так модуль USART который // на периферийных шин-прежнему будет активным в то время как процессор и HSB будет // остановлен). // - // Модули связи с внешними цепями, как правило, будет отключен // перед входом в спящий режим, который остановит работы модуля: это не // в случае режима сна заморожены. // - // Когда прерывания USART происходит, это будет после процессора до которой будет // выполнение кода обработчика прерывания затем вернуться к а (1) петли ниже // выполнить инструкции спать снова.
while(1) { // Если есть шанс, что любой PB операций записи являются неполными, процессор // должен выполнять операции чтения из любого зарегистрироваться на шины PB до // выполнение сна инструкции. // AVR32_INTC.ipr[0]; // Пустышка читать } }
Работать должно так: по прерываниям от PWM должно выдаваться параллельно число по ножкам PB1-PB9 с увеличением на 1. PWM работает на частоте 31250Гц(вывел на отдельную ножку PA7,смотрю по осциллографу) , т.е на ножке PB1 должен быть меандр с частотой в 2 раза меньше,а у меня порядка 90кГц и не зависит от PWM ( меняю частоту PWM, PB1 остается прежним). Не судите строго, я с С недавно разбераюсь, пытался из нескольких примеров скомпоновать. http://electronix.ru/forum/style_images/1/...icons/icon9.gif
--------------------
Глупых вопросов не бывает, бывают глупые ответы!
|
|
|
|
|
May 31 2011, 01:45
|
Частый гость
 
Группа: Свой
Сообщений: 157
Регистрация: 7-10-07
Из: Санкт-Петербург
Пользователь №: 31 137

|
Цитата(gotty @ May 18 2011, 09:50)  Выделить некоторый объём флешь, очень просто - объявите массив нужного размера с нужным выравниванием - вот вам и страница "для личный нужд". А резве в этом случае массив не в ОЗУ будет расположен? Если не прав, то как указать компоновщику, что данные должны располагаться именно в ОЗУ?
--------------------
Если работает через раз - значит не работает!
|
|
|
|
|
May 31 2011, 12:49
|
Местный
  
Группа: Свой
Сообщений: 437
Регистрация: 23-04-05
Из: Таганрог
Пользователь №: 4 425

|
Цитата(Maximm @ May 31 2011, 05:45)  А резве в этом случае массив не в ОЗУ будет расположен?
Если не прав, то как указать компоновщику, что данные должны располагаться именно в ОЗУ? В компоновщике нет понятий "ОЗУ" или "Flash". Компоновщик оперирует секциями, и размещает эти секции в памяти так, как указано в его скрипте (пусть даже в скрипте по-умолчанию, который в компоновщик вшит намертво). А данные в секции размещает компилятор. По-умолчанию в GCC данные попадают в секцию .DATA. Если данные надо разместить в другую секцию, то это делается специальными директивами, в общем случае разными для разных компиляторов.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|