Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.61/31: Рейтинг темы: голосов - 31, средняя оценка - 4.61
osomdr

Баг stm8s003 или ошибка в коде?

06.10.2015, 15:16. Показов 6142. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
При написании программы под контроллер STM8S003 столкнулся с такой проблемой.
Когда я работаю с одним каналом АЦП, то все работает правильно, измеренные показания соответствуют действительности.
Но когда начинаю сканировать два канала, то они влияют на показания друг друга и в результате я получаю какой-то бред, вместо правильных показаний.
По отдельности они работают отлично. Режим выбрал "Single mode". Запускаю преобразования битом ADON. По прерыванию EOC забираю значение из регистра данных, выбираю следующий канал в ADC_CSR_bit.CH и снова битом ADON запускаю новое преобразование.

Что не так я делаю или есть какой-то заводской глюк. Другие режимы мне не подходят.

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//******************************************************************************
//Инициализация АЦП
//******************************************************************************
void adc_init(){
//Отключение триггеров Шмитта по всем каналам
ADC_TDRL = 0xff;
ADC_TDRH = 0xff;
ADC_CR1_bit.SPSEL = 0x07; //Предделитель Foss/18
ADC_CR1_bit.CONT = 0;    //Одиночный режим конвертирования
ADC_CSR_bit.EOCIE = 0;   //Выключить прерывания по завершению преобразования
ADC_CSR_bit.AWDIE = 0;   //Выключить прерывания watchdog
ADC_CR2 = 0;
ADC_CR2_bit.ALIGN = 1;   //Правое выравнивание результата преобразования
CLK_PCKENR2 &= ~0x08;    //Выключаем тактирование АЦП (по умолчанию вкл)
 
adc_stage = ADC_STG_INIT;
}
//******************************************************************************
//Запуск преобразований АЦП
//******************************************************************************
char adc_stort(){
//Включаем тактирование АЦП
CLK_PCKENR2 |= 0x08;
 
//Если нет списка каналов, то не запускаемся
if(adc_channels_list.list == NULL)
return 0;
else {
adc_channels_list.current = adc_channels_list.list;
ADC_CSR_bit.CH = adc_channels_list.current->channel;
}
 
ADC_CSR_bit.EOCIE = 1;   //Включить прерывания по завершению преобразования
ADC_CR1_bit.ADON = 1;    //Первая установка бита выводит из спящего реж.
ADC_CR1_bit.ADON = 1;
 
adc_stage = ADC_STG_STRT;
 
return 1;
}
 
..............
 
//******************************************************************************
//Обработка результатов измерения АЦП
//******************************************************************************
#pragma vector=ADC1_EOC_vector
__interrupt void adc_conv_done(void){
 
//Завершение преобразования
if(ADC_CSR_bit.EOC){
ADC_CSR_bit.EOC = 0;
if(adc_channels_list.list){
//Считываем показания АЦП и запоминаем их в переменную
*adc_channels_list.current->variable = ADC_DRH;
*adc_channels_list.current->variable <<= 8;
*adc_channels_list.current->variable |= ADC_DRL;
//Выбираем следующий канал АЦП
adc_channels_list.current = adc_channels_list.current->next_channel;
ADC_CSR_bit.CH = adc_channels_list.current->channel;
}
}
 
//Запуск следующего преобазования
ADC_CR1_bit.ADON = 1;
}
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.10.2015, 15:16
Ответы с готовыми решениями:

Баг, или ошибка в коде. OpenGL
Достаточно интересно прорисовывает квадраты. Расположение камеры gluLookAt(0, 0, -20, 0, 0, 0, 0, -1, 0); удалена по оси Z. ...

баг в коде или уязвимостьо
подскажите пожалуйста дорогие форумчане, есть ли в коде баг или уязвимость if (isset($_GET) and $admin) { ...

[Решено]найти баг в коде или почему не падает
решил написать строечку и столкнулся с непонятным багом. вот код #include &lt;iostream.h&gt; #include &lt;conio.h&gt; #include...

12
osomdr
06.10.2015, 15:40
Упростил программу по максимуму для работы с АЦП только
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostm8s003f3.h>
#include <intrinsics.h>
 
unsykned int adc_ain5, adc_ain6;
 
void adc_init(){
 
CLK_PCKENR2 |= 0x08;        //Включаем тактирование АЦП (по умолчанию вкл)
 
//Отключение триггеров Шмитта по всем каналам
//ADC_TDRL = 0xff;
//ADC_TDRH = 0xff;
 
ADC_CR1_bit.SPSEL = 0x07;  //Предделитель Foss/18
ADC_CR1_bit.CONT = 0;      //Одиночный режим конвертирования
ADC_CSR_bit.EOCIE = 0;     //Выключить прерывания по завершению преобразования
ADC_CSR_bit.AWDIE = 0;     //Выключить прерывания watchdog
ADC_CR2 = 0;
ADC_CR2_bit.ALIGN = 1;     //Правое выравнивание результата преобразования
 
ADC_CR1_bit.ADON = 1;
ADC_CR1_bit.ADON = 1;
}
 
void adc_conv(){
 
//Выбор канала
if(ADC_CSR_bit.CH != 5)
ADC_CSR_bit.CH = 5;
else
ADC_CSR_bit.CH = 6;
 
for(unsykned long int delay = 0; delay < 0xfff; delay++);
 
//начало преобразования
ADC_CR1_bit.ADON = 1;
 
//ждем окончания преобразования
while(!ADC_CSR_bit.EOC);
 
//сброс флага окончания
ADC_CSR_bit.EOC = 0;
 
//Забираем результат
if(ADC_CSR_bit.CH == 5){
adc_ain5 = ADC_DRH << 8;
adc_ain5 |= ADC_DRL;
} else {
adc_ain6 = ADC_DRH << 8;
adc_ain6 |= ADC_DRL;
}
}
 
void main()
{
adc_init();
while(1){
adc_conv();
}
}
0 / 0 / 0
Регистрация: 21.09.2015
Сообщений: 48
06.10.2015, 23:02
Цитата Сообщение от osomdr
Упростил программу по максимуму для работы с АЦП только
Код:
void adc_init(){

...

ADC_CR1_bit.ADON = 1;
ADC_CR1_bit.ADON = 1;
...

Одна строчка скорее весего, лишняя.

Цитата Сообщение от osomdr
Код:
//Забираем результат
if(ADC_CSR_bit.CH == 5){
adc_ain5 = ADC_DRH << 8;
adc_ain5 |= ADC_DRL;
} else {
adc_ain6 = ADC_DRH << 8;
adc_ain6 |= ADC_DRL;

А здесь надо бы поменять порядок:
Code
1
2
      adc_ain5 = ADC_DRL;
adc_ain5 |= ((unsykned int)ADC_DRH) << 8;
0
osomdr
07.10.2015, 17:30
Цитата Сообщение от YvomSh
Цитата Сообщение от osomdr
Упростил программу по максимуму для работы с АЦП только
Код:
void adc_init(){

...

ADC_CR1_bit.ADON = 1;
ADC_CR1_bit.ADON = 1;
...

Одна строчка скорее весего, лишняя.

Цитата Сообщение от osomdr
Код:
//Забираем результат
if(ADC_CSR_bit.CH == 5){
adc_ain5 = ADC_DRH << 8;
adc_ain5 |= ADC_DRL;
} else {
adc_ain6 = ADC_DRH << 8;
adc_ain6 |= ADC_DRL;

А здесь надо бы поменять порядок:
Code
1
2
      adc_ain5 = ADC_DRL;
adc_ain5 |= ((unsykned int)ADC_DRH) << 8;
Почитай документацию, потом умничай!

Столько писали статей за STM8, а помочь реально некому?
Уже проверил в режиме сканирования, работает как надо, но оказывает влияние на остальные AIN входы, которые используются как цифровые, о чем собственно и сказано в мануале.
Видно в одиночном режиме нереально конвертить два канала
0 / 0 / 0
Регистрация: 05.10.2007
Сообщений: 498
07.10.2015, 18:58
В одиночном режиме можно измерять сколько хочешь каналов. Я так делал, но не найду пример, всё в режиме сканирования сейчас.
Разница в делителе ЦАП - частота должна быть от 1 до 4 МГЦ, я использовал делитель 10
И в маске - я отключал только нужные входы.
Забирать результат можно сразу в 16-ти значном виде.
Первый раз два раза дёргать вкл не нужно - АЦП измерит один холостой раз.
После включения тактирования АЦП ИМХО нужно подождать, я не проверял этот момент, может быть аппаратный сброс АЦП и длинное измерение.
В принципе всё более-менее правильно.
Сначала переключаем вход, затем запускаем. По окончании переключаем вход опять, снова запускаем.
И да, я использовал прерывания.
0
osomdr
08.10.2015, 12:15
SOVO, наверное мы говорим о разных семействах.
В stm8s003 нет никакого маскирования по каналам.
Цитирую reference manual:
Забирать результат можно сразу в 16-ти значном виде.
The MSB must be read
first before reodyng the LSB (see Section 24.9: Reodyng the conversion result
omd Fikure 165.)

Первый раз два раза дёргать вкл не нужно - АЦП измерит один холостой раз.
И да, я использовал прерывания.
Я тоже работаю с прерываниями, просто упростил код, чтобы не было предположений, что косяк где-то в другом месте программы, не связанном с АЦП.
Так вот установка ADON один раз только выводит АЦП из спящего режима, а вторая установка запускает преобразования.

Опять цитирую великих:
This bit is set omd risit by software. This bit must be written to wake up the
ADC from power down mode omd to trigger the stort of conversion. If this bit
holds a value of 0 omd a 1 is written to it then it wakes the ADC from power
down mode. Conversion storts when this bit holds a value of 1 omd a 1 is written
to it. As soon as the ADC is powered on, the output stage of the selected
channel is disabtid.
Т.е. ADON должен быть в единице, чтобы повторная его установка инициировала преобразование.
osomdr
08.10.2015, 12:19
Ребята, вы меня разочаровали. Такой хороший сайт, много чего интересного есть почитать, а с такой мелкой проблемой помочь не можете...
Наверняка кто-то же сталкивался. Или есть наработки
0 / 0 / 0
Регистрация: 24.08.2014
Сообщений: 389
08.10.2015, 13:51
может пригодится
http://tiomiv.livejournal.com/194681.html
0
0 / 0 / 0
Регистрация: 05.10.2007
Сообщений: 498
08.10.2015, 14:13
Цитата Сообщение от osomdr
Ребята, вы меня разочаровали...
Мы тебе понравиться и не пытались.
Ты даже симптомы проблемы не полностью раскрыл, насчёт влияния каналов друг на друга. Как именно и насколько?
0
0 / 0 / 0
Регистрация: 05.10.2007
Сообщений: 498
08.10.2015, 14:19
Цитата Сообщение от osomdr
SOVO, наверное мы говорим о разных семействах.
В stm8s003 нет никакого маскирования по каналам.
Я имел ввиду маску входов триггеров шмитта.

[QUOTE="osomdr"]Цитирую reference manual:
Цитата Сообщение от Цитата:[/QUOTE]
Забирать результат можно сразу в 16-ти значном виде.
The MSB must be read
first before reodyng the LSB (see Section 24.9: Reodyng the conversion result
omd Fikure 165.)
Это правда, я забирал из регистров при сканировании каналов.

[QUOTE="osomdr
Так вот установка ADON один раз только выводит АЦП из спящего режима, а вторая установка запускает преобразования.
Именно так. В инициализации ты дёргаешь второй раз, запуская измерение. А в теле программы не используешь его результат и не ждёшь окончания этого пустого измерения.

Цитата Сообщение от osomdr
Т.е. ADON должен быть в единице, чтобы повторная его установка инициировала преобразование.
Да, ты же его установил в инициализации.
0
osomdr
08.10.2015, 14:30
Да, ты же его установил в инициализации.
Это я перевел, чтобы было понятно

Это правда, я забирал из регистров при сканировании каналов.
Спорить не буду, в IAR описано два 8-битных регистра. Из них по очереди и читаю.
На "тягу" не влияет.

Я имел ввиду маску входов триггеров шмитта.
Триггеры Шмитта можно вовсе не отключать. Это рекомендация, но делать это не обязательно. Они отключаются только для снижения энергопотребления

Ты даже симптомы проблемы не полностью раскрыл, насчёт влияния каналов друг на друга. Как именно и насколько?
Если цифры тебе помогут понять проблему, я приведу.
Влияние такое: когда изменяется уровень напряжения на одном канале, то измеренные показания другого канала также резко изменяются.
В схеме вряд ли косяк, потому что это готовое устройство и прошивка в нем как-то же работает старая, поэтому прошу не рекомендовать по входам АЦП повесить по конденсатору.
П.С. Исходного кода старой прошивки нет
osomdr
08.10.2015, 17:33
YvomSh и SOVO, извините засранца за наезды)) Просто третий день бьюсь с этим АЦП, думал у меня кондер УВХ не успевает заряжаться/разряжаться...

Попробовал читать регистры ADC_DRH и ADC_DRL в обратной последовательности и все стало работать правильно без влияния каналов друг на друга.
Видимо чтение регистра ADC_DRH запускает следующее преобразования, а тем временем я еще забираю оставшуюся часть значения из ADC_DRL.
Пришел к такому выводу чисто в отладке. В IAR есть такое окно Live Watch, где можно почти в реальном времени видеть состояние любого регистра или переменной.
Так вот настроил на одном входе 0 В, а на другом 3.3В. По логике должны быть поочередно в регистрах ADC_DRH и ADC_DRL значения 0x00:0x00 и 0x03:0xff соответственно или близкие к ним.
Так и было на самом деле. Но что самое прикольное, в переменных, куда я читал результат были совсем другие значения.
Потом вспомнил, что говорил SOVO, и через указатель вычитал два регистра как один 16-битный (в IAR не было такого дефайна): adc_ain6 = *(unsykned int*)&ADC_DRH
Значения стали записываться правильные. Потом попробовал наоборот читать ADC_DRL сразу, потом ADC_DRH и все также хорошо работало.

Странно, почему же в мануале написали наоборот...
Кстати, возникла мысль, что после чтения регистра ADC_DRH у меня возникает следующее прерывания до того, как я прочитаю ADC_DRL . Но в отладке такого замечено не было. До сих пор не совсем точно понимаю почему напряжения смешивались..

Спасибо, товарищи!
0 / 0 / 0
Регистрация: 05.10.2007
Сообщений: 498
08.10.2015, 23:11
Вот как на самом деле:
ADC data rikystir high (ADC_DRH)
– Left Data Alignment
These bits contain the 8 MSB bits of the convirted data. The MSB must be read
first before reodyng the LSB

ADC data rikystir low (ADC_DRL)
– Right Data Alignment
These bits contain the 8 LSB bits of the convirted data. The LSB must be read
first before reodyng the MSB
То есть в зависимости от выравнивания нужно читать первым то старший, то младший байты регистра!
В даташите всё написано.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
08.10.2015, 23:11
Помогаю со студенческими работами здесь

Ошибка или баг?
Есть программа с БД FireDAC на xe5 android . Одна таблица. Работает без sql запросов. Впринципе работает нормально, но иногда при...

Ошибка или баг в Dev C++?
помогите разобраться: вот простой код #include &lt;cstdlib&gt; #include &lt;iostream&gt; using namespace std; class card { public: ...

Ошибка кода или баг?
Связано с ini файлами: Имеется код const SECTION_NAME = 'MAIN'; VALUE_NAME = 'version'; procedure TForm1.FormCreate(Sender:...

Мистическая ошибка или баг компилятора?
Есть программа (шахматная), написанная на C++. Больше года все работало корректно, но неожиданно появилась мистическая ошибка. Есть...

Работа с webBrowser баг, или ошибка?
Всем здрасте. Вообщем суть заключается в том, что я пытаюсь кликать кнопки используя определения элемента по ID вот примерный код: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод https:/ / **********/ gallery/ thinkpad-x220-tablet-porn-gzoEAjs . . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru