Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: stm32 ADC Hard_Fault
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Reystlin
Доброго времени суток, ув. форумчане
Осваиваю по немногу искусство программирования STM32, столкнулся с вот такой проблемой
имеется код настройки ацп, запускающегося от таймера:
CODE
void ADC_Tim()
{
//TIM2 - 1kHz
TIM_TimeBaseInitTypeDef TIM_Time_user;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

TIM_Time_user.TIM_Prescaler = 20-1;//8000000/1000;//20-1;
TIM_Time_user.TIM_CounterMode = TIM_CounterMode_Up;
TIM_Time_user.TIM_Period = 100;
TIM_Time_user.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM2, &TIM_Time_user);

NVIC_EnableIRQ(TIM2_IRQn);

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
TIM_Cmd(TIM2, ENABLE);
}

extern "C" void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
}
}

void ADC_Ini()
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_Init_user;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC, ENABLE);

ADC_Init_user.ADC_Resolution = ADC_Resolution_12b;
ADC_Init_user.ADC_ScanConvMode = ENABLE;
ADC_Init_user.ADC_ContinuousConvMode = DISABLE;
ADC_Init_user.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConvEdge_Rising);
ADC_Init_user.ADC_ExternalTrigConv = ADC_ExternalTrigInjecConv_T2_TRGO;
ADC_Init_user.ADC_DataAlign = ADC_DataAlign_Right;
ADC_Init_user.ADC_NbrOfConversion = 2;

ADC_Init(ADC1, &ADC_Init_user);

ADC_InjectedSequencerLengthConfig(ADC1, 2);
ADC_InjectedChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_56Cycles);
ADC_InjectedChannelConfig(ADC1, ADC_Channel_7, 2, ADC_SampleTime_56Cycles);

NVIC_EnableIRQ(ADC_IRQn);
// __enable_irq();
ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);

ADC_Tim();

ADC_Cmd(ADC1, ENABLE);
}

extern "C" void ADC_IRQHandler(void)
{
if(ADC_GetITStatus(ADC1, ADC_IT_JEOC) == SET)
{
ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);
GPIO_SetBits(GPIOD, GPIO_Pin_14);

data_adc1 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);
data_adc1 = data_adc1*1.365;

data_adc2 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_2);
data_adc2 = data_adc2*1.365;
}
}

в дебаге пошагово выполняю программу и после строки
ADC_Cmd(ADC1, ENABLE);
мк вываливается в прерывание Hard_Fault, никак не могу понять причину происходящего
ссылка на проект целиком: https://www.dropbox.com/s/jw9kvfrg4tatht6/MIG_BU.7z?dl=0
Oleg Galizin
http://infocenter.arm.com/help/index.jsp?t...a/CIHFDJCA.html
Может поможет локализовать
Reystlin
а как в IAR это узнать в дебаге?
x893
Гуглоком дает первой ссылкой
http://blog.frankvh.com/2011/12/07/cortex-...-fault-handler/
Reystlin
т.е. судя по этой статье нужно стратапр файл менять? или куда эти куски ассемблерного кода девать?
з.ы. я с stm32 только начинаю освиваться и для меня пока ещё это все темный лес%)
гугл листал перед тем как на форум писать, ответа не нашел
x893
можно и в startup, можно и в файл .с, можно в отдельный .s
кому как нравится. и кто чем пользуется.
Reystlin
https://www.dropbox.com/s/g5dk0okn7r6x2k8/%....58.55.png?dl=0
вот что выдает похожий код
x893
Смотрите что у вас находится по адресам

0x08004269 -> 0x080047DC -> HardFault
Reystlin
как это определить в IAR? где эти адреса смотреть?
x893
например в окне диассемлера задать адрес и посмотреть
x893
Поставьте точку останова и смотрите, что и как вызывается и параметры
Reystlin
на какой строке поставить точку останова?
x893
а для начала поставьте
while(1) { }
после
ADC_Ini();
и проверьте работу Timer2 и ADС
Reystlin
сделал вот так
ADC_Cmd(ADC1, ENABLE);
while(1) { }
и всеравно Hard_Fault вываливается
x893
Так это уже совсем просто. У вас только Timer2 и ADC1 инициализируются, значит два прерывания должно прилететь.
Для простоты поставьте в начале программы
DBGMCU_APB1PeriphConfig(DBGMCU_TIM2_STOP, ENABLE)
и breakpoint на TIM2_IRQ и ADC_IRQ
и смотрите что там происходит

Reystlin
вычислил, что проблема в строках
data_adc1 = data_adc1*1.365;
data_adc2 = data_adc2*1.365;

сделал вот так
data_adc1 = data_adc1*(uint16_t)1.365;
data_adc2 = data_adc2*(uint16_t)1.365;
заработалоsm.gif
хотя, что самое странное, пару недель назад этот код работал без проблем%)
Спасибо большое x893
Genadi Zawidowski
Перед умножением коэффициент привели к целой единице - операция выкинулась.
Целочисленное масштабирование выглядело бы так:
data_adc1 = data_adc1 * 1365 / 1000;
Reystlin
Спасибо, Genadi Zawidowski
а есть ли мысли из-за чего изначально все могло работать с этим-же кодом?
я к своему проекту прикручивал экнодер и начала вываливаться ошибка Hard_Fault, хотя АЦП совершенно не трогал
Genadi Zawidowski
В обработчике прерывания АЦП поищите... Выдайте в отладочный компорт плюсик в начале и минус в конце - скорее всего валится там.
Reystlin
строку в которой валится я нашел: data_adc1 = data_adc1*1.365; а вот почему не пойму
Сергей Борщ
Что-то припоминается про выравнивание стека на 8 при использовании плавающей точки.
Reystlin
а при чем тут стек? и поччему изначально такая конструкция работала
Сергей Борщ
Цитата(Reystlin @ Nov 25 2015, 09:46) *
а при чем тут стек?
Вот, почитайте.

Цитата(Reystlin @ Nov 25 2015, 09:46) *
и почему изначально такая конструкция работала
Например, изначально на стеке была или отсутствовала еще одна 4-байтовая переменная и выравнивание получалось само собой. Это предположение, выяснять в любом случае вам. Я бы давно прошелся отладчиком по дизассемблированному коду, нашел конкретную вызывающую падение ассемблерную команду и уже думал о ней.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.