AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
01.11.2016, 18:46
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 7,072
Сказал спасибо: 3,054
Сказали Спасибо 3,223 раз(а) в 2,188 сообщении(ях)
|
Re: Работа с AD7799
Код:
|
void spi_write(unsigned char c)
{
unsigned char i;
for(i=8; i; i--)
{
if(c & 0x80) PORTB |= (1 ‹‹ SPI_DOUT); // ... - сначала выдать данные, ...
else PORTB &= ~(1 ‹‹ SPI_DOUT);
PORTB &= ~(1 ‹‹ SPI_SCLK); // ... а потом сказать "АЦП - принимай".
delayMicroseconds(2);
if(c & 0x80) PORTB |= (1 ‹‹ SPI_DOUT); // Здесь, наоборот, ...
else PORTB &= ~(1 ‹‹ SPI_DOUT);
PORTB |= (1 ‹‹ SPI_SCLK);
delayMicroseconds(2);
c ‹‹= 1;
}
}
.....
.....
//Читать 16-bit в переменную data
PORTB &= ~(1 ‹‹ SPI_CS);
unsigned short int data;
unsigned char lowbyte, highbyte;
lowbyte = spi_read();
highbyte = spi_read();
data = lowbyte + highbyte; // Небольшая неточность.
data = lowbyte + (highbyte ‹‹ 8);
PORTB |= (1 ‹‹ SPI_CS); |
|
|
|
Сказали "Спасибо" ForcePoint
|
|
|
01.11.2016, 19:18
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,446
Сказал спасибо: 99
Сказали Спасибо 317 раз(а) в 233 сообщении(ях)
|
Re: Работа с AD7799
На какой частоте работает контроллер? Там эти задержки, скорее всего, совсем не нужны.
Что за компилятор? Почему shortint, а не просто int?
|
|
|
|
01.11.2016, 20:45
|
|
Временная регистрация
Регистрация: 24.08.2010
Сообщений: 74
Сказал спасибо: 41
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: Работа с AD7799
Godzilla82,
Для экспериментов в выходные купил себе Arduino UNO, подумал что это подает мне для экспериментов.
Сообщение от Godzilla82
|
Что за компилятор? Почему shortint, а не просто int?
|
Среда разработки и компилятор Arduino IDE. можно и просто int, разница вроде только в написание. Но int красивее)
Сообщение от Godzilla82
|
На какой частоте работает контроллер? Там эти задержки, скорее всего, совсем не нужны.
|
Кварц стоит на 16Мгц., подозреваю что и контроллер тоже настроен на 16Мгц.
P.S. Я не понимаю синтаксис Arduino IDE, и нет желания в нем разбираться, по мне он какой то муторный. По этому стараюсь писать на С.
P.S. Раньше в школе ходил на кружок программирования, а спустя 15 лет опять стало интересно, вот опять начал потихоньку познавать. В общем хобби, интересно и познавательно!
Спасибо!
|
|
|
|
02.11.2016, 09:59
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,446
Сказал спасибо: 99
Сказали Спасибо 317 раз(а) в 233 сообщении(ях)
|
Re: Работа с AD7799
Сообщение от Mr.Denis
|
можно и просто int, разница вроде только в написание. Но int красивее)
|
Обычно тип int соответствует разрядности так называемого машинного слова. У 8-битных AVR оно равно 16 бит, а всякие префиксы small- short- вводятся тогда, когда слово уже 32 или 64 бита.
Сообщение от Mr.Denis
|
подозреваю что и контроллер тоже настроен на 16Мгц.
|
И какое время занимает выполнение однотактовой инструкции? И сколько инструкций (и по сколько тактов) между изменениями состояния CLK?
Сообщение от Mr.Denis
|
По этому стараюсь писать на С.
|
Ну тогда я бы советовал выбрать нормальный компилятор: WinAVR, IAR, CodeVision. Хотя у дурдурины вроде бы GCC как и в WinAVR.
P.S. А что за контроллер? Mega328?
Последний раз редактировалось Godzilla82; 02.11.2016 в 10:01.
|
|
|
Сказали "Спасибо" Godzilla82
|
|
|
02.11.2016, 11:08
|
|
Прописка
Регистрация: 14.09.2010
Сообщений: 105
Сказал спасибо: 9
Сказали Спасибо 15 раз(а) в 11 сообщении(ях)
|
Re: Работа с AD7799
Сообщение от Godzilla82
|
Ну тогда я бы советовал выбрать нормальный компилятор: WinAVR, IAR, CodeVision. Хотя у дурдурины вроде бы GCC как и в WinAVR.
|
Да вполне нормальный там компилятор. Полностью совместим с WinAVR, поддерживаются ПОЧТИ! все библиотеки от WinAVR. Но он расширен до С++. В чем то это даже удобнее обычного Си. Но вот сама IDE точнее ее редактор не удобен. Если есть программатор то можно вполне пользоваться теми-же WinAVR, IAR, CodeVision, а программу "заливать" через SPI. Благо на UNO есть даже отдельный разъем для этого.
К стати если таки ТС будет пользоваться Arduino IDE то рекомендую не использовать конструкций типа:
PORTB |= (1 ‹‹ SPI_SCLK);
Лучше пользоваться функциями типа: digitalWrite(), digitalRead(). Код при этом получится не оптимальным, но в противном случае может возникнуть не совместимость.
Последний раз редактировалось AlexPi; 02.11.2016 в 11:21.
|
|
|
|
02.11.2016, 15:15
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,446
Сказал спасибо: 99
Сказали Спасибо 317 раз(а) в 233 сообщении(ях)
|
Re: Работа с AD7799
Сообщение от AlexPi
|
Лучше пользоваться функциями типа: digitalWrite(), digitalRead(). Код при этом получится не оптимальным, но в противном случае может возникнуть не совместимость.
|
Вот я и советовал уйти на другую среду программирования, чтобы не пользоваться дурдуриновскими функциями, а писать программу самому с нуля, работая с железом напрямую.
|
|
|
|
03.11.2016, 21:28
|
|
Временная регистрация
Регистрация: 24.08.2010
Сообщений: 74
Сказал спасибо: 41
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: Работа с AD7799
Здравствуйте!
Всем огромное Спасибо за советы и участие в данной теме!
К сожалению программатора у меня нет, поэтому пока буду использовать arduino.(
При Вашей помощи мне немного удалось разобраться с программным SPI и прицепами его работы! к сожалению железо пока еще не готово, и проверить корректность программного SPI нет возможности. Поэтому пока продолжаю ковыряться с теорией. Теперь следующая стадия теоретически понять как работать непосредственно с AD7799, а именно последовательность действий. На первой странице этой темы -Alan- дал уже очень сильную подсказку и у меня сложилась следующая картина:
Я так понимаю что мне перед началом работы с AD7799 нужно вначале сделать Reset, в даташите написано, что если 32 такта подряд отправлять 1(еденицу), то происходит сброс. Вот как я вижу эту функцию:
Код:
|
// функция Reset
PORTB &= ~(1 ‹‹ SPI_CS);
spi_write(0xFF);
spi_write(0xFF);
spi_write(0xFF);
spi_write(0xFF);
PORTB |= (1 ‹‹ SPI_CS); |
Дальше нужно инициализировать/настроить АЦП.
Для этого служат 2(два) 16-bit регистров, Регистр режима(MODE REGISTER) и регистр конфигурации(CONFIGURATION REGISTER). Прежде чем работать с одним из режимов, я должен в регистре связи(COMMUNICATION REGISTER) выбрать регистр с которым я хочу в дальнейшем работать. У меня получилась примерно вот такая картина:
Код:
|
PORTB &= ~(1 ‹‹ SPI_CS);
spi_write(0x08); // Выбираем регистр режима
// что-то записываем, например FF
spi_write(0xFF); // Старший байт
spi_write(0xFF); // Младший байт
PORTB |= (1 ‹‹ SPI_CS);
PORTB &= ~(1 ‹‹ SPI_CS);
// что-то записываем, например FF
spi_write(0x10); // Выбираем регистр конфигурации
spi_write(0xFF); // Старший байт
spi_write(0xFF); // Младший байт
PORTB |= (1 ‹‹ SPI_CS); |
Подскажите пожалуйста, правильно я понимаю что, по такому принципу происходит настройка АЦП? Этот код инициализации выполняется один раз до основного цикла?
Чтение из АЦП происходит уже в основном цикле и имеет примерный вид:
Код:
|
unsigned short int data;
unsigned char lowbyte, highbyte;
PORTB &= ~(1 ‹‹ SPI_CS);
spi_write(0x58);
lowbyte = spi_read();
highbyte = spi_read();
PORTB |= (1 ‹‹ SPI_CS);
data = lowbyte + (highbyte ‹‹ 8); |
Скажите пожалуйста, ход мысли верный или нет?
Единственное надо еще подумать как определить что АЦП готов передать данные. Тут я понимаю есть 2 варианта, либо по пину RDY заведенному на прерывание, либо постоянно читать регистр статуса?
Если читать регистр статуса, то тогда нужно написать условие которое будет проверять этот бит в регистре. Не могу пока сообразить как написать это условие на ум приходит что-то типа:
Код:
|
if(spi_read()==0x80){
// Данные готовы можно читать.
} |
Но подозреваю что это не правильно!(
Подскажите пожалуйста, как написать условие которое будет проверять только 1(один) определенный бит из 8(восьми)?
Спасибо!
|
|
|
|
03.11.2016, 21:59
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,446
Сказал спасибо: 99
Сказали Спасибо 317 раз(а) в 233 сообщении(ях)
|
Re: Работа с AD7799
Сообщение от Mr.Denis
|
Подскажите пожалуйста, как написать условие которое будет проверять только 1(один) определенный бит из 8(восьми)?
|
PHP код:
|
if(STATUS & 0b10000000) ...
|
Перед тем как читать регистр состояния командой spi_read(), надо выбрать действие и объект, записав соответствующий код при помощи spi_write().
А зачем использовать программный SPI, когда есть аппаратный?
Работать с ним не сложно.
Последний раз редактировалось Godzilla82; 03.11.2016 в 22:03.
|
|
|
Сказали "Спасибо" Godzilla82
|
|
|
04.11.2016, 00:36
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 7,072
Сказал спасибо: 3,054
Сказали Спасибо 3,223 раз(а) в 2,188 сообщении(ях)
|
Re: Работа с AD7799
1. Судя по диаграммам на стр. 20 и 21 - сигнал выбора должен оставаться активным всё время обмена данными с АЦП.
Код:
|
PORTB &= ~(1 ‹‹ SPI_CS);
запись коммуникационного регистра;
настройка режима;
чтение;
и т.п.;
PORTB |= (1 ‹‹ SPI_CS); |
2.
Код:
|
if (!(spi_read() & 0x80))
{ // Данные готовы можно читать. } |
|
|
|
Сказали "Спасибо" ForcePoint
|
|
|
04.11.2016, 02:48
|
|
Временная регистрация
Регистрация: 24.08.2010
Сообщений: 74
Сказал спасибо: 41
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: Работа с AD7799
Godzilla82,
Спасибо!
Я понимаю что, прежде чем читать регистр состояния к нему нужно обратится через запись в регистр связи.
Буду пробывать работать с АЦП как через аппаратный так и через программный SPI.
C программным решил попробовать разобраться из-за интереса и просто для практики.
ForcePoint,
Спасибо!
Вы предполагаете что после каждого сброса CS все настройки АЦП обнуляются?
Смотрел я в даташите эти диаграммы, но смущает вот что:
Не думаю что разработчики с делали так что, при чтение нужно каждый раз конфигурировать АЦП. Когда одно устройство на шине SPI думаю глобально в этом проблем нет, так как один раз сконфигурировал АЦП, активировал CS и забыл, а что делать если на шине SPI несколько устройств!? Тогда каждый раз придется конфигурировать АЦП перед чтением?
Вы могли бы мне рассказать почему именно data = lowbyte + (highbyte ‹‹ 8 )?
Если я правильно понимаю, то операция highbyte ‹‹ 8 приведет к тому что highbyte=0?
Не совсем уловил смысл, пытаюсь разобраться, но пока не очень получается(
Спасибо!
Последний раз редактировалось Mr.Denis; 04.11.2016 в 03:13.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 07:10.
|
|