Здравствуйте, начал изучение ARM с готовых примеров на плате stm32f4discovery. Пример взят с http://microtechnics.ru/programmirovani ... programmy/. В итоге при настройке проекта и компиляции ругается на следующее. Читал в интернете все возможное связанное с данной ошибкой, безрезультатно, помогите.
Building configuration: test - Debug
Updating build tree...
main.c
Error[Pe020]: identifier "USART1_IRQn" is undefined C:\STM32F4\test\main.c 70
Error while running C/C++ Compiler
Total number of errors: 1
Total number of warnings: 0
Откуда у тебя в коде это USART1_IRQn взялось??.
И вообще что за привычка выкладывать ошибку не показывая исходник в котором компилятор сею ошибку нашел???
Компилятор указывает конкретную строку в майне, а именно 70
// Включаем прерывания и запускаем USART
NVIC_EnableIRQ (USART1_IRQn); --- и есть строка 70
USART_Cmd(USART1, ENABLE);
Взято из примера по ссылке. Смотрим функции в библиотеке _STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn), т.е. нужно передать параметр IRQn, смотрим stm32f4xx.h, видим определение переменной
typedef enum IRQn
{...
#if defined (STM32F40_41xxx)
......
USART1_IRQn = 37, /*!< USART1 global Interrupt */
ну по ссылке копипастом код программы.... есть все. Спойлер// Цепляем нужные файлы
#include "stm32f4xx.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_usart.h"
#include "stm32f4xx_gpio.c"
#include "stm32f4xx_rcc.c"
/*
1. Во-первых включаем тактирование модуля.
2. Затем включаем тактирование нужных портов контроллера (ножки Tx/Rx).
3. Настраиваем пины для работы в режиме альтернативных функций.
4. Запускаем модуль USART.
5. И наконец, включаем нужные прерывания и начинаем высылать/принимать данные.
Вроде бы все, что нужно упомянул, переходим к делу. Создаем новый проект и пишем программу:*/
/*******************************************************************/
// Объявляем переменные
GPIO_InitTypeDef gpio;
USART_InitTypeDef usart;
// Пусть нам надо передать 8 байт, создадим массив для данных
uint8_t sendData[8];
uint8_t bytesToSend = 8;
// Счетчик отправленных байт
uint8_t sendDataCounter = 0;
/*******************************************************************/
// Инициализация всего, что нам надо
void initAll()
{
// Включаем прерывания
__enable_irq();
// И вот еще функция, которой не было при работе с STM32F10x,
// но которую нужно вызывать при использовании STM32F4xx
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
// А теперь настраиваем модуль USART
USART_StructInit(&usart);
usart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
usart.USART_BaudRate = 9600;
USART_Init(USART1, &usart);
/*******************************************************************/
// Функция main()
int main()
{
// Для начала заполним массив передаваемыми данными
sendData[0] = 0x11;
sendData[1] = 0x22;
sendData[2] = 0x33;
sendData[3] = 0x44;
sendData[4] = 0x55;
sendData[5] = 0x66;
sendData[6] = 0x77;
sendData[7] = 0x88;
// Вызываем функцию инициализации
initAll();
// Включаем прерывание по окончанию передачи
USART_ITConfig(USART1, USART_IT_TC, ENABLE);
while(1)
{
// А тут мы ничего не делаем, вся работа у нас в прерывании
__NOP();
}
}
/*******************************************************************/
// Обработчик прерывания
void USART1_IRQHandler()
{
// Проверяем, действительно ли прерывание вызвано окончанием передачи
if (USART_GetITStatus(USART1, USART_IT_TC) != RESET)
{
// Очищаем флаг прерывания
USART_ClearITPendingBit(USART1, USART_IT_TC);
// Отправляем байт данных
USART_SendData(USART1, sendData[sendDataCounter]);
// Если отправили все данные, начинаем все сначала
if (sendDataCounter == bytesToSend)
{
sendDataCounter = 0;
}
}
}
Иначе было б еще куча ошибок, а тут только на ней затыкается.
Не знаю, что у Вас за библиотека. В репозитарии кокоса 1.7.7 нет никакого упоминания о STM32F40_41xxx. Оно вроде бы и логично, ведь общее прерывание от 1 Usart есть кажется во всем семействе. Кто Вам мешает написать в самом начале программы #define STM32F40_41xxx и не разгадывать ребусы?
#if defined (STM32F40_41xxx)
...
USART1_IRQn = 37, /*!< USART1 global Interrupt
...
Как оказалось, в настройках проекта необходимо было указать в графе Defined symbols: (one per line) --> вот это STM32F40_41xxx, и тогда параметр USART1_IRQn успешно находил компилятор. Вопрос дальше))). Как поступить со следующим???
Building configuration: test2 - Debug
Updating build tree...
main.c
Linking
Error[Li005]: no definition for "USART_ITConfig" [referenced from C:\STM32F4\test2\Debug\Obj\main.o]
Error[Li005]: no definition for "USART_StructInit" [referenced from C:\STM32F4\test2\Debug\Obj\main.o]
Error[Li005]: no definition for "USART_Init" [referenced from C:\STM32F4\test2\Debug\Obj\main.o]
Error[Li005]: no definition for "USART_Cmd" [referenced from C:\STM32F4\test2\Debug\Obj\main.o]
Error while running Linker
Total number of errors: 4
Total number of warnings: 0
Вопрос отпадает, подобное уже встречалось, как оказалось необходимо было включить еще #include "stm32f4xx_usart.c", но почему данный файл автоматически не подключился? Далее я закомментировал строчку и всеравно работает!!! Что такое?
Это порочная практика. Необходимо указать компилятору, что он должен компилировать этот файл, а линкеру - использовать соответствующий объектный файл при сборке.