Страница 1 из 3
GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Пн дек 29, 2014 19:35:34
karidumo
Добрый вечер!
Купил себе STM32VLDISCOVERY и решил начать с ней играться.
Но почему-то, когда я начинаю тактировать 2 порт, всё рушиться.
Написал простой код по зажиганию светодиода, при нажатии кнопки, он компилится, заливаю, но ничего не происходит...
Решил сделать дебаг, все падает на строчке:
Код: Выделить всё
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
Вот полный код прошивки написан в CoIDE:
Спойлер
Код: Выделить всё
#include <stm32f10x_rcc.h>
#include <stm32f10x_gpio.h>
#include "stm32f10x.h"
#include "stm32f10x_conf.h"
void Delay(volatile uint32_t nCount);
GPIO_InitTypeDef GPIO_InitStructure;
void init()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; // использовать выводы PC8 и PC9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // на выход
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //задаем номер вывода, если кнопка подключена, например к 6 порту, то пишем GPIO_Pin_6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //порт будет работать как цифровой вход с подтяжкой к земле
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
volatile int main(void)
{
init();
while(1)
{
GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET);
GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET); // включить зеленый светодиод, подключенный к Led PC9
if(GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_0) != 0 )// Если нажата кнопка PA0
{
GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_SET);// погасить зеленый светодиод, подключенный к Led PC9
}
else
{
GPIO_ResetBits(GPIOC, GPIO_Pin_8); // погасить синий светодиод, подключенный к Led PC8
}
Delay(2000000);
}
}
//-------
void Delay(volatile uint32_t nCount)
{
for (; nCount > 0; nCount--);
}
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Пн дек 29, 2014 21:14:05
oleg110592
когда я начинаю тактировать 2 порт, всё рушиться
что значит рушиться?
все падает на строчке:
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
на этой строчке нет включения тактирования - тут заполнение структуры.
Прогнал в симуляторе Keilа - нигде ничего не рушится.
Код, я так понимаю отсюда:
http://alex-exe.ru/radio/stm32/stm32-gpio-spl/
рекомендовал бы для большей наглядности SPL не пользоваться, например:
Код: Выделить всё
// Выставляем тактирование в APB2
RCC->APB2ENR |= RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA;
// Конфигурируем CRL регистры.
GPIOC->CRL &= ~GPIO_CRL_CNF5; // Сбрасываем биты CNF для бита 5. Режим 00 - output Push-Pull
GPIOC->CRL |= GPIO_CRL_MODE5_0; // Выставляем бит MODE0 для пятого пина. Режим MODE01 = Max Speed 10MHz
имхо это понятнее и по документации легче разбираться
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Пн дек 29, 2014 21:25:57
karidumo
Спойлер
oleg110592 писал(а):когда я начинаю тактировать 2 порт, всё рушиться
что значит рушиться?
все падает на строчке:
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
на этой строчке нет включения тактирования - тут заполнение структуры.
Прогнал в симуляторе Keilа - нигде ничего не рушится.
Код, я так понимаю отсюда:
http://alex-exe.ru/radio/stm32/stm32-gpio-spl/
рекомендовал бы для большей наглядности SPL не пользоваться, например:
Код: Выделить всё
// Выставляем тактирование в APB2
RCC->APB2ENR |= RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA;
// Конфигурируем CRL регистры.
GPIOC->CRL &= ~GPIO_CRL_CNF5; // Сбрасываем биты CNF для бита 5. Режим 00 - output Push-Pull
GPIOC->CRL |= GPIO_CRL_MODE5_0; // Выставляем бит MODE0 для пятого пина. Режим MODE01 = Max Speed 10MHz
имхо это понятнее и по документации легче разбираться
Да, код от туда. С SPL новчику как мне понятнее пока.
На этой строке управление переходит в startup_stm32f10x_md.c,и там на этом цикле зависает всё (бесконечный цикл):
Код: Выделить всё
static void Default_Handler(void)
{
/* Go into an infinite loop. */
while (1)
{
}
}
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Пн дек 29, 2014 21:38:04
oleg110592
непонятно почему попадает в Default_Handler, вроде должен туда попадать, если не объявлен обработчик прерывания - тут прерываний нет
вы не одиноки:
в CooCox очень часто прога вылетает в Default_Handler и там крутися в пустом цикле. 80% вылетов в Default_Handler происходит при тактирование GPIOC во время инициализации порта. В чём дело?
Всё больше хочется свалить с кокоса и библиотек ST... даже блин GPIO_Write Использует GPIOx->ODR = - так что спокойно затирает все преидущие биты в порту...
отсюда:
http://forum.easyelectronics.ru/viewtop ... 9&start=50
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Пн дек 29, 2014 22:29:56
balmer
Может расположение стека в памяти неправильно настроено? Вот и падает при обращении к несуществующему блоку памяти...
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Пн дек 29, 2014 22:59:14
karidumo
balmer писал(а):Может расположение стека в памяти неправильно настроено? Вот и падает при обращении к несуществующему блоку памяти...
настройки по дефолту все стоят, вот области памяти
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 00:02:12
ЛеонидК
Может я чего-то не понял.
GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET);
GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET); // включить зеленый светодиод, подключенный к Led PC9
Два раза одно и тоже, это какая-то хитрость?
GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_SET);// погасить зеленый светодиод, подключенный к Led PC9
Каким образом Pin_8 гасит Led PC9? Выше та же команда включает.
GPIO_ResetBits(GPIOC, GPIO_Pin_8); // погасить синий светодиод, подключенный к Led PC8
Здесь один вопрос. Почему для одного и то же используются разные команды
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 09:39:48
karidumo
Спойлер
ЛеонидК писал(а):Может я чего-то не понял.
GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET);
GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET); // включить зеленый светодиод, подключенный к Led PC9
Два раза одно и тоже, это какая-то хитрость?
GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_SET);// погасить зеленый светодиод, подключенный к Led PC9
Каким образом Pin_8 гасит Led PC9? Выше та же команда включает.
GPIO_ResetBits(GPIOC, GPIO_Pin_8); // погасить синий светодиод, подключенный к Led PC8
Здесь один вопрос. Почему для одного и то же используются разные команды
Да, вы правы это мой косяк, пока сидел пытался запустить напутал уже с коментами, вот исправленный:
Код: Выделить всё
while(1)
{
GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_SET); // включить зеленый светодиод, подключенный к Led PC9
if(GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_0) != 0 )// Если нажата кнопка PA0
{
GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_SET);// включить синий светодиод, подключенный к Led PC8
}
else
{
GPIO_ResetBits(GPIOC, GPIO_Pin_8); // погасить синий светодиод, подключенный к Led PC8
}
Delay(2000000);
}
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 09:54:32
ЛеонидК
Я думаю в GPIO_WriteBit есть параметр Bit_SET и Bit_Reset.
Думаю существует как GPIO_ResetBits так и GPIO_SetBits.
Непонятно, почему включается GPIO_WriteBit, а выключается GPIO_ResetBits.
Я понимаю, что это, наверное, одно и тоже, но выглядит странно.
Если Pin_9 включается и никогда не выключается, зачем повторять включение.
Нужно вынести за цикл.
В исходном тексте было больше логики, только нужно было не два включения pin_9, а включить Pin_9 и Pin_8, а при нажатии кнопки выключать, например, Pin_9, а при не нажатой Pin_8 и вставить после включения еще одну задержку, тогда оба светодиода будут мигать. Один при нажатой кнопке, а другой при не нажатой.
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 10:05:44
oleg110592
без SPL, повторюсь нагляднее:
Код: Выделить всё
GPIOC->BSRR = GPIO_BSRR_BR5; // Сбросили бит.
GPIOC->BSRR = GPIO_BSRR_BS5; // Установили бит.

Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 10:15:17
ЛеонидК
oleg110592!
Посмотри это рядышком и попробуй ответить, что нагляднее.
GPIO_ResetBits(GPIOC, GPIO_Pin_8); // Сбросили бит.
GPIOC->BSRR = GPIO_BSRR_BR5; // Сбросили бит.
В конечном итоге и то и другое сведется к одному и тому же. Да в первом еще и команда вызова, поэтому размер будет больше, но причем наглядность. В первом варианте любой скажет, что это сброс бита, а во втором, если не знаешь, что это, никогда не догадаешься. Так, что речь не о наглядности.
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 10:18:57
cahek80
oleg110592 писал(а):рекомендовал бы для большей наглядности SPL не пользоваться, например:
Это кому как, я вот тоже больше через spl привык инициализировать. Ну или через сейчас модный HAL.
Если приложение начнет занимать непомерно много памяти - тогда да, откажусь.
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 10:24:10
cahek80
karidumo, судя по приложенному коду всё должно работать, если не забуду - могу вечером попробовать запустить у себя.
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 10:25:47
oleg110592
не только команда вызова:
Код: Выделить всё
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->BRR = GPIO_Pin;
}
Код: Выделить всё
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
{
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_BIT_ACTION(BitVal));
if (BitVal != Bit_RESET)
{
GPIOx->BSRR = GPIO_Pin;
}
else
{
GPIOx->BRR = GPIO_Pin;
}
}
зачем это все, если почитать документацию
этот вариант, имхо, лучшее, но это дело вкуса
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 10:54:31
ЛеонидК
oleg110592!
Я говорил о наглядности. assert_param если включено.
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 11:23:52
oleg110592
а что ненаглядного в GPIOC->BSRR = GPIO_BSRR_BR5;?
GPIOC->BSRR понятно, что регистр GPIOС_BSRR, а GPIO_BSRR_BR5, если что можно глянуть дефайн
#define GPIO_BSRR_BR5 ((uint32_t)0x00200000) /*!< Port x Reset bit 5 */
все согласно документации
не будем разжигать тут холивар SPL vs регистры - кому как удобнее, я только свое мнение выразил.
Короче проверил подобный код из (ссылки второго поста) на STM32VLDISCOVERY, Keil - все работает, синий светодиод мигает, зеленый зажигается при нажатии кнопки, работает в дебаге. На всякий случай рабочий код:
Спойлер
Код: Выделить всё
#include "stm32f10x.h"
GPIO_InitTypeDef GPIO_InitStructure;
void init() // инициализация
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; // использовать выводы PC8 и PC9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // на выход
GPIO_Init(GPIOC, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // использовать вывод PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // на вход
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void delay(unsigned long p) // задержка
{
while(p>0){p--;}
}
int main(void)
{
init(); // инициализация
while(1) // в бесконечном цикле крутиться программа
{
if(GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_0))// Если нажата кнопка PA0
{
GPIO_SetBits(GPIOC, GPIO_Pin_9); // включить зеленый светодиод, подключенный к Led PC9
}
else
{
GPIO_ResetBits(GPIOC, GPIO_Pin_9);// погасить зеленый светодиод, подключенный к Led PC9
}
GPIO_SetBits(GPIOC, GPIO_Pin_8); // включить синий светодиод, подключенный к Led PC8
delay(2000000);
GPIO_ResetBits(GPIOC, GPIO_Pin_8); // погасить синий светодиод, подключенный к Led PC8
delay(2000000);
}
}
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 11:42:17
HHIMERA
ЛеонидК писал(а):oleg110592!
Посмотри это рядышком и попробуй ответить, что нагляднее.
GPIO_ResetBits(GPIOC, GPIO_Pin_8); // Сбросили бит.
GPIOC->BSRR = GPIO_BSRR_BR5; // Сбросили бит.
Нагляднее
Код: Выделить всё
#define LED_BLUE_ON (GPIOC->BSRR = GPIO_BSRR_BS8)
#define LED_BLUE_OFF (GPIOC->BSRR = GPIO_BSRR_BR8)
#define LED_GREEN_ON (GPIOC->BSRR = GPIO_BSRR_BS9)
#define LED_GREEN_OFF (GPIOC->BSRR = GPIO_BSRR_BR9)
..................
LED_BLUE_ON;
LED_BLUE_OFF;
LED_GREEN_ON;
LED_GREEN_OFF;
но никак не
GPIO_ResetBits(GPIOC, GPIO_Pin_8);
который не несёт никакого смысла...
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 14:04:30
ЛеонидК
HHIMERA!
Наглядно, то что понятно.
GPIO_ResetBits(GPIOC, GPIO_Pin_8); // Понятно и без объяснения и чтения литературы
Приведенное тобой я понимаю и пользуюсь сам, но это совсем не очевидно.
Твои рассуждения не более чем надувание щек.
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 14:06:48
oleg110592
то ж самое без SPL и с учетом рекомендаций выше - точно так же работает:
Спойлер
Код: Выделить всё
#include "stm32f10x.h"
#define LED_BLUE_ON (GPIOC->BSRR = GPIO_BSRR_BS8)
#define LED_BLUE_OFF (GPIOC->BSRR = GPIO_BSRR_BR8)
#define LED_GREEN_ON (GPIOC->BSRR = GPIO_BSRR_BS9)
#define LED_GREEN_OFF (GPIOC->BSRR = GPIO_BSRR_BR9)
#define BUTTON (GPIOA->IDR & GPIO_IDR_IDR0)
void init() // инициализация
{
// Выставляем тактирование в APB2
RCC->APB2ENR |= RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA;
// Конфигурируем CRH и CRL регистры.
GPIOC->CRH &= ~(GPIO_CRH_CNF8 | GPIO_CRH_CNF9); // Режим 00 - output Push-Pull
GPIOC->CRH |= (GPIO_CRH_MODE8_1 | GPIO_CRH_MODE9_1); //выход, 2MHz
}
void delay(unsigned long p) // задержка
{
while(p>0){p--;}
}
int main(void)
{
init(); // инициализация
while(1) // в бесконечном цикле крутиться программа
{
if(BUTTON)// Если нажата кнопка PA0
{
LED_GREEN_ON; // включить зеленый светодиод, подключенный к Led PC9
}
else
{
LED_GREEN_OFF;// погасить зеленый светодиод, подключенный к Led PC9
}
LED_BLUE_ON; // включить синий светодиод, подключенный к Led PC8
delay(2000000);
LED_BLUE_OFF; // погасить синий светодиод, подключенный к Led PC8
delay(2000000);
}
}
размер программы:
Program Size: Code=468 RO-data=304 RW-data=0 ZI-data=1024
с использованием SPL размер был:
Program Size: Code=728 RO-data=340 RW-data=4 ZI-data=1028
Re: GPIO не отзывается.. STM32VLDISCOVERY
Добавлено: Вт дек 30, 2014 14:15:54
ЛеонидК
karidumo!
Насколько я понял, ты только начинаешь.
Думай сам. Поменьше слушай советы.
Мы ведь из страны советов. Правда, большинство советчиков понятия не имеют что это, но инстинкт передается по наследству.
Освоишь SPL и пойдешь дальше.
А потом уже будешь надувать щеки как они. Если захочешь.