for (i = 0; i < 5; i++) {
master_arr[i] = SPDR;
SPDR = master_arr[i];
}
Это тоже сомнительно. Какова цель? Как:
a = b;
b = a;
И есть еще одна необъявленная в декларации номер для массива (i = 0..4!) соотв. volatile unsigned char master_arr [4];
и соответственно - хаотичное значение (master_arr [4]) при i = 4.
Последний раз редактировалось veso74 Пт июл 07, 2023 16:23:25, всего редактировалось 3 раза.
veso74, Какова цель? - отладка, человек хочет увидеть, что слейв все принял верно, на мастере он и не ловит ответ. warptred12
да. наконец то. сами посмотрите где младший байт частоты до передачи, и куда вы его помещаете при приеме и склейке.
коли транспорт заработал, включите SPI на полную скорость, проверьте - не спотыкается ли.
да и надо переходить на целевой МК, т.е. на чем будете собирать - что бы работал и там.
a797945, я не понимаю как и где мне его посмотреть, когда я принимаю полученные байты на слейве - я присваиваю их значение элементам массива master_array и отправляю присвоенные значения обратно, а потом уже склеиваю их в переменной fG, эти элементы массива я никак не меняю, но при передаче этих элементов массива, отправленные данные я никак не изменяю, тогда почему они приходят на мастера со сдвигом?
Добавлено after 4 minutes 54 seconds: veso74, я отправляю значения элементов массива обратно, чтобы увидеть на SPI анализаторе что я сохранил в эти элементы массивов.
Да увидел ошибку с for, там действительно должно быть 4, спасибо. Но ничего не изменилось, все так же сдвигает данные почему-то.
"почему они приходят на мастера со сдвигом?"
нет там сдвига.
не понимаете, потому, что торопитесь. медленно продумайте что я сказал про SPI.
когда слейв принимает 1-й байт от мастера из слейва в мастер уходит случайное состояние его сдвигового регистра. не торопясь прокрутите в голове такой мультик.
а 4-й байт слейв хоть и записывает в DR уже уйти не может - мастер свой 4-й отослал и передачу больше не тактирует. перечитайте не торопясь - думаю поймете.
Добавлено after 32 minutes 54 seconds: warptred12, " я не понимаю как и где мне его посмотреть"
я про это:
мастер
...
unsigned long int w ; // w as WORD
unsigned int h[2]; // h as HALF-WORD
unsigned char b[4]; // b as BYTE
...
dFi.w = F*167.77216;
...
SPI_MasterTransmit(Cnt & 0x03);
SPI_MasterTransmit(dFi.b[0]);
SPI_MasterTransmit(dFi.b[1]);
SPI_MasterTransmit(dFi.b[2]);
...
сразу не посмотрел код, теперь забираю свои слова, что транспорт работает - код не рабочий.
если и сделал вид, вероятно это закидоны протеуса, в "железе" корректно работать не будет.
чой-то народ не среагировал на это безобразие:
interrupt [SPI_STC] void spi_isr(void)
{
unsigned char i=0;
for(i=0;i<5;i++) {
master_arr = SPDR;
SPDR = master_arr ;
}
}
и отсутствие очистки флага SPIF перед разрешением прерывания.
можно поправить, но предлагаю отказаться от прерывания на spi.
попробуйте так принять пачку:
unsigned char b1,b2,b3,b4;
while(PINB.2==1) // висим пока 1, как 0 идем дальше
while(!(SPSR & (1<<SPIF)));// висим пока 0, как 1 идем дальше
b1 = SPDR;
while(!(SPSR & (1<<SPIF)));
b2 = SPDR;
while(!(SPSR & (1<<SPIF)));
b3 = SPDR;
while(!(SPSR & (1<<SPIF)));
b4 = SPDR;
a797945, некоторые байты просто не записываются, скриншот приложу. Так же протеус ругается PC=0x0136 SPDR Write collision. Written data(0xFF) is ignored. Это опять слейв шлет обратно мусорные байты в регистр данных или данные просто не сохраняются в определенные биты памяти ?
вы зачем голову отключаете, когда вставляете чужой код?
я же писал "допишите", а не замените; и dFi.w вы выкинуть не можете вы из него dFi.b[] берете, давайте хоть на 1 умножим. у вас мастер ничего путного не передает.
мастер должен отсылать 9 байт : 4- канал и "частота" и 5- пустышек чтобы протактировать передачу от слейва - возврат fG.
вставте это:
dFi.w = F*1 ;
PORTB &= ~(1<<PORTB0);
SPI_MasterTransmit(Cnt & 0x03);
SPI_MasterTransmit(dFi.b[0]);
SPI_MasterTransmit(dFi.b[1]);
SPI_MasterTransmit(dFi.b[2]);
SPI_MasterTransmit(0xff); //пустышка
SPI_MasterTransmit(0xff); // младший байт из fG
SPI_MasterTransmit(0xff); // 2-й из fG
SPI_MasterTransmit(0xff); // 3-й из fG
SPI_MasterTransmit(0xff); // старший из fG
PORTB |= (1<<PORTB0);
в слейве сделайте начало приема таким:
...
while(PINB.2==1); // <- здесь я пропустил ";"
unsigned char b1,b2,b3,b4; // <- переменные должны быть объявлены здесь
while(!(SPSR & (1<<SPIF)));
...
здесь и моя опечатка была - ";" пропустил - в смысле не поставил.
и Вы выкинули b1,b2,b3,b4 наверх - сделав их глобальными, а это абсолютно бессмысленно, они должны быть локальными - если регистров достаточно и компилятор неленивый прокрутит их в РОН, вообще не обращаясь в ОЗУ.
жаль нет флага активности передачи, по этому:
или физически соединить PINB.2 (SS) и PINB.1 (для примера) - начало передачи контролировать по PINB.1.
или применять программную синхр., типа 4-х 0x55 подряд, с пятого начало полезной инф.
a797945, перепробовал много вариаций, предложенного вами варианта, но итог все равно тот же. Еще и протеус начал ругаться PC=0x0190 SPDR Write collision. Written data(0x00) is ignored, как он может ругаться, что 0 записывается в SPDR, если в коде я нигде не записываю 0.
Write collision - одна операция не завершена, начинается другая (но есть вероятность, что это только в симуляции, поэтому нужен и тест реального устройства).
Остальные порты свободные на обоих МК? Идея: попробуйте с другим способом отладки: LCD, LCD/I2c, UART и т.д. Аппаратный UART, программный UART ... много вариантов есть.