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

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Вс апр 10, 2022 19:11:44

А в "Частотомер шкала для UW3DI" зачем нужна коррекция для каждого диапазона? (путем запоминания соответствующего коэффициента в eeprom). Просто как идея. Шкала не может быть откалиброван один раз и, таким образом, будет калибрована во всем рабочем диапазоне (как в случае с обычным частотомером)? А и кнопки + и - для операции, которая будет выполнена один раз ... Не могу уловить идею, скорее потребность в ней.

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Вс апр 10, 2022 19:18:33

Идея в том, что при индикации уточняется разброс частот кварцевого генератора по диапазонам, которые мы не измеряем напрямую (к примеру, как в "макеевской" шкале).

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Вс апр 10, 2022 19:22:19

Понял, спасибо. Коррекция будет как сдвиг +/-, а не как напр. пропорциональный коэффициент.
Если нужно много "трогать" софт для нового микроконтроллера, проще новый софт написать (напр. на PIC) :).

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Вт май 17, 2022 15:08:27

Подскажите плиз, пытаюсь с помощью PonyProg прошить, все ок, но почему не активен RSTDISBLE во фьюзах. Инерфес подключения parallel.

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Вт май 17, 2022 16:26:43

интерфейс не влияет, просто есть два способа программирования контроллера : пар и посл.....и скрин выложи, где ты там такой фьюз нашёл...

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Вт май 17, 2022 17:49:21

Изображение Изображение

Добавлено after 1 minute 52 seconds:
Изображение

Добавлено after 1 minute 52 seconds:
программирую ат13, но не суть , хочу задизэйблить вывод Резет. Дык а как? Слышал что вроде этой методой можно даже с "неправильными" фузами МК исправлять. Что-то тут не то.

Добавлено after 8 minutes 9 seconds:
а почему я в эту PonyProg влез???. Дело в том что прошивка у меня в .bin и eeprom тоже в .bin. иначе бы обошелся проссто UsbASP и дудой, но том прошиваются только .hex прошивки.

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Вт май 17, 2022 18:06:16

тема про 2313, а не про 13ю.......(надо же в вопросе указывать о причине идиотизма...))))...)
=====
открыл файл бин, сохранил в хекс, какие проблемы ????????????
====
если бит не активен, то не прошьешь его
Последний раз редактировалось 1en2 Вт май 17, 2022 18:10:13, всего редактировалось 1 раз.

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Вт май 17, 2022 18:12:46

вот такеннный программатор у меня через LPT
Изображение

Добавлено after 5 minutes 48 seconds:
тема про 2313, а не про 13ю.......(надо же в вопросе указывать о причине идиотизма...))))...)
=====


таки шо мне
тему заводить ВСЁ по прошивке и программированию AT90S2313/ATTiny2313 ради этого мелкого вопроса.

Ну мог бы я написать что прошиваю 2313, а не 13, ситуация аналогичная RSTDISBL не активен! Почему?
Это так дожно быть или что-то не так делаю?
В специфику отличий между .bin и .hex и в вопрос их конвертации не вникал. Попобую, напишите какой прогой это сделать. Вероятно ponyProg подойдет. А если она подойдет ТО зачем этот длинный Круг почему нельзя понипрогой все прошить и заодно и фузы выставить как надо?

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Вт май 17, 2022 18:24:57

пони и сохраняет (и конвертирует бин-хекс) и пишет, что может....а нельзя, значит нельзя....а параллельного программатора (не интерфейса, а способа прошивки) для тини у тебя нет (там 12 В используется)

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Вт май 17, 2022 23:04:34

ситуация аналогичная RSTDISBL не активен! Почему?

Данный бит переводит вывод Reset (PB5) в состояние обычного ввода/вывода, а он нужен (в вашем случае) для подачи на него 12 В… и чтобы Вы по ошибке не установили этот бит, он в программе не доступен. Так что всё правильно если он не активен.

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Пт май 20, 2022 08:59:07

программирую ат13, но не суть , хочу задизэйблить вывод Резет. Дык а как?

а почему я в эту PonyProg влез???. Дело в том что прошивка у меня в .bin и eeprom тоже в .bin. иначе бы обошелся проссто UsbASP и дудой, но том прошиваются только .hex прошивки.
Как вариант - ну, саму прошивку залей через PonyProg, а фьюзы потом отдельно измени уже через UsbASP :)
Прошитую в Пони "Прочитать" > "изменить"

Вариант 2
Открыть прошивку .bin в PonyProg, пересохранить «Сохранить как», файл в нём же, но уже как .нех

Вариант 3
Сконвертировать файл сторонней программой... типа https://www.radiokot.ru/forum/viewtopic.php?p=3476468

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Пт май 20, 2022 16:17:24

да, так и сделал, прошил в Пони, фузы прошил в USBasp

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Пн июн 05, 2023 12:32:19

Пишу код для слейва в виде Attiny2313, суть такова: мастер AT90CAN128 отправляет значение частоты и номер генератора по SPI, а слейв принимает сигнал по USI и на основе полученных значений выдает частоту на выходе(переменная fG отвечает за частоту, nG за номер ножки на выходе).
Проблема заключается в том, что частота присутствует на всех выходах тиньки, и она не соответствует отправленной по 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    PORTB6     // MISO or Data Out
#define USCK  PORTB7     // Clock

unsigned int fG;
unsigned int fG1;
unsigned int fG2;
unsigned int fG3;
unsigned char nG;
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)
    PORTB |= 1<<CS;                     // Activate Pull-Up resistor on PB0
    PCMSK|=1<<CS;                       // Active Interrupt on PB1
    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;
    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) {
// Switch-Case to respond according to request from Master:
    case 0:               // If reqID value is zero (just initialized), then first message is the reqID.
    reqID = USIDR;      // Read in from USIDR register
    USISR = 1<<USIOIF;  // Clear Overflow bit         
    case 'T':
// Write value to send back into USIDR and clear the overflow bit:
    USIDR = nG & 0x03;
    USISR = 1<<USIOIF;       
    index++;            // Increment index to transmit the folloing element next
    break;         
    case 'H':       
// Write value to send back into USIDR and clear the overflow bit:
    USIDR = fG1;
    USISR = 1<<USIOIF;
    index++;            // Increment index to transmit the folloing element next
    break;
// Write value to send back into USIDR and clear the overflow bit:
    case 'B':
    USIDR = fG2;
    USISR = 1<<USIOIF;
    index++;            // Increment index to transmit the folloing element next
    break;   
// Write value to send back into USIDR and clear the overflow bit:
    case 'I':
    USIDR = fG3;
    USISR = 1<<USIOIF;
    index++;            // Increment index to transmit the folloing element next
    break;   
    default:
// Default option of Switch-Case. Send 'reqID' back for debugging.
    USIDR = reqID;
    fG=fG1+fG2+fG3;
    USISR = 1<<USIOIF;         
    }     
}

//***********************************************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)    //set 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) //хранение старого значения
{
   static unsigned int fG_old = 0;

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

void set_out_pin (unsigned char num){
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) {   //проверка, не изменилось ли старое значение
    SetUpTim1A(fG);
    fG_old = fG;
 }
 //nG=0;     //номер генератора
 //fG=773;  //частота генератора
 set_out_pin (nG);
 SetUpTim1A(fG);
 }
}

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Пн июн 05, 2023 13:33:36

На первый взгляд не понимаю всю логику устройства, но сначала замкните swich с break; в case 0: ...
(если не намеренно: плюс условие вторым символом)

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Пн июн 05, 2023 13:53:08

На первый взгляд не понимаю всю логику устройства, но сначала замкните swich с break; в case 0: ...
(если не намеренно: плюс условие вторым символом)

Логика такая: по внешнему прерыванию отслеживается начало-конец передачи, внешнее прерывание включает прерывание по переполнению 4-х битного таймера USI, в прерывании высчитывается значение переменных nG и fG и эти значения выставляют номер генератора и частоту.
Брейк в конце не помог.

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Пн июн 05, 2023 14:16:14

Более 20 строк чужого кода сложно анализировать: от идеи до реализации.
А сам генератор работает? (без канала связи, со статической установкой частоты и канала в начале).
Потом тестово можно закодировать данных (частота и канал) на входе, опять без канала связи.
Останется неисправность/неточность в канале связи или на стороне передачи данных.
Так устраните ошибку/неправильная настройка в каждой подсистеме.

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Пн июн 05, 2023 14:40:27

Более 20 строк чужого кода сложно анализировать: от идеи до реализации.
А сам генератор работает? (без канала связи, со статической установкой частоты и канала в начале).
Потом тестово можно закодировать данных (частота и канал) на входе, опять без канала связи.
Останется неисправность/неточность в канале связи или на стороне передачи данных.
Так устраните ошибку/неправильная настройка в каждой подсистеме.

Без USI все работает, в цикле задаю переменные nG и fG и на выходе получается требуемая частота и требуемый выходной порт. Код мастера тоже рабочий, потому что раньше он работал, но к сожалению тинька сгорела вместе с прошивкой.
Генерация частоты происходит на таймере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, ну и соответственно генерируется чатота на выходе.
Но даже без мастера он дергает всеми пинами в произвольном порядке.
UPD: после того как подставил вычисление fG и nG в основной цикл, МК стал дергать PB0, на изменения в коде мастера не реагирует.

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Пн июн 05, 2023 16:12:11

Разбейте все действие на заранее проверенные события (debug). Установите, напр. LEDs как исполнительные устройства, чтобы понять, что не работает: кодирование команды, передача ее по каналу связи, декодирование, выполнение ... - case 0, case 'T' ... Я бы добавил последовательный порт для контроля, но вряд ли в этом МК для него в память найдется место.

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Пн июн 05, 2023 16:36:13

warptred12, Не нашел места, где у вас значение nG хоть как-то задается.

Re: ВСЁ по прошивке и программированию AT90S2313/ATTiny2313

Пн июн 05, 2023 16:56:32

Скорректировал код, значения nG и fG, действительно нигде не записывались, но ничего не изменилось. Все так же на выходе PB0 4 герца.
Сейчас буду пробовать отсеивать по очереди участки кода, но пока особо мыслей нет, теоретически все должно работать.

    Код:
    #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)
        PORTB |= 1<<CS;                     // Activate Pull-Up resistor on PB0
        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)    //set 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) //хранение старого значения
    {
       static unsigned int fG_old = 0;

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

    void set_out_pin (unsigned char num){
     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) {   //проверка, не изменилось ли старое значение
        SetUpTim1A(fG);
        fG_old = fG;
        }

     nG= ch_num;                         //номер генератора
     fG= dFi.b[0]+dFi.b[1]+dFi.b[2];     //частота генератора
     if (flag_RT = 1) {
     set_out_pin (nG);
     SetUpTim1A(fG);
     }
     }
    }
Ответить