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

STM32F407IG6 и Keil

Здраствуйте. Уважаемые форумчане, начинаю пробовать MCU STM32F407IG6 для этого скачал и установил Keil MDK-ARM ver. 4.53 с ограничением кода в 32 кБ. При создании нового проекта (new uVision project) keil предлагает подтянуть файл startup_stm32f4xx.s который в свою очередь ссылается на system_stm32f4xx.c. В файле system_stm32f4xx.c содержится инициализация HSE и PLL. После запуска отладки при входе в функцию main сразу происходит вход в system_stm32f4xx.c и соответсвенно инициализация HSE и PLL. После этого уже не представляется возможным произвести переинициализацию HSE и PLL по своему усмотрению (Поскольку HSE задействован как SYSCLK и бит HSE_ON сбросить нельзя). Если не подключать к проекту файл startup_stm32f4xx.s то keil ругается следующим образом:

main.axf: Error: L6320W: Ignoring --entry command. Cannot find argument 'Reset_Handler'.

main.axf: Warning: L6320W: Ignoring --first command. Cannot find argument '__Vectors'.

Итак вопрос: поскольку я только начинаю пробовать STM32F407IG6 как мне произвести инициализацию системы тактирования. Т.е. я сперва хочу использовать только HSE - внешний кварц частотой 25 МГц, без PLL, затем в другом проекте или в этом же задействовать PLL и сконфигурировать его по своему усмотрению.

Поделиться сообщением


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

Я так понимаю, сзади вас стоит мужик с наганом и не дает отказаться от стартапа. А при попытке поправить эти текстовые файлы под свои нужды - кидает гранату?

Поделиться сообщением


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

.s лучше не трогать, там ничего править не нужно.

Лучше скопируйте system_stm32f4xx.c к себе в папку с прочими исходниками, да и поправьте под свои нужды.

У семейства f1xx можно было дефайнами выбрать разные варианты инициализации, видимо для f4xx это сложнее сделать, индусы не осилили :).

 

Поделиться сообщением


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

Поскольку HSE задействован как SYSCLK и бит HSE_ON сбросить нельзя

А разве нельзя "перезадействовать" HSI как SYSCLK, а потом уже и с PLL развлекаться?

Поделиться сообщением


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

Если не подключать к проекту файл startup_stm32f4xx.s то keil ругается следующим образом:

main.axf: Error: L6320W: Ignoring --entry command. Cannot find argument 'Reset_Handler'.

main.axf: Warning: L6320W: Ignoring --first command. Cannot find argument '__Vectors'.

Итак вопрос: поскольку я только начинаю пробовать STM32F407IG6 как мне произвести инициализацию системы тактирования. Т.е. я сперва хочу использовать только HSE - внешний кварц частотой 25 МГц, без PLL, затем в другом проекте или в этом же задействовать PLL и сконфигурировать его по своему усмотрению.

Как уже ответили коллеги, не стОит отказываться от уже вылизанного startup*.s, который делает не что иное, как создает таблицу векторов, а самое главное - заполняет первые два слова начальным значением стека и стартовым адресом. Упомянутая ругня компоновщика об этом и говорит, как только startup*.s был выведен из проекта.

 

Писать программы можно как угодно, но просто разумнее придерживаться стандартов. Например, CMSIS, который и описывает, как рекомендуется построить по крайней мере начальный код, чтобы добраться до main(). Если хочется сделать все своими руками, напишите свою функцию

 

void Reset_Handler(void)

 

и на нее будет передано управление сразу же после старта процессора (почему - смотрите, что такое слабое определение WEAK).

Хотите остаться в рамках стандарта, но переопределить тактирование - прислушатесь к тому, что SSerge ответил.

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

Поделиться сообщением


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

Не вижу в чем проблема.

Для F4 серии ST выложил специальный инструмент - эксель файл, который генерит system_stm32f4xx.c для любой частоты автоматически по указанным вами параметрам. Для работы с ним разрешите макросы в вашем экселе. Сгенерите необходимую вам частоту, скопируйте оттуда и разбирайтесь, если нужно менять частоту в программе. ИМХО, с примерами разбираться гораздо проще. Или сразу создайте файл который вам нужен и подцепите его в проект.

Ссылка, смотрите AN3988

 

Поделиться сообщением


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

Для F4 серии ST выложил специальный инструмент - эксель файл,
Если бы ST еще догадался эксель для этого файла выложить...

Там работы на два часа - прочитать описание PLL в руководстве пользователя и прямо по этому руководству прописать десяток регистров. Заодно будет понимание - как оно работает и как, в случае необходимости, перенастроить на лету. Что все носятся с этими стартапами как со священной коровой? Файл-то элементарный.

 

Поделиться сообщением


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

Большое спасибо всем за рекомендации.

Я продолжаю пробовать STM407IG6, а в частности на данный момент остановился на таймере Basic Timer TIM7, данный таймер имеет генерацию прерываний по переполнению. Я создал файл stm32f4xx_it.c в котором описал обработчик прерывания:

void TIM7_IRQHandler (void)
{
    unsigned int flag=0;
    if (flag==0) 
        flag=1;
};

В функции main я разрешил тактирование TIM7, разрешил update interrupt, разрешил счет, в регистре TIM7->ARR=0xFFFF. Но в обработчик прерывания по переполнению я не попадаю. Я предполагаю, что возможно нужно разрешить глобально все прерывания, но в многочисленной документации не нашел как это сделать.

Поделиться сообщением


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

Большое спасибо всем за рекомендации.

В функции main я разрешил тактирование TIM7, разрешил update interrupt, разрешил счет, в регистре TIM7->ARR=0xFFFF. Но в обработчик прерывания по переполнению я не попадаю. Я предполагаю, что возможно нужно разрешить глобально все прерывания, но в многочисленной документации не нашел как это сделать.

Еще надо разрешить прерывание в NVIC:

 

NVIC_EnableIRQ (TIM7_IRQn);

 

Опционально:

NVIC_SetPriority (TIM7_IRQn, myTIM7Priority);

 

То есть, четыре пункта:

- правильное имя обработчика прерывания (свериться с startup файлом)

- разрешение соответствующих прерываний в самом устройстве TIM7

- разрешение прерывания по вектору в NVIC

- глобальное разрешение прерывания

 

P.S. только заметил в твоем коде:

 

void TIM7_IRQHandler (void)
{
    unsigned int flag=0;
    if (flag==0)
        flag=1;
};

 

Переменная flag - локальная, не "видна" снаружи и исчезнет с выходом из прерывания. Уж если, то правильней:

 

static unsigned int flag = 0;
void TIM7_IRQHandler (void)
{...

 

если она должна быть видна лишь в рамках текущего модуля (файла *.c),

 

либо:

volatile unsigned int flag = 0;
void TIM7_IRQHandler (void)
{...

 

и соответственно

 

extern volatile unsigned int flag;

 

в заголовочном файле, предоставляемом другим модулям.

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

Поделиться сообщением


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

Спасибо, разобрался.

На данный момент пробую периферийный модуль USART3. Привожу пример кода:

int main (void) {                    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);    //Разрешаем тактирование порта G
    GPIOG->MODER|=GPIO_MODER_MODER6_0;                                        //PG6 output mode
    GPIO_WriteBit(GPIOG, GPIO_Pin_6, Bit_SET);                        //Зажигаем PG6
    /****************************Инициализаций USART***************************/
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);            //Разрешаем тактирование USART3
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);                //Разрешаем тактирование порта С
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);    //Выбираем альтернативную функцию для USART3 TX PC10
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3);    //Выбираем альтернативную функцию для USART3 RX PC11    
    USART3->BRR=25000000/153600;                    //Скорость передачи
    USART3->CR2|=USART_CR2_STOP_1;                //2 Стоп-бита
    USART3->CR1|=USART_CR1_RE | USART_CR1_TE | USART_CR1_UE;
    while(1){
        USART3->DR=170;
        while((USART3->SR&USART_SR_TXE)==0){};
            USART3->SR&=~USART_SR_TC;
};
}

Проблема заключается в следующем: смотрю в отладчике значение регистра USART3->DR, данное значение всегда=0 и на ножке USART3 tx всегда единица, т.е. передачи нет.

 

И еще вопрос по поводу отладчика в Keil когда я ставлю точку останова в прерывании от TIM7 после строки i1=TIM7->CNT; То значение i1 в окне Watch1 i1=0; а значение TIM->CNT в View->System Viewer -> TIM7 совершенно произвольное - не совсем понятно с чем это связанно.

Поделиться сообщением


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

int main (void) {                    
    while(1){
        USART3->DR=170;
        while((USART3->SR&USART_SR_TXE)==0){};
            USART3->SR&=~USART_SR_TC;
};
}

По идее очистка флага TC в данном случае не обязательна, т.к выполняется последовательность чтения из SR и записи в DR. В этом случае TC сбрасывается сам. Учтите, что TXE показывает состояние DR, а не завершение передачи. Вообще правильно ли настроена скорость UART'а?

 

Проблема заключается в следующем: смотрю в отладчике значение регистра USART3->DR, данное значение всегда=0 и на ножке USART3 tx всегда единица, т.е. передачи нет.

Ножку tx чем смотрите? Осциллографом надеюсь?

И еще вопрос по поводу отладчика в Keil когда я ставлю точку останова в прерывании от TIM7 после строки i1=TIM7->CNT; То значение i1 в окне Watch1 i1=0; а значение TIM->CNT в View->System Viewer -> TIM7 совершенно произвольное - не совсем понятно с чем это связанно.

Оно не произвольное, просто когда вы останавливаетесь на любой строчке кода в отладке, переферия продолжает работать, приостанавливается только выполнение кода. Соответственно таймер продолжает считать. Да и все окна в keil'e (local, watch, memory.....) обновляются с периодом ~1 сек. По это и получаются разные значения в CNT. Кстати по этой же причине можете и не увидеть дерганье ножкой TX через отладчик.

 

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

Поделиться сообщением


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

Сейчас поправил:

USART3->BRR=0x0A2C; //9600

 

while(1){

USART3->DR=170;

while((USART3->SR&USART_SR_TC)==0){};

USART3->SR&=~USART_SR_TC;

};

Но изменений никаких нет. На ТХ постоянно единица.

Ножку tx чем смотрите? Осциллографом надеюсь?

Ножку TX смотрю осциллографом.

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

Поделиться сообщением


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

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

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

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

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

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

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

×
×
  • Создать...