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

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

Вт июл 11, 2023 12:35:32

veso74, да, боюсь еще хуже будет, сейчас весь код вроде как до минимума сокращен, а вот если что-то еще добавлять, будут дополнительные проблемы.

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

Вт июл 11, 2023 17:35:56

Код:
volatile unsigned long int fG;
volatile unsigned char b1,b2,b3,b4;
...
fG = 0 |b2 | (b3<<8)| (b4<<16);

В некоторых компиляторах вычисляется неправильно. Проверьте свой. Если нет, то с cast, и по частям.
Код:
volatile uint32_t fG;
volatile uint8_t b1, b2, b3, b4;
...
fG = (uint32_t)b2;
fG |= ((uint32_t)b3 << 8);
fG |= ((uint32_t)b4 << 16);

(Переверните пример в своих типах данных. Я не умею работать с этими длинными типами :P ).

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

Вт июл 11, 2023 18:29:43

ничего не понимаю - ЗАЧЕМ вы разломали мастера?
в вашем сообщении от Пн июл 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;

fG = 0 |b2 | (b3<<8)| (b4<<16);
while(!(SPSR & (1<<SPIF)));
SPDR = 0x11;
while(!(SPSR & (1<<SPIF)));
SPDR = 0x12;
while(!(SPSR & (1<<SPIF)));
SPDR = 0x13;
while(!(SPSR & (1<<SPIF)));
SPDR = 0x14;

сползание должно было прекратиться. это надо проверить и вернуться к передаче fG от слейва.

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

Вт июл 11, 2023 18:40:18

a797945, вот что получается на выходе.
Код мастера:
Спойлер
Код:
#include <mega128.h>
#include <io.h>
#include <delay.h>

volatile unsigned char   reqTr,reqTm;

struct Tmr_t {
    unsigned char n;           
    double  F;
};

struct Tmr_t   T;       

unsigned char chrT;

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;

void SPI_MasterTransmit(unsigned char cData);

void IOInit(void) {

  PORTA = 0b00000000;
  DDRA  = 0b11111111;

  PORTB = 0b00001001;
  DDRB  = 0b11110111;

  PORTC = 0b00010000;
  DDRC  = 0b11111111;
 
  PORTD = 0b01101100;
  DDRD  = 0b10111011;
 
  PORTE = 0b00000011;
  DDRE  = 0b11111110;

  PORTF = 0b00000000;
  DDRF  = 0b11111110;

  PORTG = 0b00000000;
  DDRG  = 0b11111111;
 
  reqTr=0;
  reqTm=0;
}


void SPI_MasterInit(void) {
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);    /* Enable SPI, Master, set clock rate fck/16 */
}

void SPI_MasterTransmit(unsigned char cData) {
    SPDR = cData;                        /* Start transmission */
    while(!(SPSR & (1<<SPIF)));        /* Wait for transmission complete */
}

void SPITransmitFreq(unsigned char Cnt, double F) { //F- значение частоты
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);
}
void main(void)
{
chrT=0x01;
T.n=0;
T.F=0;
SPI_MasterInit();
IOInit();
while (1)
      {
      unsigned char nG=2;
     double fG=100;
      SPITransmitFreq(T.n, T.F);//T.F-значение частоты, T.n-номер генератора

               switch(nG) {
                  case 0:   {T.n=0; T.F=fG; reqTm=1;}; break;   
                  case 1:   {T.n=1; T.F=fG; reqTm=1;}; break;
                  case 2:   {T.n=2; T.F=fG; reqTm=1;}; break;
                    }

      }
}

Код слейва:
Спойлер
Код:
#include <mega8.h>
#include <math.h>
#include <io.h>
#include <delay.h>

#define  F_CPU (8000000)
#define  VFG_TIMER_MAX (65535)
#define  VFG_DDR DDRD
#define  VFG_PORT PORTD

volatile unsigned char i=0;
volatile unsigned long int fG;
volatile unsigned char nG;
unsigned int N[]={1,8,64,256,1024};
//BYTE STORAGE
volatile unsigned char master_arr [4];
//BYTE COUNTER
volatile int reqID;
volatile int flagRT=0;

void setup (void)
{
#asm("cli")
DDRB |= (1 << PORTB4);              //configure MISO as output
SPCR |= (1 << SPE) | (0 << MSTR);   //configure slave mod and interrupt
#asm("sei")
}

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

void main(void)
{
VFG_DDR = 0b00000111;
DDRC = 0b11111111;
setup();
#asm("sei")
for(;;) {
unsigned char b1,b2,b3,b4;
while(PINB.1==1);
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;

fG = 0 |b2 | (b3<<8)| (b4<<16);
while(!(SPSR & (1<<SPIF)));
SPDR = 0x11;
while(!(SPSR & (1<<SPIF)));
SPDR = 0x12;
while(!(SPSR & (1<<SPIF)));
SPDR = 0x13;
while(!(SPSR & (1<<SPIF)));
SPDR = 0x14;
        }         
}
Вложения
Безымянный.pdf
(405.25 KiB) Скачиваний: 38

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

Вт июл 11, 2023 18:52:48

подключили PINB1 к линии SS ?

за сползание еще подумаю, а пока покажите ответ если
заменить SPDR = 0x12; на SPDR =(unsigned char)(fG&0xff);

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

Вт июл 11, 2023 18:55:35

a797945,
Вложения
Безымянный.pdf
(397.78 KiB) Скачиваний: 30

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

Вт июл 11, 2023 19:02:10

надо бороться с обнаружением 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);

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

Вт июл 11, 2023 19:06:53

a797945, а если использовать внешнее прерывание INT1, например ?
Вот что получилось на выходе.
Вложения
Безымянный.pdf
(409.96 KiB) Скачиваний: 37

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

Вт июл 11, 2023 21:11:31

01 02 03 04 всегда идут последовательно, но не вовремя - значит и читает слейв не вовремя, как если PINB1 болтается в воздухе

пошел курить даташит

Добавлено after 2 hours 19 seconds:
возможно, если вставить какую задержку в поллинг pinb1 он в протеусе и заработает, а в "железе" может работал бы и так. но от поллинга по-хорошему все равно надо отказываться (думал это делать позже).
лучше на прерывании : спад на INT1 - прием 4-х байт, склеивание fG, побайтный возврат fG, выход из прерывания.

соответственно линию не на PINB2+PINB1 а на PINB2+INT1

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

Вт июл 11, 2023 21:33:17

Даже не нужно возвращать данные для сравнения.
В слейве, в Debug, AVR откройте Data Memory и найдете какие значения принимали переменные.

Ниже: пример с моим термореле на ATtiny13A и DS18B20.
Изображение

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

Вт июл 11, 2023 22:01:51

veso74, ну да, в датамемори все тоже самое что и на spi анализаторе. Просто на spi анализаторе можно время приема-передачи увидеть и все наглядней. А изза того что я отправляю обратно данные обратно на мастера, они могут искажаться ?
a797945, завтра попробую подумать, как это можно сделать, потом отпишусь отпишусь.

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

Вт июл 11, 2023 22:46:06

ориентировочная "рыба", без сверки с даташитом, заменил обработчик, 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);   
}

//----------
ISR(INT1_vect)
{
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;

fG = 0 |b2 | (b3<<8)| (b4<<16);
while(!(SPSR & (1<<SPIF)));
SPDR =(unsigned char)(fG&0xff);
while(!(SPSR & (1<<SPIF)));
SPDR =(unsigned char)((fG>>8)&0xff);
while(!(SPSR & (1<<SPIF)));
SPDR =(unsigned char)((fG>>16)&0xff);
while(!(SPSR & (1<<SPIF)));
SPDR =(unsigned char)((fG>>24)&0xff);
while(!(SPSR & (1<<SPIF)));
}
//----------
int main(void)
{

   int_ini();
   sei();
    while (1)
    {
    }
}

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

Ср июл 12, 2023 10:45:00

a797945, вот что получилось.

код слейва:
Спойлер
Код:
#include <mega8.h>
#include <math.h>
#include <io.h>
#include <delay.h>

#define  F_CPU (8000000)
#define  VFG_TIMER_MAX (65535)
#define  VFG_DDR DDRD
#define  VFG_PORT PORTD

volatile unsigned char b1,b2,b3,b4;
volatile unsigned char i=0;
volatile unsigned long int fG;
volatile unsigned char nG;
unsigned int N[]={1,8,64,256,1024};
//BYTE STORAGE
volatile unsigned char master_arr [4];
//BYTE COUNTER
volatile int reqID;
volatile int flagRT=0;

void setup (void)
{
#asm("cli")
DDRB |= (1 << PORTB4);              //configure MISO as output
SPCR |= (1 << SPE) | (0 << MSTR);   //configure slave mod and interrupt
//Включим ножки INT0 и INT1 (PD2 и PD3)  на вход
DDRD &= ~(0b00001100);
//поодтянем резистор на ножках INT0 и INT1 (PD2 и PD3) к питанию
PORTD |= 0b00001100;
//включим прерывания INT0 и INT1 по нисходящему фронту
MCUCR |= (1<<ISC01);
//разрешим внешние прерывания INT0 и INT1
GICR |= (1<<INT0); 
#asm("sei")
}

interrupt [EXT_INT0] void ext_int0_isr(void)
{
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;

fG = 0 |b2 | (b3<<8)| (b4<<16);
while(!(SPSR & (1<<SPIF)));
SPDR =(unsigned char)(fG&0xff);
while(!(SPSR & (1<<SPIF)));
SPDR =(unsigned char)((fG>>8)&0xff);
while(!(SPSR & (1<<SPIF)));
SPDR =(unsigned char)((fG>>16)&0xff);
while(!(SPSR & (1<<SPIF)));
SPDR =(unsigned char)((fG>>24)&0xff);
while(!(SPSR & (1<<SPIF)));
}
//***********************************************timer1************************************************

void main(void)
{
VFG_DDR = 0b00000111;
DDRC = 0b11111111;
setup();
SPDR = 0;
#asm("sei")
while(1) {
}         
}


Добавлено after 33 minutes 20 seconds:
veso74, с
Спойлер
Код:
volatile uint32_t fG;
volatile uint8_t b1, b2, b3, b4;
...
fG = (uint32_t)b2;
fG |= ((uint32_t)b3 << 8);
fG |= ((uint32_t)b4 << 16);
результат тот же.
Вложения
Безымянный10.pdf
(493.29 KiB) Скачиваний: 41

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

Ср июл 12, 2023 18:42:36

зачем вы опять сломали мастера? это начинает утомлять :kill:
при таком мастере слейв корректно работать не может - он отсылает 8 байт, а чем теперь занимается мастер не понятно. на скрине 6 байт. там где вы не доломали слейв умудряется отсылать 01 02 03 04 FF 01 два последних это первые 2 принятые от мастера.

для остальных должен озвучить информацию (покаяться):
мои предположения о причинах неработы поллинга на PINB2 и PINB1 не более чем не подтвержденные гипотезы.
на самом деле я допустил ошибку - оглядываясь вперед не поставил ожидание флага
...
SPDR =0x14;
while(!(SPSR & (1<<SPIF))); <--
}
...
и слейв положив 0х14 в SPDR сразу уходил на ожидание 0 на SS, но мастер еще передавал последний байт - слейв проваливался на прием первого байта, а когда мастер начинал новую посылку слейв был уже смещен на байт и так по циклу.

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

Ср июл 12, 2023 19:25:21

a797945, вот что я мастером отправляю:
Спойлер
Код:
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):
Спойлер
Код:
unsigned char b1,b2,b3,b4;
while(PINB.1==1);
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;
fG = 0 |b2 | (b3<<8)| (b4<<16);
while(!(SPSR & (1<<SPIF)));
SPDR = 0x11;
while(!(SPSR & (1<<SPIF)));
SPDR = 0x12;
while(!(SPSR & (1<<SPIF)));
SPDR = 0x13;
while(!(SPSR & (1<<SPIF)));
SPDR = 0x14;
while(!(SPSR & (1<<SPIF)));

Ниже скрин полученных данных, на мастере я ничего не менял.
Вложения
Безымянный.pdf
(388.92 KiB) Скачиваний: 42

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

Ср июл 12, 2023 19:51:32

убрал внешнее прерывание int0...
и ss переключил?

на мастере я ничего не менял...
по скинам хорошо видно как "не менял"

выровнил количество байт на мастере и на слейве?

свободное время у меня вышло - дальше самостоятельно

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

Вт мар 12, 2024 17:11:07

вопрос открыт еще на данный момент, сижу думаю

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

Пт мар 15, 2024 13:15:55

На данный момент проблема заключается в том, что slave не может обработать посылки от мастера, я модульно тестировал блоки кода программы и нормально работает пока что только код отвечающий за генерацию частоты. Снизу скину код мастера atmega128 и attiny2313.
Мастер:
Код:
#include <mega128.h>
#include <io.h>
#include <delay.h>

volatile unsigned char   reqTr,reqTm;

struct Tmr_t {
    unsigned char n;           
    unsigned long int  F;
};

struct Tmr_t   T;       

unsigned char chrT;

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;

void SPI_MasterTransmit(unsigned char cData);

void IOInit(void) {

  PORTA = 0b00000000;
  DDRA  = 0b11111111;

  PORTB = 0b00001001;
  DDRB  = 0b11110111;

  PORTC = 0b00010000;
  DDRC  = 0b11111111;
 
  PORTD = 0b01101100;
  DDRD  = 0b10111011;
 
  PORTE = 0b00000011;
  DDRE  = 0b11111110;

  PORTF = 0b00000000;
  DDRF  = 0b11111110;

  PORTG = 0b00000000;
  DDRG  = 0b11111111;
 
  reqTr=0;
  reqTm=0;
}

void SPI_MasterInit(void) {
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);    /* Enable SPI, Master, set clock rate fck/128 */
}

void SPI_MasterTransmit(unsigned char cData) {
    SPDR = cData;                        /* Start transmission */
    while(!(SPSR & (1<<SPIF)));        /* Wait for transmission complete */
}

void SPITransmitFreq(unsigned char Cnt, unsigned long int F) { //F- значение частоты
dFi.w = F*167.77216;
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);
}
void main(void)
{
chrT=0x01;
T.n=0;
T.F=0;
SPI_MasterInit();
IOInit();
while (1)
      {
      unsigned char nG=1;
      unsigned long int fG=10;
      SPITransmitFreq(T.n, T.F);//T.F-значение частоты, T.n-номер генератора

               switch(nG) {
                  case 0:   {T.n=0; T.F=fG; reqTm=1;}; break;   
                  case 1:   {T.n=1; T.F=fG; reqTm=1;}; break;
                  case 2:   {T.n=2; T.F=fG; reqTm=1;}; break;
                    }

      }
}

Слэйв:
Код:
#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

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

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

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

void SetUpTim1A(unsigned long int Foc)              //calculate value OCR1A register
{
    unsigned long int TimDiv;
    unsigned char ClockSelect=0;
    unsigned char i=0;
    for(i=0;i<=4;i++) {
        TimDiv = 1*((F_CPU/((Foc/167.77216)*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")   
}

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

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);
}
}
Ответить