реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Проигрывание мелодии на ATmega32, Не получается переделать под Attiny2313
Sergey529
сообщение Feb 11 2012, 12:58
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 12-12-11
Пользователь №: 68 814



Имеется готовый проект для проигрывания мелодий из списка. Написан в WinAvr под ATMega8535. Для формирования различных длительностей и интервалов используется таймер-счетчик 2. Скомпилировал под ATMega32 - все отлично работает. Переделал под Т/С0 - тоже работает. Начал переделывать под ATtiny2313 c использованием Т/С0 - не работает.. Точнее мелодии звучат в несколько раз медленнее, и ниже тональностью. Частота тактирования МК - 8МГц. Ссылка на исходник проекта http://chipenable.ru/files/course/sound-li...dAvr-WINAVR.rar . Очень прошу помочь..
Мой код:
Код
#include "sound.h"

#define LOOP 0xff

PROGMEM unsigned int FurElise[] =  
        {
            18, 1,
            n8,e2, n8,xd2, n8,e2, n8,xd2, n8,e2, n8,b1, n8,d2, n8,c2, n4,a1, n8,p,
            n8,c1, n8,e1, n8,a1, n4,b1, n8,p, n8,e1, n8,xg1, n8,b1, n4,c2, n8,p, n8,e1,
            n8,e2, n8,xd2, n8,e2, n8,xd2, n8,e2, n8,b1, n8,d2, n8,c2, n4,a1, n8,p, n8,c1,
            n8,e1, n8,a1, n4,b1, n8,p, n8,e1, n8,c2, n8,b1, n4,a1,
            0
        };


PROGMEM unsigned int Mozart[] =
        {
            16, 1,
            n16, xf1, n16, e1, n16,xd1, n16,e1, n4,g1, n16,a1, n16,g1, n16,xf1, n16,g1,
            n4,b1, n16,c2, n16,b1, n16,xa1, n16,b1, n16,xf2, n16,e2, n16,xd2, n16,e2,
            n16,xf2, n16,e2, n16,xd2, n16,e2, n4,g2, n8,e2, n8,g2, n32,d2, n32,e2,
            n16,xf2, n8,e2, n8,d2, n8,e2, n32,d2, n32,e2, n16,xf2, n8,e2, n8,d2, n8,e2,
            n32,d2, n32,e2, n16,xf2, n8,e2, n8,d2, n8,xc2, n4,b1,
            0
        };

PROGMEM unsigned int Minuet[] =
        {
            18, 1,
            n4,d2, n8,g1, n8,a1, n8,b1, n8,c2, n4,d2, n4,g1, n4,g1, n4,e2, n8,c2,
            n8,d2, n8,e2, n8,xf2, n4,g2, n4,g1, n4,g1, n4,c2, n8,d2, n8,c2, n8,b1,
            n8,a1, n4,b1, n8,c2, n8,b1, n8,a1, n8,g1, n4,xf1, n8,g1, n8,a1, n8,b1,
            n8,g1, n4,b1, n2,a1,
            0
        };


PROGMEM unsigned int Sirene2[] =
        {
            1, LOOP,
            ms(500), c2, ms(500), g2,
            0
        };

//-----------------------------звуковой модуль----------------------------------
//указатели на регистры порта
#define PIN_SOUND (*(&PORT_SOUND-2))
#define DDR_SOUND (*(&PORT_SOUND-1))

//заглушка - пустая мелодия
PROGMEM unsigned int Empty[] =
        {
            1, 1,
            n4, p,
            0
        };

PROGMEM unsigned int PROGMEM* melody[] = {Empty, FurElise, Mozart, Minuet, Sirene2};

//переменные звукового модуля
volatile static unsigned int *pSong;
volatile static unsigned char state = SOUND_STOP;
volatile static unsigned int  durationNote = 0;
volatile static unsigned int  toneNote = 0;
volatile static unsigned char indexNote = 0;
volatile static unsigned char statReg = 0;
volatile static unsigned char repeat = 0;

#ifndef SOUND_BPM  
  static unsigned char bpm = 0;
#endif


//флаги
#define SOUND_VOLUME     0
#define SOUND_GEN        1

#define SOUND_BPM_SONG    0
#define SOUND_REPEAT_SONG 1
#define SOUND_START_SONG  2
#define SOUND_COUNTER_CAP 256
#define SOUND_PROG_COUNTER 31
  
//инициализация звукового модуля
void SOUND_Init(void)
{
  //настройка вывода мк на выход
  PORT_SOUND &= ~(1<<PINX_SOUND);
  DDR_SOUND |= (1<<PINX_SOUND);
  
  //настройка таймера T2
  TIMSK |= (1<<TOIE0);  
  TCCR0A = (0<<COM0A1)|(0<<COM0A0)|(0<<WGM01)|(0<<WGM00);  //режим - нормал, прескалер -
  TCCR0B = (0<<FOC0A)|(0<<WGM02)|(0<<CS02)|(0<<CS01)|(1<<CS00);
  TCNT0 = 0;    
  OCR0A = 0;
  
  //инициализация переменных
  pSong = (unsigned int *)pgm_read_word(&(Empty));
  state = SOUND_STOP;
  durationNote = 0;
  toneNote = 0;
  repeat = 0;
  indexNote = 0;
  statReg = 0;
#ifndef SOUND_BPM  
  bpm = 0;
#endif
}


void SOUND_SetSong(unsigned char numSong)
{
    if (numSong <= SOUND_AMOUNT_MELODY) {
      pSong = (unsigned int *)pgm_read_word(&(melody[numSong]));
    }
}



//обработчик команд звукового модуля
void SOUND_Com(unsigned char com)
{
unsigned char saveSreg = SREG;
  cli();
  switch (com){
    
    /*команда стоп:*/
    case SOUND_STOP:
      state = SOUND_STOP;
      TIMSK &= ~(1<<OCIE0A);
      PORT_SOUND &= ~(1<<PINX_SOUND);
      break;
      
   /*команда воспроизведение*/
    case SOUND_PLAY:
      if (state == SOUND_PAUSE){
        state = SOUND_PLAY;          
        TIMSK |= (1<<OCIE0A);
      }
      else {
      #ifndef SOUND_BPM  
        bpm = pgm_read_word(&(pSong[SOUND_BPM_SONG]));
      #endif
        indexNote = SOUND_START_SONG;
        repeat = pgm_read_word(&(pSong[SOUND_REPEAT_SONG]));
        durationNote = 0;
        state = SOUND_PLAY;          
        TIMSK |= (1<<OCIE0A);        
      }
      break;  
      
      /*команда пауза*/
      case SOUND_PAUSE:
        state = SOUND_PAUSE;  
        TIMSK &= ~(1<<OCIE0A);
      break;
      
    default:
      break;
  }
  SREG = saveSreg;
}

//проиграть мелодию под номером numSong
void SOUND_PlaySong(unsigned char numSong)
{
   if (numSong <= SOUND_AMOUNT_MELODY) {
      pSong = (unsigned int *)pgm_read_word(&(melody[numSong]));
   }
   #ifndef SOUND_BPM  
     bpm = pgm_read_word(&(pSong[SOUND_BPM_SONG]));
   #endif
   indexNote = SOUND_START_SONG;
   repeat = pgm_read_word(&(pSong[SOUND_REPEAT_SONG]));
   durationNote = 0;
   state = SOUND_PLAY;          
   TIMSK |= (1<<OCIE0A);      
}




inline static void SOUND_Duration(void)
{
  static unsigned char counter = 0;
  
  if (state == SOUND_PLAY){  
    if (durationNote){
       counter++;
       counter &= SOUND_PROG_COUNTER;
       if (!counter){
          durationNote--;  
       }
    }
    else {
      durationNote = pgm_read_word(&(pSong[indexNote]));
      if (durationNote) {
#ifndef SOUND_BPM
        durationNote = durationNote/bpm;
#endif
        indexNote++;
        toneNote = pgm_read_word(&(pSong[indexNote]));
        if (toneNote!=P) {
          statReg |= (1<<SOUND_VOLUME);
        }
        else{
          statReg &= ~(1<<SOUND_VOLUME);
        }
        indexNote++;
        TIFR |=(1<<OCF0A);
      }
      else{
        if (repeat == LOOP){
          indexNote = SOUND_START_SONG;
          durationNote = 0;
          return;
        }
        repeat--;
        if (!repeat){
          state = SOUND_STOP;
          TIMSK &= ~(1<<OCIE0A);
          PORT_SOUND &= ~(1<<PINX_SOUND);
          return;
        }
        else{
          indexNote = SOUND_START_SONG;
          durationNote = 0;
        }
        
      }        
    }
}
  
}


inline static void SOUND_Tone(void)
{
  static unsigned int tone = 0;
  
  if (statReg & (1<<SOUND_GEN)){
    if (statReg & (1<<SOUND_VOLUME)){
       PORT_SOUND ^= (1<<PINX_SOUND);
    }
    tone = toneNote;
    statReg &= ~(1<<SOUND_GEN);
  }

  if (tone > SOUND_COUNTER_CAP) {
    tone -= SOUND_COUNTER_CAP;
  }
  else {
    OCR0A = tone;
    statReg |= (1<<SOUND_GEN);
  }
}

//прерывания таймера Т2_____________________________________
ISR(TIMER0_OVF_vect)
{
  SOUND_Duration();
  BUT_Debrief();
}


ISR(TIMER0_COMPA_vect)
{
  SOUND_Tone();
}


Код
#ifndef SOUND_H
#define SOUND_H

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "buttons.h"

//*************************** настройки *************************************

#define SOUND_BPM       24  //если закомментировать длительность нот будет
                              //расчитываться из заданного в мелодии BPM`а

#define SOUND_F_CPU     8U //тактовая частота мк
#define SOUND_TIM_PRE   1U  //зачение предделителя таймера

#include "tone.h"   //здесь определены частота и длительности нот

//пин мк на котором будет генериться звук
#define PORT_SOUND PORTD
#define PINX_SOUND 0

//количество мелодий
#define SOUND_AMOUNT_MELODY 4

//***************************************************************************

//команды звукового модуля
#define SOUND_STOP      0
#define SOUND_PLAY      1
#define SOUND_PAUSE     2

//функции звукового модуля
void SOUND_Init(void);
void SOUND_SetSong(unsigned char numSong);
void SOUND_Com(unsigned char com);
void SOUND_PlaySong(unsigned char numSong);

#endif //SOUND_H


Сообщение отредактировал Sergey529 - Feb 11 2012, 13:00
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Feb 13 2012, 04:11
Сообщение #2


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (Sergey529 @ Feb 11 2012, 20:58) *
Точнее мелодии звучат в несколько раз медленнее, и ниже тональностью.

ИМХО на лицо проблема тактирования микроконтроллера... Тактовый генератор у Вас правильно настроен?


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
Sergey529
сообщение Feb 13 2012, 07:26
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 12-12-11
Пользователь №: 68 814



Цитата(haker_fox @ Feb 13 2012, 07:11) *
ИМХО на лицо проблема тактирования микроконтроллера... Тактовый генератор у Вас правильно настроен?
,
Вроде бы правильно - пробовал во фьюзах прошивать и RC-цепь 8 МГц, и внешний кварц 8 МГц. Реультат один и тот же. В Makefile указана частота - 8 МГц.. "Где собака порылась?" Сегодня вечером попробую осциллографом посмотреть, что там на ногах кварца. А в коде, в настройках таймера все в порядке?
Go to the top of the page
 
+Quote Post
Sergey529
сообщение Feb 13 2012, 15:51
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 12-12-11
Пользователь №: 68 814



Тему можно закрывать - контроллер с завода шел c установленным в 0 (enabled) фьюз-битом С - Divide Clock by 8 . Установил его в 1, стало все в порядке. Мелодии проигрываются правильно.
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Feb 14 2012, 02:10
Сообщение #5


Познающий...
******

Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125



QUOTE (Sergey529 @ Feb 13 2012, 23:51) *
Тему можно закрывать - контроллер с завода шел c установленным в 0 (enabled) фьюз-битом С - Divide Clock by 8 . Установил его в 1, стало все в порядке. Мелодии проигрываются правильно.

Гм! А Вы фьюзы не проверяете перед прошивкой?

З.Ы. Тему можете самостоятельно закрыть. Внизу страницы есть опции модератора...


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
Sergey529
сообщение Feb 27 2012, 15:39
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 12-12-11
Пользователь №: 68 814



Проверяю. Просто был невнимателен, не посмотрел на "Div. clock by 8". Хотел еще задать вопрос. В вышеописанной программе хотелось бы из main обратиться к переменной STATE, находящейся в sound.c. Т.е. в main проверить то, что state стало равно SOUND_STOP.

Код
state = SOUND_STOP;
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 1 2012, 04:29
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Цитата(Sergey529 @ Feb 27 2012, 19:39) *
В вышеописанной программе хотелось бы из main обратиться к переменной STATE, находящейся в sound.c. Т.е. в main проверить то, что state стало равно SOUND_STOP.
Код
state = SOUND_STOP;
убрать volatile static для state, в sound.h добавить extern unsigned char state; в главном модуле не забыть проинклюдить sound.h


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Sergey529
сообщение Mar 3 2012, 19:43
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 12-12-11
Пользователь №: 68 814



ARV, огромное спасибо! Исправил свои ошибки, добавил ваши замечания. Все отлично получилось. Мне это нужно было для формирования задержки в 10 сек между мелодиями - т.е. по окончании проигрывания, запускается ТС1. В итоге закончил программную часть своего устройства - датчика намокания. При намокании датчика, устройство играет выбранную мелодию и мигает номер установленной мелодии на индикаторе (к проекту добавлен вывод номера мелодии на семисегментный индикатор и формирование паузы между мелодиями).
Go to the top of the page
 
+Quote Post
ipkentik
сообщение Apr 13 2013, 17:02
Сообщение #9





Группа: Новичок
Сообщений: 1
Регистрация: 13-04-13
Пользователь №: 76 488



а вот у меня из этого примера - один сплошной звук идет. монотонный. как быть? куда смотреть?
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd June 2025 - 16:18
Рейтинг@Mail.ru


Страница сгенерированна за 0.01435 секунд с 7
ELECTRONIX ©2004-2016