Форум РадиоКот 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, прикрепляю проект в протеусе.
|
Автор: | pyzhman [ Чт июл 23, 2015 16:53:54 ] |
Заголовок сообщения: | Re: 8051 и adc0808 |
Программу и прошивку выкладывайте. Мне вот лень тыкаться на том сайте. |
Автор: | denya [ Чт июл 23, 2015 20:11:01 ] | ||
Заголовок сообщения: | Re: 8051 и adc0808 | ||
извиняюсь, выкладываю прошивку и текст программы.
|
Автор: | 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 ![]() |
Автор: | 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 = (N*Vref)/256 Надеюсь вы эту формулу имеете ввиду, ваша запись не совсем понятна Исправил вызовом функции через переменную: U_AB = ADC_AB_U();... ...В даташиде посмотрел формулу: U = N/256*Uref. В чем может быть ошибка? ![]() Однако дело не в этом. Посмотрите ДШ еще более внимательно и вы увидите, что у вас просто перепутаны местами MSB и LSB! Картинка, которую вы нашли вместе с проектом и на которой показано подключение микросхем АЦП и МК вводит в заблуждение ![]() Теперь сделайте новое подключение порта МК к АЦП так: 21 вывод АЦП к Р1.7 20 вывод АЦП к Р1.6 ... 17 вывод АЦП к Р1.0 После этого ваша программа заработает правильно ![]() Или, не трогая схему подключения, в программе "отзеркальте" принятый байт с АЦП. Например, приняли А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/ |