[an error occurred while processing this directive]
Ответ:
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Александр Николаевич 25 декабря 2002 г. 08:12
В ответ на: DTMF отправлено Химик 31 августа 2001 г. 11:13

#include "io2313.h"
#include "ina90.h"

typedef unsigned char INT8U;
typedef signed char INT8S;
typedef unsigned int INT16U;
typedef signed int INT16S;

flash INT8S SIN_TBL[]={
0,3,6,9,12,16,19,22,25,28,31,34,37,40,43,46,
49,51,54,57,60,63,65,68,71,73,76,78,81,83,85,88,
90,92,94,96,98,100,102,104,106,107,109,111,112,113,115,116,
117,118,120,121,122,122,123,124,125,125,126,126,126,127,127,127,
127,127,127,127,126,126,126,125,125,124,123,122,122,121,120,118,
117,116,115,113,112,111,109,107,106,104,102,100,98,96,94,92,
90,88,85,83,81,78,76,73,71,68,65,63,60,57,54,51,
49,46,43,40,37,34,31,28,25,22,19,16,12,9,6,3,
0,-3,-6,-9,-12,-16,-19,-22,-25,-28,-31,-34,-37,-40,-43,-46,
-49,-51,-54,-57,-60,-63,-65,-68,-71,-73,-76,-78,-81,-83,-85,-88,
-90,-92,-94,-96,-98,-100,-102,-104,-106,-107,-109,-111,-112,-113,-115,-116,
-117,-118,-120,-121,-122,-122,-123,-124,-125,-125,-126,-126,-126,-127,-127,-127,
-127,-127,-127,-127,-126,-126,-126,-125,-125,-124,-123,-122,-122,-121,-120,-118,
-117,-116,-115,-113,-112,-111,-109,-107,-106,-104,-102,-100,-98,-96,-94,-92,
-90,-88,-85,-83,-81,-78,-76,-73,-71,-68,-65,-63,-60,-57,-54,-51,
-49,-46,-43,-40,-37,-34,-31,-28,-25,-22,-19,-16,-12,-9,-6,-3
};

#define sin(n) SIN_TBL[n]
#define cos(f) sin(f+64)

/*INT8U UARTBuf[16];
INT8U UARTBuf_Head=0, UARTBuf_Tile=0, UARTBuf_Count=0;

interrupt [UART_UDRE_vect] void UART_UDRE_v(void){
UDR=UARTBuf[UARTBuf_Tile];
UARTBuf_Tile++;
UARTBuf_Tile&=0x0F;
if((--UARTBuf_Count)==0){
UCR&=~(1< };
}

void putchar(INT8U outchar){
while(UARTBuf_Count>15);
UARTBuf[UARTBuf_Head]=outchar;
UARTBuf_Head++;
UARTBuf_Head&=0x0F;
UARTBuf_Count++;
UCR|=(1<}*/

void putchar(INT8U outchar){
while(USR&(1< UDR=outchar;
}

void Write_uc(INT8U c) {
char i,j;
i=0;
j=0;
while(c>=100) {c-=100;i++;};
if (i){
putchar('0'+i);
j=0xFF;
};
i=0;
while(c>=10) {c-=10;i++;};
if (i|j) putchar('0'+i);
putchar('0'+c);
}

INT8U sqrt(INT16U L){
INT8U div = 1, rslt = 0;
if(L==0)
return(0);
do{
L-=div;
div+=2;
rslt++;
}while(L>div);
if(L>(div>>1))
rslt++;
return rslt;
}

volatile INT16U Timer;

void Delay(INT16U msd){
Timer=msd;
while(Timer);
}

#define SAMPLCOUNT 16
/*697,770,852,941,1209,1336,1477,1633*/
/*flash INT16U dtmf_freq[]={3654,4037,4467,4934,6339,7004,7744,8562}; */
flash INT16U dtmf_freq[]={3956,4371,4836,5341,6862,7583,8384,9269};
#define DTMFFREQCOUNT 7
flash INT16U aon_freq[]={3670,4719,5767,6816,7864,8913};
#define AONFREQCOUNT 6

INT8U bufiv2[SAMPLCOUNT];

volatile INT8U GF=0;
#define IVCOMPLETE 0
#define IVACTIVE 1
#define OVERLOAD 2

INT8U GetMagnitude(INT16U freq, INT8U * bufiv1){
INT8U fase_tmp, in_values_i, in_values_s, in_v, *in_vp;
INT16S ssin=0, scos=0;
INT16U fase=0;
INT8U a,b;
in_values_i=SAMPLCOUNT;
in_vp=&(bufiv1[SAMPLCOUNT-1]);
do{
in_v=*(in_vp--);
in_values_s=0x01;
do{
fase_tmp=(fase>>8);
if ((in_v&in_values_s)!=0){
ssin+=sin(fase_tmp);
scos+=cos(fase_tmp);
}else{
ssin-=sin(fase_tmp);
scos-=cos(fase_tmp);
};
fase+=freq;
}while((in_values_s<<=1)!=0);
}while(--in_values_i);
if(ssin<0)
ssin=-ssin;
if(scos<0)
scos=-scos;
a=ssin>>8;
b=scos>>8;
return(sqrt((a*a)+(b*b)));
}

void GetMagnitudes(INT16U flash *FreqArray, INT8U FreqCount, INT8U *MagnitudesArray){
INT8U i;
INT8U bufiv1[SAMPLCOUNT];
while((GF&(1< _CLI();
for(i=0;i bufiv1[i]=bufiv2[i];
GF&=~(1< _SEI();
for(i=0;i MagnitudesArray[i]=GetMagnitude(FreqArray[i], bufiv1);
/*Write_uc(MagnitudesArray[i]);
putchar(',');*/
};
/*putchar(0x0a);
putchar(0x0d); */
}

interrupt [TIMER0_OVF0_vect] void TIMER0_OVF0_vect_(void){
static INT8U in_values_i, in_values_s, in_values_tmp;
INT8U in_values_s_tmp;
TCNT0=(255-6+1);
in_values_s_tmp=in_values_s;
if((GF&(1< GF|=(1< if((GF&(1< GF|=(1< GF&=~(1< }else
GF&=~(1< in_values_tmp=0;
in_values_i=SAMPLCOUNT-1;
in_values_s_tmp=0x01;
};
if((ACSR&(1< in_values_tmp|=in_values_s_tmp;
in_values_s_tmp<<=1;
if(in_values_s_tmp==0){
if(in_values_i==0){
GF&=~(1< GF|=(1< Timer--;
}else{
bufiv2[in_values_i--]=in_values_tmp;
in_values_tmp=0;
in_values_s_tmp=0x01;
};
};
in_values_s=in_values_s_tmp;
}

flash INT8U DTMFDecTbl[4][4]={
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};

INT8U SampForWait=0;
INT8U LastDTMF=0xFF;
INT8U a[4][DTMFFREQCOUNT];

void AnalSeq(void){
INT8U i,j;
INT8U k1,k2,n1,n2;
INT16U k;
for(i=0;i<3;i++)
for(j=0;j a[i][j]=a[i+1][j];
GetMagnitudes(dtmf_freq, DTMFFREQCOUNT, a[3]);

if(SampForWait>0)
SampForWait--;
if(SampForWait==0){
for(j=0;j k=0;
for(i=0;i<4;i++)
k+=a[i][j];
a[0][j]=(k>>2);
};

k=0;
for(j=0;j<4;j++)
k+=a[0][j];
for(j=0;j<4;j++)
a[0][j]=(((INT16U)(a[0][j]))<<8)/k;
k=0;
for(j=4;j k+=a[0][j];
for(j=4;j a[0][j]=(((INT16U)(a[0][j]))<<8)/k;

k1=0;n1=0;
for(i=0;i<4;i++){
if(a[0][i]>k1){
k1=a[0][i];
n1=i;
};
};

k2=0;n2=4;
for(i=4;i if(a[0][i]>k2){
k2=a[0][i];
n2=i;
};
};

j=0;
for(i=0;i if((i!=n1)&&(i!=n2))
if(a[0][i]>j)
j=a[0][i];

if(j<0x40)
if((k1>0x80)&&(k2>0x80))
if(LastDTMF==0xFF)
LastDTMF=DTMFDecTbl[n1][n2-4];
if((k1<0x60)||(k2<0x60))
LastDTMF=0xFF;
};
}

INT8U GetDTMF(void){
INT8U r;
r=LastDTMF;
AnalSeq();
if(r!=LastDTMF){
SampForWait=4;
return(LastDTMF);
};
return(0xFF);
}

void DialDigit(INT8U digit){
INT8U N;
putchar(digit);
switch(digit){
case '0': N=10;break;
default: N=digit-'0';
};
do{
DDRB|=(1<<2);
Delay(6);
DDRB&=~(1<<2);
Delay(4);
}while(--N);
}

void PhoneDial(INT8U * PhoneNumber, INT8U digitcount){
INT8U i;
/*DDRB|=((1<<2)|(1<<3));*/
for(i=0;i DialDigit(PhoneNumber[i]);
Delay(50);
if((i==0)&&(PhoneNumber[i]=='8'))
Delay(400);
};
/*DDRB&=~((1<<2)|(1<<3)); */
}

C_task main(void){
INT8U i, c;
INT16U j;
INT8U PhoneNumber[13];
PORTB&=~((1<<2)|(1<<3)|(1<<4));
UBRR=6; /*38400 bod for XTAL=8*/
UCR|=(1< _SEI();
ACSR=0; /*Enable AnalogComparator, Disable AnalogComparator interrupt*/
TCCR0=3; /*Init Timer0 to CK/64*/
TIMSK|=(1< _WDR();
WDTCR=(1< i=j=0;
putchar('s');
DDRB|=(1<<4);
do{
_WDR();
c=GetDTMF();
if((GF&(1< putchar('|');
if(c==0xFF)
j++;
if((c>='0')&&(c<='9')){
PhoneNumber[i++]=c;
putchar(c);
j=0;
};
if(c=='#')
i=0;
}while((i<13)&&(c!='*')&&(j<1000));
putchar('c');
DDRB&=~(1<<4);
ACSR|=(1< WDTCR|=(1< WDTCR&=~(1< if((c=='*')&&(i!=0))
PhoneDial(PhoneNumber, i);
MCUCR|=((1< DDRB|=(1<<4);
_SLEEP();
}


Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru