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

GPIOD->BSRR |= GPIO_BSRR_BS2;            //Request -> 1
    Delay(1);
    GPIOD->BSRR |= GPIO_BSRR_BR2;            //Request -> 0
    
    while(!(GPIOD->IDR & GPIO_IDR_IDR3)) {}    //ждать Ready
    
        for(i=0; i<16; i++)
        {
            GPIOD->BSRR |= GPIO_BSRR_BS6;            //Read -> 1
            buf[i] = GPIO_ReadInputData(GPIOC);
            GPIOD->BSRR |= GPIO_BSRR_BR6;            //Read -> 0
        }
        
    while(1)
    {
        
    }

Когда программа запускается по сбросу, лог. анализатор показывает обмен сигналами между МК и внешним устройством.

Если я запускаю программу в отладчике, на строчке

 

while(!(GPIOD->IDR & GPIO_IDR_IDR3)) {} //ждать Ready

отладчик зависает. Объясните начинающему (стаж 4,5 мес), почему так происходит?

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


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

IDR, который для GPIOD, часом не мониторится в окошке Keil-а? Если так, то отладчик флажок вычитывает.

Обычно, флажки, сбрасываемые чтением, в окошках отладчика смотреть не полезно (при отладке ;) ).

 

"Зависает" и "не идет дальше" - не одно и то же.

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


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

IDR, который для GPIOD, часом не мониторится в окошке Keil-а? Если так, то отладчик флажок вычитывает.

Это не бит с доступом типа "сброс при чтении".

 

mihlit, когда заходите в отладку, процессор прошивается актуальной прошивкой, запускает ее выполнение, успевает сколько-то выполниться и затем отладчик сбрасывает его, начиная выполнять код заново. Поэтому с большой долей вероятности обмен Ваш уже завершился с устройством и повторный обмен не предусмотрен - поэтому лог. 1 на линии больше никогда не будет.

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


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

В IDR при чтении нисего не сбрасывается.

Для GPIOD->BSRR не надо |=, просто =

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


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

"Поэтому с большой долей вероятности обмен Ваш уже завершился с устройством и повторный обмен не предусмотрен - поэтому лог. 1 на линии больше никогда не будет."

Действительно, сейчас внешнее устройство снимает сигал готовности, после передачи пакета данных.

Получается, что я в режиме отладки не могу посмотреть данные в buf[]?

 

Кнопки пошагового выполнения становятся неактивными - это "Зависает" или "не идет дальше"?

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

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


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

Действительно, сейчас внешнее устройство снимает сигал готовности, после передачи пакета данных.

Получается, что я в режиме отладки не могу посмотреть данные в buf[]?

Можете. Для этого Вам необходимо пересмотреть протокол передачи данных. Ну или на крайний случай, сделайте временный костыль: в начале main() сделайте задержку секунды в 3.

Кстати. Галочка в настройках отладчика Download To Flash->Reset and Run не стоит? Сбросьте ее.

 

Кнопки пошагового выполнения становятся неактивными - это "Зависает" или "не идет дальше"?

Они в любом случае будут недоступны, если процессор находится в состоянии выполнения команд. Стоит Вам поставить точку останова на Ваш "зацикленный" круг ада - и Вы увидите, что кнопки разблокируются.

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


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

Можете. Для этого Вам необходимо пересмотреть протокол передачи данных.

Я примерно это и предполагал - поэтому и уже снова открыл Quartus.

Галочка в настройках отладчика Download To Flash->Reset and Run

не очень разбираюсь в Кейле, искал в свойствах проекта, (волшебная палочка :biggrin: ) не нашел.

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


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

Я примерно это и предполагал - поэтому и уже снова открыл Quartus.

 

не очень разбираюсь в Кейле, искал в свойствах проекта, (волшебная палочка :biggrin: ) не нашел.

Flash->Configure Flash Tools->Debug->Settings->Flash Download->Reset and Run.

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


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

Дважды смотрел вкладку, но искал установленные птички - поэтому и не увидел. Сброшена она.

Ладно, спасибо всем, буду переделывать прошивку CPLD. Смущает только одно - всегда МК был мастером для периферии, а теперь что, по прерыванию обрабатывать прием данных, а если они сейчас не нужны? Ладно, разберусь.

Еще раз всем спасибо.

 

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


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

Чтобы не плодить тем, спрошу здесь, кто-нибудь подскажите:

Есть в GPIO регистр GPIOx_AFRH.

Как в нем установить AFRH15[3:0] =5?

Записать магическое число 0х50000000 или есть какой-то дефайн? Смотрел stm32f4xx.h, stm32f4_gpio.h - не нашел. Ткните-пните в нужном направлениию

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


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

Чтобы не плодить тем, спрошу здесь, кто-нибудь подскажите:

Есть в GPIO регистр GPIOx_AFRH.

Как в нем установить AFRH15[3:0] =5?

Записать магическое число 0х50000000 или есть какой-то дефайн? Смотрел stm32f4xx.h, stm32f4_gpio.h - не нашел. Ткните-пните в нужном направлениию

В stm32f4xx_gpio.h есть

#define GPIO_AF_SPI1          ((uint8_t)0x05)  /* SPI1 Alternate Function mapping      */
#define GPIO_AF_SPI2          ((uint8_t)0x05)  /* SPI2/I2S2 Alternate Function mapping */
#define GPIO_AF_SPI4          ((uint8_t)0x05)  /* SPI4 Alternate Function mapping      */
#define GPIO_AF_SPI5          ((uint8_t)0x05)  /* SPI5 Alternate Function mapping      */
#define GPIO_AF_SPI6          ((uint8_t)0x05)  /* SPI6 Alternate Function mapping      */

А в В stm32f4xx_gpio.c есть

void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
{
  uint32_t temp = 0x00;
  uint32_t temp_2 = 0x00;
  
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
  assert_param(IS_GPIO_AF(GPIO_AF));
  
  temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));
  GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4));
  temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
  GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;
}

По сути делает то, что Вам нужно.

 

Если не используете SPL, то что мешает вовсе использовать самописные #define?

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


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

Смотрел я GPIO_PinAFConfig, но по своей неопытности предположил, что как-то по аналогии со 103 серией, без приведения к uint32_t и сдвигов можно обойтись.

Спасибо за ответ, у меня код рабочий с SPL написан, но в целях самообразования попытался обойтись записью в регистры - не получилось.

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


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

Смотрел я GPIO_PinAFConfig, но по своей неопытности предположил, что как-то по аналогии со 103 серией, без приведения к uint32_t и сдвигов можно обойтись.

Спасибо за ответ, у меня код рабочий с SPL написан, но в целях самообразования попытался обойтись записью в регистры - не получилось.

А что конкретно не получилось?

Записать в AFRH15[3:0] число 5 можно, например, так

GPIOA->AFRH = 5UL << 28;

или так

GPIOA->AFRH = 0x50000000;

что абсолютно равнозначно. Разница в удобстве записи и восприятия.

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


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

GPIOA->AFRH = 0x50000000;

Ассистент после -> предлагал только "AFR", если я вводил "AFRH", появлялся крест на строке "не объявлено uint32_t"

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


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

Записать магическое число 0х50000000 или есть какой-то дефайн? Смотрел stm32f4xx.h, stm32f4_gpio.h - не нашел. Ткните-пните в нужном направлениию

Любое битовое поле в регистре в общем случае записывается в два прохода:

сначала выставляются 1 в нужных позициях

затем 0

Можно наоборот, порядок не важен.

Для этого нужно знать: имя модифицируемого регистра, позицию битового поля внутри регистра, маску этого битового поля и нужное значение.

Оформить эти 2 строчки кода можно в виде макроса

// Макрос записи в регистр reg битовой последовательности val в позицию pos (по младшему разряду)
// msk - маска битового поля
#define TuneBitField(reg,val,pos,msk) \
                {(reg) |= (((val) << (pos))&(msk)); \
                (reg) &= (((val) << (pos))|~(msk));}

Имена регистров ( в вашем случае это GPIOA->AFRH), позиции и маски битовых полей описываются в .h-файле на конкретный микроконтроллер. Берёте их оттуда и подставляете в качестве аргументов макроса. В качестве значения val подставляете требуемое 5.

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


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

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...