Пт июн 09, 2023 14:54:10
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]);//флаги передачи
Пт июн 09, 2023 15:01:25
Пт июн 09, 2023 15:41:54
switch(reqID) {
...
...
case 3:
dFi.b[2] = USIDR;
USISR = 1<<USIOIF; // Clear Overflow bit
reqID++; // !!
flag_RT = 1;
break;
}
reqID %=4;
...
Пт июн 09, 2023 15:58:21
//https://weathergadget.wordpress.com/2016/05/19/usi-spi-slave-communication/
#include <tiny2313.h>
#include <math.h>
#include <io.h>
#include <delay.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<<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;
}
}
//***********************************************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=0;
for(i=0;i<=4;i++) {
TimDiv = (F_CPU/(2*(Foc/167.77216)*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;
//PORTA |= (1<<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;
//PORTB |= (1<<6);
}
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
VFG_PORT = (VFG_PORT^nG)&(nG);
}
void main(void)
{
static unsigned int fG_old = 0;
unsigned long int tmp;
Tim1Init();
UpdateTim1A(fG);
SpiSlaveInit();
//DDRA=0b11111111;
//DDRB=0b11111111;
DDRD=0b11110111;
#asm("sei")
for(;;) {
//delay_ms(1);
PORTD &= (~((1<<0)|(1<<1)|(1<<2)|(1<<4)|(1<<5)|(1<<6)));
//PORTB &= (~(1<<3)|(1<<4)|(1<<6));
//PORTA &= (~(1<<0)|(1<<1));
if (fG_old != fG) { //old value detction
SetUpTim1A(fG);
fG_old = fG;
}
nG = ch_num; //generator number
fG = dFi.b[1] << 8;
tmp = dFi.b[2] << 16;
fG |= tmp;
tmp = dFi.b[2] << 24;
fG |= tmp; //generator frequency
set_out_pin (nG);
SetUpTim1A(fG);
}
}
Пт июн 09, 2023 16:11:48
Пт июн 09, 2023 16:27:12
Пт июн 09, 2023 16:38:04
void main(void)
{
static unsigned int fG_old = 0;
unsigned long int tmp;
Tim1Init();
UpdateTim1A(fG);
SpiSlaveInit();
//DDRA=0b11111111;
DDRB=0b11111111;
DDRD=0b11110111;
#asm("sei")
for(;;) {
//delay_ms(1);
PORTD &= (~((1<<0)|(1<<1)|(1<<2)|(1<<4)|(1<<5)|(1<<6)));
//PORTB &= (~(1<<3)|(1<<4)|(1<<6));
//PORTA &= (~(1<<0)|(1<<1));
if (fG_old != fG) { //old value detction
SetUpTim1A(fG);
fG_old = fG;
}
nG=1<<ch_num; //generator number
fG = dFi.b[1] << 8;
tmp = dFi.b[2] << 16;
fG |= tmp;
tmp = dFi.b[2] << 24;
fG |= tmp; //generator frequency
//set_out_pin (nG);
SetUpTim1A(fG);
}
}
Пт июн 09, 2023 17:11:00
Пт июн 09, 2023 17:14:39
dFi.w = (unsigned long int)((float)F * 167.77216);
Пт июн 09, 2023 17:31:21
Пт июн 09, 2023 19:17:45
Пт июн 09, 2023 19:20:45
Пт июн 09, 2023 19:25:51
Вт июл 04, 2023 16:20:49
#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 long int fG;
unsigned char nG;
unsigned int N[]={1,8,64,256,1024};
unsigned char flag_RT = 0;
unsigned char ch_num = 0;
// Массив корторый приходит от мастера
volatile unsigned char master_arr [3];
// Массив который отдаем от мастеру
volatile unsigned char slave_arr [3];
// счетчик входящих байт
volatile int countSPIb = -1;
void setup (void)
{
// Настройка SPI как SLAVE
DDRB |= (1 << PORTB4); // Настроить вывод MISO1 на выход
SPCR |= (1 << SPIE) | (1 << SPE) | (0 << MSTR); // Прерывание включено и сам SPI как SLAVE
}
interrupt [SPI_STC] void spi_isr(void) // Прерывание SPI1 - пришел байт
{
if (countSPIb < 0) { // пришла "пустышка"
countSPIb++; // увеличивам счетчик
SPDR = slave_arr [countSPIb]; // подгружаем нулевой байт массива ведомого
PORTC |= (1<<0);
return; // выходим из процедуры
}
master_arr [countSPIb] = SPDR1; // получаем байт от мастера
countSPIb++; // увеличиваем счетчик
SPDR = slave_arr [countSPIb]; // отдаем байт ведомого (+1 индекс)
PORTC |= (1<<1);
if (countSPIb >= sizeof(master_arr)) { // если кончился массив
PORTC |= (1<<2);
countSPIb = -1; // обнуляем счетчик и ждем следующий обмен
}
} // Конец SPI - пришел байт
//***********************************************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 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/(2*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 long int freq) //old value storage
{
static unsigned long int fG_old = 0;
if (fG_old != freq)
{
SetUpTim1A(freq);
fG_old = freq;
}
}
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
VFG_PORT = (VFG_PORT^nG)&(nG);
}
void main(void)
{
static unsigned long int fG_old = 0;
unsigned long int tmp;
int i;
VFG_DDR = 0b00000111;
DDRC = 0b11111111;
setup();
Tim1Init();
#asm("sei")
for(;;) {
if(PINB.2==0) {countSPIb = -1;} //сброс в случае глюка связи
if (fG_old != fG) { //old value detction
SetUpTim1A(fG);
fG_old = fG;
}
for (i = 0; i < sizeof(master_arr); i++) {
nG = master_arr[i]; //generator number
fG = master_arr[i] << 8;
tmp = master_arr[i] << 16;
fG |= tmp;
tmp = master_arr[i] << 24;
fG |= tmp;
//generator frequency
UpdateTim1A(fG);
SetUpTim1A(fG);
}
}
}
Вт июл 04, 2023 17:39:02
for (i = 0; i < sizeof(master_arr); i++) {
nG = master_arr[i]; //generator number
fG = master_arr[i] << 8;
tmp = master_arr[i] << 16;
fG |= tmp;
tmp = master_arr[i] << 24;
fG |= tmp;
//generator frequency
UpdateTim1A(fG);
SetUpTim1A(fG);
}
Вт июл 04, 2023 17:51:48
Вт июл 04, 2023 18:05:06
Вт июл 04, 2023 18:44:17
#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 long int fG;
unsigned char nG;
unsigned int N[]={1,8,64,256,1024};
unsigned char flag_RT = 0;
unsigned char ch_num = 0;
// Массив корторый приходит от мастера
volatile unsigned char master_arr [4];
// Массив который отдаем от мастеру
volatile unsigned char slave_arr [4];
// счетчик входящих байт
volatile int countSPIb = -1;
void setup (void)
{
// Настройка SPI как SLAVE
DDRB |= (1 << PORTB4); // Настроить вывод MISO1 на выход
SPCR |= (1 << SPIE) | (1 << SPE) | (0 << MSTR); // Прерывание включено и сам SPI как SLAVE
}
interrupt [SPI_STC] void spi_isr(void) // Прерывание SPI1 - пришел байт
{
if (countSPIb < 0) { // пришла "пустышка"
countSPIb++; // увеличивам счетчик
SPDR = slave_arr [countSPIb]; // подгружаем нулевой байт массива ведомого
PORTC |= (1<<0);
return; // выходим из процедуры
}
master_arr [countSPIb] = SPDR1; // получаем байт от мастера
countSPIb++; // увеличиваем счетчик
SPDR = slave_arr [countSPIb]; // отдаем байт ведомого (+1 индекс)
PORTC |= (1<<1);
if (countSPIb >= sizeof(master_arr)) { // если кончился массив
PORTC |= (1<<2);
countSPIb = -1; // обнуляем счетчик и ждем следующий обмен
}
} // Конец SPI - пришел байт
//***********************************************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 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/(2*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 long int freq) //old value storage
{
static unsigned long int fG_old = 0;
if (fG_old != freq)
{
SetUpTim1A(freq);
fG_old = freq;
}
}
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
VFG_PORT = (VFG_PORT^nG)&(nG);
}
void main(void)
{
static unsigned long int fG_old = 0;
unsigned long int tmp;
int i;
VFG_DDR = 0b00000111;
DDRC = 0b11111111;
setup();
Tim1Init();
#asm("sei")
for(;;) {
if(PINB.2==0) {countSPIb = -1;} //сброс в случае глюка связи
if (fG_old != fG) { //old value detction
SetUpTim1A(fG);
fG_old = fG;
}
nG = master_arr[0]; //generator number
fG = master_arr[1] << 8;
tmp = master_arr[2] << 16;
fG |= tmp;
tmp = master_arr[3] << 24;
fG |= tmp; //generator frequency
UpdateTim1A(fG);
SetUpTim1A(fG);
}
}
Вт июл 04, 2023 19:54:15
interrupt [SPI_STC] void spi_isr(void) // Прерывание SPI1 - пришел байт
{
if (countSPIb < 0) { // пришла "пустышка"
countSPIb++; // увеличивам счетчик
SPDR = slave_arr [countSPIb]; // подгружаем нулевой байт массива ведомого
PORTC |= (1<<0);
return; // выходим из процедуры
}
master_arr [countSPIb] = SPDR1; // получаем байт от мастера
countSPIb++; // увеличиваем счетчик
SPDR = slave_arr [countSPIb]; // отдаем байт ведомого (+1 индекс)
PORTC |= (1<<1);
if (countSPIb >= sizeof(master_arr)) { // если кончился массив
PORTC |= (1<<2);
//countSPIb = -1; // обнуляем счетчик и ждем следующий обмен
}
}
...
void main(void){
...
for(;;){
...
if (countSPIb >= sizeof(master_arr)){
nG = master_arr[0]; //generator number
fG = (master_arr[1] << 8)|(master_arr[2] << 16)|(master_arr[3] << 24);
UpdateTim1A(fG);
SetUpTim1A(fG);
countSPIb = -1;
}
}
}
Ср июл 05, 2023 12:28:06
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;
}
}
if (fG_old != fG) { //old value detction
SetUpTim1A(fG);
fG_old = fG;
}