Например TDA7294

Форум РадиоКот :: Просмотр темы - 8051 и adc0808
Форум РадиоКот
https://radiokot.ru/forum/

8051 и adc0808
https://radiokot.ru/forum/viewtopic.php?f=61&t=119254
Страница 1 из 1

Автор:  denya [ Чт июл 23, 2015 15:52:20 ]
Заголовок сообщения:  8051 и adc0808

Помогите подружить мк 8051 ( в протеусе взял функциональный аналог AT89C51RD2) и ацп ADC0808.
Вроде все просто, нашел схему, нашел даже пример кода на си, сделал, вывожу данные через uart, на выходе 6 -ти значные числа, хотя максимум может быть 255, уже не знаю в чем дело может быть.
Пример взял вот отсуда http://www.8051projects.net/wiki/ADC080 ... g_Tutorial, прикрепляю проект в протеусе.

Вложения:
test.rar [16.79 KiB]
Скачиваний: 175

Автор:  pyzhman [ Чт июл 23, 2015 16:53:54 ]
Заголовок сообщения:  Re: 8051 и adc0808

Программу и прошивку выкладывайте. Мне вот лень тыкаться на том сайте.

Автор:  denya [ Чт июл 23, 2015 20:11:01 ]
Заголовок сообщения:  Re: 8051 и adc0808

извиняюсь, выкладываю прошивку и текст программы.

Вложения:
program.rar [2.49 KiB]
Скачиваний: 179

Автор:  denya [ Сб июл 25, 2015 16:11:10 ]
Заголовок сообщения:  Re: 8051 и adc0808

неужто ни кто не работал с этим ацп ?

Автор:  Rtmip [ Вс июл 26, 2015 11:01:41 ]
Заголовок сообщения:  Re: 8051 и adc0808

denya,
1 - замените в симуляции генератор на логическом элементе генератором протеуса на 300-500 кГц.
2 - Vref сделайте 5 В, ваши 12 В... это уж слишком путает показания.
3 - посмотрите в своем проекте функцию
Цитата:
printf ("%u\n", ADC_rezult());

Сейчас она передает в терминал слово, а не байт.
Если перевести принятые цифры в шестнадцатиричный вид, то вы увидите, что то
что принимает сейчас терминал выглядит так: ХХ00 - это два байта, где ХХ это байт с вашей полезной
информацией, той что принял МК от АЦП через порт1.
А 00 это, то что вы добавляете в программе функцией printf, просто два нуля.
Поэтому такие странные цифры в терминале :))
Проще говоря, смотрите printf или выводите инфу в терминал просто загрузив байт данных в SBUF :idea:

Автор:  denya [ Вс июл 26, 2015 14:50:40 ]
Заголовок сообщения:  Re: 8051 и adc0808

Да, ошибка была как раз в том, что выводило слово, а не байт.
Исправил вызовом функции через переменную:
U_AB = ADC_AB_U();
Теперь выводит диапазон верно, но значение не совсем корректны:
например при опорном напряжении в 5 вольт и входящем 1, выдает значение 204, что соответствовать должно 4 вольтам, а не 1.
Соответственно наоборот тоже самое, подаю 4 вольта, на выходе 51.
Что странно, 0, 2, 3 и 5 вольт если подать, выдает корректно.
В даташиде посмотрел формулу: U = N/256*Uref.
В чем может быть ошибка?

Автор:  Rtmip [ Вт июл 28, 2015 00:28:23 ]
Заголовок сообщения:  Re: 8051 и adc0808

denya писал(а):
Да, ошибка была как раз в том, что выводило слово, а не байт.
Исправил вызовом функции через переменную:
U_AB = ADC_AB_U();...
...В даташиде посмотрел формулу: U = N/256*Uref.
В чем может быть ошибка?
U = (N*Vref)/256 Надеюсь вы эту формулу имеете ввиду, ваша запись не совсем понятна :))
Однако дело не в этом.
Посмотрите ДШ еще более внимательно и вы увидите, что у вас просто перепутаны местами MSB и LSB!
Картинка, которую вы нашли вместе с проектом и на которой показано подключение микросхем АЦП и МК вводит в заблуждение :kill:
Теперь сделайте новое подключение порта МК к АЦП так:
21 вывод АЦП к Р1.7
20 вывод АЦП к Р1.6
...
17 вывод АЦП к Р1.0
После этого ваша программа заработает правильно :idea:
Или, не трогая схему подключения, в программе "отзеркальте" принятый байт с АЦП.
Например, приняли А0Н, измените его в 05Н.
Приняли 80Н, измените его в 01Н и так далее.
Совет, протеусу все равно, а вам удобнее будет если частоту на АЦП подавать небольшую.
Чтобы данные в терминале были нагляднее сделайте Vref = 2,55 Вольт.
Тогда цифры в терминале будут соответствовать входному напряжению, но без десятичной точки.
P.S. А вот как вы через переменную перешли от 2х байт к одному при работе функции printf не понял? :)

Автор:  denya [ Вс авг 02, 2015 07:11:47 ]
Заголовок сообщения:  Re: 8051 и adc0808

отзеркалил байт, все стало хорошо, спасибо :)
А про 2 байта и функции printf, почему я передалю 2 байта? не совсем понял что вы имеите в виду.

p/s. Нашел метод отзеркаливания байта, но не понял до конца суть работы:

uint8_t InverseByte(uint8_t b)
{
uint8_t ret = 0;
for( uint8_t i = 0x80; i; i >>= 1 )
{
if( b & 1 )
ret |= i;
b >>= 1;
}
return ret;
}

Что проверяет условие if( b & 1 ) ? если исходный байт 00110000, то условие сравнивает весь байт? или бит, который находится в позиции i ?

Автор:  Rtmip [ Пн авг 03, 2015 00:22:20 ]
Заголовок сообщения:  Re: 8051 и adc0808

denya писал(а):
отзеркалил байт, все стало хорошо, спасибо :)
Прекрасно :)
denya писал(а):
не совсем понял что вы имеите в виду.

Я спрашивал про вот это:
Цитата:
Исправил вызовом функции через переменную:
U_AB = ADC_AB_U();
- не понял как работает? :))
Вообще, заглянул в доку от Кейла и понял, что проще можно делать.
Например так:
Код:
   number = 173;             //например надо вывести 1,73 V. Выводим:
   printf ("%bu,%bu%bu%c V\n",number/100,(number/10)%10,number%10);

В терминале будет: 1,73 V
Или просто вывести 173:
Код:
printf ("%bu\n",number);

denya писал(а):
p/s. Нашел метод отзеркаливания байта, но не понял до конца суть работы:
Хорошая функция, мне понравилась, только в названии InverseByte некорректно. Но это неважно.
В условии if( b & 1 ) единица это маска, накладываемая на байт:
Код:
0b00110000    //исходный байт
&
0b00000001    //маска

Условие сравнивает биты в самом младшем разряде байтов.
То есть, восемь раз проверяем, что находится самом младшем бите изменяемого байта b.
Если проверяемый(самый младший) бит равен единице, то пишем единицу в соответствующую позицию
измененного(зеркального) байта ret. Если нет, то там остается нуль.
Затем сдвиг вправо исходного байта и счетчика i, значит потом будет проверяться следующий бит.

Автор:  denya [ Пн авг 03, 2015 09:30:26 ]
Заголовок сообщения:  Re: 8051 и adc0808

теперь все ясно, спасибо :)

Автор:  Const14 [ Чт авг 06, 2015 10:13:29 ]
Заголовок сообщения:  Re: 8051 и adc0808

Rtmip писал(а):
Хорошая функция, мне понравилась, только в названии InverseByte некорректно.

Действительно, название функции некорректно. Правильное название этой операции РЕВЕРСИЯ.
В книге Генри Уоррена "Алгоритмические трюки для программистов" приводится вариант этой операции без использования цикла.
Думаю, что с учётом сказанного функцию можно переписать в виде:

uint8_t ReverseByte(uint8_t b)
{
uint8_t ret;

ret = ((b & 0x55)<<1) | ((b & 0xAA)>>1);
ret = ((ret & 0x33)<<2) | ((ret & 0xCC)>>2);
ret = ((ret & 0x0F)<<4) | ((ret & 0xF0)>>4);

return ret;
}
Такая функция, тоже должна понравиться :)

Автор:  Rtmip [ Сб авг 08, 2015 01:59:09 ]
Заголовок сообщения:  Re: 8051 и adc0808

Плюсую.
Практически функция хороша, но вот мысленно ее "прокрутить" сложно :))
Спасибо, взял на заметку.
Вы напишите об этой функции в тему по трюкам: http://radiokot.ru/forum/viewtopic.php?f=62&t=78185&start=100

Автор:  Ser60 [ Сб авг 08, 2015 04:30:40 ]
Заголовок сообщения:  Re: 8051 и adc0808

Во многих силлабовских 8051 контроллерах (например, серия C8051F9xx и в новой серии EFM8) имеется модуль CRC для подсчёта контрольной суммы, в состав которого входит блок аппаратной инверсии битов байта. Для этого байт b подлежаший инвертированию следует сначала записать в регистр CRC0FLIP. При последующем чтении из этого регистра порядок битов ранее записанного байта автоматически инвертируется. На С это занимает 2 строчки кода:
CRC0FLIP = b;
b = CRC0FLIP;

Автор:  denya [ Пн авг 10, 2015 09:15:25 ]
Заголовок сообщения:  Re: 8051 и adc0808

Const14 писал(а):
Rtmip писал(а):
Хорошая функция, мне понравилась, только в названии InverseByte некорректно.

Действительно, название функции некорректно. Правильное название этой операции РЕВЕРСИЯ.
В книге Генри Уоррена "Алгоритмические трюки для программистов" приводится вариант этой операции без использования цикла.
Думаю, что с учётом сказанного функцию можно переписать в виде:

uint8_t ReverseByte(uint8_t b)
{
uint8_t ret;

ret = ((b & 0x55)<<1) | ((b & 0xAA)>>1);
ret = ((ret & 0x33)<<2) | ((ret & 0xCC)>>2);
ret = ((ret & 0x0F)<<4) | ((ret & 0xF0)>>4);

return ret;
}
Такая функция, тоже должна понравиться :)


Да, я использовал именно эту функцию, а с циклом для общего развития интересовался :)

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/