Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F407IG6 и Keil
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
sidy
Здраствуйте. Уважаемые форумчане, начинаю пробовать 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 и сконфигурировать его по своему усмотрению.
DpInRock
Я так понимаю, сзади вас стоит мужик с наганом и не дает отказаться от стартапа. А при попытке поправить эти текстовые файлы под свои нужды - кидает гранату?
SSerge
.s лучше не трогать, там ничего править не нужно.
Лучше скопируйте system_stm32f4xx.c к себе в папку с прочими исходниками, да и поправьте под свои нужды.
У семейства f1xx можно было дефайнами выбрать разные варианты инициализации, видимо для f4xx это сложнее сделать, индусы не осилили sm.gif.
ViKo
Цитата(sidy @ Jul 5 2012, 17:39) *
Поскольку HSE задействован как SYSCLK и бит HSE_ON сбросить нельзя

А разве нельзя "перезадействовать" HSI как SYSCLK, а потом уже и с PLL развлекаться?
KnightIgor
Цитата(sidy @ Jul 5 2012, 16:39) *
Если не подключать к проекту файл 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 ответил.
topkin
Не вижу в чем проблема.
Для F4 серии ST выложил специальный инструмент - эксель файл, который генерит system_stm32f4xx.c для любой частоты автоматически по указанным вами параметрам. Для работы с ним разрешите макросы в вашем экселе. Сгенерите необходимую вам частоту, скопируйте оттуда и разбирайтесь, если нужно менять частоту в программе. ИМХО, с примерами разбираться гораздо проще. Или сразу создайте файл который вам нужен и подцепите его в проект.
Ссылка, смотрите AN3988
Сергей Борщ
QUOTE (topkin @ Jul 6 2012, 07:27) *
Для F4 серии ST выложил специальный инструмент - эксель файл,
Если бы ST еще догадался эксель для этого файла выложить...
Там работы на два часа - прочитать описание PLL в руководстве пользователя и прямо по этому руководству прописать десяток регистров. Заодно будет понимание - как оно работает и как, в случае необходимости, перенастроить на лету. Что все носятся с этими стартапами как со священной коровой? Файл-то элементарный.
sidy
Большое спасибо всем за рекомендации.
Я продолжаю пробовать 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. Но в обработчик прерывания по переполнению я не попадаю. Я предполагаю, что возможно нужно разрешить глобально все прерывания, но в многочисленной документации не нашел как это сделать.
KnightIgor
Цитата(sidy @ Jul 10 2012, 14:53) *
Большое спасибо всем за рекомендации.
В функции 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;


в заголовочном файле, предоставляемом другим модулям.
sidy
Спасибо, разобрался.
На данный момент пробую периферийный модуль 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 совершенно произвольное - не совсем понятно с чем это связанно.
sidy
Что интересно, бит USART_SR_TC устанавливается и очищается, но передачи нет. 05.gif
PoReX
Цитата(sidy @ Jul 13 2012, 16:32) *
Код
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'а?

Цитата(sidy @ Jul 13 2012, 16:32) *
Проблема заключается в следующем: смотрю в отладчике значение регистра USART3->DR, данное значение всегда=0 и на ножке USART3 tx всегда единица, т.е. передачи нет.

Ножку tx чем смотрите? Осциллографом надеюсь?
Цитата(sidy @ Jul 13 2012, 16:32) *
И еще вопрос по поводу отладчика в Keil когда я ставлю точку останова в прерывании от TIM7 после строки i1=TIM7->CNT; То значение i1 в окне Watch1 i1=0; а значение TIM->CNT в View->System Viewer -> TIM7 совершенно произвольное - не совсем понятно с чем это связанно.

Оно не произвольное, просто когда вы останавливаетесь на любой строчке кода в отладке, переферия продолжает работать, приостанавливается только выполнение кода. Соответственно таймер продолжает считать. Да и все окна в keil'e (local, watch, memory.....) обновляются с периодом ~1 сек. По это и получаются разные значения в CNT. Кстати по этой же причине можете и не увидеть дерганье ножкой TX через отладчик.
sidy
Сейчас поправил:
USART3->BRR=0x0A2C; //9600

while(1){
USART3->DR=170;
while((USART3->SR&USART_SR_TC)==0){};
USART3->SR&=~USART_SR_TC;
};
Но изменений никаких нет. На ТХ постоянно единица.
Цитата(PoReX @ Jul 17 2012, 10:51)
Ножку tx чем смотрите? Осциллографом надеюсь?

Ножку TX смотрю осциллографом.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.