Программирование ATtiny13

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

BOB51 писал(а):У адуринки есть другой способ
я все пытаюсь как-то от ардуинки выше подпрыгнуть.
Ну так пока с переменным успехом. Нужны базовые знания по МК и логике.
Вот пытаюсь разобраться.
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15585
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Программирование ATtiny13

Сообщение BOB51 »

А я наоборот - к абсолютным знаниям по конкретным кристаллам под ассемблером добавил ардуинкин Си/С++.
теперь для прикладного применения в максимально жестких условиях можно "переферийку с мозгом" под ассемблером и с полным "потрошением" МК соорудить, а для дальнейшей обработки уже "ардуиноподобные" поставить.
8)
Вариантов подхода достаточно много...
:beer:
Реклама
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

[uquote="olegue",url="/forum/viewtopic.php?p=3874426#p3874426"]И снова здравствуйте!
Вот есть у меня такая задумка

Добавлено after 25 minutes 18 seconds:
есть синтезатор на аttiny13 и lm7001
Lm 7001 управляется с тиньки по 3 пинам


Добавлено after 2 minutes 51 second:
Изображение[/uquote]

Помогите разобраться
у меня есть код для тиньки, он для СБ диапазона
А мне нужно для Двойки сделать

Вот код в котором я попробовал тупо написать частоту Двойки и мою ПЧ. Не удивительно, что ничего у меня не вышло.

Код: Выделить всё

typedef  unsigned char byte ;
typedef  unsigned int  real ;

#include <tiny13.h>
#include <bcd.h>
#include <delay.h>


#define CE   PORTB.2       
#define CL   PORTB.1       
#define DA   PORTB.0        

void lm7001SendByte(byte k) 
{
  byte i ;

  for (i = 0; i < 8; i++) {
    if (k&0x1) DA = 1;
    else
    DA = 0;
    delay_us(3);
    CL = 1;
    delay_us(3);
    CL = 0;
    k = k >> 1;
    delay_us(3);
    DA = 0;
  }
}

  
  // Формируем команды
void send_lm7001(){
  real divisor;

  //divisor = (27030 + 465) / 10;  //делим на шаг заданный программно для микросхемы 
  divisor = (140575 + 10700) / 10;  //делим на шаг заданный программно для микросхемы
  //         частота + ПЧ
  // пример: (частота + пч) * (кварц / шаг делителя) / реальный кварц
  //          (27135 + 455) * (7200 / 10) / 7200 = 2759
  //          (27135 + 455) * (7200 / 9) / 8000 = 2759

  CL = 0; 
  CE = 1; 
  delay_us(3);

  lm7001SendByte(divisor & 0x00FF);
  lm7001SendByte((divisor & 0xFF00)>>8);
  lm7001SendByte(0b11010000);  
  // Настройка делителя синтезатора (1-Fmin,101 - 9кГц шаг)
  //                                (1-Fmin, 001 - 10кГц шаг)
  delay_us(3);
  CE = 0; 
}

void main(void)
{
PORTB=0x00;
DDRB=0x07;
delay_ms (20);
send_lm7001();      //  отправляем частоту  
delay_ms (200);
    
while (1)
{
#asm("sleep");
}
}      

подскажите как сделать что бы работало для Двойки.

Добавлено after 2 minutes 43 seconds:
счас частота стоит на 161 102.5 что бы я не менял в коде.
Понимаю что не понимаю сути, но пробовал читать, но увы.
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

http://radio-hobby.org/modules/news/art ... oryid=1155

почитал здесь, только вот не совсем понимаю
Рассмотрим примеры составления управляющей последовательности. Предположим, что синтезатор применен в УКВ радиоприемнике с промежуточной частотой 10,7 МГц, который принимает сигнал с несущей частотой 100 МГц. Шаг частотной сетки — 50 кГц.



Найдем необходимый коэффициент деления частоты. Если гетеродин работает на частоте ниже принимаемой, его частота равна 100 - 10,7 = 89,3 МГц. Коэффициент деления
Кдел = 89300:50 = 1786 = 6FA (hex) = 0110 1111 1010 (bin).
на входе F in подаем частоту с гетеродина, а оцифрованнгое значение этой частоты где находится и как сравнивается?
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
radteh
Друг Кота
Сообщения: 3087
Зарегистрирован: Пт мар 09, 2007 15:01:52
Откуда: Биробиджан

Re: Программирование ATtiny13

Сообщение radteh »

Тип данных unsigned int применённый для переменной divisor в микроконтроллерах AVR ограничен размером 2 байта или числа 0...65000. Возможно в этом и проблема, стоит попробовать изменить тип данных на больший.
Реклама
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Программирование ATtiny13

Сообщение NStorm »

Кстати да. Только 65535 максимальное.
Да вообще если эта часть так и будет статической, лучше макросом задавать.

Код: Выделить всё

#define DIVISOR (140575 + 10700)/10;
...
  lm7001SendByte(DIVISOR & 0x00FF);
  lm7001SendByte((DIVISOR & 0xFF00)>>8);
...
Так оно будет вычисляться на этапе компиляции и не тратить кучу ресурсов МК на лишние расчет. Но если уже как есть, то вот так:

Код: Выделить всё

divisor = (unsigned long)(140575 + 10700) / 10;
Последний раз редактировалось NStorm Вт янв 19, 2021 19:08:22, всего редактировалось 1 раз.
Реклама
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

radteh писал(а):Тип данных unsigned int применённый для переменной divisor
а я сюда смотрю

Код: Выделить всё

 real divisor;
а оказывает есть еще

Код: Выделить всё

typedef  unsigned char byte ;
typedef  unsigned int  real ;
ок, буду пробовать. спасибо.!
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Программирование ATtiny13

Сообщение NStorm »

Да, в Си нет такого типа, как "real". Но typedef позволяет создавать свои типы.
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

NStorm,

Код: Выделить всё

divisor = (unsigned long)(140575 + 10700) / 10;
не прокатило!
сижу, дальше чешу репу.
напряжение стоитт колом на выходе синтезатора.

Добавлено after 41 minute 1 second:
поставил в другой приенмик и перешил снова на 27030 - все отлично работает. Напряжение скачет как-только катушку гетеродина трогаю
Аватара пользователя
radteh
Друг Кота
Сообщения: 3087
Зарегистрирован: Пт мар 09, 2007 15:01:52
Откуда: Биробиджан

Re: Программирование ATtiny13

Сообщение radteh »

А переменная так и осталась объявлена как real? Если переменная объявлена как real (unsignet int), а присваивается значение unsignet long, то он всё равно не влезет.
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Программирование ATtiny13

Сообщение NStorm »

radteh, там присваивается только тому, что в скобках (140575 + 10700), потом оно делится на 10 и должно влезть. Для теста просто можно написать divisor = 15127; временно.
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

NStorm писал(а):divisor = 15127
так это число в 2 байта влазит. Тогда зачем до unsignet long расширять?

Я тут прикинул , запущу приенмик на 28000, поменяю контур и посмотрю будет ли работать, может это прибавит ясности.
Это я к тому что может выход гетеродина как-то не так себя ведет.
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Программирование ATtiny13

Сообщение NStorm »

olegue, это если вы напишите сразу это значение. Когда вы пишите divisor = (140575 + 10700)/10, компилятор смотрит на тип divisor и обрезает значение скобок до его величины, т.е. до 0xFFFF, потом делит уже это значение на 10 и в divisor попадает 6553, а не 15127. Чтобы этого не происходило, я сначала и предложил написать (unsigned long), чтобы 140575 и 10700 компилятор сложил как 32-битную величину.

Добавлено after 8 minutes 18 seconds:
Хотя с оптимизацией тут возможно как статическую величину на этапе компиляции и посчитает правильно...
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

NStorm,

понял, согласен. Попробую.

Добавлено after 3 hours 40 minutes 17 seconds:
Воткнул эту строчку
divisor = 15127;

Но, увы, напряжение стоит колом, а частота гетеродина гдето вдалеке от 151 270
Придется применить план Б и запустить приемник гдето в районе 28000 кгц

Добавлено after 37 minutes 5 seconds:
может с выходом гетеродина что-то не так.

Добавлено after 4 hours 36 minutes 59 seconds:
Не реагирует Lm7001 на сигнал с 20 вывода мс3362

странно, частотомер туда вешаю, и он мне частоту показывает
вывод 20 нормально на 3.3к повесил, коворят там открыты коллектор.
Странно
Аватара пользователя
radteh
Друг Кота
Сообщения: 3087
Зарегистрирован: Пт мар 09, 2007 15:01:52
Откуда: Биробиджан

Re: Программирование ATtiny13

Сообщение radteh »

А нет ли нужды менять кварц на LM7001?
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

И снова здравствуйте!

У меня есть код синтезатора для Attiny13 и Lm7001 на четыре частоты (автор audiocd)
Код написан для CodeVisionAVR.
Спойлер

Код: Выделить всё

Chip type               : ATtiny13A
AVR Core Clock frequency: 4,800000 MHz
Memory model            : Tiny
External RAM size       : 0
Data Stack size         : 16
*******************************************************/
typedef  unsigned char byte ;
typedef  unsigned int  real ;
typedef  unsigned long  unreal ;

#include <tiny13a.h>
#include <bcd.h>
#include <delay.h>
//#include <sleep.h>

#define CE   PORTB.2   //   
#define CL   PORTB.1   //   
#define DA   PORTB.0   //     

byte
   set, sw_key ;// номер запомненной позиции настройки
unreal     
   f_tun;

 unreal eeprom  set_frq  [4]=
   {163300, 163550, 163950, 164150};
 byte eeprom    chan0=0;


// Declare your global variables here


void lm7001SendByte(byte k)
{
  byte i ;

  for (i = 0; i < 8; i++) {
    if (k&0x1) DA = 1;
    else
    DA = 0;
    delay_us(3);
    CL = 1;
    delay_us(3);
    CL = 0;
    k = k >> 1;
    delay_us(3);
    DA = 0;
  }
}

void write_lm7001(){
    real frq;
  frq=(f_tun - 10700) / 25 ;

  CL = 0; // CL
  CE = 1; // CE
  delay_us(3);

  lm7001SendByte(frq & 0x00FF);
  lm7001SendByte((frq & 0xFF00)>>8);

  lm7001SendByte(0b10100000); // - 25k
  delay_us(3);
  CE = 0; // CE
}
/*
void MCU_Off()
{
#asm("sei");
sleep_enable();
powerdown();
#asm("sleep");
}
*/

void blink ()  // мигаем диодом
{
if (set == 0){
   PORTB.3=1;
   delay_ms(20);
   PORTB.3=0;
   delay_ms(20);
  }
if (set == 1){
   PORTB.3=1;
   delay_ms(20);
   PORTB.3=0;
   delay_ms(20);
   PORTB.3=1;
   delay_ms(20);
   PORTB.3=0;
   delay_ms(20);
  }
if (set == 2){
   PORTB.3=1;
   delay_ms(20);
   PORTB.3=0;
   delay_ms(20);
   PORTB.3=1;
   delay_ms(20);
   PORTB.3=0;
   delay_ms(20);
   PORTB.3=1;
   delay_ms(20);
   PORTB.3=0;
   delay_ms(20);
  }
if (set == 3){
   PORTB.3=1;
   delay_ms(20);
   PORTB.3=0;
   delay_ms(20);
   PORTB.3=1;
   delay_ms(20);
   PORTB.3=0;
   delay_ms(20);
   PORTB.3=1;
   delay_ms(20);
   PORTB.3=0;
   delay_ms(20);
   PORTB.3=1;
   delay_ms(20);
   PORTB.3=0;
   delay_ms(20);
  }

}


void main(void)
{

// Input/Output Ports initialization
// Port B initialization
// Function: Bit5=In Bit4=In Bit3=Out Bit2=Out Bit1=Out Bit0=Out
DDRB=0b001111;
// State: Bit5=T Bit4=P Bit3=0 Bit2=0 Bit1=0 Bit0=0
PORTB=01000;
sw_key = 0;


    chan=chan0;            //   читаем из еепром номер канала
    f_tun = set_frq [set0];     //   устанавливаем частоту
    write_lm7001  ();


while (1){
      // Place your code here
   if(PINB.4 == 0){
   sw_key = 1;
   delay_ms(10);
   }
   if (sw_key && (PINB.4 ==1)) {
   sw_key = 0;
   chan++;
   if (chan>3)
   chan=0;
   f_tun = set_frq [chan];
   write_lm7001  ();
   blink ();
   }

      }
}

Но я решил тоже потренировать и дорабоать код. для Этого решил перенести его в Proteus, но там как известно синтаксис WinAvr
поэтому я перебил на WinAVR, но не смог одолеть поддержску EEProm.

В итоге вообще не стал использовать EEprom. Просто объявил массив частот. Но все равно не уверен что все работает хорошо, так как в отладличке Протеуса в переменной
Frq, т.е вычесленную частоту вижу какую-то дичь.

Вот что получилось в протеусе
Спойлер

Код: Выделить всё

typedef  unsigned char byte ;
typedef  unsigned int  real ;
typedef  unsigned long  unreal ;

#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/iotn13.h>
#include <avr/eeprom.h>
#include <util/delay.h>

//#define CE   PORTB.2   //   
//#define CL   PORTB.1   //   
//#define DA   PORTB.0   //     


#define   SetBit(reg, bit)          reg |= (1<<bit)           
#define   ClearBit(reg, bit)       reg &= (~(1<<bit))
#define   InvBit(reg, bit)          reg ^= (1<<bit)
#define   BitIsSet(reg, bit)       ((reg & (1<<bit)) != 0)
#define   BitIsClear(reg, bit)    ((reg & (1<<bit)) == 0)

byte   set, set0; 
byte sw_key ;// номер запомненной позиции настройки
unreal       f_tun;
uint8_t  eepromstring[5]={"Test"};
real frq;

    unreal set_frq[4]   ;
   // unreal set_frq[4]  EEMEM =   {163300, 163550, 163950, 164150};
  
    
 //byte  EEMEM   chan0=0;    
 byte     chan0=0; 
byte    chan=0; 
// Declare your global variables here
void lm7001SendByte(byte k) 
{
  byte i ;

  for (i = 0; i < 8; i++) {
    if (k&0x1)
       SetBit(PINB, 0);
       //DA = 1;        // DA   PORTB.0  
    else
       SetBit(PINB, 0);
    //DA = 0;            // DA   PORTB.0  
   _delay_us(3);
    SetBit(PINB, 1);
    //CL = 1;           //  CL   PORTB.1 
    _delay_us(3);
    SetBit(PINB, 1);
    //CL = 0;          //  CL   PORTB.1    
    k = k >> 1;
    _delay_us(3);
    SetBit(PINB, 0);
    //DA = 0;          // DA   PORTB.0  
  }
}

void write_lm7001(){
   // real frq;
  frq=(f_tun - 10700) / 25 ;

  //CL = 0; // CL     //  CL   PORTB.1    
   SetBit(PORTB, 1);
  //CE = 1; // CE    // CE   PORTB.2
   SetBit(PORTB, 2);
  _delay_us(3);

  lm7001SendByte(frq & 0x00FF);
  lm7001SendByte((frq & 0xFF00)>>8);

  lm7001SendByte(0b10100000); // - 25k
  _delay_us(3);
   
  //CE = 0; // CE    // CE   PORTB.2
   SetBit(PORTB, 0);
}
/*
void MCU_Off()
{
#asm("sei");
sleep_enable();
powerdown();
#asm("sleep");
}
*/
void blink ()  // мигаем диодом
{
if (set == 0){
   SetBit(PORTB, 3);
     _delay_ms(20); 

ClearBit(PORTB, 3) ;  
   _delay_ms(20); 
  } 
if (set == 1){
   
   SetBit(PORTB, 3);
   _delay_ms(20); 
ClearBit(PORTB, 3);   
   _delay_ms(20); 
   SetBit(PORTB, 3);
   _delay_ms(20); 
ClearBit(PORTB, 3)  ; 
   _delay_ms(20); 
  } 
if (set == 2){
   SetBit(PORTB, 3);
   _delay_ms(20); 
ClearBit(PORTB, 3)  ; 
   _delay_ms(20); 
   SetBit(PORTB, 3);   
   _delay_ms(20); 
ClearBit(PORTB, 3);
   _delay_ms(20); 
   SetBit(PORTB, 3);   
   _delay_ms(20); 
ClearBit(PORTB, 3) ;  
   _delay_ms(20); 
  } 
if (set == 3){
SetBit(PORTB, 3);   
   _delay_ms(20); 
ClearBit(PORTB, 3)   ;
   _delay_ms(20); 
SetBit(PORTB, 3);   
   _delay_ms(20); 
ClearBit(PORTB, 3)   ;
   _delay_ms(20); 
SetBit(PORTB, 3);   
   _delay_ms(20); 
ClearBit(PORTB, 3)   ;
   _delay_ms(20); 
SetBit(PORTB, 3);      
   _delay_ms(20); 
ClearBit(PORTB, 3);
   _delay_ms(20); 
  } 

}
int main(void)
{
// Input/Output Ports initialization
// Port B initialization
// Function: Bit5=In Bit4=In Bit3=Out Bit2=Out Bit1=Out Bit0=Out 
DDRB=0b001111;
// State: Bit5=T Bit4=P Bit3=0 Bit2=0 Bit1=0 Bit0=0 
   PORTB |(1<<3);
   PORTB &=~(1<<0)|(1<<1)|(1<<2)|(1<<4);
//PORTB=01000;
sw_key = 0;

    set_frq[0]=145450;
   set_frq[1]=145500;
   set_frq[2]=145550;
   set_frq[3]=145600;
    
 
   
    chan=chan0;            //   читаем из еепром номер канала 
    f_tun = set_frq [set0];     //   устанавливаем частоту 
    write_lm7001  ();

while (1){
      // Place your code here
   if BitIsClear(PINB, 0)  {
   //if(PINB.4 == 0){
   //if(PINB &(1<<4)){
   sw_key = 1;
   _delay_ms(10);
   }
   if (sw_key && BitIsSet(PINB, 0)) {   // Если кнопка отжата переключаем частоту
   sw_key = 0;
   chan++;
      set=chan;
   if (chan>3){   chan=0; set=0;}
   f_tun = set_frq [chan];
   write_lm7001  ();
   blink ();
   }

      }
}

В железе не провелял. Осцилографом в Протеусе посмотрел, вроде дает сигналы на соответствующие ноги Лм7001, но вот в том что все правильно большие сомнения
посмотрите пож если кому не лень

Интересует правильно ли расчитывается частота в переменной Frq

Добавлено after 6 minutes 54 seconds:
Изображение
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Программирование ATtiny13

Сообщение Ivanoff-iv »

с чего это в протеусе винавр? кому это известно?
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Программирование ATtiny13

Сообщение NStorm »

olegue, к Протеусу можно подключить CVAVR и использовать его.
Аватара пользователя
olegue
Собутыльник Кота
Сообщения: 2977
Зарегистрирован: Сб май 21, 2016 11:04:52
Откуда: Беларусь

Re: Программирование ATtiny13

Сообщение olegue »

используемый компилятор задаем при создании проекта, winAvr, masm и еще что то

Добавлено after 44 seconds:
NStorm, была такая мысль, но я не нашел как это сделать
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Программирование ATtiny13

Сообщение NStorm »

В меню System вроде есть настройки компиляторов. Там надо указать путь к CVAVR, тогда его станет давать выбирать. Но точно не скажу.
Ответить

Вернуться в «AVR»