بسم الله والصلاة على رسول الله ...
السلام عليكم ...
أخي الكريم ستجد في الرابط أدناه موقعا به كيفية تحول المتحكم () إلى كاشف () و لكن مبرمج كيف يكشف نغمة محددة عندما يجدها يخرج حالة منطقية معينة ، إما واحد أي 5 فولط أو صفر، و به أيضا التحكم بمخارج عدة ، وهذا هو الرابط :
http://pe1grl.khds.nl/dtmf/dtmf.htm
أما الرابط التالي فستجد فيه الأمر نفسه تقريبا، مع اختلافات بسيطة :
http://www.romanblack.com/DTMF/DTMF_alg.htm
|
مشكور اخي على المساعدة انا وجدت نفس الموقعين ولكن الكود غير مفهوم بالنسبة الي لان الاول بلغة الاسمبلي والموقع الثاني هذا الكود
فياريت حدا من الاخوة يشرحلنا الكود وتسلسلو
/************************************************** ****************************
SG_DTMF.c DTMF accurate sinewave generator
Copyright: Open-Source, Feb 2011, written by
www.RomanBlack.com
MCU: P18F8527
Dev.Board: SmartGLCD (MikroE SmartGLCD 240x128 module)
Oscillator: HSPLL 32.0 MHz (8MHz xtal)
Compiler: MikroC v7.0 (or MikroC PRO 4.0)
This uses a zero-error DDS algorithm to generate 2 good quality sinewaves
at the same time on one PIC PWM output, and both sinewaves have extremely
accurate frequencies. This project uses the algorithm to generate
2 sinewaves for telephone DTMF use, but it could also be used for
polyphonic music generation of many exact notes with defined waveshapes.
The sinewave table for this project has a range of 0-99 and 64 samples.
For a full description of theory see;
www.RomanBlack.com/one_sec.htm#BDA
Note!! This uses 40x16 text mode on GLCD.
************************************************** ****************************/
// Global Variables
unsigned long waveA absolute 0x15; // 32bit accumulators for the 2 sinewaves
unsigned char waveA_2 absolute 0x17; // overload for fast access to byte 2
unsigned long waveB absolute 0x19;
unsigned char waveB_2 absolute 0x1B; // overload for fast access to byte 2
unsigned long BDA_periodA; // 32bit periods for the 2 sinewaves
unsigned long BDA_periodB;
unsigned char drow; // DTMF selected row and column
unsigned char dcol;
unsigned char tp_x; // will hold results of Touch Panel adc values
unsigned char tp_y;
unsigned char text[4]; // holds 3 digit number + NULL, for text display
// defines for the DTMF sine frequencies
// Sinewave is a lookup table of 64 steps, to generate 1633 Hz each step is 1633 * 64
// 24bit Binary divider uses byte2 (/65536)
// PWM freq is 128 PIC instructions (8Mhz xtal *PLL) = 62500 Hz
// So the math is; Fout * 64 * 65536 / Fpwm
// we can use a constant Fout * (64 * 65536 / 62500) = Fout * 67.108864
#define Frow0 46775 // 697 Hz DTMF rows
#define Frow1 51674 // 770 Hz
#define Frow2 57177 // 852 Hz
#define Frow3 63149 // 941 Hz
#define Fcol0 81135 // 1209 Hz DTMF columns
#define Fcol1 89657 // 1336 Hz
#define Fcol2 99120 // 1477 Hz
#define Fcol3 109589 // 1633 Hz
#include "T6963C_MikroC.h" // include this if using MikroC (older)
//#include "T6963C_MikroC_PRO.h" // include this if using MikroC PRO
#include "TPfast.c" // needed for my TouchPanel functions
// sinewave table, range 0-99, 64 entries
const unsigned char sine64[64] = {
50,54,59,64,68,73,77,81,85,88,91,93,95,97,98,99,99 ,99,98,97,95,93,91,88,85,81,77,73,68,64,59,54,
50,45,40,35,31,26,22,18,14,11,8,6,4,2,1,0,0,0,1,2, 4,6,8,11,14,18,22,26,31,35,40,45 };
//================================================== ===========================
// DRAW SELECTED BUTTON
//================================================== ===========================
void draw_selected_button(unsigned char which)
{
//-------------------------------------------------------
// this draws one button black, the other 3 are white.
// it is used to change the selected button onscreen.
// if which==0 the top row of buttons is drawn
//-------------------------------------------------------
#define BLEFT 38
unsigned char butx;
if(!which) // top group of buttons
{
// clear all 4 buttons, then draw one solid
T6963C_box(BLEFT, 52, 240, 52+14, T6963C_BLACK);
if(drow == 0) butx = 42*0;
if(drow == 1) butx = 42*1;
if(drow == 2) butx = 42*2;
if(drow == 3) butx = 42*3;
if(drow >= 4) butx = 42*4;
T6963C_box(BLEFT+butx, 52, BLEFT+butx+35, 52+14, T6963C_WHITE);
}
else // bottom group of buttons
{
// clear all 4 buttons, then draw one solid
T6963C_box(BLEFT, 52+32, 240, 52+32+14, T6963C_BLACK);
if(dcol == 0) butx = 42*0;
if(dcol == 1) butx = 42*1;
if(dcol == 2) butx = 42*2;
if(dcol == 3) butx = 42*3;
if(dcol >= 4) butx = 42*4;
T6963C_box(BLEFT+butx, 52+32, BLEFT+butx+35, 52+32+14, T6963C_WHITE);
}
}
//-----------------------------------------------------------------------------
//================================================== ===========================
// MAKE DTMF TONE
//================================================== ===========================
void make_DTMF_tone(void)
{
//-------------------------------------------------------
// this generates the 2 accurate sinewaves together.
// a DDS algorithm calculation is done once every PWM cycle,
// then the 2 sinewaves are generated by the PIC PWM module.
// For a full description of algorithm;
www.RomanBlack.com/one_sec.htm#BDA
// NOTE! for good speed PWM TMR2 is manually polled, not an interrupt.
//-------------------------------------------------------
unsigned char pwm;
// loop and generate dual sinewave DTMF tone
while(1)
{
while(!PIR1.TMR2IF); // wait until PWM cycle starts (sync to PWM)
PIR1.TMR2IF = 0;
// calc the A sinewave,
waveA += BDA_periodA; // zero-error Accumulation
pwm = sine64[waveA_2 & 0x3F]; // Binary Divide output (/65536) and keep 6 bits
if(drow == 4) pwm = 0; // disable if row is OFF
// calc the B sinewave, and ADD the 2 waves together
waveB += BDA_periodB;
if(dcol != 4) pwm += sine64[waveB_2 & 0x3F]; // only enable if col is ON
// scale the summed sinewaves and place in PWM module
pwm = (pwm >> 1); // scale 0-200 back to 0-100 for PWM
pwm += 14; // offset to centre waveform (100 into centre of 128)
CCPR2L = pwm; // load added sinewaves into PWM module
// finally check for any screen buttons pressed and return
if(ADRESH > 52) return; // if touchpanel pressed
TPfast_StartRead();
}
}
//-----------------------------------------------------------------------------
//================================================== ===========================
// MAIN
//================================================== ===========================
void main()
{
//-------------------------------------------------------
// setup PIC 18F8527 for SmartGLCD pins
CMCON = 0x07; // turn off comparators (make all pins digital)
ADCON0 = 0b00000001; // ADC module on (used for touchpanel)
ADCON1 = 0b00001101; // AN0,AN1 are adc inputs, 0v-5v range
ADCON2 = 0b00110010; // ADC result left justified (0-255 range)
LATA = 0b00000000;
TRISA = 0b00000011; // RA0,RA1 analog inputs (TP)
LATC = 0b00000110; // LEDs off at start
TRISC = 0b00000000; // C1, C2 backlight LED
TRISE = 0b01111111; // RE7 is ouput for PWM
LATG = 0b00000001; // LED off at start
TRISG = 0b00000000; // G0 backlight LED
LATJ = 0b01000000; // RJ6=FS (1=font6 0=font8), RJ5=MD
TRISJ = 0b00000000; // GLCD control port
BacklightRed = 1; // control the GLCD backlight leds; 0=on, 1=off
BacklightGreen = 0;
BacklightBlue = 1;
//-------------------------------------------------------
// startup delay, let the PSU voltage stabilise etc.
Delay_ms(10);
// Initialize T6963C GLCD
//T6963C_init(240, 128, 8); // init for MikroC PRO version
T6963C_init(240, 128, 6, &PORTH, &PORTJ, 2, 1, 0, 4); // init for MikroC version
T6963C_graphics(1); // graphics mode = on
T6963C_text(1); // text mode = on (now both are on)
T6963C_cursor(1); // cursor and blink don't seem to work?
T6963C_cursor_blink(1);
// setup PWM module
T2CON = 0b00000100; // TMR2 on, prescale 1:1
PR2 = (128-1); // PWM at period = 128
CCPR2L = 0; // start PWM = 0% by default
CCP2CON = 0b00001100; // PWM module ON, output A on PORTE.F7
// NOTE!! make sure CCP2MX is set to RE7 in the PIC config (edit project)
//-------------------------------------------------------
// draw stuff on GLCD that remains constant
// write the text that will not change
T6963C_Write_Text("SmartGLCD sinewave DTMF generator", 0, 0, T6963C_ROM_MODE_XOR);
T6963C_Write_Text("Select the 2 DTMF tones;", 1, 4, T6963C_ROM_MODE_XOR);
T6963C_Write_Text("Row; 697 770 852 941 OFF", 1, 7, T6963C_ROM_MODE_XOR);
T6963C_Write_Text("Col; 1209 1336 1477 1633 OFF", 1, 11, T6963C_ROM_MODE_XOR);
T6963C_Write_Text("x= y=", 0, 15, T6963C_ROM_MODE_XOR);
// default starting values for the DTMF row and col
drow = 0;
BDA_periodA = Frow0;
dcol = 0;
BDA_periodB = Fcol0;
draw_selected_button(0); // draw both rows of buttons
draw_selected_button(1);
//-------------------------------------------------------
// main running loop
while(1)
{
//-----------------------------------------
Delay_mS(30);
// get TouchPanel X value
TPfast_SetX();
Delay_uS(500);
TPfast_StartRead(); // start TP adc conversion
tp_x = TPfast_Read();
// get TouchPanel Y value
TPfast_SetY();
Delay_uS(500);
TPfast_StartRead(); // start TP adc conversion
tp_y = TPfast_Read();
// (optional) format and display TP X and Y values to screen
ByteToStr(tp_x,text);
T6963C_Write_Text(text, 2, 15, T6963C_ROM_MODE_XOR);
ByteToStr(tp_y,text);
T6963C_Write_Text(text, 2+8, 15, T6963C_ROM_MODE_XOR);
//-----------------------------------------
// check for any buttons pressed and show selected button
// and change the selected DTMF tone.
if(tp_y > 115 && tp_y < 155) // if top group of buttons pressed
{
if(tp_x > 39) drow = 0, BDA_periodA = Frow0;
if(tp_x > 85) drow = 1, BDA_periodA = Frow1;
if(tp_x > 125) drow = 2, BDA_periodA = Frow2;
if(tp_x > 167) drow = 3, BDA_periodA = Frow3;
if(tp_x > 210) drow = 4, BDA_periodA = Frow3;
draw_selected_button(0); // redraw top group
}
if(tp_y > 52 && tp_y < 94) // if bottom group of buttons pressed
{
if(tp_x > 39) dcol = 0, BDA_periodB = Fcol0;
if(tp_x > 85) dcol = 1, BDA_periodB = Fcol1;
if(tp_x > 125) dcol = 2, BDA_periodB = Fcol2;
if(tp_x > 167) dcol = 3, BDA_periodB = Fcol3;
if(tp_x > 210) dcol = 4, BDA_periodB = Fcol3;
draw_selected_button(1); // redraw bottom group
}
// wait for screen to be NOT touched
while(1)
{
TPfast_StartRead(); // start TP adc conversion
tp_y = TPfast_Read();
if(tp_y < 30) break; // break if not touched
}
// now go and loop and make the tone, until screen pressed again
make_DTMF_tone();
}
}
//-----------------------------------------------------------------------------