Trisector

Коротенький "бип"

43 сообщения в этой теме

солар    186

Не-не-не. В студии такое не проканает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Trisector    139

@солар

увы.

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

а сейчас бы разобраться, как проверять отдельный бит регистра порта на соответствие единице

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    291
Только что, Trisector сказал:

как проверять отдельный бит регистра порта на соответствие единице

Да ёпрст ... Яже пример дал! Там всё имеется! Второй или третий пост буквально!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
солар    186
1 минуту назад, artos5 сказал:

... ё... ... ...! ...! ...!

Нервы, батенька, нервы. ТС пишет

4 минуты назад, Trisector сказал:

разобраться

, а не тупо скопировать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Trisector    139

вот в этом выражении:

if((PINB&0x01)==0)

проверяется бит 0? только один бит?

7 минут назад, солар сказал:

, а не тупо скопировать.

Дада.

Изменено пользователем Trisector

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    291
8 минут назад, Trisector сказал:

проверяется бит 0?

Да , а уже в следующей буквально строчке , проверяется единица )

13 минуты назад, солар сказал:

Нервы, батенька, нервы. ТС пишет

В смысле? Нервы в порядке , просто яже пример дал и в протеусе можно покрутить и разобраться что да как )

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Trisector    139

Объясню, откуда берутся вопросы.

Распечатал книги Белова и Шпака, но примеры оттуда не работают, хотя они и используют АВР студио. Поэтому каждую команду приходится проверять и корректировать.

Вот такая конструкция:

while(PINB.0==1);

у меня в студии вызывает ошибку, хотя в книге у него все красиво.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    291
Только что, Trisector сказал:

Вот такая конструкция:

while(PINB.0==1);

Так это в cvavr такие фокусы ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Trisector    139

Может, какую-то другую среду попробовать, более дружелюбную?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    291

Cvavr возьми , как в книге использует автор , потом придет уже осознание для других сред .

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Trisector    139
6 минут назад, artos5 сказал:

Cvavr

"Компилятор Си, входящий в состав CodeVisionAVR, имеет некоторые отличия от AVR-GCC (WinAVR), в том числе собственный синтаксис".

Ясно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
солар    186
if((PINB&0x01)==0)

PINB это байт, то бишь восемь бит. Этот байт по И перемножается с маской (тоже байтом) 0х01, т.е. с 0b00000001. В итоге все биты кроме нулевого сбрасываются в 0. А вот значение нулевого бита остается таким, какой в младшем бите PINB. И именно он сравнивается с нулем.

  • Одобряю 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Trisector    139

Все получилось.

Теперь осталась одна проблема - как использовать PB5 в качестве входа, не устанавливая RSTDISBL в 0.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    291
17 минут назад, Trisector сказал:

 

Никак ! Только RSTDISBL

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Aleksei80    0

Я для себя многое почерпнул от сюда: https://radioparty.ru/programming/avr/c/239-lesson7 - операторы управления битами. 

Тут для себя нужно хорошо запомнить, что DDR, PORT, PIN - это восьми битовые регистры .В них можно записывать и с них можно считывать данные.  Записывать можно в десятичном, двоичном, шестнадцатеричном виде. Это, например, так: DDRD = 12; - это в десятичном. Или так : DDRD = 0b00001100; (нули вначале можно не писать) - это в двоичном виде. Или так: DDRD = 0x0C; (нули вначале можно не писать) - это в шестнадцатеричном виде . Это всё одинаковая запись, которая означает, что нулевой, первый, 4-ый, 5-ый, 6-ой и 7-ой биты порта D будут работать на вход, а 2-ой и 3-ий биты порта D будут работать на выход. Регистр DDR определяет режим работы порта(направление передачи информации).  Как я уже писал, нули вначале можно не писать, НО лучше писать - поначалу будете меньше путаться, а также желательно не использовать без особой надобности десятичную систему (лучше шестнадцатеричную).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Aleksei80    0

С регистром PORT ситуация такая:

Первое - при записи единицы в какой-нибудь бит регистра DDR регистр PORT будет управлять уровнем сигнала на ножке МК (при записи единицы  в такой же бит регистра PORT - на соответствующей ножке порта будет логическая 1 и, соответственно, при записи нуля в тот же бит регистра PORT - на соответствующей ножке порта будет логический 0 ).  Например: DDRD = 0x08;  и PORTD = 0x08; будет означать, что на ножке PD3 будет логическая единица (условно 5 вольт).

Второе - при записи нуля в какой-нибудь бит регистра DDR регистр PORT будет управлять подтягивающим резистором внутри МК (сопротивлением около 10 - 100 кОм) на соответствующей ножке МК (при записи единицы  в такой же бит регистра PORT - на соответствующую ножку порта будет подтянут резистор к питанию и, соответственно, при записи нуля в тот же бит регистра PORT - на соответствующей ножке порта будет высоко импедансное состояние ).  Например: DDRD = 0xF7( что в двоичном виде означает  0b11110111);  и PORTD = 0x08; будет означать, что на ножке PD3 будет логическая единица (условно 5 вольт  через подтягивающий резистор), НО в этом случае ведётся запись информации в регистр PIN, т.е. в этом случае в регистр PIND в третий бит запишется единица.

А вообще пройдите по ссылке - там очень много полезной информации.

Изменено пользователем Aleksei80

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Похожие публикации

    • Автор: parovoZZ
      Поставил LUFA, следом абсолютно не нужный мне ASF. Но в упор не понимаю - как создать проект на базе этой библиотеки из студии? Приходится вручную копировать папку с заголовочниками LUFA, прописывать пути в makefile, лишние телодвижения по добавлению папки в свойства проекта. Если я это делаю всё вручную, то тогда для чего это расширение? Примеры я могу и так покрутить. ЗЫ - не слишком высокий скилл в юзании Atmel Studio/
    • Автор: Zver2011
      Всем привет! 
      Дано: Контроллер подсветки рабочей зоны кухни, реализованный на Tiny 13A.  Светодиодная лента длиной 2,3 метра, led 5050, 120 светодиодов/метр. Принципиальная схема устройства ниже:

      Код прошивки:
      #include <tiny13.h> #include <delay.h> int triggered = 0; int ontimer = 0; void main(void) { // Input/Output Ports initialization // Port B initialization // Function: Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=Out DDRB=(0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (1<<DDB0); // State: Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=0 PORTB=(0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0); // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 37,500 kHz // Mode: Fast PWM top=0xFF // OC0A output: Non-Inverted PWM // OC0B output: Disconnected // Timer Period: 6,8267 ms // Output Pulse(s): // OC0A Period: 6,8267 ms Width: 0 us TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00); TCCR0B=(0<<WGM02) | (1<<CS02) | (0<<CS01) | (0<<CS00); TCNT0=0x00; OCR0A=0x00; OCR0B=0x00; while (1) { if (PINB.1==1) { triggered = 1; ontimer = 60; }; if (ontimer > 0) { ontimer--; } else { triggered = 0; }; if (triggered) { if (OCR0A<255) { OCR0A++; }; } else { if (OCR0A>0) { OCR0A--; }; }; delay_ms(10); } } Возникшая проблема:
      Греется полевой транзистор при работе. 
      Изначально поискав информацию на данную проблему, начал прикидывать. 
      Смотрим график зависимости пропускаемого тока стока (ID )от приложенного напряжения  затвор-сток (VGS),  при температуре окруж. среды 25 градусов: ID = 14 А (2,3 метра светодиодной ленты не могут столько кушать, по крайней мере я такую не видел).

      Было предположение что частота переключения ШИМ высокая - отсюда транзистор в не определенном состоянии = нагрев. Рассчитал макс. частоту так:
      Rg = 100 Ом, Vgs = 5V
      Заряд затвора:
      Qiss = Ciss * Vgs = 1800pF * 5v = 9nC
      Скрость нарастания:
      S = Rgate * Qiss = 100Ohm * 9nC = 0.009mV*sec
      Время на открытие или закрытие транзистора:
      t=S / Vgs = 0.002mV*sec * 3.2v = 4.5uSec
      Период  - это открытие + закрытие:
      T = t + t = 4.5uSec + 4.5uSec = 9uSec
      Максимальная частота переключения:
      F < 1 / T = 1 / 9uSec = 111KHz
      Ток через затвор (G) и цифровой выход Tiny 13A:
      I = Qiss / t = 2mA
      Максимальный выходной ток GPIO у Tiny 13A 40.0mA
      2mA < 40.0mA
      Выставил частоту ШИМ на 37,5 кHz. Вуаля - при подключении 1м светодиодной ленты (тестировал на обрезке), нагрева нет. Но как только подключил все 2,3 метра - транзистор стал снова спустя время греться, аж дотронуться не возможно.  Захотел померить ток, который потребляет 1 метр ленты, проверить продавца. Потребление 1 метра ленты оказалось вместо заявленных 600 мА, все 1,85 А, причем заметил странную вещь - ток начал возрастать спустя время на сотые доли  и дошел до 1,9 А. Дальше ждать не стал. Режим амперметра в мультиметре сломался?
      Далее подумал что слишком большая мощность рассеивается на транзисторе. Если учесть то, что при открытом транзисторе, его переход можно представить в виде линейного резистора с маленькой величиной сопротивления,  можно рассчитать рассеиваемую мощность на транзисторе:
      Смотрим сопротивление транзистора в открытом состоянии при VGS = 5В : RDS(on) = 0.18 Ом
      P1 = 1,9*1,9*0,18 = 0,65 Вт. (1 метр св.ленты).
      Раз мы взяли потребление 1 метра ленты  1, 9 А, тогда 2,3 метра потребляют  = 4,4 А. (Теперь не уверен в своем мультиметре).
      P2=4.4*4.4*0.18 = 3.5 Ватт - довольно таки многовато я думаю.
      В общем: Правильно ли я делаю расчеты? Что упустил?  Как снизить нагрев транзистора, без применения вентиляторов и здоровенных радиаторов? Есть вариант замены светодиодной ленты на что нибудь поменьше жрущее (60 светодиодов/ метр например), но в будущем еще много раз придется сталкиваться с полевиками, хотелось бы разобраться .
    • Автор: Денис Оробей
       Помогите написать простую задачку (для вас - простую, а я не шарю), на плате контроллера-конструнтора KIT-8515 нужно  сделать вот это: "Пусть движковыми переключателями задаются два четырехзначных операнда.  Напишите и протестируйте программу, при работе которой после нажатия кнопки 1 операнды складывались, а при нажатии кнопки 2 операнды вычитались, а результат операции выводился на светодиоды"
      Прикреплённый файл - начало задачки.
      Заранее благодарствую:)
      123.rar
    • Автор: Николай Зубий
      Как сделать  устройство, выводящие на индикатор время, прошедшее с момента последней перезагрузки контроллера?
    • Автор: forestdozor
      Здравствуйте!

      Мне нужно измерить длительность импульса. Для этого сначала применял внешнее прерывание, а теперь перешел на режим захвата таймера в Atmega 328.
      Однако сейчас происходит странное: Через определенное таймер просто останавливается. Гугл результатов не дает, ни у кого захват таймера 1 не останавливается.
      Подскажите пожалуйста, что делать?
      Среда разработки CodeVisionAVR v3.12. Сейчас попробовал версию 3.3, толку нет. Не работает. Код максимально упростил, но по прежнему толку ноль.
      Переполнение таймера 0 так же работает отлично, до тех пор, пока что-то не произойдет с прерыванием по захвату. Как только что-то произошло - мк останавливается...
      Может немножко подождать, и увеличить значение счетчика current_timp еще на пару значений... Совсем не знаю что делать.
       
       
      interrupt [TIM1_OVF] void timer1_ovf_isr(void)
      {
      TCNT1H = 0x00;
      TCNT1L = 0x00;
      }
      // Timer1 input capture interrupt service routine
      interrupt [TIM1_CAPT] void timer1_capt_isr(void)
      {
       
             TCNT1H = 0x00;
             TCNT1L = 0x00;           // Это уже уровень танцев с бубном "авось поможет" - не помогает.
         
              current_timp++;          // Все упрощено до максимума. Мне бы он хоть количество периодов для начала...
              
        //  }
      }
      // Прерывание по переполнению первого таймера
      interrupt [TIM0_OVF] void timer0_ovf_isr(void)
      {
      // Обнуление счетного регистра.
      TCNT0=0x00;

          
          counter ++;
          if (counter > 10)
          {
                  lcd_clear();
                  sprintf(buffer,"%d us", current_timp);
                  lcd_gotoxy(0,0);
                  lcd_puts(buffer);
                  counter = 0;
          }
          
          
      }

      // Главный цикл программы
      void main(void)
      {

      #pragma optsize-
      CLKPR=(1<<CLKPCE);
      CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
      #ifdef _OPTIMIZE_SIZE_
      #pragma optsize+
      #endif

      // Port B initialization
      // Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
      DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
      // State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
      PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
      // Port C initialization
      // Function: Bit6=In Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out
      DDRC=(0<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
      // State: Bit6=T Bit5=1 Bit4=1 Bit3=1 Bit2=1 Bit1=1 Bit0=1
      PORTC=(0<<PORTC6) | (1<<PORTC5) | (1<<PORTC4) | (1<<PORTC3) | (1<<PORTC2) | (1<<PORTC1) | (1<<PORTC0);
      // Port D initialization
      // Function: Bit7=Out Bit6=Out Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
      DDRD=(1<<DDD7) | (1<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
      // State: Bit7=1 Bit6=1 Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
      PORTD=(1<<PORTD7) | (1<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
      // Делители таймера 0 рассчитаны таким образом , что его тактовая частота = 15,625 КГц. Расчет был на применение в схеме семисегментников, но с LCD индикатором будет информативнее.
      TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);
      TCCR0B=(0<<WGM02) | (1<<CS02) | (0<<CS01) | (1<<CS00);
      TCNT0=0x00;
      OCR0A=0x00;
      OCR0B=0x00;
       
      // Настройка таймера 1
      TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
      TCCR1B=(1<<ICNC1) | (1<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
      TCNT1H=0x00;
      TCNT1L=0x00;
      ICR1H=0x00;
      ICR1L=0x00;
      OCR1AH=0x00;
      OCR1AL=0x00;
      OCR1BH=0x00;
      OCR1BL=0x00;
      // Разрешение прерывания по переполнению таймера 0
      TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (1<<TOIE0);
      // Timer/Counter 1 Interrupt(s) initialization
      TIMSK1=(1<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (1<<TOIE1);