|
|
  |
SPI отправка и получение данных с регистров ведомого устр. |
|
|
|
Apr 10 2011, 16:38
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737

|
Доброго времени суток, есть проблема чтения и записи регистров модуля акселерометра работающего через SPI. Подскажите как на Си читать и писать в регистры данного модуля. Например нужно отправить с меги 16 значение 0b00000101 в регистр $16. SPI разобрался как конфигурировать, проблема за малым. Спасибо
MMA7455L_____________.pdf ( 519.11 килобайт )
Кол-во скачиваний: 334
|
|
|
|
|
Apr 10 2011, 17:56
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737

|
т.е. для записи в регистр ММА7455 можно так: SPI_MasterTransmit(0b11011000); //записываю в 16 регистр мма7455 SPI_MasterTransmit(0b00000101); // значение 0b00000101 где SPI_MasterTransmit ф-ция записи в регистр ???
|
|
|
|
|
Apr 12 2011, 11:40
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737

|
ясно, спасибо, буду пробовать
|
|
|
|
|
Apr 17 2011, 18:09
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737

|
Уже неделю пытаюсь добиться работы акселерометра. Но все никак. Подозрение вызывает потребляемый ток 1.7 mA По ДШ 490 мкА максимум. Питаю акселерометр от L78L33. МК от 5В. Согласование уровней МК - Датчик сделал на мосфетах по AN97055. Черт его знает, что не так.
Вот ф-ция отправки и получения
void SPI_MasterTransmit(char cReg, char cData) { unsigned char x; CS=0; //прижимаем CS к земле, давая понять что передача пошла SPDR=(((cReg&0x3F)<<1)|0x80); /* Start transmission */ while(!(SPSR&(1<<SPIF)));/* Wait for transmission complete */ x = SPDR;//dummy read SPDR = cData; while(!(SPSR&(1<<SPIF)));/* Wait for transmission complete */ x = SPDR;//dummy read CS=1; }
unsigned char SPI_MasterReceive(char cReg) { unsigned char x; CS=0;// прижимаем CS к земле, давая понять что передача пошла SPDR=((cReg&0x3F)<<1); // write in the register address with the read comman while(!(SPSR&(1<<SPIF))); /* Wait for reception complete */ x=SPDR;//dummy read CS=1; return x; /* Return data register */ }
Кому не лень, гляньте код, и еще насколько я понял из ДШ SPI должен быть "вариант 0" для МК Мега16 я пользую такую настройку
SPCR=0b01010011; /*{ 7: SPIE: SPI Interrupt Enable 6: SPE: SPI Enable 5: DORD: Data Order 4: MSTR: Master/Slave Select 3: CPOL: Clock Polarity 2: CPHA: Clock Phase 1,0: Bits 1, 0 – SPR1, SPR0: SPI Clock Rate Select 1 and 0 }*/
|
|
|
|
|
Apr 17 2011, 18:36
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
В функции SPI_MasterReceive у вас присутствует алгоритмическая ошибка, на возможность которой я указал еще в посте №3. Для того, чтобы что-то прочитать мастер должен что-либо передать. Причем запись и чтение идет одновременно, но информация которую должен получать мастер сдвинута по времени как минимум на один байт. Вы первой транзакцией в функции SPI_MasterReceive передаете адрес регистра, но по окончании передачи в регистре приемника SPI вовсе не искомое значение регистра, а некий мусор. Для получения значения нужно, не отпуская CS, произвести еще одну запись, передав dummy-байт. Только после завершения передачи этого второго незначащего байта в регистре приемника SPI будет значение регистра, адрес которого вы передали первым байтом. Все это хорошо видно на времянке Figure11. SPI Timing Diagram for 8-Bit Register Read (4 Wire Mode) из даташит.
Эскизы прикрепленных изображений
|
|
|
|
|
Apr 17 2011, 18:41
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737

|
unsigned char SPI_MasterReceive(char cReg) { unsigned char x; CS=0;// прижимаем CS к земле, давая понять что передача пошла //x = SPDR;//dummy read //while(!(SPSR & (1<<SPIF))); /* Wait for reception complete */ SPDR=((cReg&0x3F)<<1); // write in the register address with the read comman while(!(SPSR&(1<<SPIF))); /* Wait for reception complete */ SPDR=0x00;//DUMMY BYTE while(!(SPSR & (1<<SPIF))); x=SPDR; CS=1; return x; /* Return data register */
Както так?
Сообщение отредактировал eugmai86 - Apr 17 2011, 18:42
|
|
|
|
|
Apr 17 2011, 18:45
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737

|
Прошиваю) Пишу в $16 регистр 0b00000101 (включаю акселерометр в measurement mode), считываю регистр $16 а там 255.
Сообщение отредактировал eugmai86 - Apr 17 2011, 19:00
|
|
|
|
|
Apr 17 2011, 19:10
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737

|
Боюсь что датчик вышел из строя, мне не нравится его ток 1.7 мА в режиме "выключен". В ДШ 2.5 - 10 мкА написано в таком режиме. Хотя странно, больше 3.3 я ему не давал, SPI по уровням с МК согласован...
|
|
|
|
|
Apr 17 2011, 19:27
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(eugmai86 @ Apr 18 2011, 00:45)  Пишу в $16 регистр 0b00000101 А вы уверены что именно в этот регистр? В даташите 16-тиричные адреса регистров указаны. А у вас какое-то странное преобразование адреса, переданного в функцию, происходит при записи его непосредственно в регистр передатчика SPI. Код SPDR=((cReg&0x3F)<<1); Что это? Для чего? Цитата(eugmai86 @ Apr 18 2011, 01:10)  SPI по уровням с МК согласован... Как именно согласовывали?
|
|
|
|
|
Apr 17 2011, 19:30
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 20-03-11
Пользователь №: 63 737

|
Чтоб датчик понял "write" MSB должен быть 1, дальше 6 бит адреса и один dont care bit. Чтоб датчик понял "read" MSB должен быть 0, дальше 6 бит адреса и один dont care bit. Беру cReg в hex дальше ((cReg&0b00111111)<<1)|0b10000000 Это преобразование взято из апноута по данному акселерометру (AN3468). При его использовании не надо вручную переставлять биты регистра который нужно записать/считать, а просто указать его в шестнадцатеричной форме. Согласование уровней, апноут AN97055
Сообщение отредактировал eugmai86 - Apr 17 2011, 19:32
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|