Здравствуйте ребятушки коты, вот пытаюсь подключить цифровой потенциометр MCP41010 к mege 8. У меня 2 вопроса: 1-я пишу все кодом, т.е. начиная от чип селекта и заканчивая данными, все контролируется кодом (каков шанс на успех?). 2- если потенциометр имеет 255 разрядность, и имеет 8 бит данных, то что ему посылать? 128 это будет половина, а 64 1/4? PS пока что он вообще не реагирует после включения он показывает 4,25 кОм(половину от своего сопротивления), а во время прошивки уходит в режим высокого R.
http://ww1.microchip.com/downloads/en/D ... 11195c.pdf У потенциометра ТРИ вывода. Управляемый (двигающийся) называется вайпер (wiper). И еще два: нижний В и верхний А. Нулевой код означает НИЖНЕЕ положение вайпера. Код 0xFF - это ВЕРХНЕЕ положение вайпера. Так же вайпер имеет собственное ПОСЛЕДОВАТЕЛЬНОЕ сопротивление порядка 100 Ом. Зависимость его величины от параметров питания и температуры имеется в даташите.
я ему посылал и 0 и 255 и 128, глухо) показывает 4,5 во всех, со 128 вроде и правильно)) но что то мне подсказывает что он не пашет, т.к. это в любых случаях он показывает. Вот кусок моей функции посыла 8го бита(такие же для 64,32,16 итп) может что не так, гляньте прошу): //***************** void con (int sss) { if ((sss&128)==128) { PORTC = (PORTC|0x8); //включаю пин С4 (тактовый) PORTC = (PORTC|0x10);//включаю к нему С5(если восьмой бит = 1) _delay_ms(100); PORTC = (PORTC&0xf7);//выключаю такт, при этом по С5(данные) еще есть (лог 1), т.к. если я правильно понял // то резистор забирает бит по спаду такта _delay_ms(50); PORTC= (PORTC&0xe7);// ну и убираю данные с пина С5. _delay_ms(150); } else { PORTC = (PORTC|0x8); PORTC = (PORTC&0xef); _delay_ms(100); PORTC = (PORTC&0xf7); _delay_ms(50); PORTC= (PORTC&0xe7); _delay_ms(150); // и еще 7 бит так же. } } int main() { DDRC=0xff;
con(128); PORTC=(PORTC|0x2);// включаю чип селект и по идее потенциометр должен грузить в этот момент принятые данные в //свой исполнительный регистр. _delay_us(150); } //************* PS задержку _ms - взял чтобы посмотреть что там происходит, припаял светодиоды ко всем, за неимением осциллографа приходится выкручиваться), а так стоит us.
то что ему посылать? КОД. У меня один знакомый на кофейной гуще умеет годать, но на этом форуме вроде таких нет.
Жалко что не КОТ, на этом форуме таких полно. А гОдание на кофейной гуще было бы не в этом разделе форума думаю, так что не по сути уважаемый выстрелили.
Абсолютно все Вы сделали неправильно и совсем не по картинке. Замечания к коду: 1. Для активизации CS нужно выставить на этом пин лог. 0, а не 1 как в коде. 2. В чип надо передавать 2 байта согласно Fig 5.1. Первый байт - код опеации, второй байт данные. 3. Данные считываются чипом по нарастающему фронту clock-a. Т.е. сначала надо выставить бит на линии SI, потом поднять clock, потом его опустить и только потом менять данные. 4. Я не понял в чем идея IF-THEN-ELSE оператота в функции con()? 5. Не вижу посылки более чем одного бита в этой функции.
Абсолютно все Вы сделали неправильно и совсем не по картинке. Замечания к коду: 1. Для активизации CS нужно выставить на этом пин лог. 0, а не 1 как в коде. 2. В чип надо передавать 2 байта согласно Fig 5.1. Первый байт - код опеации, второй байт данные. 3. Данные считываются чипом по нарастающему фронту clock-a. Т.е. сначала надо выставить бит на линии SI, потом поднять clock, потом его опустить и только потом менять данные. 4. Я не понял в чем идея IF-THEN-ELSE оператота в функции con()? 5. Не вижу посылки более чем одного бита в этой функции.
1. Я сначала включаю CS, PORTC=(PORTC|0x02); а затем его выключаю PORTC=(PORTC&0xfd); 2. так и есть, я несколько раз написал что у меня 8 бит с 128 по 1 десятичные кодируются так, т.е. я писал функцию которая будет облегчать передачу резистору значения, например если передать 17 в кон то это и будут первые 8 бит" 0001 0001 " которые будут переданы так как есть благодаря сравнению if - else в Serial input(т.е. это означает 5 бит - пригтовится к записи данных и 1 бит - включить потенциометр). я доделал функцию (сократив кучу сравнений в цикл) : ***************************** void con (int easy) { int s,ss,sss,i; sss=easy;
for (ss=7;ss>=0;ss--) { s=pow(2,ss); if ((sss&s)==s) { PORTC = (PORTC|0x10);// включаю 1(если она там) _delay_us(20); PORTC = (PORTC|0x8); //включаю клок _delay_us(100); PORTC = (PORTC&0xf7);//выкл клок _delay_us(20); PORTC= (PORTC&0xef);// выкл единицы. _delay_us(140); } else { PORTC = (PORTC&0xef); // аналогично только для нуля- "включаю" ноль _delay_us(20); PORTC = (PORTC|0x8); // включаю клок _delay_us(100); PORTC = (PORTC&0xf7);//выкл _delay_us(20); PORTC= (PORTC&0xef);// "выкл" нуля, знаю что глупо выглядит но не вижу тут грубейшей ошибки. _delay_us(140); } } } ******************************** 3. и да, тут уже я читая ДШ понял ошибку с передачей по началу клока, сейчас должно быть правильно. (но не пашет, я уже даже зафигачил A на W как на картинке реостатового режима) 5. - посылка есть и посылка эта 16 бит, т.к. вызов фции кон идет 2 раза, один передаю 17, второй значение положения движка. PS - Ужасный фейловый вопрос - в какой послед ности отправлять биты? от 1 к 8? или от 8 к 1? потому что сейчас я отправляю от 8 к 1. (на рисуночке из раздела 5 так и написано, два не исп бита потом С1 потом С0...) и еще может я его подключаю не верно в плане измерения сопротивления - подключаю омметр к А замкнутому на W и воторой щуп на B.
Я сначала включаю CS, PORTC=(PORTC|0x02); а затем его выключаю PORTC=(PORTC&0xfd);
Надо делать наоборот: сначала PORTC=(PORTC&0xfd); а потом PORTC=(PORTC|0x02); Сигнал CS активизируется нулем! Посмотрите в отладчике состояния пинов порта про посылке каждого бита байта.
Я сначала включаю CS, PORTC=(PORTC|0x02); а затем его выключаю PORTC=(PORTC&0xfd);
Надо делать наоборот: сначала PORTC=(PORTC&0xfd); а потом PORTC=(PORTC|0x02); Сигнал CS активизируется нулем!
Как так, смотрите порт с = (PORTC&0xfd) это значит что только 1 и 1 дадут 1, а C1 будет 0!, т.к. маска 0xFD наложенная даже на 1111 1111 даст 1111 1101, неужели не так? Да и как, если вы говорите что активируем прием нулем на чип селекте, так? то тогда все правильно - сначала я его включаю в 1, потом выключаю! и активирую нулем! я не понимаю уже ничего))) Если мы сделаем так "сначала PORTC=(PORTC&0xfd); а потом PORTC=(PORTC|0x02);" то выйдет что сначала был 0, потом 1.
Ser60 писал(а):
Protobear писал(а):
Посмотрите в отладчике состояния пинов порта про посылке каждого бита байта.
Возможно, что насчет CS мы говорим об одних и тех-же вещах. Предполагая, что в самом начале программы CS установлен в 1, работать с чипом следует так:
PORTC=(PORTC&0xfd); // активизировать чип - после этой команды на выводе CS чипа должно быть 0В затем послать 2 байта в чип, не трогая при этом CS PORTC=(PORTC|0x02); // деактивировать чип - после этой команды на CS должна быть лог. 1
Если делаете именно так, то все правильно. Насчет отладчика, зависит от вашей среды отладки. Я с AVR работал только в Atmel Studio. В версии 6.0, например, зайдите в Project -> Properties и в закладке Tool нужно чтобы было выставлено AVR Simulator. После этого можно начинать отладку Debug -> Start debugging и включить I/O view (Debug -> Windows -> I/O View). С другими IDE для AVR я не работал и как делать то-же самое в них не знаю, хотя более чем уверен, что можно.
Где функция передачи данных? Если просто подёргать ногами то далеко не уедишь. То что я вижу это просто вкючение порта и выключение. Где SPI ? или трёхпроводный протокол.
_________________ Ни один домашний кот незнает что он домашний.
А он и пытается реализовать физический и канальный уровни. Сначала написать выталкивание байта с клоками, как функцию, а потом только передавать в нее управляющие байты и данные логической части протокола.
Я тоже могу "Обосрать" себя, но раз вы кот настолько высокоКвАЛифицированный, то могли бы подкинуть совет толковый не по вашему мировоззрению этой проблемы, а исходя из моих злоключений. То что я отвергаю аппаратный spi не значит что я плохо пытаюсь. Хотя может вы говорили о моем питании, тогда да - есть хочется всегда.
А он и пытается реализовать физический и канальный уровни. Сначала написать выталкивание байта с клоками, как функцию, а потом только передавать в нее управляющие байты и данные логической части протокола.
Хвала Господу что есть коты, которые улавливают суть
Все, заработал, всем спасибо))))). единственное не понятно почему то не работает цикл в контроллере, пришлось писать условия побитовых сравнений для всех 8 бит ( 128 64 32 16 8 4 2 1). есть идеи?? почему не пашет цикл. возможно double имеет какой то мусор в себе и не возводит четко в степень? или как? потому что только когда 255 то горел диод подключенный на тру, а когда давал допустим 64, то диод на тру не горел ни разу, а все 8 бит горел фолсовоусловный диод. (дело в том что компилятор ругается когда в функции pow(s,x) x не является даблом или флотом.)
Зачем Вы вообще используете функцию pow()? Заведите переменную и присвойте ей значение 128 до входа в цикл. В самом цикле, в конце его, просто делите эту переменную на 2 для следующей итерации. Деление можно организовать сдвигом на 1 бит вправо. МК Вам только спасибо скажет. Или организуйте цикл так:
for (s=128; s!=0; s = s>>1) { if ((sss&s) == s) ...
Зачем Вы вообще используете функцию pow()? Заведите переменную и присвойте ей значение 128 до входа в цикл. В самом цикле, в конце его, просто делите эту переменную на 2 для следующей итерации. Деление можно организовать сдвигом на 1 бит вправо. МК Вам только спасибо скажет. Или организуйте цикл так:
for (s=128; s!=0; s = s>>1) { if ((sss&s) == s) ...
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения