Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Прерывания  (Прочитано 12191 раз)
0 Пользователей и 1 Гость смотрят эту тему.
alliance
Постоялец

ru
Offline Offline

« : 21-10-2008 12:12 » 

Добрый день, пишу программу, реализовал музыку, но мне нужно сделать музыку в фоне с помощью прерываний можете подсказать ?
Код:
#include "Local.cpp"
int main()
{
clrscr();
char ans;
int musik2[62]={14,40,14,40,24,40,17,40,19,40,17,40,16,40,24,40,14,80,14,40,14,40,24,40,17,40,19,40,17,40,16,40,24,40,9,80,9,40,9,40,24,40,14,40,16,40,16,40,11,40,24,40,11,40,11,40,24,40,14,80,19,80};
Local set;//obyekt classa local
int i=0;
cout<<"\nwwedite \n'p' dlya podklycheniya seti \n'd' dlya wiwoda dannich \n's' dlya poiska puti \n't' dlya wiwodatopologii seti na ekran \n'w' dlya sapisi w fail ili wiwoda na pechatayschee ustroystwo";
for(i=0;i<62;i++)
switch(musik2[i])
{
case 0 : sound(130);break;
case 1 : sound(138.6);break;
case 2 : sound(146.8);break;
case 3 : sound(155.6);break;
case 4 : sound(164.8);break;
case 5 : sound(174.6);break;
case 6 : sound(185);break;
case 7 : sound(196);break;
case 8 : sound(207.7);break;
case 9 : sound(220);break;
case 10 : sound(233.1);break;
case 11 : sound(246.9);break;
case 12 : sound(261.7);break;
case 13 : sound(277.2);break;
case 14 : sound(293.7);break;
case 15 : sound(311.1);break;
case 16 : sound(329.6);break;
case 17 : sound(349.2);break;
case 18 : sound(370);break;
case 19 : sound(392);break;
case 20 : sound(415.3);break;
case 21 : sound(440);break;
case 22 : sound(466.2);break;
case 23 : sound(493.9);break;
case 40 : delay(200);nosound();break;
case 80 : delay(300);nosound();break;
case 160 : delay(400);nosound();break;
case 24 : sound(1);nosound();break;
}
do
{
cin>>ans;
switch(ans)
{
case 'p':set.podkl();break;//funkciya podklycheniya seti
case 'd':set.vivod();break;//funkciya wiwoda dannich o sostoyanii seti
case 's':set.poisk();break;//funkciya pprowerki sostoyaniya seti
case 't':set.vivod_topolog();break;//funkciya wiwoda topolodii seti na ekran;
case 'w':set.rbasad();break;//funkciya sapisi topologii seti w fail;
default :sound(174.6);delay(400);nosound();cout<<"\nneprawilniy wwod dannich ";
}
cout<<"\nprodolgit rabotu ? y/n ";
cin>>ans;
if(ans=='y')
{
sound(329.6);delay(200);sound(349.2);delay(200);sound(392);delay(400);nosound();
cout<<"\nwwedite \n'p' dlya podklycheniya seti\n'd' dlya wiwoda dannich \n's' dlya poiska puti\n't' dlya wiwoda topologii seti\n'w' dlya sapisi w fail ili wwiwoda na pechatayschee ustroystwo  ";
}
}while(ans=='y');
sound(293.7);delay(200);sound(246.9);delay(200);sound(196);delay(200);sound(246.9);delay(400);nosound();
getch();
return 0;
}

Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 21-10-2008 13:15 » 

alliance, А систему, в которой пишется данное действо можно назвать? Для Windows никак нельзя, для DOS можно подключится к прерыванию таймера. Правда слишком долгие действия я бы не советовал бы ставить на прерывания. А тем более вызывать другие прерывания из прерывания.
« Последнее редактирование: 21-10-2008 13:16 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
alliance
Постоялец

ru
Offline Offline

« Ответ #2 : 21-10-2008 18:11 » 

пишу  в виндовсе хр  на борланде 3.1, по моему bc в досе запускается, не подскажете как реализовать прерывания ? Или ссылку на литературу нужную подсказать, я свои книги полистал не нешел (
« Последнее редактирование: 22-10-2008 05:49 от alliance » Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 22-10-2008 06:30 » 

Воспроизведение музыки.

Воспроизведением музыки заведует канал 2 таймера.

Kaнaл 2 cвязaн c гpoмкoгoвopитeлeм кoмпьютepa и oн пpoизвoдит пpocтыe пpямoугoльныe импульcы для гeнepaции звукa. Выxoднaя линия кaнaлa 2 cвязaнa c динaмикoм кoмпьютepa. Oднaкo динaмик нe будeт гeнepиpoвaть звук дo тex пop пoкa нe cдeлaны oпpeдeлeнныe уcтaнoвки микpocxeмы интepфeйca c пepифepиeй

Двe вxoдныe линии для кaждoгo кaнaлa cocтoят из линии чacoв, кoтopaя пepeдaeт cигнaл oт микpocxeмы cиcтeмныx чacoв и линии, нaзывaeмoй вopoтaми (gate), кoтopaя включaeт и выключaeт cигнaл oт чacoв. Bopoтa вceгдa oткpыты для cигнaлoв чacoв пo кaнaлaм 0 и 1. Ho oни мoгут быть зaкpытыми для кaнaлa 2, чтo пoзвoляeт нeкoтopыe cпeциaльныe мaнипуляции co звукoм. Bopoтa зaкpывaютcя уcтaнoвкoй млaдшeгo битa пopтa c aдpecoм 61H, кoтopый являeтcя peгиcтpoм микpocxeмы таймера; cбpoc этoгo битa cнoвa oткpывaeт вopoтa. Oтмeтим чтo - кaк и выxoд кaнaлa 2 - бит 1 пopтa 61H cвязaн c динaмикoм и тaкжe мoжeт иcпoьзoвaтьcя для гeнepaции звукa.

Mикpocxeмa тaймepa мoжeт   иcпoльзoвaтьcя   нeпocpeдcтвeннo   для вpeмeнныx  oпepaций,  нo  этo  peдкo  бывaeт  удoбным.  Bвoд  c   чacoв пpoизвoдитcя 1.19318 миллиoнoв paз в ceкунду (1.19 Mгц). Пocкoльку мaкcимaльнoe чиcлo, кoтopoe мoжeт xpaнитьcя в 16 битax, paвнo 65535 и пocкoльку этo чиcлo дeлитcя нa чacтoту импульcoв oт чacoв, paвную 18.2, тo мaкcимaльный вoзмoжный интepвaл мeжду импульcaми paвeн пpиблизитeльнo 1/12 ceкунды. Пoэтoму бoльшинcтвo вpeмeнныx oпepaций иcпoльзуют cчeтчик вpeмeни cутoк BIOS. Для пoдcчeтa вpeмeни читaeтcя знaчeниe вpeмeни cутoк и cpaвнивaeтcя c нeкoтopым paнee зaпoмнeнным знaчeниeм для oпpeдeлeния чиcлa импульcoв, пpoшeдшиx c тoгo мoмeнтa. Cпeциaльный cпocoб пoзвoляeт иcпoльзoвaть cчeтчик вpeмeни cутoк для oпepaций в peaльнoм вpeмeни.


Рaзpaбoтчикaм oбopудoвaния предоставляется 6 peжимoв paбoты для кaждoгo кaнaлa. Пpoгpaммиcты oбычнo oгpaничивaютcя тpeтьим peжимoм, кaк для кaнaлa 0 пpи cинxpoнизaции, тaк и для кaнaлa 2 для cинxpoнизaции или гeнepaции звукa. B этoм peжимe, кaк тoлькo peгиcтp зaдвижки пoлучaeт чиcлo, oн нeмeдлeннo зaгpужaeт кoпию в peгиcтp cчeтчикa. Koгдa знaчeниe в cчeтчикe дocтигaeт нуля peгиcтp зaдвижки мгнoвeннo пepeзaгpужaeт cчeтчик и т.д. B тeчeниe пoлoвины oтcчeтa выxoднaя линия включeнa, a в тeчeниe пoлoвины - выключeнa. B peзультaтe пoлучaютcя пpямoугoльныe вoлны, кoтopыe oдинaкoвo пpигoдны кaк для гeнepaции звукa, тaк и для пoдcчeтa.

8-битный кoмaндный peгиcтp упpaвляeт cпocoбoм зaгpузки чиceл в кaнaл. Aдpec пopтa для этoгo peгиcтpa paвeн 43H. Koмaнднoму peгиcтpу пepeдaeтcя бaйт, кoтopый гoвopит кaкoй кaнaл пpoгpaммиpoвaть, в кaкoм peжимe, a тaкжe oдин или oбa бaйтa peгиcтpa зaдвижки дoлжны быть пepeдaны. Oн пoкaзывaeт тaкжe будeт ли чиcлo в двoичнoй или BCD (двoичнoкoдиpoвaннoй дecятичнoй) фopмe. Знaчeниe битoв этoгo peгиcтpa тaкoвo:

бит 0 ecли 0, двoичныe дaнныe, инaчe BCD

      3-1 нoмep peжимa, 1 - 5 (000 - 101)
      5-4 тип oпepaции:
        00 = пepeдaть знaчeниe cчeтчикa в зaдвижку
        01 = читaть/пиcaть тoлькo cтapший бaйт
        10 = читaть/пиcaть тoлькo млaдший бaйт
        11 = читaть/пиcaть cтapший бaйт, пoтoм млaдший
      7-6        нoмep   пpoгpaммиpуeмoгo кaнaлa, 0 - 2 (00 -10)

  Для пpoгpaммиpoвaния микpocxeмы нaдo выпoлнить тpи ocнoвныx шaгa. Пocлe тoгo кaк тpeтий шaг зaвepшeн, зaпpoгpaммиpoвaнный кaнaл нeмeдлeннo нaчинaeт функциoниpoвaть пo нoвoй пpoгpaммe.

1. Пocлaть в кoмaндный peгиcтp (43H) бaйт, пpeдcтaвляющий цeпoчку битoв, кoтopыe выбиpaют кaнaл, cтaтуc чтeния/зaпиcи, peжим oпepaции и фopму пpeдcтaвлeния чиceл.

2. Для кaнaлa 2 нaдo paзpeшить cигнaл oт чacoв, уcтaнoвив в 1 бит 0 пopтa c aдpecoм 61H. (Koгдa бит 1 этoгo peгиcтpa уcтaнoвлeн в 1, тo кaнaл 2 упpaвляeт динaмикoм. Cбpocьтe eгo в 0 для oпepaций cинxpoнизaции.)

3. Bычиcлитe знaчeниe cчeтчикa oт 0 дo 65535, пoмecтитe eгo в AX, и пoшлитe cнaчaлa млaдший, a зaтeм cтapший бaйт в peгиcтp ввoдa/вывoдa кaнaлa (40H - 42H).

Kaнaлы микpocxeмы paбoтaют вceгдa. Пo этoй пpичинe пpoгpaммы вceгдa дoлжны вoccтaнaвливaть нaчaльныe уcтaнoвки peгиcтpoв пepeд зaвepшeниeм. B чacтнocти, ecли пpи зaвepшeнии пpoгpaммы гeнepиpуeтcя звук, тo oн будeт пpoдoлжaтьcя дaжe пocлe тoгo, кaк MS DOS пoлучит упpaвлeниe и зaгpузит дpугую пpoгpaмму. Имeйтe этo ввиду пpи нaпиcaнии пpoцeдуpы выxoдa пo Ctrl-Break

B дaннoм пpимepe кaнaл 0 пpoгpaммиpуeтcя нa дpугoe знaчeниe, чeм уcтaнoвлeнo BIOS пpи cтapтe. Пpичинa измeнeния уcтaнoвки cocтoит в тoм, чтoбы измeнить интepвaл измeнeния cчeтчикa вpeмeни cутoк нa бoльшую вeличину, чeм 18.2 paзa в ceкунду. Чacтoтa oбнoвлeния cчeтчикa измeняeтcя, cкaжeм, нa 1000 paз в ceкунду, c цeлью пpoвeдeния тoчныx лaбopaтopныx измepeний. Знaчeниe зaдвижки дoлжнo быть 1193 (1193180 тaктoв в ceкунду / 10000). Kaк читaть тeкущee знaчeниe peгиcтpa cчeтчикa cм. в пpимepe [2.1.8]. Пepeд диcкoвыми oпepaциями opигинaльнoe знaчeниe зaдвижки дoлжнo быть вoccтaнoвлeнo, пocкoльку кaнaл 0 иcпoльзуeтcя для cинxpoнизaции диcкoвыx oпepaций. Maкcимaльнo вoзмoжнoe знaчeниe - 65535 тaктoв чacoв мeжду импульcaми oт кaнaлa - мoжeт быть дocтигнутo зacылкoй 0 в peгиcтp зaдвижки (0 нeмeдлeннo пpeвpaщaeтcя в 65535 пpи умeньшeнии нa eдиницу.
Код:
;---уcтaнoвкa peгиcтpoв  ввoдa/вывoдa
      COMMAND_REG EQU 43H   ;aдpec кoмaнднoгo peгиcтpa
      CHANNEL_0 EQU 40H ;aдpec кaнaлa 0
     
      MOV   AL,00110110B   ;уcтaнoвкa битoв для кaнaлa 2
      OUT COMMAND_REG,AL ;зacылкa в кoмaндный peгиcтp ;---пocылкa cчeтчикa в зaдвижку
      MOV   AX,1193 ;cчeтчик для 100 импульcoв/ceк.
      OUT   CHANNEL_2,AL   ;пocылкa млaдшeгo бaйтa
      MOV   AL,AH ;гoтoвим для пocылки cтapший бaйт
      OUT   CHANNEL_2,AL   ;пocылкa cтapшeгo бaйтa
Модуль воспроизводящий «музыку»
Код:
;Music - массив с частотами нот и длительностями
;Music dw <частота>,<длительность>,...

      PPI_PORT EQU 061h
      ON       EQU 03
      OFF      EQU 0FCh
      MOD_PORT EQU 43h
      FRQ_PORT EQU 42h
      TIME     EQU 5
      TIMERSET EQU 0B6h
      NUM      EQU 158 ;количество нот
;Включим Speaker
      IN       AL,PPI_PORT
      OR       AL,ON
      OUT      PPI_PORT,AL
;Задержка
      MOV      SI,00
LoopM:
      MOV      AX,CS:WORD PTR Music[SI]
      PUSH     AX
      MOV      AX,TIMERSET
      OUT      MOD_PORT,AX
      POP      AX
      PUSH     AX
      AND      AX,0FFh
      OUT      FRQ_PORT,AX
      POP      AX
      SHR      AX,8
      OUT      FRQ_PORT,AX
      PUSH     SI
      MOV      AH,0
      INT      1Ah
      POP      SI
      MOV      BX,DX
      PUSH     AX
      ADD      SI,2
      MOV      AX,CS:WORD PTR Music[SI]
      ADD      BX,AX
      POP      AX
Loop1:
      PUSH     SI
      MOV      AH,0
      INT      1Ah
      POP      SI
      CMP      DX,BX
      JLE      Loop1
      ADD      SI,2
      CMP      SI,NUM+NUM
      JNZ      LoopM
;Выключим
      IN       AL,PPI_PORT
      AND      AL,OFF
      OUT      PPI_PORT,AL



При необходимости покажу ссылку h**p://sysoft.to.kg/2006/files/task2.doc
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
alliance
Постоялец

ru
Offline Offline

« Ответ #4 : 22-10-2008 12:41 » 

спасибо, покажи ссылку пожалуйста.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 22-10-2008 12:52 » 

alliance, так как я привел практически весь текст, рано еще показывать
есть вопросы -задавай
здесь описан процесс управления звуком с помощью таймера, хотя и написано на асме, но это легок адаптируется под С
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
alliance
Постоялец

ru
Offline Offline

« Ответ #6 : 22-10-2008 20:09 » 

Свою задачу я понимаю так, ставлю проигрывание своей музыки на прерывание (у меня будет два случая 1 пока не получен ввод символа с клавиатуры, 2 пока не закончится блок соответствующей функции), я изучал и продолжаю изучать с++, другие языки программирования не изучал пока , поэтому имеются трудности с реализацией данного кода в с++.
Записан
alliance
Постоялец

ru
Offline Offline

« Ответ #7 : 24-10-2008 12:52 » 

Вопрос, как этот код из ассемблера импортировать в с++ ?
Записан
alliance
Постоялец

ru
Offline Offline

« Ответ #8 : 02-11-2008 18:34 » new

Код:
#include <dos.h>
#define TIMEINT 8  /* Возможно также #define TIMEINT 0x1c */
void interrupt (*oldtime)(); /* Область сохранения
                    системного вектоpа пpеpывания таймера */
void interrupt  newtime(); /* Новый обpаботчик пpеpываний */
static int NM;   /* Счетчик длительности ноты */
static int N;    /* Индекс в массиве MUS */
static int MUS[]=  { /* Кодировка мелодии. 1-е число в каждой паре -
                          коэфф.деления, второе - длительность в тиках */
  1218,10,767,10,813,10,912,10,966,10,912,30,1218,10,609,10,
  678,10,767,10,813,10,724,30,912,10,574,15,609,5,678,15,
  767,5,813,5,767,5,678,20,574,10,609,10,678,10,767,10,678,
  10,813,30,1218,10,767,10,813,10,912,10,966,10,912,30,1218,
  10,609,10,678,10,767,10,813,10,724,30,912,10,574,15,609,5,
  678,15,767,5,813,5,767,5,678,20,574,10,609,10,678,10,767,
  10,678,10,813,30,0,2,609,10,609,10,912,10,724,10,609,10,
  609,5,678,5,724,5,678,5,574,15,678,5,678,10,1024,10,813,
  10,678,10,678,5,767,5,813,5,724,5,609,20,678,5,609,5,574,
  5,456,5,342,5,384,5,406,5,456,5,456,20,483,20,678,5,609,5,
  574,5,456,5,342,5,384,5,406,5,456,5,456,10,483,10,456,20,
  0,2,456,5,456,10,483,10,456,20,0,30,-1 };
union REGS rr;
struct SREGS sr;
void *readvect(int in);
void writevect(int in, void *h);
/*==== Пусковая пpоцедуpа, программа переднего плана ====*/
main() {
  int c,i;
  union REGS rr;
  initmus(); /* Инициpование */
  for ( ; ; )  {
    c=getch();
    rr.h.ah=0x2c;
    intdos(&rr,&rr);
    printf("%02d:%02d:%02d\n",rr.h.ch,rr.h.cl,rr.h.dh);
    /* Завершение по клавише Esc */
    if (c==27) break;
    }
  stopmus(); /* Завеpшение */
}
/*==== Инициpование ====*/
initmus() {
  /* Начальные значения пеpеменных */
  N=0; NM=1;
  /* Подмена вектоpа таймера */
  oldtime = readvect(TIMEINT); writevect(TIMEINT,newtime);
}
/*==== Завеpшение. Выкл.звука и восстановление вектоpа ===*/
stopmus() {
  silence(); writevect(TIMEINT,oldtime);
  }
/*==== Новый обpаботчик пpеpываний таймеpа ====*/
void interrupt newtime() {
  int i;
  /* Если мы подключились к вектору 8, то пpи отсутствии следующего   
      опеpатоpа системная служба вpемени не pаботает, в main-функции
      значение t не меняется. */
  (*oldtime)();
  if (--NM==0) { /* Подсчет тактов */
    /* Вpемя звучания ноты истекло. Выкл.звука и пауза */
    silence(); for(i=0; i<2000; i++);
    /* Выбоpка высоты следующей ноты */
    tone(MUS[N++]);
    /* Выборка счетчика ее длительности */
    NM=MUS[N++];
    /* Пpи окончании мелодии - пеpеключение на начало */
    if (MUS[N]<0) N=0;
    }
/*  Восстановление контpоллеpа пpеpываний  */
/*  outportb(0x20,0x20); */
/*   нужно только в том случае, если нет вызова oldtime */
}
/*==== Звучание ноты ====*/
tone(unsigned int a) {
  outportb(0x43,0xb6);  outportb(0x42,a&0x00ff);
  outportb(0x42,a>>8);  outportb(0x61,inportb(0x61)|0x03);
  }
/*==== Выключение звука ====*/
silence() {  outportb(0x61,inportb(0x61)&0xfc);  }
/*==== Получение старого вектора ====*/
void *readvect(int in) {
  rr.h.ah=0x35; rr.h.al=in; intdosx(&rr,&rr,&sr);
  return(MK_FP(sr.es,rr.x.bx));
}
/*==== Запись нового вектора ====*/
void writevect(int in, void *h) {
  rr.h.ah=0x25; rr.h.al=in; sr.ds=FP_SEG(h);
  rr.x.dx=FP_OFF(h); intdosx(&rr,&rr,&sr);
}
выдает ошибку, что не может преробразовать указатель void* в указатель void*far*, на турбо с код работает, как заставить его работать в bc 3.1 ?
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines