Jump to content

    
Sign in to follow this  
RadiatoR

1 апреля толи от keil толи от F042

Recommended Posts

Имеется F042k6u6

К нему подключеан аналоговый мультиплексор HEF4051B. Он мультиплексирует аналоговые сигналы с 6 (на схеме есть 7 - не юзаю) ножек на 1 в ADC контроллера. (Схема старая, поэтому грязь и ужас, не обращайте внимания)

fe801a02948e.png

 

Частота смены 333Hz, что более чем норм.

Код следующий:

Опрос ADC 333Hz просто в таймере:

if(ADC1->ISR&ADC_ISR_ADRDY)ADC_start;

 

Вот обработчик прерывания:

void ADC1_IRQHandler(void)
   {
       static byte ADCChan=0;
       //static byte last;
       if(ADC1->ISR&ADC_ISR_EOC)
       {
           ADCVal[ADCChan++]=ADC1->DR;
           if(ADCChan>5)
           {
               ADCChan=0;
               ADC_ready=true;
           }
           GPIOB->BRR=7;
           GPIOB->BSRR=ADCChan;
       }
   }

 

Вот осциллограмма:

d62b6b7f5ed4.png

 

Зеленый - аналоговый сигнал

Желтый - бит 1

Голубой - бит 2

Фиолетовый - бит 3

 

Смотрите - я при каждом прерырвании инкрементирую канал и выставляю его, но у меня выставляются следующие значения канала:

0

1

0

1

2

3

4

5

Почему я так и не смог понять. Проблема решилась очень странно - я добавил в функцию переменную last (я хотел через нее было тестить, но обнаружил что с ней работает норм). В итоге если она закомменчена - не работает, а если присутствует, то работает. Хотя сам компилятор ее оптимизирует и хекс остается одинаковым - проверен побайтно через STlink utility.

 

Как это понимать? Первоапрельский розыгрыш?

 

ps. причем last должен обязательно быть static, иначе не работает

Edited by ЯadiatoR

Share this post


Link to post
Share on other sites
А всякий раз по входу в ADC1_IRQHandler

static byte ADCChan=0; - не смущает?

А вас смущает? Если да, советую почитать учебник.

Кстати, "byte" вместо "int" на АРМе - это мощно. Наводит на мысль о тяжёлом наследии 8051 :biggrin:

Share this post


Link to post
Share on other sites
А вас смущает? Если да, советую почитать учебник.

Кстати, "byte" вместо "int" на АРМе - это мощно. Наводит на мысль о тяжёлом наследии 8051 :biggrin:

 

Ну я большую часть практики писал под AVR, да и сейчас 32кб арм не такая роскошь, хотя занято получается около 12 кб. Но все равно я остаюсь экономным - по крайней мере это не мешает.

Share this post


Link to post
Share on other sites
Как это понимать?

Посмотрите map файл, какая переменная выше ADCChan.

Скорее всего там какой-нить массив, и вы вышли за его границы.

Использовать byte вместо int на F042 себе дороже, ибо доступ к невыровненным данным чреват ловлей исключения.

А может компилятор собирает невыровненный int где-то...

Share this post


Link to post
Share on other sites
Но все равно я остаюсь экономным - по крайней мере это не мешает.

Какая же это экономия? "byte" - 4 буквы, а "int" - три :biggrin:

Бросайте эту пустую экономию. Экономить надо начинать, когда байты кончились. Это не значит, что нужно взять и выделить себе массив на 100500 байт просто для прикола. Но вот так крохоборствовать по поводу этих байтиков - себе дороже выйдет.

Share this post


Link to post
Share on other sites

Что-то идет непонятное

 

ddiv_reciptbl      0x08003836   Data         128  ddiv.o(.constdata)
.constdata         0x080038b6   Section       64  fdiv.o(.constdata)
fdiv_tab           0x080038b6   Data          64  fdiv.o(.constdata)
.data              0x20000000   Section        9  adc.o(.data)
ADCChan            0x20000007   Data           1  adc.o(.data)
last               0x20000008   Data           1  adc.o(.data)
.data              0x2000000c   Section       18  ans-3.o(.data)

 

Как раз получается последняя идет на 9 байт

 

Попробовал изменить byte на uint и закомментил ласт - вообще после первого цикла перестает работать.

Вернулся на byte и last

Share this post


Link to post
Share on other sites
Что-то идет непонятное

Вернулся на byte и last

А что лежит от 0x2000_0000 до 0x2000_0006?

По какому адресу располагается ADCVal, каков его тип и размер.

Заменить ADCVal[ADCChan++] на

ADCVal[ADCChan] =

+

ADCChan++;

пробовали?

 

Share this post


Link to post
Share on other sites
Попробовал изменить byte на uint и закомментил ласт - вообще после первого цикла перестает работать.

Вернулся на byte и last

Какие-то танцы с бубном. Внутрисхемного отладчика нет что ли?

Share this post


Link to post
Share on other sites
Заменить ADCVal[ADCChan++] на

ADCVal[ADCChan] =

+

ADCChan++;

пробовали?

Пробовал - нее помогало.

 

Какие-то танцы с бубном. Внутрисхемного отладчика нет что ли?

Конечно есть - толку было не много...

 

ps. Я не мог остановиться на мысли, что производители мк и кейла дураки, а я такой самый умный. И пошел копать в глубину проекта.

И в одном из исходников я обнаружил как думаете что? Верно - переход за индекс массива. Что-то становилось не так и все ломалось к чертям. Поправил это дело и все стало работать нормально.

Все таки не дураки там сидят, хотя помню копался с NSS у SPI на чипе - вот я задолбался, а оказалось он в еррата описан и на кристалле не работал...

 

Оффтпик:

как вставлять сразу несколько цитат?

Share this post


Link to post
Share on other sites
И пошел копать в глубину проекта. И в одном из исходников я обнаружил как думаете что?

Прежде чем глубоко копать нужно посмотреть map-файл - площадь раскопок сократиться.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this