ничего не понимаю - ЗАЧЕМ вы разломали мастера? в вашем сообщении от Пн июл 10, 2023 19:19:12 - там правильно все отправлялось. вы что не видите: 02 64 00 00 ff ff ff ff ff - это и есть то что назначено: nG = 2; fG =100; - это и есть 0x00000064 и 5 любых байт (в данном случае ff) чтоб протактировать передачу со слейва.
щас чуть позже посмотрю слейв
Добавлено after 43 minutes 17 seconds: на всякий случай поясню последовательность вчерашних действий: когда передача мастера пошла правильно, попросил со слейва вернуть 01 02 03 04 11 12 13 14 чтоб понять, что отправлять последовательно может, не сразу увидел сползание начала передачи, а она привязывалась к PINB2 - предположил, что линия на регистер порта и не приходит, а уходим в SPI; предложил аппаратно соединить PINB2 с PINB1, чтоб и в SPI уходил сигнал и на PINB1 его в прошивке "видеть". вот каким должен был быть блок приема/отправки слейва: while(PINB.1==1); unsigned char b1,b2,b3,b4; while(!(SPSR & (1<<SPIF))); b1 = SPDR; SPDR = 1; while(!(SPSR & (1<<SPIF))); b2 = SPDR; SPDR = 2; while(!(SPSR & (1<<SPIF))); b3 = SPDR; SPDR = 3; while(!(SPSR & (1<<SPIF))); b4 = SPDR; SPDR = 4;
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
надо бороться с обнаружением SS на слейве, с остальным похоже все нормально можно заменить: SPDR = 0x11; на SPDR =(unsigned char)(fG&0xff); SPDR = 0x12; на SPDR =(unsigned char)((fG>>8)&0xff); SPDR = 0x13; на SPDR =(unsigned char)((fG>>16)&0xff); SPDR = 0x14; на SPDR =(unsigned char)((fG>>24)&0xff);
01 02 03 04 всегда идут последовательно, но не вовремя - значит и читает слейв не вовремя, как если PINB1 болтается в воздухе
пошел курить даташит
Добавлено after 2 hours 19 seconds: возможно, если вставить какую задержку в поллинг pinb1 он в протеусе и заработает, а в "железе" может работал бы и так. но от поллинга по-хорошему все равно надо отказываться (думал это делать позже). лучше на прерывании : спад на INT1 - прием 4-х байт, склеивание fG, побайтный возврат fG, выход из прерывания.
соответственно линию не на PINB2+PINB1 а на PINB2+INT1
veso74, ну да, в датамемори все тоже самое что и на spi анализаторе. Просто на spi анализаторе можно время приема-передачи увидеть и все наглядней. А изза того что я отправляю обратно данные обратно на мастера, они могут искажаться ? a797945, завтра попробую подумать, как это можно сделать, потом отпишусь отпишусь.
ориентировочная "рыба", без сверки с даташитом, заменил обработчик, INT0 или INT1 удалите сами, в слейв переносите вдумчиво. Спойлер
Код:
#include <avr/io.h> #include <avr/interrupt.h>
//---------- void int_ini(void) { //Включим ножки INT0 и INT1 (PD2 и PD3) на вход DDRD &= ~(0b00001100); //Подтянем резистор на ножках INT0 и INT1 (PD2 и PD3) к питанию PORTD |= 0b00001100;
//включим прерывания INT0 и INT1 по нисходящему фронту EICRA|=(1<<ISC11)|(1<<ISC01); //разрешим внешние прерывания INT0 и INT1 EIMSK|=(1<<INT1)|(1<<INT0); }
зачем вы опять сломали мастера? это начинает утомлять при таком мастере слейв корректно работать не может - он отсылает 8 байт, а чем теперь занимается мастер не понятно. на скрине 6 байт. там где вы не доломали слейв умудряется отсылать 01 02 03 04 FF 01 два последних это первые 2 принятые от мастера.
для остальных должен озвучить информацию (покаяться): мои предположения о причинах неработы поллинга на PINB2 и PINB1 не более чем не подтвержденные гипотезы. на самом деле я допустил ошибку - оглядываясь вперед не поставил ожидание флага ... SPDR =0x14; while(!(SPSR & (1<<SPIF))); <-- } ... и слейв положив 0х14 в SPDR сразу уходил на ожидание 0 на SS, но мастер еще передавал последний байт - слейв проваливался на прием первого байта, а когда мастер начинал новую посылку слейв был уже смещен на байт и так по циклу.
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);
а вот как принимаю(убрал внешнее прерывание int0): Спойлер
На данный момент проблема заключается в том, что slave не может обработать посылки от мастера, я модульно тестировал блоки кода программы и нормально работает пока что только код отвечающий за генерацию частоты. Снизу скину код мастера atmega128 и attiny2313. Мастер:
#define CS PORTD3 // Chip select #define DO PORTB5 // MISO or Data Out #define USCK PORTB7 // Clock
volatile unsigned long int fG; volatile unsigned char nG; volatile unsigned int N[]={1,8,64,256,1024};
volatile char reqID = 0; // This is for the first byte we receive, which is intended to be the request identifier //volatile unsigned char index = 0; // this is to send back the right element in the array
void SpiSlaveInit() { #asm("cli") USICR = ((1<<USIWM0)|(1<<USICS1)); // Activate 3- Wire Mode and use of external clock but NOT the interrupt at the Counter overflow (USIOIE) PORTD |= 1<<CS; // Activate Pull-Up resistor on PD3 //PCMSK |= 1<<CS; // Active Interrupt on PD3 GIMSK |= 1<<INT1; // General Interrupt Mask Register / INT1 bit activates external interrupts MCUCR |= 1<<ISC10; #asm("sei") }
// External Interrupt 0 service routine interrupt [EXT_INT1] void ext_int1_isr(void) { if(PIND.3 == 0){ //PORTD |= (1<<5); // If edge is falling, the command and index variables shall be initialized // and the 4-bit overflow counter of the USI communication shall be activated: reqID = 0; //index = 0; USICR |= (1<<USIOIE); USISR = 1<<USIOIF; // Clear Overflow bit } else{ // If edge is rising, turn the 4-bit overflow interrupt off: USICR &= ~(1<<USIOIE); //PORTD |= (1<<6); } }
interrupt [USI_OVERFLOW] void usi_ovf_isr(void) { unsigned char b1,b2,b3,b4; while(PIND.3 == 1); switch(reqID) { case 0: b1 = USIDR; nG = b1; if((USISR&(1 << USIOIF))==1) USISR = 1<<USIOIF; // Clear Overflow bit reqID++; break; case 1: b2 = USIDR; fG = (unsigned long int)b2; USISR = 1<<USIOIF; // Clear Overflow bit reqID++; break; case 2: b3 = USIDR; fG |= ((unsigned long int)b3 << 8); USISR = 1<<USIOIF; // Clear Overflow bit reqID++; break; case 3: b4 = USIDR; fG |= ((unsigned long int)b4 << 16); USISR = 1<<USIOIF; // Clear Overflow bit reqID = 0; break; } }
void UpdateTim1A(unsigned long int freq) //old value storage { static unsigned long int fG_old = 0; if (fG_old != freq) { SetUpTim1A(freq); fG_old = freq; } }
void main(void) { static unsigned long int fG_old = 0; VFG_DDR = 0b00000111; SpiSlaveInit(); //DDRA=0b11111111; //DDRB=0b11111111; DDRD=0b00000000; #asm("sei") for(;;) { if (fG_old != fG) { //old value detction SetUpTim1A(fG); fG_old = fG; } UpdateTim1A(fG); } }
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 47
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения