Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Что за жесткий глюк?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
DimanVIP
Есть простенький РАБОЧИЙ код, где по прерыванию таймера моргает светик:
Код
void InitAll(void)
{    
  GPIO_InitTypeDef GPIO_Config;
  TIM_TimeBaseInitTypeDef TIM_BaseConfig;
  NVIC_InitTypeDef  NVIC_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
  RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOBEN, ENABLE);

  GPIO_Config.GPIO_Pin = LD_GREEN | LD_BLUE;
  GPIO_Config.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_Config.GPIO_OType = GPIO_OType_PP;
  GPIO_Config.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(LD_PORT, &GPIO_Config);

  TIM_BaseConfig.TIM_Prescaler = 1000 - 1;
  TIM_BaseConfig.TIM_Period = 8-1;
  TIM_BaseConfig.TIM_ClockDivision = 0;
  TIM_BaseConfig.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM4, &TIM_BaseConfig);

  TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
  TIM_ARRPreloadConfig(TIM4, ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_Init(&NVIC_InitStructure);

  TIM_Cmd(TIM4, ENABLE);
}
int main(void){
    InitAll();
    while(1)
      {}
}

Но стоит в любое место добавить инициализацию пары других ножек:
Код
  GPIO_InitTypeDef GPIO_Config_Enc;
  RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOAEN, ENABLE);

  GPIO_Config_Enc.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_Config_Enc.GPIO_Mode = GPIO_Mode_IN;
  GPIO_Config_Enc.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Config_Enc.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(GPIOA, &GPIO_Config_Enc);

И не важно, каких ножек, какого порта и в каком режиме.
Можно структуру вообще не инициализировать, разницы нет.

Как прерывание перестает работать!

Что это за ерунда такая?
ISK2010
Подозреваю, что вообще добавление любого кода может это вызвать. А потому что надо все поля структур инициализировать. Где у вас строчка "NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;"? Без нее как повезет, может случайно это место в памяти будет не нулевым, и включится ваше прерывание. И про "NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;" не забутьте.
777777
Цитата(ISK2010 @ Sep 19 2011, 09:24) *
Подозреваю, что вообще добавление любого кода может это вызвать. А потому что надо все поля структур инициализировать. Где у вас строчка "NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;"? Без нее как повезет, может случайно это место в памяти будет не нулевым, и включится ваше прерывание. И про "NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;" не забутьте.


Кстати, может кто-нибудь объяснит в чем глубокий смысл - сначала заполнять структуру, а потом вызывать функцию, котороая перепишет эту структуру в регистры? Я сразу заполняю регистры, в этом случае описанные глюки невозможны: ненужные регистры инициализируются при сбросе описанным в даташите образом, поэтому нет необходимости инициализировать их в программе.
scifi
Цитата(777777 @ Sep 20 2011, 09:01) *
Кстати, может кто-нибудь объяснит в чем глубокий смысл - сначала заполнять структуру, а потом вызывать функцию, котороая перепишет эту структуру в регистры? Я сразу заполняю регистры, в этом случае описанные глюки невозможны: ненужные регистры инициализируются при сбросе описанным в даташите образом, поэтому нет необходимости инициализировать их в программе.

Согласен, коллега :-) Я так же делаю. Жалкое оправдание типа "так быстрее программируется" не проходит, так как руководство всё равно читать надо, а прямое программирование регистров на деле оказывается совсем не трудоёмким. Я и макросы с определениями регистров делаю сам, не хочется подстраиваться под разных писателей заголовочных файлов. В результате программа не привязана к конкретному компилятору и легко переносится на другой.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.