Проблема при связи SPI и USI AT90CAN128 и Attiny2313
-
warptred12
- Открыл глаза
- Сообщения: 76
- Зарегистрирован: Чт июн 01, 2023 11:30:34
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
veso74, да, боюсь еще хуже будет, сейчас весь код вроде как до минимума сокращен, а вот если что-то еще добавлять, будут дополнительные проблемы.
- Реклама
-
veso74
- Поставщик валерьянки для Кота
- Сообщения: 1907
- Зарегистрирован: Сб май 05, 2012 20:24:52
- Откуда: KN34PC, Болгария
- Контактная информация:
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
Код: Выделить всё
volatile unsigned long int fG;
volatile unsigned char b1,b2,b3,b4;
...
fG = 0 |b2 | (b3<<8)| (b4<<16);Код: Выделить всё
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);Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
ничего не понимаю - ЗАЧЕМ вы разломали мастера?
в вашем сообщении от Пн июл 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 от слейва.
в вашем сообщении от Пн июл 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 от слейва.
-
warptred12
- Открыл глаза
- Сообщения: 76
- Зарегистрирован: Чт июн 01, 2023 11:30:34
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
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 КБ) 55 скачиваний
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
подключили PINB1 к линии SS ?
за сползание еще подумаю, а пока покажите ответ если
заменить SPDR = 0x12; на SPDR =(unsigned char)(fG&0xff);
за сползание еще подумаю, а пока покажите ответ если
заменить SPDR = 0x12; на SPDR =(unsigned char)(fG&0xff);
- Реклама
-
warptred12
- Открыл глаза
- Сообщения: 76
- Зарегистрирован: Чт июн 01, 2023 11:30:34
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
a797945,
- Вложения
-
- Безымянный.pdf
- (397.78 КБ) 73 скачивания
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
надо бороться с обнаружением 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);
можно заменить:
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);
-
warptred12
- Открыл глаза
- Сообщения: 76
- Зарегистрирован: Чт июн 01, 2023 11:30:34
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
a797945, а если использовать внешнее прерывание INT1, например ?
Вот что получилось на выходе.
Вот что получилось на выходе.
- Вложения
-
- Безымянный.pdf
- (409.96 КБ) 59 скачиваний
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
01 02 03 04 всегда идут последовательно, но не вовремя - значит и читает слейв не вовремя, как если PINB1 болтается в воздухе
пошел курить даташит
Добавлено after 2 hours 19 seconds:
возможно, если вставить какую задержку в поллинг pinb1 он в протеусе и заработает, а в "железе" может работал бы и так. но от поллинга по-хорошему все равно надо отказываться (думал это делать позже).
лучше на прерывании : спад на INT1 - прием 4-х байт, склеивание fG, побайтный возврат fG, выход из прерывания.
соответственно линию не на PINB2+PINB1 а на PINB2+INT1
пошел курить даташит
Добавлено after 2 hours 19 seconds:
возможно, если вставить какую задержку в поллинг pinb1 он в протеусе и заработает, а в "железе" может работал бы и так. но от поллинга по-хорошему все равно надо отказываться (думал это делать позже).
лучше на прерывании : спад на INT1 - прием 4-х байт, склеивание fG, побайтный возврат fG, выход из прерывания.
соответственно линию не на PINB2+PINB1 а на PINB2+INT1
-
warptred12
- Открыл глаза
- Сообщения: 76
- Зарегистрирован: Чт июн 01, 2023 11:30:34
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
veso74, ну да, в датамемори все тоже самое что и на spi анализаторе. Просто на spi анализаторе можно время приема-передачи увидеть и все наглядней. А изза того что я отправляю обратно данные обратно на мастера, они могут искажаться ?
a797945, завтра попробую подумать, как это можно сделать, потом отпишусь отпишусь.
a797945, завтра попробую подумать, как это можно сделать, потом отпишусь отпишусь.
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
ориентировочная "рыба", без сверки с даташитом, заменил обработчик, 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)
{
}
}
-
warptred12
- Открыл глаза
- Сообщения: 76
- Зарегистрирован: Чт июн 01, 2023 11:30:34
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
a797945, вот что получилось.
код слейва:
Добавлено after 33 minutes 20 seconds:
veso74, с результат тот же.
код слейва:
Спойлер
Код: Выделить всё
#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) {
}
}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 КБ) 65 скачиваний
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
зачем вы опять сломали мастера? это начинает утомлять
при таком мастере слейв корректно работать не может - он отсылает 8 байт, а чем теперь занимается мастер не понятно. на скрине 6 байт. там где вы не доломали слейв умудряется отсылать 01 02 03 04 FF 01 два последних это первые 2 принятые от мастера.
для остальных должен озвучить информацию (покаяться):
мои предположения о причинах неработы поллинга на PINB2 и PINB1 не более чем не подтвержденные гипотезы.
на самом деле я допустил ошибку - оглядываясь вперед не поставил ожидание флага
...
SPDR =0x14;
while(!(SPSR & (1<<SPIF))); <--
}
...
и слейв положив 0х14 в SPDR сразу уходил на ожидание 0 на SS, но мастер еще передавал последний байт - слейв проваливался на прием первого байта, а когда мастер начинал новую посылку слейв был уже смещен на байт и так по циклу.
при таком мастере слейв корректно работать не может - он отсылает 8 байт, а чем теперь занимается мастер не понятно. на скрине 6 байт. там где вы не доломали слейв умудряется отсылать 01 02 03 04 FF 01 два последних это первые 2 принятые от мастера.
для остальных должен озвучить информацию (покаяться):
мои предположения о причинах неработы поллинга на PINB2 и PINB1 не более чем не подтвержденные гипотезы.
на самом деле я допустил ошибку - оглядываясь вперед не поставил ожидание флага
...
SPDR =0x14;
while(!(SPSR & (1<<SPIF))); <--
}
...
и слейв положив 0х14 в SPDR сразу уходил на ожидание 0 на SS, но мастер еще передавал последний байт - слейв проваливался на прием первого байта, а когда мастер начинал новую посылку слейв был уже смещен на байт и так по циклу.
-
warptred12
- Открыл глаза
- Сообщения: 76
- Зарегистрирован: Чт июн 01, 2023 11:30:34
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
a797945, вот что я мастером отправляю:
а вот как принимаю(убрал внешнее прерывание int0):
Ниже скрин полученных данных, на мастере я ничего не менял.
Спойлер
Код: Выделить всё
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);Спойлер
Код: Выделить всё
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 КБ) 70 скачиваний
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
убрал внешнее прерывание int0...
и ss переключил?
на мастере я ничего не менял...
по скинам хорошо видно как "не менял"
выровнил количество байт на мастере и на слейве?
свободное время у меня вышло - дальше самостоятельно
и ss переключил?
на мастере я ничего не менял...
по скинам хорошо видно как "не менял"
выровнил количество байт на мастере и на слейве?
свободное время у меня вышло - дальше самостоятельно
-
warptred12
- Открыл глаза
- Сообщения: 76
- Зарегистрирован: Чт июн 01, 2023 11:30:34
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
вопрос открыт еще на данный момент, сижу думаю
-
warptred12
- Открыл глаза
- Сообщения: 76
- Зарегистрирован: Чт июн 01, 2023 11:30:34
Re: Проблема при связи SPI и USI AT90CAN128 и Attiny2313
На данный момент проблема заключается в том, что 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);
}
}

