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

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

Вт июн 06, 2023 13:20:21

Пишу код для слейва в виде Attiny2313, суть такова: мастер AT90CAN128 отправляет значение частоты и номер генератора по SPI, а слейв принимает сигнал по USI и на основе полученных значений выдает частоту на выходе(переменная fG отвечает за частоту, nG за номер ножки на выходе).
Генерация частоты происходит на таймере1, в функции SetUpTim1A(unsigned int Foc) - подставляем значение частоты fG, там расчитывается значение регистра OCR1A. В функции void set_out_pin (unsigned char num) - подставляем значение nG, эта функция подставляет значение заданного вывода МК в функцию прерывания и таким образом генерируется частота. В функции SpiSlaveInit() - выставляются настройки USI и разрешаются внешние прерывания и прерывания по переполнению. В функции прерывания interrupt [EXT_INT1] void ext_int1_isr(void) - проверяется состояние пина PD3: при Falling edge - разрешаются прерывания по переполнению таймера USI, при Rising edge -запрещаются.
В функции interrupt [USI_OVERFLOW] void usi_ovf_isr(void) - каждое прерывание считывается по байту входящей информации, и на основании полученных данных устанавливается значение fG и nG, ну и соответственно генерируется чатота на выходе.
Но даже без мастера он дергает всеми пинами в произвольном порядке.
Проблема заключается в том, что частота присутствует на выходе PB0 тиньки, и она не соответствует отправленной по SPI.
Код мастера:
Код:
void SPI_MasterInit(void) {
   SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0);   /* Enable SPI, Master, set clock rate fck/16 */
}

void SPI_MasterTransmit(uint8_t cData) {
   SPDR = cData;                  /* Start transmission */
   while(!(SPSR & (1<<SPIF)));      /* Wait for transmission complete */
}void SPITransmitFreq(uint8_t Cnt, double F) { //F- значение частоты, Cnt - номер генератора
   dFi.w = F*167.77216; //частота передаваемая через SPI, какое-то фиксированное число 167.77216
   PORTB &= ~_BV(PB0);
   SPI_MasterTransmit(Cnt & 0x03);//0x03-маска
   SPI_MasterTransmit(dFi.b[0]);//флаги передачи
   SPI_MasterTransmit(dFi.b[1]);//флаги передачи
   SPI_MasterTransmit(dFi.b[2]);//флаги передачи
   PORTB |= _BV(PB0);
}

Код слейва:
Код:
#include <tiny2313.h>
#include <math.h>
#include <io.h>

#define  F_CPU (8000000)
#define  VFG_TIMER_MAX (65535)
#define  VFG_DDR DDRB
#define  VFG_PORT PORTB

#define CS    PORTD3     // Chip select
#define DO    PORTB5     // MISO or Data Out
#define USCK  PORTB7     // Clock

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;
Union32 dFi;

unsigned int fG;
unsigned char nG;
unsigned int N[]={1,8,64,256,1024};
unsigned char flag_RT = 0;
unsigned char ch_num = 0;

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

//***********************************************USI************************************************

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<<PCIE;                     // General Interrupt Mask Register / PCIE bit activates external interrupts
    #asm("sei")
}

// External Interrupt 0 service routine
interrupt [EXT_INT1] void ext_int1_isr(void) {   
   
    if((PIND & (1<<CS))== 0){

// 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);
    }
}

interrupt [USI_OVERFLOW] void usi_ovf_isr(void) {
switch(reqID) {
   case 0:
      ch_num = USIDR;
      USISR = 1<<USIOIF;  // Clear Overflow bit
      reqID++;
   break;
   case 1:
      dFi.b[0] = USIDR;
      USISR = 1<<USIOIF;  // Clear Overflow bit
      reqID++;
   break;
   case 2:
      dFi.b[1] = USIDR;
      USISR = 1<<USIOIF;  // Clear Overflow bit
      reqID++;
   break;
   case 3:
      dFi.b[2] = USIDR;
      USISR = 1<<USIOIF;  // Clear Overflow bit
      reqID++;
      flag_RT = 1;
   break;
    }     
}

//***********************************************timer1************************************************

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;
 for(i=0;i<=4;i++) {
    TimDiv = (F_CPU/(2*16*Foc*N[i])-1);
    if(TimDiv >= 0 && TimDiv<VFG_TIMER_MAX){
     ClockSelect=i+1;
     break;
    }
 }
    #asm("cli")
    OCR1A = TimDiv;
    TCCR1B = (1<<WGM12) | (ClockSelect<<CS10);
    #asm("sei")
}

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);
}

void main(void)
{
 static unsigned int fG_old = 0;
 SpiSlaveInit();
 Tim1Init();
 UpdateTim1A(fG);
 
#asm("sei")
for(;;) {
 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
 if (flag_RT = 1) {
 set_out_pin (nG);
 SetUpTim1A(fG);
 }
 }
}

Огрызок схемы электрической принципиальной:
[url=https://img.radiokot.ru/files/153456/medium/35nbn9zmek.png]

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

Вт июн 06, 2023 14:39:51

1 Смысл плодить темы, не закончив предыдущую?
2 Схема не читается абсолютно.
3 Было ведь написано, что свич у вас заклинен на 0 кейсе. Значит регулировка частот просто недоступна. Зато доступен выбор пина порта В, для выхода генерации, если мастер со славой нормально контачат. Этот вариант вам и предлагалось опробовать и отладить. Потом уже занялись бы частотой.

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

Вт июн 06, 2023 16:46:40

Добавил архив с схемой(P-CAD) и прошивками ATTINY2313 и AT90CAN128.

Добавлено after 23 minutes 3 seconds:
1 Смысл плодить темы, не закончив предыдущую?
2 Схема не читается абсолютно.
3 Было ведь написано, что свич у вас заклинен на 0 кейсе. Значит регулировка частот просто недоступна. Зато доступен выбор пина порта В, для выхода генерации, если мастер со славой нормально контачат. Этот вариант вам и предлагалось опробовать и отладить. Потом уже занялись бы частотой.

1) Я считаю, что тема достаточно сложная и интресная, поэтому вынес отдельно. Также не видел похожих тем.
2) Скинул нормальную.
3) Я не знаю как мне проверить нормально ли они контачат.

Добавлено after 5 minutes 50 seconds:
Нашел ошибку в функции иницилзаци USI:
Код:
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
    GIMSK|=1<<INT1;                     // General Interrupt Mask Register
    //ISC11/ISC10 MCUCR
    #asm("sei")
}

Теперь внешние прерывания INT1 работают. В протеусе теперь показывает на всех пинах PB0,PB1,PB2 напряжение. Частота не генерируется.
Вложения
KD8105.rar
Добавил архив с схемой(P-CAD) и прошивками ATTINY2313 и AT90CAN128.
(511.15 KiB) Скачиваний: 31

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

Ср июн 07, 2023 02:13:36

PCAD-а у меня нет, так что схему все одно не увижу. Универсальный вариант - конвертировать в pdf. Акробат есть практически у всех. :)
3) Я не знаю как мне проверить нормально ли они контачат.

Порт В у вас практически пуст, за исключением 5 и 7 битов. Посылаете мастером любой из доступных номеров пина и смотрите светодиодом, осциллографом или что там у вас есть - "переехал" ли генератор на заданную ногу Attiny2313. Этим самым выясните - есть ли вообще хоть какой-то обмен данными, и реагирует ли на него Attiny2313. Отладите эту часть, а потом уже можно заняться и частотой, так как, похоже, придется усложнить протокол обмена данными, включив него и значения reqID.
Ну и такие схемы лучше отлаживать в железе. Протеус он такой протеус...

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

Ср июн 07, 2023 13:56:00

Вот в ПДФе схнма.

Добавлено after 1 hour 21 minute 58 seconds:
Со стороны мастера все впорядке, он что-то отправляет и это похоже на управляющий сигнал.
На стороне слейва только порт PB0 горит, но частоты там нет.

Добавлено after 44 minutes 31 second:
Ниже прикрепил осцилограмы выходных сигналов.

Добавлено after 2 minutes 22 seconds:
Вот ссылка на пример с которого писал код организации связи SPI-USI.
https://weathergadget.wordpress.com/201 ... unication/

Добавлено after 40 minutes 42 seconds:
С мастера все сигналы идут нормально, судя по осцилограмме, а вот слейв вообще не реагирует. Изменил регистры прерываний по внешнему сигналу GIMSK = 1<<INT1, на GIMSK |= 1<<PCIE - маска прерываний по измению уровня входящего сигнала и вернулся к прежней проблеме - 4 Гц на PB0. В прерываниях пробовал дергать пинами и пришел к выводу, что оба прерывания не работают. Также убирал функции расчёта частоты и прерываний Таймера1, результат тот же. Ещё нашел ошибку в том, что неправильно обозвал функцию прерывания по изменению уровня на входе, ошибку исправил - результат тот же.
Вложения
Безымянный.pdf
(648.71 KiB) Скачиваний: 42
P-CAD EDA - [Sheet1].pdf
(86.07 KiB) Скачиваний: 33

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

Ср июн 07, 2023 15:36:17

Уже какой-то конструктив...
Теперь понятно, что слейв просто не понимает или не видит мастера. Тут возможно или частота обмена данными не "в размер" или USI неверно настроен.

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

Ср июн 07, 2023 16:27:35

Тут возможно или частота обмена данными не "в размер" или USI неверно настроен.

По идее частота никак не должна влиять, ведь у меня постоянно идет опрос ножки PD3(CS) при изменении уровня логического сигнала, а прерывание PCIE - управляет прерываниями по переполнению 4-х битного таймера(включает/выключает их), а вот в функции прерывания этого таймера побайтово должны приниматься сигналы и я уже в мейне подставляю полученые байты в переменную fG и nG и там уже высчитывается значение частоты и номер вывода. Еще и для протеуса на работе в компе CPU не хватает и он инфу не в реал тайме отображает, попробую дома прогнать, может результат изменится, но я так думаю, что наврятли.

Добавлено after 32 minutes 53 seconds:
Вернулся к внешним прерываниям INT1:
Код:
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)                 
    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){

// 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);
    }
}

В регистре MCUCR установил также прерывания при любом изменении логического уровня на INT1, теперь есть хоть какая-то реакция на изменения входных данных от мастера, при изменении переменных nG и fG в прошивке мастера - меняются выходы и частота на слейве. Но я не знаю пока как это структурировать.
Последний раз редактировалось warptred12 Ср июн 07, 2023 16:29:20, всего редактировалось 1 раз.

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

Ср июн 07, 2023 16:28:45

warptred12 писал(а):По идее частота никак не должна влиять
Значит в даташитах ерунду пишут?
стр. 138 даташита писал(а):The main features of the USI are:
• Two-wire Synchronous Data Transfer (Master or Slave, fSCLmax = fCK/16)
• Three-wire Synchronous Data Transfer (Master, fSCKmax = fCK/2, Slave fSCKmax = fCK/4)
Если учесть, что 4-битный счетчик работает по обоим фронтам входного сигнала, то и "неправильное" прерывание, при завышенной частоте вполне вероятно.
Увидел ваше дополнение. Проблема решена?

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

Ср июн 07, 2023 17:21:00

На мастере clock rate = fck/16, а как на слейве это настроить непонятно.
Добавлено after 1 minute 59 seconds:
Увидел ваше дополнение. Проблема решена?

Ну теперь пины и частота меняются, но частоты и пины рандомно работают. Так что не решена.

Добавлено after 47 minutes 6 seconds:
Вот такие крокозябры генерируются на выходе, честно говоря даже не знаю, с чем это может быть связано.
Вложения
Безымянный1.pdf
Осцилограма в протеусе
(605.65 KiB) Скачиваний: 51

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

Ср июн 07, 2023 19:12:02

Как будто модуляция какая-то присутствует...
warptred12 писал(а):На мастере clock rate = fck/16, а как на слейве это настроить непонятно.

Здесь надо под приемник подстраиваться. Attiny2313 у вас на 8МГц работает без делителя? Значит частота обмена должна быть не более 2МГц для 2 проводного или 500КГц для трехпроводного соединений.

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

Чт июн 08, 2023 11:42:11

Частота по линии SCK 32.5 кГц, SS 1 кГц, MOSI 4 кГц. Так же в протеусе подключил SPI DEBUGGER и окончательно убедился что мастер все правильно передает. Частота тактирования аттини и атмеги - 8 МГц.

Добавлено after 15 minutes 30 seconds:
Сделал скриншот терминала SPI Debuger'а, там все верно: 1 байт - номер генератора(2), 2- байт частота в хексадермальном формате А7(1Гц- это 167), остальные байты нули.
Вложения
Безымянный2.pdf
(477.37 KiB) Скачиваний: 35

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

Чт июн 08, 2023 13:27:13

Обана! Интрига становится все интереснее. :))
Появились уже 2!! значимых байта, что, в принципе-то и правильно. Но и вопросы появились:
1. Что такое "остальные байты"? Откуда берутся и зачем вообще нужны?
2. Как и где в коде приемника обрабатывается первый байт и как приемник "понимает" - где какой?

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

Чт июн 08, 2023 13:58:13

Обана! Интрига становится все интереснее. :))
Появились уже 2!! значимых байта, что, в принципе-то и правильно. Но и вопросы появились:
1. Что такое "остальные байты"? Откуда берутся и зачем вообще нужны?
2. Как и где в коде приемника обрабатывается первый байт и как приемник "понимает" - где какой?


1. Мастер передает 4 байта информации по SPI: 1 байт-номер генератора, он отвечает за то на какой ножке слейва будет генерироваться чатота, это значение подставляется в переменную nG, 3 остальных байта - численное значение частоты в хексадермальном формате, умноженное на число 167.

2. В прерывании USI_OVERFLOW, они передаются последовательно и записываются в объединение dFi, а потом подставляются в переменные nG(номер выходного пина) и fG(частота), а эти переменные подставляются в функции расчета регистра прерываний Таймера1 OCR1A(частота) и в само прерывание Таймера1(номер выходной ножки).

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

Чт июн 08, 2023 14:04:44

Не пробовали на реальном устройстве?
Proteus ... МК с прерывания ... у меня было много сюрпризов (и потраченные часы на поиск неточностей).

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

Чт июн 08, 2023 14:26:44

veso74, попробую, но мне кажется скорее, что я где-то накосячил или что-то не учел.

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

Чт июн 08, 2023 14:31:40

warptred12,
...
...
case 3:
dFi.b[2] = USIDR;
USISR = 1<<USIOIF; // Clear Overflow bit
reqID++;
reqID = 0;
flag_RT = 1;
break;

Попробуйте так.

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

Чт июн 08, 2023 14:36:16

MOHCTEP, не помогло, просто горит пин PB0.

Добавлено after 1 minute 45 seconds:
На мастере nG(номер ножки) = 2, fG(частота) = 2222.

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

Чт июн 08, 2023 14:55:22

Тогда у меня больше вариантов нет. Слепите на макетке реальную схему. Думаю в качестве мастера даже второй Attiny2313 подойдет, для отладки.

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

Чт июн 08, 2023 15:55:14

Решил проверить кейсы светодиодиками и это дало результаты, в прерываниях инт1 они горят и 1 и 2 кейсы тоже, но 3 и 4 кейс не горят, значит они не работают. Теперь вопрос в том почему они не работают.
Вложения
Безымянный3.pdf
(498.57 KiB) Скачиваний: 32

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

Чт июн 08, 2023 16:07:45

Возможно посылка мастера таки = 2 байтам? Ну и где-то в коде еще гасите светодиоды, через паузу, для динамики.
Ответить