реклама на сайте
подробности

 
 
> stm32 ADC Hard_Fault
Reystlin
сообщение Nov 22 2015, 12:14
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 6-09-15
Пользователь №: 88 307



Доброго времени суток, ув. форумчане
Осваиваю по немногу искусство программирования 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

Сообщение отредактировал IgorKossak - Nov 23 2015, 13:20
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 23)
Oleg Galizin
сообщение Nov 22 2015, 13:30
Сообщение #2





Группа: Участник
Сообщений: 14
Регистрация: 25-03-07
Пользователь №: 26 499



http://infocenter.arm.com/help/index.jsp?t...a/CIHFDJCA.html
Может поможет локализовать
Go to the top of the page
 
+Quote Post
Reystlin
сообщение Nov 22 2015, 18:03
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 6-09-15
Пользователь №: 88 307



а как в IAR это узнать в дебаге?
Go to the top of the page
 
+Quote Post
x893
сообщение Nov 22 2015, 18:25
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Гуглоком дает первой ссылкой
http://blog.frankvh.com/2011/12/07/cortex-...-fault-handler/
Go to the top of the page
 
+Quote Post
Reystlin
сообщение Nov 22 2015, 18:53
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 6-09-15
Пользователь №: 88 307



т.е. судя по этой статье нужно стратапр файл менять? или куда эти куски ассемблерного кода девать?
з.ы. я с stm32 только начинаю освиваться и для меня пока ещё это все темный лес%)
гугл листал перед тем как на форум писать, ответа не нашел
Go to the top of the page
 
+Quote Post
x893
сообщение Nov 22 2015, 19:32
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



можно и в startup, можно и в файл .с, можно в отдельный .s
кому как нравится. и кто чем пользуется.
Go to the top of the page
 
+Quote Post
Reystlin
сообщение Nov 22 2015, 20:03
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 6-09-15
Пользователь №: 88 307



https://www.dropbox.com/s/g5dk0okn7r6x2k8/%....58.55.png?dl=0
вот что выдает похожий код
Go to the top of the page
 
+Quote Post
x893
сообщение Nov 22 2015, 21:40
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Смотрите что у вас находится по адресам

0x08004269 -> 0x080047DC -> HardFault
Go to the top of the page
 
+Quote Post
Reystlin
сообщение Nov 22 2015, 21:50
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 6-09-15
Пользователь №: 88 307



как это определить в IAR? где эти адреса смотреть?
Go to the top of the page
 
+Quote Post
x893
сообщение Nov 22 2015, 21:52
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



например в окне диассемлера задать адрес и посмотреть
Go to the top of the page
 
+Quote Post
Reystlin
сообщение Nov 22 2015, 21:56
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 6-09-15
Пользователь №: 88 307



https://www.dropbox.com/s/lrnptgci2m4hqqn/%....52.09.png?dl=0
https://www.dropbox.com/s/x0ul0hbjuq4189p/%....53.56.png?dl=0
Go to the top of the page
 
+Quote Post
x893
сообщение Nov 22 2015, 22:03
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Поставьте точку останова и смотрите, что и как вызывается и параметры
Go to the top of the page
 
+Quote Post
Reystlin
сообщение Nov 22 2015, 22:47
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 6-09-15
Пользователь №: 88 307



на какой строке поставить точку останова?
Go to the top of the page
 
+Quote Post
x893
сообщение Nov 22 2015, 23:54
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



а для начала поставьте
while(1) { }
после
ADC_Ini();
и проверьте работу Timer2 и ADС
Go to the top of the page
 
+Quote Post
Reystlin
сообщение Nov 23 2015, 04:57
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 6-09-15
Пользователь №: 88 307



сделал вот так
ADC_Cmd(ADC1, ENABLE);
while(1) { }
и всеравно Hard_Fault вываливается
Go to the top of the page
 
+Quote Post
x893
сообщение Nov 23 2015, 21:37
Сообщение #16


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Так это уже совсем просто. У вас только Timer2 и ADC1 инициализируются, значит два прерывания должно прилететь.
Для простоты поставьте в начале программы
DBGMCU_APB1PeriphConfig(DBGMCU_TIM2_STOP, ENABLE)
и breakpoint на TIM2_IRQ и ADC_IRQ
и смотрите что там происходит

Go to the top of the page
 
+Quote Post
Reystlin
сообщение Nov 23 2015, 23:30
Сообщение #17


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 6-09-15
Пользователь №: 88 307



вычислил, что проблема в строках
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

Сообщение отредактировал Reystlin - Nov 23 2015, 23:30
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Nov 24 2015, 00:40
Сообщение #18


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Перед умножением коэффициент привели к целой единице - операция выкинулась.
Целочисленное масштабирование выглядело бы так:
data_adc1 = data_adc1 * 1365 / 1000;
Go to the top of the page
 
+Quote Post
Reystlin
сообщение Nov 24 2015, 04:54
Сообщение #19


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 6-09-15
Пользователь №: 88 307



Спасибо, Genadi Zawidowski
а есть ли мысли из-за чего изначально все могло работать с этим-же кодом?
я к своему проекту прикручивал экнодер и начала вываливаться ошибка Hard_Fault, хотя АЦП совершенно не трогал
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Nov 24 2015, 08:04
Сообщение #20


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



В обработчике прерывания АЦП поищите... Выдайте в отладочный компорт плюсик в начале и минус в конце - скорее всего валится там.
Go to the top of the page
 
+Quote Post
Reystlin
сообщение Nov 24 2015, 12:16
Сообщение #21


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 6-09-15
Пользователь №: 88 307



строку в которой валится я нашел: data_adc1 = data_adc1*1.365; а вот почему не пойму
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 24 2015, 13:11
Сообщение #22


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Что-то припоминается про выравнивание стека на 8 при использовании плавающей точки.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Reystlin
сообщение Nov 25 2015, 06:46
Сообщение #23


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 6-09-15
Пользователь №: 88 307



а при чем тут стек? и поччему изначально такая конструкция работала
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 25 2015, 08:33
Сообщение #24


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Reystlin @ Nov 25 2015, 09:46) *
а при чем тут стек?
Вот, почитайте.

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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 13:28
Рейтинг@Mail.ru


Страница сгенерированна за 0.01588 секунд с 7
ELECTRONIX ©2004-2016