Обсуждаем контроллеры компании Atmel.
Ответить

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Чт июн 08, 2023 16:11:41

MOHCTEP, посылка точно равна 4 байтам, потому что передаваемое значение по SPI long int. Светодиоды я гашу в мейне, не знаю должны ли они гореть или мигать. У меня они просто горят.
Спойлер
Код:
void main(void)
{
 static unsigned int fG_old = 0;
 SpiSlaveInit();
 Tim1Init();
 UpdateTim1A(fG);
 PORTD &= (~((1<<0)|(1<<1)|(1<<2)|(1<<4)|(1<<5)|(1<<6))); //гашу светодиоды
 DDRD=0x77;
#asm("sei")
for(;;) {
    if (flag_RT = 1) {
        if (fG_old != fG) {             //old value detction
        SetUpTim1A(fG);
        fG_old = fG;
    }
    nG= ch_num;                         //generator number
    fG= dFi.b[0]+dFi.b[1]+dFi.b[2];     //generator frequency
    set_out_pin (nG);
    SetUpTim1A(fG);
    }
}
}

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Чт июн 08, 2023 16:29:13

warptred12, :) Не гасите. Эту строку перенесите внутрь бесконечного цикла for(;;) {..., только добавьте еще небольшую задержку, чтоб можно было увидеть зажженные светодиоды.

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Чт июн 08, 2023 16:47:24

MOHCTEP, ну теперь мигает только светодиод подключенный к PD6, PD0,PD1,PD5 - просто горят, а PD2,PD4 - не горят. Как то странно, по идее все включенные светодиоды должны мигать.

Добавлено after 6 minutes 25 seconds:
Чуть позже загорелся PB2 и светоиод, подключенный к ноге PD6 - перестал мигать.

Добавлено after 57 seconds:
Потом и PB1 загорелся.

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Чт июн 08, 2023 16:49:30

Действительно странно. Как будто INT1 у вас настроено только на спад (переход 1--0). С остальным вообще не понятно.
Может слишком большую задержку сделали? Попробуйте ее уменьшить или закомментировать.

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Чт июн 08, 2023 16:56:15

MOHCTEP, уменьшил задержку до 1мс и теперь мигают PD6,PD0,PD1,PD5. INT1 - настроено на изменение логического уровня, потому что во время спада передаются эти 4 байта и включаются прерывания таймера USI, когда идет rising edge - прерывание выключает этот таймер.

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Чт июн 08, 2023 17:12:05

Ну теперь видно, что INT1 вроде работает как задумано (PD5, PD6). А вот с мастера, все одно, только 2 байта приходят, что ли? Но тогда непонятно, как reqID сбрасывается... Раз PD0,PD1 мигают, значит в соответствующие кейсы вы попадаете. Но сброс идет в 3 кейсе, а судя по светодиодам вы до него не достаете. Чудеса однако.

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Чт июн 08, 2023 23:33:28

Здесь что должно происходить?
fG= dFi.b[0]+dFi.b[1]+dFi.b[2]

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Пт июн 09, 2023 11:06:56

a797945, рассчитывается числовое значение переменной fG(частоты), оно складывается из 3-х байтов полученных значений частоты. Потом эта переменная подставляется в функцию SetUpTim1 и там высчитывается значение регистра стравнения OCR1A и потом в самом прерывании Таймера1 мы дергаем ножкой PB0-PB2 в зависимости от полученного значения nG по SPI. Ну так должно бы по крайней мере, попробывал из этих функций тоже подергать свободными ножками и ничего не получилось.
Спойлер
Код:
void Tim1Init(void)
{
    #asm("cli")
    TCCR1A = (1<<COM1A0);                       //toggle on compare
    TCCR1B = (1<<WGM12)|(1<<CS12)|(1<<CS10);    // set timer CTC mode, prescaler 1024
    TIMSK = (1<<OCIE1A);
    #asm("sei")
}

void SetUpTim1A(unsigned int Foc)    //calculate value OCR1A register
{
    unsigned int TimDiv;
    unsigned char ClockSelect=0;
    unsigned char i=0;
    for(i=0;i<=4;i++) {
        TimDiv = (F_CPU/(2*(Foc/167)*N[i])-1)+0.5;
        if(TimDiv >= 0 && TimDiv<VFG_TIMER_MAX){
        ClockSelect=i+1;
        break;
        }
    }
    OCR1A=TimDiv;
    TCCR1B = (1<<WGM12) | (ClockSelect<<CS10);
   
}


void UpdateTim1A(unsigned int freq)             //old value storage
{
   static unsigned int fG_old = 0;

   if (fG_old != freq)
   {
      SetUpTim1A(freq);
      fG_old = freq;
   }
}

void set_out_pin (unsigned char num){           //output pin selection
    nG=1<<num;
    VFG_DDR = nG;
}

interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
    VFG_PORT = (VFG_PORT^nG)&(nG);
}

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Пт июн 09, 2023 11:49:38

Сколько памяти осталось на ATtiny?
Запустите UART и просмотрите результаты на компьютере (на реальном устройстве).
В противном случае борьба будет сложной. Что-то куда-то не рассчитывается/не конвертируется/переносится.
Особенно с некоторыми компиляторами, где есть особенности: например. больше 4-5-6 выражений подряд считает не правильно.
Нужно разбить на шаги на временные переменные. Просто даю идею - проверьте и это. И сasting variable.
Последний раз редактировалось veso74 Пт июн 09, 2023 13:02:39, всего редактировалось 1 раз.

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Пт июн 09, 2023 11:54:07

veso74, Program size: 706 words (1412 bytes), 68,9% of FLASH. Пока нет возможности на реальном устройстве затестить, нет чипа. Я думаю, что проблема в том, что я как-то не так считываю полученные данные по SPI, потому что функция генерации частоты прекрасно работала без USI. А сейчас она тупо не робит, может я как-то не так считываю полученную информацию в основном цикле.

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Пт июн 09, 2023 12:15:03

т.е. так и задумано?
передатчик "разрезает" переменную - приемник не "склеивает" байты, а суммирует.

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Пт июн 09, 2023 12:32:48

a797945, передатчик отправляет 4 байта информации в хексадермальном формате, моя задача их получить, склеить и подставить в функцию. Но из этих 4-х байт, 1 байт я должен подставить в переменную nG, а остальные 3 в переменную fG.
Спойлер
Код:
void SPITransmitFreq(unsigned char Cnt, double F) { //F- значение частоты
    dFi.w = F*167.77216; //частота передаваемая через SPI, какое-то фиксированное число 167.77216
    PORTB &= ~(1<<PORTB0);
    SPI_MasterTransmit(Cnt & 0x03);//0x03-маска
    SPI_MasterTransmit(dFi.b[0]);//флаги передачи
    SPI_MasterTransmit(dFi.b[1]);//флаги передачи
    SPI_MasterTransmit(dFi.b[2]);//флаги передачи
   PORTB |= (1<<PORTB0);
}

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Пт июн 09, 2023 12:52:26

елки-палки.
... моя задача их получить, склеить...
ну так склеить, а здесь dFi.b[0]+dFi.b[1] - суммирование.

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Пт июн 09, 2023 12:54:53

a797945, а как их склеить ?

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Пт июн 09, 2023 13:04:11

(dFi.b[0] | dFi.b[1]<<8 | dFi.b[2]<<16)
символ | - побитное ИЛИ

я таким не пользовался: (мне надо уточнять как правильно объявляется объединение)
typedef union
{
unsigned long int w ; // w as WORD
unsigned int h[2]; // h as HALF-WORD
unsigned char b[4]; // b as BYTE
} Union32;
но если здесь верно - можете брать dFi.w&0x00ffffff (погасив старший байт), только проверьте, чтоб младший и старший байты попадали на свои места.

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Пт июн 09, 2023 13:12:32

Код:
unsigned int fG;

Код:
fG = dFi.b[0] | dFi.b[1]<<8 | dFi.b[2]<<16;

также не складывается корректно.
---
Да, а797945, добавили 32 bit.
Последний раз редактировалось veso74 Пт июн 09, 2023 13:23:39, всего редактировалось 3 раз(а).

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Пт июн 09, 2023 13:18:09

кстати, да
у вас же unsigned int - 2-х байтовое

сорри, мозги привыкли, что у меня как правило int - 32-битное

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Пт июн 09, 2023 14:01:31

fG изменил на unsigned long int и начало в проетусе ругаться, что не хватает памяти.
С такой записью: fG = (dFi.b[1]<<8 | dFi.b[2]<<16 | dFi.b[3]<<32), пишет предупреждение shift result will be 0.

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Пт июн 09, 2023 14:10:53

не
Код:
... dFi.b[3] << 32

а так:
Код:
... dFi.b[3] << 24

---
Если не получается полностью (так это с некоторыми компиляторами) - по частям:
Код:
fG = dFi.b[1] << 8;
uint32_t tmp = dFi.b[2] << 16;
fG |= tmp;
tmp = dFi.b[2] << 24;
fG |= tmp;

Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313

Пт июн 09, 2023 14:33:52

veso74, все равно не помогает, кейс 2 и 3 тупо не выполняются.
Спойлер
Код:
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<<6);
    PORTD |= 1<<CS;                     // Activate Pull-Up resistor on PD3
    GIMSK |= 1<<INT1;                   
    MCUCR |= 1<<ISC10;
    #asm("sei")
}

// External Interrupt 0 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{     
    if((PIND & (1<<CS))== 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;
   flag_RT = 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) {
switch(reqID) {
   case 0:
      PORTD |= (1<<0);
        ch_num = USIDR;
      USISR = 1<<USIOIF;  // Clear Overflow bit
        reqID++;
   break;
   case 1:
        PORTD |= (1<<1);
      dFi.b[1] = USIDR;
      USISR = 1<<USIOIF;  // Clear Overflow bit
      reqID++;
   break;
   case 2:
        PORTD |= (1<<2);
      dFi.b[2] = USIDR;
      USISR = 1<<USIOIF;  // Clear Overflow bit
        reqID++;
   break;
   case 3:
        PORTD |= (1<<4);
      dFi.b[3] = USIDR;
      USISR = 1<<USIOIF;  // Clear Overflow bit
      reqID = 0;
       flag_RT = 1;
    break;
    }     
}
Ответить