Jump to content

Recommended Posts

помогите, делаю этот таймер http://sxem.org/2-vse-stati/22-tajmery/38-tajmer-na-atmega8 и он идет очень медленно, одна секунда равняется 3,5 минутам, как это исправить

Скрытый текст



// *****************************************************************************
// Project: Таймер на АТmega8
// Author: VasylYE
// Module description:
// *****************************************************************************

#include <avr\io.h>              // Most basic include files
#include <avr\interrupt.h>       // Add the necessary ones
//#include <avr\signal.h>        // here
//#define __AVR_ATmega8__
#include <avr\pgmspace.h>
#include <string.h>


//******************************************************************************
//  Определение констант
//******************************************************************************
#define IND_PORT  PORTD
#define IND_DDR  DDRD

#define IND_COM PORTB
#define IND_CDDR DDRB
#define IND_PIN PINB

#define IND_CA1   PB1   // Левый индикатор
#define IND_CA2   PB2
#define IND_CA3   PB3
#define IND_CA4   PB4   // Правый

#define KEY_PORT  PORTC
#define KEY_DDR DDRC
#define KEY_PIN PINC

#define KEY_HOURS PC0
#define KEY_MINUTES PC1
#define KEY_RUN PC2
#define KEY_RESET PC3

#define JUMPER PB0      // Джампер, определяющий работу после пропадания питания
#define CHECK_POWER PB5 // Вход для контроля наличия питания

#define SIGNAL_OUT PC4  // Выход для контрольного светодиода или пищалки

#define LOAD   PC5   // Выход управления нагрузкой

// Значения для таймеров
#define T0_VALUE (255-78)

#define KEY_DEBOUNCE 100

// Флаги
#define f_WholeSec 0   // Флаг указывает, что отсчитана целая секунда.
                        // Используется для мигающей точки, переключается
                        // каждые 0.5 секунд
#define f_CountDown 1  // Флаг, указывающий на то, что происходит обратный
                        // отсчет. Используется для гашения ведущих нулей в
                        // индикации часов.
#define f_TimerRunning 2 // Флаг, указывающий на то, что таймер был запущен

#define f_Power 3 // Флаг наличия общего питания

#define f_Signal 4 // Флаг работы сигнализации (звуковой или световой)


#define IND_OA 1  // Общий анод


const unsigned char DIGITS_OA[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};

//******************************************************************************
//  Глобальные переменные
//******************************************************************************
//typedef struct {
//   unsigned char Seconds;
//   unsigned char Minutes;
//   unsigned char Hours;
//} time;

//volatile time Time;
volatile unsigned char m_ucSecOnes = 0;
volatile unsigned char m_ucSecTens = 0;

volatile unsigned char m_ucMinOnes = 0;
volatile unsigned char m_ucMinTens = 0;

volatile unsigned char m_ucHrsOnes = 0;
volatile unsigned char m_ucHrsTens = 0;


volatile unsigned char sm_ucIndNum = 0;

volatile unsigned char m_ucFlags = 0;



volatile unsigned char ucKey_Run_Timeout = 0;
volatile unsigned char ucKey_Hours_Timeout = 0;
volatile unsigned char ucKey_Mins_Timeout = 0;

//******************************************************************************
//  Прерывания
//******************************************************************************
// Прерывание по переполнению таймера Т0, здесь мы выводим часы и минуты на
// индикатор, а также опрашиваем кнопки.
ISR(SIG_OVERFLOW0, ISR_NOBLOCK){ // Разрешены вложенные прервания
volatile unsigned char ucTemp = 0;  //
//volatile unsigned char ucKey_Run_Timeout;
   TCNT0 = T0_VALUE; // Перезагрузка таймера
   sm_ucIndNum++;
   	if (sm_ucIndNum > 3){
      	sm_ucIndNum = 0;
		}
	IND_COM &= ~((1<<IND_CA1)|(1<<IND_CA2)|(1<<IND_CA3)|(1<<IND_CA4));
	IND_PORT = 0xFF;
   // Во время работы таймера, когда идет отсчет, убираем ведущие ноли.
   // Если пропало питание (очищен флаг питания) индикация отключена
   switch (sm_ucIndNum){
      case 0:  {IND_COM |= (1<<IND_CA1);  // Индикация десятков часов
                ucTemp = DIGITS_OA[m_ucHrsTens];
                break;}
      case 1:  {IND_COM |= (1<<IND_CA2);  // Индикация единиц часов
                ucTemp = DIGITS_OA[m_ucHrsOnes];
                // Здесь мы мигаем точкой!
                if (m_ucFlags & (1 << f_WholeSec)){
                	ucTemp &= 0x7F;
                }
                break;}
      case 2:  {IND_COM |= (1<<IND_CA3);  // Индикация десятков минут
                ucTemp = DIGITS_OA[m_ucMinTens];
                break;}
      case 3:  {IND_COM |= (1<<IND_CA4);  // Индикация единиц минут
                ucTemp = DIGITS_OA[m_ucMinOnes];
                break;}
   }
   if (IND_PIN & (1 << CHECK_POWER)){	// Если пропало питание
	   IND_PORT = ucTemp;
	}
	else{
		IND_PORT = 0xFF;                 // отключаем индикацию
	}

   // Опрос кнопки Пуск/Пауза (KEY_RUN)
   if (!(KEY_PIN & (1 << KEY_RUN))){
      if (ucKey_Run_Timeout == 0){
         // Установка флага работы таймера
         // Этот флаг служит для блокировки кнопок и очищается
         // в обработчике прерывания таймера Т2
         m_ucFlags ^= (1 << f_CountDown);
         m_ucFlags |= (1 << f_TimerRunning);
         ucKey_Run_Timeout = 2*KEY_DEBOUNCE;
         // Устанавливаем флаг питания
         m_ucFlags |= (1 << f_Power);

         // Переключаем нагрузку
         if (m_ucFlags & (1 << f_CountDown)) KEY_PORT |= (1 << LOAD);
         else KEY_PORT &= ~(1 << LOAD);
      }
   }
   // Опрос кнопки настройки Часов
   // Только если не установлен флаг работы таймера
   if (!(m_ucFlags & (1 << f_TimerRunning))){
      if (!(KEY_PIN & (1 << KEY_HOURS))){
         if (ucKey_Hours_Timeout == 0){
            m_ucHrsOnes ++;
            if (m_ucHrsOnes > 9){
               m_ucHrsOnes = 0;
               m_ucHrsTens ++;
               if (m_ucHrsTens > 9) m_ucHrsTens = 0;
            }
            ucKey_Hours_Timeout = KEY_DEBOUNCE;
         }
      }
   }

   // Опрос кнопки настройки минут
   // Те же условия
   if (!(m_ucFlags & (1 << f_TimerRunning))){
      if (!(KEY_PIN & (1 << KEY_MINUTES))){
         if (ucKey_Mins_Timeout == 0){
            m_ucMinOnes ++;
            if (m_ucMinOnes > 9){
               m_ucMinOnes = 0;
               m_ucMinTens++;
               if (m_ucMinTens > 5) m_ucMinTens = 0;
            }
            ucKey_Mins_Timeout = KEY_DEBOUNCE;
         }
      }
   }

   // Опрос кнопки останова таймера
   if (!(KEY_PIN & (1 << KEY_RESET))){
      m_ucFlags &= ~(1 << f_CountDown);   // Очистка флагов
      m_ucFlags &= ~(1 << f_TimerRunning);
      // Отключаем нагрузку
      KEY_PORT &= ~(1 << LOAD);
      //

   }

   // Проверка наличия питания проводится только, если таймер в работе
   if (m_ucFlags & (1 << f_TimerRunning)){
   if (IND_PIN & (1 << CHECK_POWER)){ // power ok
      // Проверяем состояние джампера
      // и в зависимости от состояния флага питания делаем следующее
      if (!(m_ucFlags & (1 << f_Power))){ // Если питание пропадало
         if (IND_PIN & (1 << JUMPER)){
            // Если джампер не замкнут Останавливаем отсчет
            // нагрузка отключена
            m_ucFlags &= ~(1 << f_CountDown);
            KEY_PORT &= ~(1 << LOAD);
         }
         else{
            // Если джампер замкнут на 0
            // Продолжаем отсчет, включаем нагрузку
            m_ucFlags |= (1 << f_CountDown);
            KEY_PORT |= (1 << LOAD);
         }
         // Снова выставляем флаг, что с питанием все ок.
         if (IND_PIN & (1 << CHECK_POWER))
            m_ucFlags |= (1 << f_Power);
      }
   }
   else{ //power fail
      m_ucFlags &= ~(1 << f_Power);
      // Отключаем нагрузку
      KEY_PORT &= ~(1 << LOAD);
      // Выставляем флаг паузы отсчета
      m_ucFlags &= ~(1 << f_CountDown);
   }
   }

   if (ucKey_Run_Timeout > 0) ucKey_Run_Timeout--;
   if (ucKey_Hours_Timeout > 0) ucKey_Hours_Timeout--;
   if (ucKey_Mins_Timeout > 0) ucKey_Mins_Timeout--;


}


// Таймер Т2 работает все время, останавливается или запускается
// только отсчет времени.
// Прерывание по переполнению таймера Т2
ISR(SIG_OVERFLOW2){

   m_ucFlags ^= (1 << f_WholeSec); // Переключаем флаг
if (m_ucFlags & (1 << f_CountDown)){
   if (m_ucFlags & (1<<f_WholeSec)){
      m_ucSecOnes --;
      if (m_ucSecOnes > 9){
         m_ucSecOnes = 9;
         m_ucSecTens --;
         if (m_ucSecTens > 5){
            m_ucSecTens = 5;
            m_ucMinOnes --;
            if (m_ucMinOnes > 9){
               m_ucMinOnes = 9;
               m_ucMinTens --;
               if (m_ucMinTens > 5){
                  m_ucMinTens = 5;
                  m_ucHrsOnes --;
                  if(m_ucHrsOnes > 9){
                    m_ucHrsOnes = 9;
                     m_ucHrsTens --;
                     if(m_ucHrsTens > 9){  // Здесь мы дошли до конца отсчета
                        m_ucHrsTens = 0;
                        m_ucHrsOnes = 0;
                        m_ucMinTens = 0;
                        m_ucMinOnes = 0;
                        m_ucSecTens = 0;
                        m_ucSecOnes = 0;
                        // Очищаем флаг отсчета
                        m_ucFlags &= ~(1 << f_CountDown);
                        m_ucFlags &= ~(1 << f_TimerRunning);
                        // Коммутируем нагрузку
                        KEY_PORT &= ~(1 << LOAD);
                     }
                  }
               }
            }
         }
      }
   }
}
};

//******************************************************************************
//  Функции
//******************************************************************************




//******************************************************************************
//  Main program
//******************************************************************************

int main(void) {
   //***************************************************************************
   // Инициализация периферии
   //***************************************************************************

//int temp0, temp1;

   // Настройка порта для сегментов индикатора
   #ifdef IND_OA
      IND_PORT = 0xFF;
   #else
      IND_PORT = 0x00;
   #endif
   IND_DDR = 0xFF;
   // Настройка порта для общих выводов индикатора
   IND_CDDR = 0x00;
   IND_COM = 0x00;

   IND_CDDR = (1<<IND_CA1)|(1<<IND_CA2)|(1<<IND_CA3)|(1<<IND_CA4);
   IND_COM |= (1<<JUMPER)|(1<<CHECK_POWER)|(0<<IND_CA1)|(0<<IND_CA2)|(0<<IND_CA3)|(0<<IND_CA4);

   // Настройка порта для кнопок
   KEY_DDR &= ~((1<<KEY_HOURS)|(1<<KEY_MINUTES)|(1<<KEY_RUN)|(1<<KEY_RESET)); // input
   KEY_DDR |= (1<<SIGNAL_OUT)|(1<<LOAD);  // output
   KEY_PORT |=(1<<KEY_HOURS)|(1<<KEY_MINUTES)|(1<<KEY_RUN)|(1<<KEY_RESET);

   // Настройка таймера Т2, который работает в Асинхронном режиме
   // и тактируется от часового кварца на 32768 Гц
///// Ждем пока не стабилизируется работа внешнего кварца
//   for(temp0=0;temp0<0x0040;temp0++)   // Wait for external clock crystal to stabilize
//   {
//       for(temp1=0;temp1<0xFFFF;temp1++);
//   }
   TIMSK &=~((1<<TOIE2)|(1<<OCIE2));   // Запрещаем TC2 прерывания
   ASSR |= (1<<AS2);                   // Режим таймера - асинхронный
                                       // тактирование от внешн. кварца (32,768kHz)
   while (ASSR & (1 << TCN2UB)){};
   TCNT2 = 0x00;
   while (ASSR & (1 << TCR2UB)){};
   TCCR2 = 0x04;           //Делитель таймера / 64 для получения
                           // переполнения каждые 0.5 секунд

   TIMSK |= (1<<TOIE2);        //set 8-bit Timer/Counter2 Overflow Interrupt Enable
////////

   // Настройка таймера Т0, который используется для динамической индикации
   // и опроса кнопок. МК работает на частоте 1 МГц без внешнего кварца
   // Загрузка регистра таймера Т0
   TCNT0 = T0_VALUE;
   // Разрешение прерываний по переполнению таймера Т0
   TIMSK |= (1<<TOIE0);
   // Пуск таймера Т0
   TCCR0 = (0<<CS02)|(1<<CS01)|(1<<CS00);

   // Разрешение глобальных прерываний
   sei();
   while(1) {             // Infinite loop; define here the
      asm ("nop");                       // system behaviour
   }

}

//******************************************************************************
//  END of File
//******************************************************************************


 

 

Share this post


Link to post
Share on other sites

А индикация нормальная, не замедленная?

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


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites

Металл-композит как альтернатива ферриту: дроссели Panasonic семейства ETQP

Современные электронные устройства требуют все более компактных и эффективных компонентов. Новые металл-композитные дроссели обладают рядом преимуществ перед дросселями с ферритовым сердечником. Они не имеют ярко выраженного насыщения, обладают отличными частотными свойствами и способны работать при температурах до 150°C и выше. Все это делает их альтернативой стандартным дросселям с ферритовым сердечником в широком спектре автомобильных и промышленных приложений.

Подробнее

                     

Новые литиевые ХИТы Fanso работают даже при +150ºС!

Когда приходится учитывать работу в экстремальных условиях, к выбору электронных компонентов подходишь с особой тщательностью. Высокие температуры, большие перепады давления, труднодоступность – все это требует специальной продукции. Склад КОМПЭЛ пополнился новыми литиевыми ХИТами Fanso, стабильно работающими даже при температуре до 150 ºС. Батарейки имеют номинальное напряжение 3,6 В, обладают ёмкостью от 700 до 14000 мАч, работоспособны в широком температурном диапазоне -20…150ºС и имеют низкий саморазряд (не более 3% в год в нормальных условиях хранения).

Подробнее о высокотемпературной линейке

У вас удивительная способность говорить противоречивые вещи в одном приложении. Так работает исправно или медленно? Счет секунд идет в прерывании второго таймера.

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


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites

А как она мигает? С интервалом в 3.5 минут?


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites

да, c интервалом в 3.5 минут, пробовал изменить кристалл но все четно, только кнопка выдает большее число вместо 1

Share this post


Link to post
Share on other sites

Изначально,с завода,мега8 идёт с включенным делителем на 8.Если фьюзы не перепрошивались то тактирование мк будет на частоте 1 Мгц.,может это влияет?

Share this post


Link to post
Share on other sites

Тогда она работала бы гораздо быстрее. Сейчас она тактируется частотой в 32768 герц! Второй таймер делит частоту на 64 предделителем и 256 ещё сам считает в итоге получается 0.5Гц - с этой частотой и должна мигать точка.

Единственное объяснение тому что секунды у вас идут с интервалом в 3.5 минут - таймер считает в 256 раз медленней! Других объяснений просто не остаётся - у тебя не работает кварцевый резонатор, а вывод ловит наводку в 50/100гц! Попробуй активировать фьюз CKOPT(поставить галочку) ИЛИ подключить внешние конденсаторы между выводами кварца и общим проводом. Убедись осциллографом что кварц работает и там есть частота в 32кГц. Иногда, вообще приходилось параллельно кварцу вешать резистор в 10МОм т.к. он набирал статику больше 4 вольт и генератор переставал работать.

Edited by Alexeyslav

Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites

закоротил ножки генератора через резистор и он заработал, правда уже слишком быстро, поэтому завтра пойду и куплю резистор на 10M, большое тебе спасибо, как только заработает нормально сниму процес роботи, а тебе + к карме

Share this post


Link to post
Share on other sites

Ты путаешь причину со следствием. Когда ты закоротил выводы генератор просто стал работать на максимальной частоте. Тебе надо добиться работы генератора на кварце - для этого там ДОЛЖНЫ БЫТЬ конденсаторы на общий провод. Они же активируются битом CKOPT в программаторе либо припаиваются внешние. Так же сам кварц может оказаться битым с низкой добротностью и не раскачивается. А резистор... поможет только если эта проблема поляризации кварца имеется, обычно это проявляется как работает-работает часов 6 а потом встаёт всё колом. Докоснёшься до кварца и опять часов 6 работает и встаёт.


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites

сли не считать кристал то так уже пробовал, не работает, вообще работает только если пальцем прикоснусь

Share this post


Link to post
Share on other sites

выводы кварца должны быть как можно ближе к выводам МК

можно попробовать корпус кварца прицепить к земле

по поводу конденсаторов, они там не нужны, т.к. при активации асинхронного таймера подключаются внутренние конденсаторы на 36пФ, НО на практике как то было, что часики начинали тикать только если коснуться отверткой одного из выводов кварца и установка внешних конденсаторов помогла., кто виновен МК или сам кварц не знаю.., второго часового кварца под рукой не было чтобы выяснить.

фьюз СКОРТ нет смысла трогать при тактировании МК внутренним калиброванным генератором

купить новый кварц

Share this post


Link to post
Share on other sites

смысл в том что оно должно работать на внутреннем генераторе, поэтому заменить его нельзя

Share this post


Link to post
Share on other sites

CKOPT как раз и подключает те самые внутренние конденсаторы, без него естественно ничего работать не будет и потребуются внешние.


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites

 

5 часов назад, Alexeyslav сказал:

CKOPT как раз и подключает те самые внутренние конденсаторы

Откуда вы это взяли? СКОРТ изменяет только режим усилителя в кварцевом генераторе.

The CKOPT Fuse selects between two different
Oscillator amplifier modes. When CKOPT is programmed, the Oscillator output
will oscillate a full rail-to-rail swing on the output.
This mode is suitable when operating
in a very noisy environment or when the output from XTAL2 drives a second clock
buffer. This mode has a wide frequency range. When CKOPT is unprogrammed, the
Oscillator has a smaller output swing.
This reduces power consumption considerably.
This mode has a limited frequency range and it cannot be used to drive other clock
buffers.

О каких либо внутренних конденсаторах здесь нет ни слова. Да и рекомендованные емкости конденсаторов для кварца одинаковы как для запрограммированного СКОРТ, так и для незапрограммированного.

 

изображение.png

Edited by Sergey-Ufa

Share this post


Link to post
Share on other sites

 все зависит от выбранного источника синхронизации.

9 часов назад, Alexeyslav сказал:

CKOPT как раз и подключает те самые внутренние конденсаторы

вы похоже путаете с источником синхронизации низкочастотным кварцевым резонатором 32.768 кГц

To use a 32.768kHz watch crystal as the clock source for the device, the Low-frequency Crystal Oscillator must be selected by setting the CKSEL Fuses to “1001”.

By programming the CKOPT Fuse, the user can enable internal capacitors on XTAL1 and XTAL2, thereby removing the need for external capacitors. The internal capacitors have a nominal value of 36pF.

Однако наше устройство тактируется внутренним RC генератором 1 MHz CKSEL Fuses to “0001”, а часовой кварц 32768 подключен к выводам TOSC1 и TOSC2 и работает совместно с асинхронным генератором таймера 2.

Share this post


Link to post
Share on other sites

Там нет условия на его применение. Независимо от выбранного источника тактирования он подключает внутренние конденсаторы к внешнему генератору.

В том же даташите на 32-й странице:

Цитата

For AVR microcontrollers with Timer/Counter Oscillator pins (TOSC1 and TOSC2), the crystal is
connected directly between the pins. By programming the CKOPT Fuse, the user can enable
internal capacitors on XTAL1 and XTAL2, thereby removing the need for external capacitors.
The Oscillator is optimized for use with a 32.768kHz watch crystal. Applying an external clock
source to TOSC1 is not recommended.

Note: The Timer/Counter Oscillator uses the same type of crystal oscillator as Low-Frequency Oscillator
and the internal capacitors have the same nominal value of 36pF

 


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Similar Content

    • By LemonTV
      Есть картинка из сайта с фьюзами, есть программа avrdude_prog3.3 Как выставить правильно фьюзы чтобы не испортить мк? Незнаю как это сделать есть прямые и инверсные фьюзы, ГДЕ СТАВИТЬ ГАЛОЧКИ И КРУЖОЧЕК НА ПРЯМЫХ ИЛИ ИНВЕРСНЫХ?


    • By Сергей Фомин
      Изучаю прерывания на attiny13. Пока остановился на прерываниях по переполнению. Сделал тестовый код в Atmel Studio и сразу через программатор заливаю на тиньку со светодиодом. Проблема в том что гореть он должен 10 секунд и выключаться, а горит примерно 20-23 секунды. Прошу помощи в правильном расчёте. Код ниже (пока учусь сильно не ругайтесь) :
      #define F_CPU 1000000 #define LED PB2 #include <avr/io.h> //#include <util/delay.h> #include <avr/interrupt.h> unsigned char work_time =384;    //  1000000/1024/256=3.8  (0.026 сек)    10/0.026=384 volatile unsigned char temp =0; ISR (TIM0_OVF_vect) {      TCNT0=0x00;     temp ++;     if (temp>=work_time)     {         PORTB &=~(1<<LED);  //Инвертируем состояние         TCCR0B=0x00    // остановка таймера         cli (); //общее запрещение прерываний     } } int main (void) {     init();               while (1)     {              } } void init () {          DDRB |= (1<<LED); // выход     PORTB =(1<<LED); //включен     TCCR0B =0x05; // установка делителя на 1024     TIMSK0 |= _BV(TOIE0);     sei();   // Либо SREG |= (1<<SREG_I); //Разрешаем прерывания глобально     TCNT0 = 0X00;        //Обнулить счётный регистр }  
    • By Вячеслав_НС
      помогите разобраться с кодом .(послать значение по шине TWI на ЦАП PCF8591) не работает в протеусе ...
      #define F_CPU 8000000UL 
      #include <stdlib.h>
      #include <avr/io.h>
      #include <util/delay.h>
      //*** ИНИЦИАЛИЗАЦИЯ ШИНЫ TWI ***/
      void TWI_Init(void)
      {
          // Установка тактовой частоты F_scl  = 100 кГц
          TWBR =32;
          TWSR &= (~((1<<TWPS1)|(1<<TWPS0)));
          TWCR |= (1 << TWEN);            // Разрешение работы TWI-модуля
      }

      /*** ЗАПУСК TWI ***/
      void TWI_Start(void)
      {
          TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
          while(!(TWCR & (1<<TWINT)));
          TWDR = 1001000; // передача адреса модуля PCF8591 в шину TWI
          TWCR=(1<<TWINT)|(1<<TWEN);
          while(!(TWCR & (1<<TWINT)));
      }
      /*** ОСТАНОВКА TWI ***/
      void TWI_Stop(void)
      {
          TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
          while(TWCR & (1<<TWSTO));        // Ожидание завершения передачи условия СТОП
      }
      /***ПЕРЕДАЧА ДАННЫХ В TWI***/
      void TWI_WriteByte(uint8_t data)
      {
          TWDR = data;                    // Загрузка данных в TWDR
          TWCR=(1<<TWINT)|(1<<TWEN);
          while(!(TWCR & (1 << TWINT)));    // Ожидание завершения передачи данных
      }
      /*** ПЕРЕДАТЬ ЗНАЧЕНИЕ В PCF8591 ***/
      void PCF8591_get(void)
      {
          TWI_Start();                // Запуск TWI
          TWI_WriteByte(0x40);        //включаем цап
          TWI_WriteByte(100);            // запись в ЦАП значения 100
          TWI_Stop();                    // Остановить TWI
      }            
          int main(void)
      {
          TWI_Init();    
          while (1)
      {
              PCF8591_get;
             _delay_ms(50);
        }
      }
    • By LegionKC
      Добрый день.
      Экспериментирую с платой TP4056 и MK ATmega8, конкретнее - пытаюсь собрать простенькое зарядное устройство с выводом параметров при зарядке/разрядке на АЦП МК. Для измерения тока нашел ACS712. Думаю, что получится выводить ток при зарядке (т.е. когда идет питание на TP4056 и нагрузка отключена) и при разрядке (питание выключено, нагрузка подключена). Нагрузка - резистор. Возникла проблема с измерением напряжения на АКБ. Вернее, проблема с отсутствием идей как это сделать. Может какую-нибудь схему делителя напряжения нужно сделать? Прошу помочь советом. Схему из пэинта прилагаю.
      Спасибо.
       

    • By IgnatiusF
      Не могу настроить таймер 0 на работу, и даже не получается понять в чем проблема. Делаю в Proteus, так как это быстрее и нагляднее.
      Пробовал и просто по переполнению делать прерывание (WGM[1..0]  00) и по совпадению (WGM[1..0]  10; OCR0A = 0 - 255), однако прерываний нет. Перед циклом ставлю TCNT0 = 0;
      Тактирование выставляю TCCR0B (CS[2..0] 001, 100, 101).
      Прерывания TIMSK0 (OCIE0A, TOIE0) выставляю, не вызываются. Даже принудительным заносом значения в регистр TIFR0 (OCF0A, TOV0).
      Прерывание пытаюсь выполнить таким образом:
      #include <avr/interrupt.h> volatile unsigned int A = 0; ISR(TIMER0_OVF_vect) { A = 1; } ... while(1) { if (A == 1) PORTB |= (1<<0); } Proteus показывает, что вывод настроен как выход, но всегда 0;
      Конкретный код привести не могу, так как у меня не заработало совсем ничего.
      Внизу я сделал вырезку из даташита на ATMEGA328 по 0 таймеру 8-бит, и занес в один PDF файл.
      ATmega328-106-112.pdf
      Прошу помочь разобраться с таймером и прерываниями для него.
  • Сообщения

    • Прошу подсказать, насколько жизнеспособна данная печатная плата - не будет ли возбудов и т.п. Требовалось собрать именно однополярную схему усилителя с 2 каналами, общим питанием и входом. Собиралось по схеме из даташита 2030/2040/2050.  
    • трансформатор в центр на место БП. БП - 2 шт. отдельные слева и справа. Выключатель 220 сзади не ставить, розетку посередине ближе к днищу - селектор-РГ выше, ближе к крышке. 220 к трансу вести прямо по днищу плотно.
    • Подскажите экран не как не помешает?
    • Спасибо. Если Вы видите это так же, как и я, значит, мозги ещё не до конца высохли (у меня ).  Радует.   Бум делать. Но справедливости ради, честно говоря, - я выделенный ряд обозначений догнать не могу.  Зачем?...   так обозначено!...  Ведь, если учитывать столбик номиналов резисторов слева других вариантов на ум не приходит.   Ну, не соединение же это нескольких направлений параллельно, в разных вариантах?  Тогда, скажем, от контакта 6 (слева) до средней точки, или 12 (справа), по семь резисторов с каждой стороны должны быть постоянно параллельно соединены.  Смысл?...   А ещё должны подключаться параллельные направления.  Для таких коммутаций, - ну сильно накручено-навороченный галетник должен быть!  А как нужно выкрутить мосх, чтобы это представить? Пробовал просчитывать параллельные соединения по положениям переключателя (если предположить, что это так).  На соответствующие номиналы из столбика слева не выхожу...   бред  какой то...   Или, что это, в противном случае, обозначает?
    • Надо просто переставить R14 влево от R15. С6 - 4.7мкФ. С7 - 1000мкФ. С8 вообще нужен? С4 - электролит 220-470мкФ + плёнка 1-2.2мкФ. В базу Q10 100мкФ с питания. R12 лучше на шину питания подключить. R1 - 200 Ом и с эмиттеров ДК на коллектор Q3 резисторы 100 Ом. MJE заменить есть на что? Хоть 649-669. BD на 1837-4793. Неправда. Токи поднять немного и всё. NJW21193-21194 (2 пары) c драйверами 1837-4793 работает отлично.  
    • схема мертворожденная, начиная от управления реле и заканчивая управлением мосфета.
×
×
  • Create New...