Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
1 / 1 / 0
Регистрация: 14.06.2014
Сообщений: 100
1

Работа с АЦП PIC16F688

26.02.2015, 20:49. Показов 2558. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте!
Подскажите пожалуйста мне про АЦП.
Если используем левое выравнивание, то надо использовать только H? но тогда ведь не точно вообще будет. будет какая-то ерунда...
Если же использовать правое выравнивание, то неизвестно как считать.... Ведь 2 регистра по 8 бит, а результат то 10 битный....
+
Код
rezultat=ADRESH;
volt=(float)rezultat*5/1023;
sprintf(otvet,"%.2f", rezultat);
lcd_puts(otvet);
Куча непонятных ошибок связанные с sprintf... (библиотеку подключил)
Однако если вместо %f поставить %d, то ошибок нет. но полная ерунда вообще становится....
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.02.2015, 20:49
Ответы с готовыми решениями:

Змейка и тетрис на PIC16F688
Столкнулся с проблемой моделирования в протеусе схемы змейки и тетриса на PIC16F688 Подобная тема...

Кто работал с PIC16F688?
PIC16F688I/P не хочет работать под дебаггером ICD3, После заливки проги при запуске пишет ...

Внутренний генератор в PIC16F688
Здравствуйте. Подскажите пожалуйста сколько МГц у PIC16F688. + Где Вы это находите в даташите,...

Змейка и тетрис на PIC16F688
Столкнулся с проблемой моделирования в протеусе схемы змейки и тетриса на PIC16F688 На...

18
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
26.02.2015, 21:21 2
Цитата Сообщение от user437 Посмотреть сообщение
Если используем левое выравнивание, то надо использовать только H? но тогда ведь не точно вообще будет.
иногда достаточно 256 уровней
Цитата Сообщение от user437 Посмотреть сообщение
Если же использовать правое выравнивание, то неизвестно как считать....
что такое битовые маски слышал?
C++
1
result &=0x3FF;
Добавлено через 1 минуту
Цитата Сообщение от user437 Посмотреть сообщение
volt=(float)rezultat*5/1023;
sprintf(otvet,"%.2f", rezultat);
а что ты выводишь то в sprintf ???
rezultat а он INT
float то volt
0
1 / 1 / 0
Регистрация: 14.06.2014
Сообщений: 100
26.02.2015, 21:27  [ТС] 3
Ой, это от моих эксперементов. Там где rezultat конечно у меня стояло volt и все равно ошибка.
Покажите пожалуйста как считать надо я додуматься не могу
Нет, не слышал.
0
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
26.02.2015, 22:03 4
Цитата Сообщение от user437 Посмотреть сообщение
Покажите пожалуйста как считать надо я додуматься не могу
давай код, посмотрим

Добавлено через 1 минуту
Цитата Сообщение от user437 Посмотреть сообщение
Нет, не слышал.
вот я и привел тебе пример как выделить 10 младших бит в int
Цитата Сообщение от ValeryS Посмотреть сообщение
C
1
result &=0x3FF;
0
1 / 1 / 0
Регистрация: 14.06.2014
Сообщений: 100
26.02.2015, 22:10  [ТС] 5
Я все равно не понял. Прошу пояснить.
C
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
#include <pic16f688.h>
#include <stdio.h>
#include "lcd.h"
 
 
int rezultat;
float volt;
char otvet[20];
 
main(){
ADCON0=0b00000011;
ADCON1=0b00100000;
ANSEL=0b00000001;
TRISC=0;
TRISA=0b00000001;
PORTA=0;
lcd_init();
lcd_clear();
lcd_goto(0);
 
rezultat=ADRESH ;
volt=(float)rezultat*5/1023;
sprintf(otvet, "%.2f", volt);
lcd_puts(otvet);
while(1){}
}
0
Нарушитель
179 / 164 / 30
Регистрация: 14.02.2013
Сообщений: 1,472
26.02.2015, 22:39 6
В некоторых библиотеках нет возможности использовать функцию sprintf для микроконтроллеров PIC16.
Используйте функцию void FloatToStr(float number, char *output);

Функция создает выходную строку output для числа с плавающей точкой number. Выходная строка содержит нормализованный формат числа number (мантисса в диапазоне от 0 до 1) со знаком в крайней левой позиции. Мантисса имеет фиксированный формат длиной 6 цифр, 0.ddddd т.е. после точки всегда следуют 5 десятичных цифр.

или МК PIC18 и выше.
0
1 / 1 / 0
Регистрация: 14.06.2014
Сообщений: 100
26.02.2015, 23:24  [ТС] 7
Владимир, так с int у меня же работает...
Мне надо, чтобы 2 числа после запятой было, а не 5)

Мне надо бы сделать на дешевом микроконтроллере, для этого вполне подходит 688.
0
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
26.02.2015, 23:42 8
user437, используйте целочисленные значения, это сэкономит вам нервы и много-много памяти контроллера .
Скажем, объявите signed long int volt; и работайте со значениями, умноженными на 1000. (то есть в милливольтах). И "округляйтесь" при выводе. Например:
C
1
printf("%d.%02d", volt/1000, abs(volt/10)%100);
Запись с виду грустная, потому что знаков после запятой в числе больше чем надо для вывода.
0
1 / 1 / 0
Регистрация: 14.06.2014
Сообщений: 100
26.02.2015, 23:55  [ТС] 9
Как я понял мои ошибки связаны с тем, что памяти не хватает. Да сколько же ему надо то тогда?! 4К мало для преобразования? Как же тогда это делать....

Сколько так будет? Мне надо 2 знака после запятой.

Добавлено через 5 минут
можно сделать тогда так:
например так:
10/3=3.333333....= нам надо вывести значение 3.33
Мы делаем целочисленными (т. к. памяти не хватает)
int a=10/3
Потом как то (как?) 10/3=.3333333....чтоб было -- найти деление
И в выводе это самое деление сократить до 2х чисел
не знаете тогда как это организовать?
0
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
27.02.2015, 00:00 10
Цитата Сообщение от user437 Посмотреть сообщение
10/3=3.333333....= нам надо вывести значение 3.33
вот так
C++
1
2
3
int a=10/3;
int b=10*100/3-a*100;
printf("%d.%d",a,b);
0
1 / 1 / 0
Регистрация: 14.06.2014
Сообщений: 100
27.02.2015, 00:32  [ТС] 11
Валерий, спасибо. Вроде как работает....
Остается понять как считать с правым сдвигом и почему с левым сдвигом считается более стабильным измерением.

Добавлено через 5 минут
Я еще один способ нашел. Завтра испробую. Если заработает и не забуду, то выложу.
0
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
27.02.2015, 00:34 12
Цитата Сообщение от user437 Посмотреть сообщение
почему с левым сдвигом считается более стабильным измерением.
потому что выбрасываются младшие разряды в которых чаще всего шум
плюс ошибки дискретизации, в измерительных приборах никогда не учитывают младший разряд
по правильному 10-разрядную АЦП нужно считать 9 разрядной
0
1 / 1 / 0
Регистрация: 14.06.2014
Сообщений: 100
27.02.2015, 10:16  [ТС] 13
потому что выбрасываются младшие разряды в которых чаще всего шум

Тогда надо наверное отбрасывать младшие разряды H - регистра, нежели старшие биты L-регистра
0
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
27.02.2015, 11:04 14
Цитата Сообщение от user437 Посмотреть сообщение
Тогда надо наверное отбрасывать младшие разряды H - регистра, нежели старшие биты L-регистра
так в H - регистре будут 8 старших разрядов отсчета а в L- 2 младших
вот так примерно
влево
C++
1
2
3
H   H  H  H  H    H  H  H  L  L  L  L  L   L  L  L
7   6  5  4   3   2  1  0  7  6  5  4  3  2  1  0
10  9  8  7   6   5  4  3   2 1  x   x  x  x  x  x
вправо
C++
1
2
3
H   H  H  H  H   H  H  H  L  L  L  L  L   L  L  L
7   6  5  4   3   2  1  0  7  6  5  4  3  2  1  0
х   х  х   х   х   х  10 9  8  7  6  5 4  3   2  1
0
1 / 1 / 0
Регистрация: 14.06.2014
Сообщений: 100
01.03.2015, 11:34  [ТС] 15
Валерий, неприятность у меня... На вход подключаю делитель напряжение (коэффициент деления 4)
Получается предварительно умножаю ADRESH*4 и делаю все тоже самое, что и без этого...
Должно получиться 11.92, а у меня 11.-1192 ... Если же умножать не на 100, а на 10, то нормально выводится 11.9
Почему так?
C
1
2
3
celoe=ADRESH*4/51;
ostatok=ADRESH*4*100/51-celoe*100;
sprintf(otvet, "%d.%d", celoe, ostatok);
Добавлено через 11 часов 45 минут
AND
почему-то выводы у которых написано C1(C2) OUT(IN) помечены как неопределенные в протеусе, хотя, хотя с ним можно снять показания АЦП.... Что это за выводы и как отключить эти Цэшки?
0
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
01.03.2015, 12:05 16
...переполнение у вас происходит. Смените тип int на signed long для переменных. И посмотрите строчку, которую советовал вам я выше. там дробная часть выводится по модулю, а вычисления дробной части сводятся к определению остатка от деления функцией "%" в сях, а не вычитанием целочисленной части из общего числа. Так проще в записи и меньше строчек.
0
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,524
01.03.2015, 12:17 17
Цитата Сообщение от user437 Посмотреть сообщение
celoe=ADRESH*4/51;
ostatok=ADRESH*4*100/51-celoe*100;
что ж ты два раза считываешь ??? во второй раз там может быть совершенно другое
C++
1
2
3
4
int value=ADRESH*4;
celoe=value/51;
ostatok=(value*100)/51-celoe*100;
sprintf(otvet, "%d.%d", celoe, ostatok);
Цитата Сообщение от user437 Посмотреть сообщение
11.92, а у меня 11.-1192
на лицо переполнение
размерность у переменных какая?

Добавлено через 3 минуты
Цитата Сообщение от Voland_ Посмотреть сообщение
остатка от деления функцией "%" в сях, а не вычитанием
деление, чаще всего дороже, умножения и вычитания
мне один раз пришлось делать через цикл(на AVR) уж очень тормозила %

Добавлено через 4 минуты
Цитата Сообщение от ValeryS Посмотреть сообщение
пришлось делать через цикл
а это мысль
если только исходные данные в миливольтах
C++
1
2
3
4
5
6
7
8
int value=ADRESH*4;
int celoe=0;
int ostatok=value;
while(ostatok>=1000)
{
ostatok-=1000;
value++;
}
0
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
01.03.2015, 13:48 18
Цитата Сообщение от ValeryS Посмотреть сообщение
деление, чаще всего дороже, умножения и вычитания
Да, действительно. Как-то не подумал. Запись '%' гораздо лаконичнее, чем вычисление остатка. В принципе если гнаться за производительностью, то и printf в данном случае не подходит.
Без вычисления остатков можно сделать так:
1) Умножаем показания АЦП на 10 в степени количества знаков после запятой. Если нужно два знака - умножаем на 100.
2) Делим результат на делитель, сопоставляющий выводимую единицу измерения с "попугаями" шкалы АЦП.
3) Выводим результат в текстовый буфер, со знаком.
4) Считаем количество байт в получившейся строке - N.
5) Выводим: Первые N-2 символов, потом точку, затем оставшиеся символы.
0
1 / 1 / 0
Регистрация: 14.06.2014
Сообщений: 100
01.03.2015, 15:14  [ТС] 19
Цитата Сообщение от ValeryS Посмотреть сообщение
что ж ты два раза считываешь ??? во второй раз там может быть совершенно другое
Код C++
1
2
3
4
int value=ADRESH*4;
celoe=value/51;
ostatok=(value*100)/51-celoe*100;
sprintf(otvet, "%d.%d", celoe, ostatok);
тоже самое же, только больше переменных.
Еслиб было бы переполнение, то наверное ostatok=ADRESH*7.84313724-celoe*100;
не помогло бы.
Но мне такая запись не очень нравится.

Итак, ребята -- в чем проблема тогда получается и каково решение?
0
01.03.2015, 15:14
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.03.2015, 15:14
Помогаю со студенческими работами здесь

Работа с АЦП ADuC842
Всем доброго времени суток, помогите пожалуйста найти решение моей проблемы! Необходимо найти...

Работа с АЦП (PIC16F676)
МК pic16f676 Задача: попробовать сделать АЦП. Код программы: #include &lt;htc.h&gt; ...

ATtiny13. Работа с АЦП (Си)
необходима информация о том, как правильно можно использовать ЦАП и компаратор в паре, а именно с...

Работа с АЦП микроконтроллером PIC
movlw b'11111111' movwf TRISA movlw b'00000001' movwf TRISB clrf TRISD bcf...

Контроль светодиода кнопкой (PIC16F688, MPLab X, XC8)
Здравствуйте. Недавно начал осваивать программирование под МК, и застрял в самом начале. Не могу...

PIC16F688 и SIM900D
Доброго времени суток, собрал GSM сигнализацию на данной связке, при включении модуль...

Работа АЦП
Доброго времени суток! Решил я немного поиграться с АЦП и написал простенький скетч, с...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru