Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как передать 7 бит по SPI ?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
uzzzer
Добрый день!
Как передать по SPI семь бит данных в семибитный сдвиговый регистр?
Есть четыре регистра соедененных каскадом,получается 7+7+7+7 битовый регистр. Но когда передаешь семибитовые числа, то данные сдвигаются, так как присутствует в передачи "0" от SPDR, как сложить данные, что бы передача была корректной.
Lmx2315
..самодельным SPI в софтовой реализации.
uzzzer
Цитата(Lmx2315 @ Jul 9 2015, 10:22) *
..самодельным SPI в софтовой реализации.


Вот только как реализовать его? Есть примерчик рабочий?
Lmx2315
Цитата(uzzzer @ Jul 9 2015, 11:24) *
Вот только как реализовать его? Есть примерчик рабочий?

рабочего примерчика для 7-ми бит нет, наверное это будет что то вроде такого:

Цитата
void spisend (char d)
{

int i=0;

PORTA &= ~0b00000010; // CS = 0
delay(1);
for (i=0;i<7;i++)
{
if ((d&0x01)==0x01) PORTA |= 0b00000100; else PORTA &= ~0b00000100; //данные MOSI
delay(1);
PORTA |= 0b00001000; // CLK
delay(1);
PORTA &= ~0b00001000;
delay(1);
d=d>>1;
}

PORTA |= 0b00000010; // CS = 1
}
Obam
Я правильно понял "четыре регистра соедененных каскадом,получается 7+7+7+7 битовый регистр."?
Если правильно, то "разложить" 28 бит в 4 байта и заслать четырьмя посылками. К примеру, MSB-first: четыре старших бита нули, а остальные 28 нужные биты подряд.
uzzzer
Цитата(Obam @ Jul 9 2015, 10:40) *
Я правильно понял "четыре регистра соедененных каскадом,получается 7+7+7+7 битовый регистр."?
Если правильно, то "разложить" 28 бит в 4 байта и заслать четырьмя посылками. К примеру, MSB-first: четыре старших бита нули, а остальные 28 нужные биты подряд.


Вы все правильно понялиsm.gif Вот в этом у меня и вопрос, как это сделать правильно?

Я уже поднимал подобный вопрос в теме:
http://electronix.ru/forum/index.php?showtopic=127773
С регистром 595 проблем нет, все шлется, индикаторы подсвечиваются и т.д. А вот с семибитными регистрами проблема.
Obam
d[0]=d[0] | (d[1] << 7);
d[1]=(d[1] >> 2) | (d[2] << 6);
d[2]=(d[2] >> 3) | (d[3] << 5);
d[3]=(d[3] >> 4);
Вот как-то так sm.gif
Lmx2315
Цитата(uzzzer @ Jul 9 2015, 11:55) *
Я уже поднимал подобный вопрос в теме:
http://electronix.ru/forum/index.php?showtopic=127773
С регистром 595 проблем нет, все шлется, индикаторы подсвечиваются и т.д. А вот с семибитными регистрами проблема.

..компонуйте ваши биты в 32-битную переменную, через сдвиги. А потом её отправляйте в 4-ре регистра.

a = 01111111
b = 01111110
c = 01111100
d = 01111000

x = (a)+(b<<7)+(c<<14)+(d<<21)

spi(x)

отправлять старшим битом вперёд.
Сергей Борщ
Цитата(Lmx2315 @ Jul 9 2015, 11:08) *
x = (a)+(b<<7)+(c<<14)+(d<<21)
Только добавить приведение c и d к 32 битам перед сдвигом. AVR имеет 16-битный int.
uzzzer
Цитата(Lmx2315 @ Jul 9 2015, 11:08) *
..компонуйте ваши биты в 32-битную переменную, через сдвиги. А потом её отправляйте в 4-ре регистра.

a = 01111111
b = 01111110
c = 01111100
d = 01111000

x = (a)+(b<<7)+(c<<14)+(d<<21)

spi(x)

отправлять старшим битом вперёд.


Немного не понятна суть метода.. получается, что a,b,c,d - это переменные, которые загоняются по очереди в регистры, тогда почему число x = (a)+(b<<7)+(c<<14)+(d<<21) в итоге получаетя 39 разрядов ?
Obam
uzzzer, см. http://electronix.ru/forum/index.php?showt...t&p=1350506
всё до тла разжёвано
uzzzer
Цитата(Obam @ Jul 9 2015, 12:38) *


???

Ссылка на эту темуsm.gif
Obam
Разве не на 7-е сообщение?
Lmx2315
Цитата(uzzzer @ Jul 9 2015, 13:30) *
Немного не понятна суть метода.. получается, что a,b,c,d - это переменные, которые загоняются по очереди в регистры, тогда почему число x = (a)+(b<<7)+(c<<14)+(d<<21) в итоге получаетя 39 разрядов ?

a,b,c,d - это ваши данные которые хотите разместить в 7-ми битных регистрах (т.е. это 32 битные переменные в микрокотроллере), заполняете младшие 7-мь бит этих переменных.
Вы заносите в каждую переменную ваши данные а потом складываете переменные по формуле для х - тоже 32 битная переменная, потому в ней не может оказаться больше 32 бит sm.gif .
Отправляете в SPI (x) .
Lerk
Вот картинка о том, что вам пытаются донести:
Нажмите для просмотра прикрепленного файла
Цветом выделены "железные" байты в SPI контроллере, жирной границей - фактические байты данных(8 бит на байт в верхней строке и 7 бит на байт в нижней). Такая посылка(нижняя) будет успешно записана в 28 разрядный сдвиговый регистр, т.к. ведущие 4 бита просто пропадут, а оставшиеся и есть значащие разряды посылки.
Obam

Вот почему MSB не нарисовать слева? Арабы мы что ли? И в десятичной и 16-ричной записи правый разряд младший…
Lerk
Цитата(Obam @ Jul 9 2015, 13:19) *
Вот почему MSB не нарисовать слева? Арабы мы что ли? И в десятичной и 16-ричной записи правый разряд младший…


потому что осциллограф.
Obam
Не флуда ради, но на рисунке регистры, а не осциллограф, тем более если MSB-first то и развертка слева sm.gif
Lerk
Цитата(Obam @ Jul 9 2015, 13:35) *
Не флуда ради, но на рисунке регистры, а не осциллограф, тем более если MSB-first то и развертка слева sm.gif


На рисунке указано, что LSB(МЗР)-first таки.

А в целом, меня не парит. Вообще странно на таком форуме видеть возмущение наличию разных стандартов записи: они были придуманы еще до нас.

А что касается осциллографа, то намек был на то, что я последнее время работаю с ним много и мне удобнее записывать данные 1-к-1. Если вам удобнее в голове постоянно делать преобразования bin2hex, hex2bin, reverse - ваше право :-) Я же остаюсь при своём.
zombi
Цитата(uzzzer @ Jul 9 2015, 10:55) *
А вот с семибитными регистрами проблема.
А что за регистры?


Цитата(Lerk @ Jul 9 2015, 14:55) *
Вообще странно на таком форуме видеть возмущение наличию разных стандартов записи: они были придуманы еще до нас.

Что за стандарты?
pavel-pervomaysk
На асме.
Такт по фронту.

; LCD names pinouts
.equ LCD = PORTB ; Порт
.equ clk = PB0 ; вывод тактов
.equ dat = PB1 ; вывод данных


CODE
send_7bits: ;
push loop ; Save loop in STACK
ldi loop,7 ; bit counter
andi tmp,0x7F ; Чистим 7й ненужный бит
out_c: ;
clc ; clearing carry flag
ror tmp ; tmp =>> 1 ( LSB first )
brcc d_zer ; Branch if Carry flag eual zero!
sbi lcd,dat ; DATA -> 1
rjmp d_one ;
d_zer: ;
cbi lcd,dat ; DATA -> 0
d_one: ;
sbi lcd,clk ; CLK -> 1
cbi lcd,clk ; CLK -> 0
dec loop ; bitcounter = -1
brne out_c ;
pop loop ; Restore loop from STACK
ret ; reеurn


Насколько я знаю, то регистр без CS (74HC164) запоминает последние такты.
К примеру их туда можно плюнуть и 1000, отобразятся только последние.
Если нужна скорость по аппаратному SPI, то выше уже показали как это сделать, собрать в слово свои 28 бит, Биты ([31...28] для MSB first), ([3...0] LSB first) очистить, и слать по очереди 4 байта.
zombi
Цитата(pavel-pervomaysk @ Jul 9 2015, 20:12) *
Биты ([31...28] для MSB first), ([3...0] LSB first) очистить, и слать

Зачем их очищать?

Цитата(pavel-pervomaysk @ Jul 9 2015, 20:12) *
На асме.

Я бы так сделал:
Код
send_7bits: push   loop
            ldi    loop,7        ; bit counter
out_c:      cbi    lcd,dat    ; DATA -> 0
            sbrc   tmp,0
            sbi    lcd,dat    ; DATA -> 1
            ror    tmp        ; tmp =>>
            sbi    lcd,clk    ; CLK  -> 1
            dec    loop          ; bitcounter = -1
            cbi    lcd,clk    ; CLK  -> 0
            brne   out_c         ;  
            pop    loop          ; Restore loop from STACK
            ret                  ; return


Сохранение/восстановление SREG добавить при необходимости.
uzzzer
Цитата(zombi @ Jul 9 2015, 17:15) *
А что за регистры?


Регистры в матричном индикаторе HDSP2001,даташит во вложениях.


Цитата(pavel-pervomaysk @ Jul 9 2015, 20:12) *
Если нужна скорость по аппаратному SPI, то выше уже показали как это сделать, собрать в слово свои 28 бит, Биты ([31...28] для MSB first), ([3...0] LSB first) очистить, и слать по очереди 4 байта.


Сейчас буду пробывать сделать и так и так. Только меня смущает вот что: Какое максимальное число можно передать таким способом? Допустим я склею 28(32) бита, потом резать по 4? Правильно? А вот склееное число, если оно будет не 32 бита, а например 255 бит или больше?К стати как лучше разобрать склееное число по 8 бит?
Сергей Борщ
Цитата(uzzzer @ Jul 10 2015, 05:55) *
пробывать
Не стоит. Попробуйте пробовать.
uzzzer
Цитата(Сергей Борщ @ Jul 10 2015, 07:54) *
Не стоит. Попробуйте пробовать.

Попробовал. Все получилось. На данном этапе вполне устраивает. Реализовал програмный SPI.

Код
void data_send(int qi, int *data, int n)
{
    int c;
for (int i=0;i<=n-1;i++)
{
    c=data[(qi-1)+5*i];
    for (int j=0;j<7;j++)
    {
        if ((c&0x40)==0x00) PORTA&=~_BV(DATA);
        else PORTA|=_BV(DATA);
        asm("nop");
        PORTA&=~_BV(SCL);
        asm("nop");
        PORTA|=_BV(SCL);
        asm("nop");
        c=(c<<1);
    }
    asm("nop");
    asm("nop");
}
}

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.