реклама на сайте
подробности

 
 
5 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> SPI отправка и получение данных с регистров ведомого устр.
eugmai86
сообщение Apr 10 2011, 16:38
Сообщение #1


Участник
*

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



Доброго времени суток, есть проблема чтения и записи регистров модуля акселерометра работающего через SPI. Подскажите как на Си читать и писать в регистры данного модуля. Например нужно отправить с меги 16 значение 0b00000101 в регистр $16. SPI разобрался как конфигурировать, проблема за малым. СпасибоПрикрепленный файл  MMA7455L_____________.pdf ( 519.11 килобайт ) Кол-во скачиваний: 334
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 10 2011, 17:14
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



На странице 18 всё написано/нарисовано (рис 13): передаем в первом байте адрес и направление передачи (1=write); второй байт - данные.
Go to the top of the page
 
+Quote Post
rezident
сообщение Apr 10 2011, 17:20
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Не нужно забывать, что SPI не просто передает или принимает, а производит обмен данными. Поэтому, чтобы что-то прочитать ведущий SPI должен что-то (dummy byte(s)) передать ведомому (акселерометру в данном случае).
Go to the top of the page
 
+Quote Post
eugmai86
сообщение Apr 10 2011, 17:56
Сообщение #4


Участник
*

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



т.е. для записи в регистр ММА7455 можно так:
SPI_MasterTransmit(0b11011000); //записываю в 16 регистр мма7455
SPI_MasterTransmit(0b00000101); // значение 0b00000101
где SPI_MasterTransmit ф-ция записи в регистр
???
Go to the top of the page
 
+Quote Post
Палыч
сообщение Apr 11 2011, 04:04
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(eugmai86 @ Apr 10 2011, 21:56) *
т.е. для записи в регистр ММА7455 можно так:
SPI_MasterTransmit(0b11011000); //записываю в 16 регистр мма7455
...........
Вы забыли, что нужно управлять ещё сигналом CS. И адрес у Вас как-то странно задан: должно быть
SPI_MasterTransmit(0b10100000); //записываю в 16 регистр мма7455
Go to the top of the page
 
+Quote Post
eugmai86
сообщение Apr 12 2011, 11:40
Сообщение #6


Участник
*

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



ясно, спасибо, буду пробовать
Go to the top of the page
 
+Quote Post
eugmai86
сообщение Apr 17 2011, 18:09
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 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
}*/
Go to the top of the page
 
+Quote Post
rezident
сообщение Apr 17 2011, 18:36
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 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) из даташит.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
eugmai86
сообщение Apr 17 2011, 18:41
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
rezident
сообщение Apr 17 2011, 18:44
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(eugmai86 @ Apr 18 2011, 00:41) *
Както так?
Названия регистров и назначение отдельных битов AVR я знаю плохо, но алгоритмически - да, примерно так.
Go to the top of the page
 
+Quote Post
eugmai86
сообщение Apr 17 2011, 18:45
Сообщение #11


Участник
*

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



Прошиваю) Пишу в $16 регистр 0b00000101 (включаю акселерометр в measurement mode), считываю регистр $16 а там 255.

Сообщение отредактировал eugmai86 - Apr 17 2011, 19:00
Go to the top of the page
 
+Quote Post
Слесарь
сообщение Apr 17 2011, 19:00
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 884
Регистрация: 7-11-09
Из: Ростовская обл.
Пользователь №: 53 484



Мож мой сырой код чем-то поможет

Код
void spi_io_w( char byte_h, char byte_l )
{
    write_byte( byte_h );
    write_byte( byte_l );
}

void write_byte( char dat )
{
    char n;
    for( n = 0; n < 8; n++ )
    {
        SCK_PIN = 1;
        DelayUs( 20 );
        if ( dat & 0x80 ) /* most sign bit first */
        {
            SDO_PIN = 1;
        }
        else
        {
            SDO_PIN = 0;
        }
        dat = ( dat << 1 ) | SDI_PIN;
        DelayUs( 100 );
        SCK_PIN = 0;
        DelayUs( 120 );
    }
}

void spi_io_24b( char * p_spi_byte_h, char * p_spi_byte_s, char * p_spi_byte_l )
{
    unsigned char byte_h = 0;
    unsigned char byte_s = 0;
    unsigned char byte_l = 0;
    char n;

    for( n = 0; n < 8; n++ )
    {
        SCK_PIN = 1;
        DelayUs( 20 );
        byte_h = ( byte_h << 1 ) | SDI_PIN;
        DelayUs( 100 );
        SCK_PIN = 0;
        DelayUs( 120 );
    }

    for( n = 0; n < 8; n++ )
    {
        SCK_PIN = 1;
        DelayUs( 20 );
        byte_s = ( byte_s << 1 ) | SDI_PIN;
        DelayUs( 100 );
        SCK_PIN = 0;
        DelayUs( 120 );
    }

    for( n=0; n < 8; n++ )
    {
        SCK_PIN = 1;
        DelayUs( 20 );
        byte_l = ( byte_l << 1 ) | SDI_PIN;
        DelayUs( 100 );
        SCK_PIN = 0;
        DelayUs( 120 );
    }

    *p_spi_byte_l = byte_l;
    *p_spi_byte_s = byte_s;
    *p_spi_byte_h = byte_h;
}
Go to the top of the page
 
+Quote Post
eugmai86
сообщение Apr 17 2011, 19:10
Сообщение #13


Участник
*

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



Боюсь что датчик вышел из строя, мне не нравится его ток 1.7 мА в режиме "выключен". В ДШ 2.5 - 10 мкА написано в таком режиме. Хотя странно, больше 3.3 я ему не давал, SPI по уровням с МК согласован...
Go to the top of the page
 
+Quote Post
rezident
сообщение Apr 17 2011, 19:27
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 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 по уровням с МК согласован...
Как именно согласовывали?
Go to the top of the page
 
+Quote Post
eugmai86
сообщение Apr 17 2011, 19:30
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post

5 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 09:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01512 секунд с 7
ELECTRONIX ©2004-2016