Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Sine Wave of Frequency 50Hz using DAC0808

Status
Not open for further replies.

xpress_embedo

Advanced Member level 4
Joined
Jul 5, 2011
Messages
1,165
Helped
161
Reputation
396
Reaction score
191
Trophy points
1,353
Location
India
Activity points
10,573
You have given me a method to generate the variable frequency wave...

Int40HZTMR0 + 20HZVAL*(ADCVAL/1023) = NEWTMR0.

As stated by you..
It is looking logical to me but when i write program considering this method it is not working properly..

Means that.. only 40Hz Sine Wave is what i am getting no change in frequency occurs here..

Don't know what to do now;

My code implementation is as follow:

Code:
void interrupt Check_Interrupt(void)
{
	if(PIR1bits.TMR1IF == 1)
		T1_ISR();
}

const unsigned char wave[180] = {128,132,137,141,146,150,155,159,163,168,172,176,180,184,188,192,196,200,203,207,210,214,217,220,223,226,229,232,234,237,239,241,243,245,247,248,250,251,252,253,254,254,255,255,255,255,255,255,255,255,254,253,252,251,250,248,247,245,243,241,239,237,234,232,229,226,223,220,217,214,210,207,203,200,196,192,188,184,180,176,172,168,163,159,155,150,146,141,137,132,128,124,119,115,110,106,101,97,93,88,84,80,76,72,68,64,60,56,53,49,46,42,39,36,33,30,27,24,22,19,17,15,13,11,9,8,6,5,4,3,2,1,1,0,0,0,0,0,1,1,2,3,4,5,6,8,9,11,13,15,17,19,22,24,27,30,33,36,39,42,46,49,53,56,60,64,68,72,76,80,84,88,93,97,101,106,110,115,119,124};

unsigned char i=0;
unsigned int adc_data = 0x00;
unsigned int timer_value,high,low;


//This is my Main while loop 
while(1)
	{
		ADCON0bits.GO = 1; //Start Conversion
		while(ADCON0bits.GO == 1);	//Wait Here for End of COnversion
		adc_data = ADRESH & 0x00FF;
		adc_data = adc_data<<8;
		adc_data = adc_data | ADRESL;
		timer_value = 65536 - ((118 + 46 * (adc_data/1024))*5);	
	}

//My Timer ISR
void T1_ISR(void)
{
	high = (0xFF00 & timer_value);
	high = high>>8;
	low = 0x00FF & timer_value;	
	TMR1H = high;
	TMR1L = low;
	PORTD = wave[i];
	i++;
	if(i == 180)
	i=0;

	PIR1bits.TMR1IF = 0;	//Clear the Timer-1 Flag Bit	
}


Delay = 139usec + 46usec(ADC_DATA/1024)

To Calculate Timer Value we have divide Delay by 0.2usec as i am using 20Mhz Crystal
Delay/0.2
As Both are in usec we will get a number, with the help of this number we will generate the values loaded into timer

Values to be loaded in the timer is TMR1H:TMR1L = 65536 - delay/0.2

Hence the whole expression in short becomes

timer_value = 65536 - ((139 + 46 * (adc_data/1024))*5);

I had change the value 139 to 118 to get accurate sine wave of 40 Hz Frequency

timer_value = 65536 - ((118 + 46 * (adc_data/1024))*5);
Thats why i had written this expression..

Timer Values are changing properly but still i am not getting any variation of the sine wave frequency..

And I had also changed my Circuit Diagram a Little..
I had removed the Extra 10K Resistor and just using a 1K POT...

---------- Post added at 22:27 ---------- Previous post was at 22:23 ----------

Oh Sorry for that post that method works absolutely fine this time...

I had changed my code as follow:-

Here is my New Code:-
Code:
/*This is My Latest program*/
#include<htc.h>
#include<string.h>
#include<stdio.h>
#include<math.h>

#define _XTAL_FREQ 20000000
#define LCD_DATA PORTB
#define RS PORTCbits.RC0
#define RW PORTCbits.RC1
#define EN PORTCbits.RC2

void lcdcmd(unsigned char value);
void lcddata(unsigned char value);
void lcdstr(unsigned char msg[]);

void T1_ISR(void);	//ISR for Generating Delay


void interrupt Check_Interrupt(void)
{
	if(PIR1bits.TMR1IF == 1)
		T1_ISR();
}

const unsigned char msg1[] = "PIC16F877A";
const unsigned char msg2[] = "MATLAB ACADEMY";
const unsigned char wave[180] = {128,132,137,141,146,150,155,159,163,168,172,176,180,184,188,192,196,200,203,207,210,214,217,220,223,226,229,232,234,237,239,241,243,245,247,248,250,251,252,253,254,254,255,255,255,255,255,255,255,255,254,253,252,251,250,248,247,245,243,241,239,237,234,232,229,226,223,220,217,214,210,207,203,200,196,192,188,184,180,176,172,168,163,159,155,150,146,141,137,132,128,124,119,115,110,106,101,97,93,88,84,80,76,72,68,64,60,56,53,49,46,42,39,36,33,30,27,24,22,19,17,15,13,11,9,8,6,5,4,3,2,1,1,0,0,0,0,0,1,1,2,3,4,5,6,8,9,11,13,15,17,19,22,24,27,30,33,36,39,42,46,49,53,56,60,64,68,72,76,80,84,88,93,97,101,106,110,115,119,124};

unsigned char i=0;
float delay;
unsigned int adc_data = 0x00;
unsigned int timer_value,high,low;
void main()
{
	TRISAbits.TRISA0 = 1;	//Channel A0 as Input Port
	TRISB = 0x00;
	TRISC = 0x00;
	TRISD = 0x00;
	EN = 0;
	lcdcmd(0x38);
	lcdcmd(0x0E);
	lcdcmd(0x01);
	lcdcmd(0x06);
	lcdcmd(0x83);
	lcdstr(msg1);
	lcdcmd(0xC1);
	lcdstr(msg2);
	lcdcmd(0x01);
//	__delay_ms(500);
	lcdcmd(0x80);
	lcdstr("Initializing....");
	lcdcmd(0xC6);
	lcdstr("DAC.......");
	lcdcmd(0x01);
	lcdcmd(0x80);
	lcdstr("See Oscilloscope");
	T1CON = 0x01;	//Select the Timer-1
	TMR1H = 0xFD;
	TMR1L = 0x49;
	//Running ADC For the First Time Before Starting the Interrupt
	//So That we Can Acquire the Delay Value
	ADCON0 = 0x81;
//Fosc/64 is Selected
//Channel-0 is Selected
//Analog-to-Digital Converter Module is Powered Up
	ADCON1 = 0xCE;
//A/D Result Format Select Bit Right Justified
//and AN0 Channel as Analog Channel
	PIE1bits.TMR1IE = 1;
	INTCONbits.PEIE = 1;
	PIE1bits.ADIE = 0;	//Disables A/D Conversion Bit
	INTCONbits.GIE = 1;
	while(1)
	{
		ADCON0bits.GO = 1; //Start Conversion
		while(ADCON0bits.GO == 1);	//Wait Here for End of COnversion
		adc_data = ADRESH & 0x00FF;
		adc_data = adc_data<<8;
		adc_data = adc_data | ADRESL;
		//timer_value = 65536 - ((118 + 46 * (adc_data/1024))*5);	
		//The above lines creates a very big logical mistake that makes my program sucks
		
		/*high = (0xFF00 & timer_value);
		high = high>>8;
		low = 0x00FF & timer_value;		
		TMR1H = high;
		TMR1L = low;*/
		//All above logic fails, finally i came with a small effective logic here
		delay = round((105.0 - 30.0 * (adc_data/1024.0))*5.0);
		//Theoretically 30 must be replaced by 45 but 45 is producing a very large freqiency
		timer_value = 65536 - delay;
	
	}
}

//Function Definition's are available Here
void lcdcmd(unsigned char value)
{
	LCD_DATA = value;
	RS = 0;
	RW = 0;
	EN = 1;
	__delay_ms(1);
	EN = 0;
}
void lcddata(unsigned char value)
{
	LCD_DATA = value;
	RS = 1;
	RW = 0;
	EN = 1;
	__delay_ms(1);
	EN = 0;
}
void lcdstr(unsigned char msg[])
{
	unsigned int j,len;	
	len = strlen(msg);
	for(j=0;j<len;j++)
	{	
		lcddata(msg[j]);
	}
}
void T1_ISR(void)
{
	TMR1H = timer_value>>8;
	TMR1L = timer_value;
	PORTD = wave[i];
	i++;
	if(i == 180)
	i=0;

	PIR1bits.TMR1IF = 0;	//Clear the Timer-1 Flag Bit	
}


Kindly ignore my comments.....
and this code works fine for me

My main logic is as follow:-

Code:
while(1)
	{
		ADCON0bits.GO = 1; //Start Conversion
		while(ADCON0bits.GO == 1);	//Wait Here for End of COnversion
		adc_data = ADRESH & 0x00FF;
		adc_data = adc_data<<8;
		adc_data = adc_data | ADRESL;
		//timer_value = 65536 - ((118 + 46 * (adc_data/1024))*5);		
		delay = round((105.0 - 30.0 * (adc_data/1024.0))*5.0);
		//Theoretically 30 must be replaced by 45 but 45 is producing a very large freqiency
		timer_value = 65536 - delay;
	
	}


void T1_ISR(void)
{
	TMR1H = timer_value>>8;
	TMR1L = timer_value;
	PORTD = wave[i];
	i++;
	if(i == 180)
	i=0;

	PIR1bits.TMR1IF = 0;	//Clear the Timer-1 Flag Bit	
}

Thank You So Much For Helping me out during this project i am really Thankful to you

---------- Post added at 22:33 ---------- Previous post was at 22:27 ----------

Thanks For Your Help...

At Last My Frequency of Sine Wave is Varying with the POT..

I have to ask few more question to do some additional task on this project..

I have to generate a second sine wave which must synchronize with the first one in frequency domain...
Means Both must have same frequency..

But i have to use a POT to change its Phase With Respect to the first One...
Do you have any idea how to do so...

Phase Shift Must be from -90 degree to +90degree

How to change my array size.. as i am using constant array in the which is located in the rom of controller..

Thanking You


Regards
Arun Sharma
 

xpress_embedo

Advanced Member level 4
Joined
Jul 5, 2011
Messages
1,165
Helped
161
Reputation
396
Reaction score
191
Trophy points
1,353
Location
India
Activity points
10,573
Hello!! BigDog Guru

Thanks for your help... in accomplishing that project...

Now i have to extend that project...
I have to generate a sine wave of exactly same frequency as that of the first sine wave... (Which is not a big task-I had done this much Part)

and then i have to provide a POT to change the phase of the Secondary Sine Wave with Respect to the First Sine Wave...

I using a Second POT connected at RA1 pin or AN1 pin of the PIC16F877A..

But i really don't know how to use both the ADC's in my project....


I have used this section of code to make run my both adc's one at a time..

but this doesn't happens..
My second_adc is always giving me 0 value

Code:
	ADCON0 = 0x81;
//Fosc/64 is Selected
//Channel-0 is Selected
//Analog-to-Digital Converter Module is Powered Up
/*************************************************
	ADCON1 = 0xCE;	//Changing this value to 0xC4
//A/D Result Format Select Bit Right Justified
//and AN0 Channel as Analog Channel
**************************************************/

	ADCON1 = 0xC4;
/*************************************************
The Above line means that A/D Result Format Select Bit
is Right Justified and AN0, AN1 and AN3 Channels are selected
**************************************************/

	PIE1bits.TMR1IE = 1;
	INTCONbits.PEIE = 1;
	PIE1bits.ADIE = 0;	//Disables A/D Conversion Bit
	INTCONbits.GIE = 1;
	while(1)
	{
		__delay_us(20);
		ADCON0bits.GO = 1; //Start Conversion
		while(ADCON0bits.GO == 1);	//Wait Here for End of COnversion
		adc_data = ADRESH & 0x00FF;
		adc_data = adc_data<<8;
		adc_data = adc_data | ADRESL;
		//timer_value = 65536 - ((118 + 46 * (adc_data/1024))*5);	
		//The above lines creates a very big logical mistal that makes my program sucks
		
		/*high = (0xFF00 & timer_value);
		high = high>>8;
		low = 0x00FF & timer_value;		
		TMR1H = high;
		TMR1L = low;*/
		//All above logic fails, finally i came with a small effective logic here
		delay = round((105.0 - 30.0 * (adc_data/1024.0))*5.0);
		//Theoretically 30 must be replaced by 45 but 45 is producing a very large freqiency
		timer_value = 65536 - delay;
		ADCON0 = 0x80;	//A/D Feature is Powered-OFF
		/************************************************
		Time to Start Second Timer located at AN1
		**************************************************/
		__delay_us(20);
		ADCON0 = 0x89;
		ADCON0bits.GO = 1;	//Start Conversion
		while(ADCON0bits.GO == 1);	//Wait Here for the End of Conversion
		adc_phase_data = ADRESH & 0x00FF;
		adc_phase_data = adc_phase_data<<8;
		adc_phase_data = adc_phase_data | ADRESL;
		ADCON0 = 0x80;	//A/D Feature is Powered-OFF

		/*****************************************
		SWITCH BACK to First Analog Channel
		******************************************/
		ADCON0 = 0x81;
	}



Here is my Proteus Simulation Files

View attachment Project.zip

And Here is my whole code

Can you tell me what's wrong this with..
Firstly apart from varying the phase i just want to check whether my second adc is working or not
Right now its not working

My Full Code
Code:
/*This is My Latest program*/
#include<htc.h>
#include<string.h>
#include<stdio.h>
#include<math.h>

#define _XTAL_FREQ 20000000
#define LCD_DATA PORTB
#define RS PORTEbits.RE0
#define RW PORTEbits.RE1
#define EN PORTEbits.RE2

void lcdcmd(unsigned char value);
void lcddata(unsigned char value);
void lcdstr(unsigned char msg[]);

void T1_ISR(void);	//ISR for Generating Delay


void interrupt Check_Interrupt(void)
{
	if(PIR1bits.TMR1IF == 1)
		T1_ISR();
}

const unsigned char msg1[] = "PIC16F877A";
const unsigned char msg2[] = "MATLAB ACADEMY";
const unsigned char wave[180] = {128,132,137,141,146,150,155,159,163,168,172,176,180,184,188,192,196,200,203,207,210,214,217,220,223,226,229,232,234,237,239,241,243,245,247,248,250,251,252,253,254,254,255,255,255,255,255,255,255,255,254,253,252,251,250,248,247,245,243,241,239,237,234,232,229,226,223,220,217,214,210,207,203,200,196,192,188,184,180,176,172,168,163,159,155,150,146,141,137,132,128,124,119,115,110,106,101,97,93,88,84,80,76,72,68,64,60,56,53,49,46,42,39,36,33,30,27,24,22,19,17,15,13,11,9,8,6,5,4,3,2,1,1,0,0,0,0,0,1,1,2,3,4,5,6,8,9,11,13,15,17,19,22,24,27,30,33,36,39,42,46,49,53,56,60,64,68,72,76,80,84,88,93,97,101,106,110,115,119,124};

unsigned char i=0;
float delay;
unsigned int adc_data = 0x00;
unsigned int adc_phase_data = 0x00;
unsigned int timer_value;
void main()
{
	TRISAbits.TRISA0 = 1;	//Channel A0 as Input Pin
	TRISAbits.TRISA1 = 1;	//Channel A1 as Input Pin
	TRISB = 0x00;
	TRISC = 0x00;
	TRISD = 0x00;
	TRISE = 0x00;
	PORTE = 0x00;
	ADCON1 = 0xC4;		//Making PORTE as Digital-IO Pin
	
/*	g:
	//EN = 0;
	__delay_ms(1000);
	//EN = 1;
	__delay_ms(1000);
	goto g;*/
	EN = 0;
	lcdcmd(0x38);
	lcdcmd(0x0E);
	lcdcmd(0x01);
	lcdcmd(0x06);
	lcdcmd(0x83);
	lcdstr(msg1);
	lcdcmd(0xC1);
	lcdstr(msg2);
	lcdcmd(0x01);
//	__delay_ms(500);
	lcdcmd(0x80);
	lcdstr("Initializing....");
	lcdcmd(0xC6);
	lcdstr("DAC.......");
	lcdcmd(0x01);
	lcdcmd(0x80);
	lcdstr("See Oscilloscope");
	T1CON = 0x01;	//Select the Timer-1
	TMR1H = 0xFD;
	TMR1L = 0x49;
	//Running ADC For the First Time Before Starting the Interrupt
	//So That we Can Acquire the Delay Value
	ADCON0 = 0x81;
//Fosc/64 is Selected
//Channel-0 is Selected
//Analog-to-Digital Converter Module is Powered Up
/*************************************************
	ADCON1 = 0xCE;	//Changing this value to 0xC4
//A/D Result Format Select Bit Right Justified
//and AN0 Channel as Analog Channel
**************************************************/

	ADCON1 = 0xC4;
/*************************************************
The Above line means that A/D Result Format Select Bit
is Right Justified and AN0, AN1 and AN3 Channels are selected
**************************************************/

	PIE1bits.TMR1IE = 1;
	INTCONbits.PEIE = 1;
	PIE1bits.ADIE = 0;	//Disables A/D Conversion Bit
	INTCONbits.GIE = 1;
	while(1)
	{
		__delay_us(20);
		ADCON0bits.GO = 1; //Start Conversion
		while(ADCON0bits.GO == 1);	//Wait Here for End of COnversion
		adc_data = ADRESH & 0x00FF;
		adc_data = adc_data<<8;
		adc_data = adc_data | ADRESL;
		//timer_value = 65536 - ((118 + 46 * (adc_data/1024))*5);	
		//The above lines creates a very big logical mistal that makes my program sucks
		
		/*high = (0xFF00 & timer_value);
		high = high>>8;
		low = 0x00FF & timer_value;		
		TMR1H = high;
		TMR1L = low;*/
		//All above logic fails, finally i came with a small effective logic here
		delay = round((105.0 - 30.0 * (adc_data/1024.0))*5.0);
		//Theoretically 30 must be replaced by 45 but 45 is producing a very large freqiency
		timer_value = 65536 - delay;
		ADCON0 = 0x80;	//A/D Feature is Powered-OFF
		/************************************************
		Time to Start Second Timer located at AN1
		**************************************************/
		__delay_us(20);
		ADCON0 = 0x89;
		ADCON0bits.GO = 1;	//Start Conversion
		while(ADCON0bits.GO == 1);	//Wait Here for the End of Conversion
		adc_phase_data = ADRESH & 0x00FF;
		adc_phase_data = adc_phase_data<<8;
		adc_phase_data = adc_phase_data | ADRESL;
		ADCON0 = 0x80;	//A/D Feature is Powered-OFF

		/*****************************************
		SWITCH BACK to First Analog Channel
		******************************************/
		ADCON0 = 0x81;
	}
}

//Function Definition's are available Here
void lcdcmd(unsigned char value)
{
	LCD_DATA = value;
	RS = 0;
	RW = 0;
	EN = 1;
	__delay_ms(1);
	EN = 0;
}
void lcddata(unsigned char value)
{
	LCD_DATA = value;
	RS = 1;
	RW = 0;
	EN = 1;
	__delay_ms(1);
	EN = 0;
}
void lcdstr(unsigned char msg[])
{
	unsigned int j,len;	
	len = strlen(msg);
	for(j=0;j<len;j++)
	{	
		lcddata(msg[j]);
	}
}
void T1_ISR(void)
{
	TMR1H = timer_value>>8;
	TMR1L = timer_value;
	PORTD = wave[i];
	PORTC = wave[i];
	i++;
	if(i == 180)
	i=0;

	PIR1bits.TMR1IF = 0;	//Clear the Timer-1 Flag Bit	
}
 

bigdogguru

Administrator
Joined
Mar 12, 2010
Messages
9,831
Helped
2,348
Reputation
4,690
Reaction score
2,274
Trophy points
1,413
Location
Southwest, USA
Activity points
62,510
I glad you managed to get your Voltage Controlled Oscillator (VCO) to function properly.

I have to generate a second sine wave which must synchronize with the first one in frequency domain...
Means Both must have same frequency..

But i have to use a POT to change its Phase With Respect to the first One...
Do you have any idea how to do so...

Phase Shift Must be from -90 degree to +90degree

How to change my array size.. as i am using constant array in the which is located in the rom of controller..

An algorithm for the Voltage Controlled Phase Shifter is as follows:

Phase Shift Must be from -90 degree to +90degree

The above criteria represents a total phase shift of 180°. Your constant array or lookup table has 181 intervals therefore a phase shift range of 180° represents an approximate range of 90 intervals, +/- 45 intervals.

The simplest method would be to implement another DAC0808 using one of the other available PORTs of the PIC16F877A.

Setting the required timer interval to the desire common frequency of the two DAC outputs.

I am assuming 10-bit ADC values, rather than the 8-bit ADC values in my previous example.

You'll need to utilize two indices, keeping the "i" index for the original waveform, the second index "j" is used in conjunction with your original constant array and an signed char variable "offset" phase value.

Code:
offset = ((ADC Value Pot2)/512.0 - 1.0) * 45.0

Adjusting the phase shift only when i=0, start of a new cycle.

Code:
if(offset < 0)
{
   j = 181 + offset;
}
else
{
   j = offset;
}

And increment "j" as you have been "i".

How to change my array size.. as i am using constant array in the which is located in the rom of controller..

Using the method I have outlined above, there should be no need to modify your constant array/lookup table.

BigDog
 

xpress_embedo

Advanced Member level 4
Joined
Jul 5, 2011
Messages
1,165
Helped
161
Reputation
396
Reaction score
191
Trophy points
1,353
Location
India
Activity points
10,573
Thanks BigDogGuru..

I am really thankful for ur post...
I am going to implement it and report the result back to you..
 

xpress_embedo

Advanced Member level 4
Joined
Jul 5, 2011
Messages
1,165
Helped
161
Reputation
396
Reaction score
191
Trophy points
1,353
Location
India
Activity points
10,573
Hello!!! BigDogGuru..
Needs your Help again..

What ever u told me..
I integrate that with my Previous Code...
But here is a Change....

in the design..

Instead of a POT we have to use two push buttons..
One is for Up and Another for Down..

Up Button Increases the Phase Shift..
Down Button Decreases the Phase Shift..


So i have decided to use another interrupt for this purpose..
i.e whenever someone presses the button my controller gets interrupt and service that routine...

But my PIC has only Interrupt Pin and i can't change my controller...
Thats Why i had designed a circuit , so that i can process multiple interrupts using a Single Interrupt pin..
Here is the Circuit of That..

Capture.PNG

But My Problem is that,
When ever i press the push button.. my controller gets interrupted...
and is not coming out of the Interrupt or is getting interrupt always. don't know why..

I am not much more familiar with the interrupts before this project..

So don't what to do..

I am attaching my code here... pls have a look on this..

Code:
/*This is My Latest program*/
#include<htc.h>
#include<math.h>

#define _XTAL_FREQ 20000000


void T1_ISR(void);	//ISR for Generating Delay
void Phase_ISR(void);


void interrupt Check_Interrupt(void)
{
	if(PIR1bits.TMR1IF == 1)
		T1_ISR();
	if(INTCONbits.INTF == 1)
		Phase_ISR();

}

const unsigned char wave[180] = {128,132,137,141,146,150,155,159,163,168,172,176,180,184,188,192,196,200,203,207,210,214,217,220,223,226,229,232,234,237,239,241,243,245,247,248,250,251,252,253,254,254,255,255,255,255,255,255,255,255,254,253,252,251,250,248,247,245,243,241,239,237,234,232,229,226,223,220,217,214,210,207,203,200,196,192,188,184,180,176,172,168,163,159,155,150,146,141,137,132,128,124,119,115,110,106,101,97,93,88,84,80,76,72,68,64,60,56,53,49,46,42,39,36,33,30,27,24,22,19,17,15,13,11,9,8,6,5,4,3,2,1,1,0,0,0,0,0,1,1,2,3,4,5,6,8,9,11,13,15,17,19,22,24,27,30,33,36,39,42,46,49,53,56,60,64,68,72,76,80,84,88,93,97,101,106,110,115,119,124};

unsigned char i=0,j=0;
float delay;

unsigned int adc_data = 0x00;

unsigned int timer_value;
signed int offset = 0;

void main()
{
	TRISAbits.TRISA0 = 1;	//Channel A0 as Input Pin

	TRISB = 0xFF;
	TRISC = 0x00;
	TRISD = 0x00;

	T1CON = 0x01;	//Select the Timer-1
	TMR1H = 0xFD;
	TMR1L = 0x49;

	//Running ADC For the First Time Before Starting the Interrupt
	//So That we Can Acquire the Delay Value
	ADCON0 = 0x81;
//Fosc/64 is Selected
//Channel-0 is Selected
//Analog-to-Digital Converter Module is Powered Up
/*************************************************/
	ADCON1 = 0xCE;	//Changing this value to 0xC4
//A/D Result Format Select Bit Right Justified
//and AN0 Channel as Analog Channel
/***************************************************/

	PIE1bits.TMR1IE = 1;
	INTCONbits.PEIE = 1;
	PIE1bits.ADIE = 0;	//Disables A/D Conversion Bit
	INTCONbits.GIE = 1;
	while(1)
	{
		__delay_ms(25);
		ADCON0bits.GO = 1; //Start Conversion
		while(ADCON0bits.GO == 1);	//Wait Here for End of COnversion
		adc_data = ADRESH & 0x00FF;
		adc_data = adc_data<<8;
		adc_data = adc_data | ADRESL;
		//timer_value = 65536 - ((118 + 46 * (adc_data/1024))*5);	
		//The above lines creates a very big logical mistal that makes my program sucks
		

		//All above logic fails, finally i came with a small effective logic here
		delay = round((105.0 - 30.0 * (adc_data/1024.0))*5.0);
		//Theoretically 30 must be replaced by 45 but 45 is producing a very large freqiency
		timer_value = 65536 - delay;
	}
}

//Function Definition's are available Here
void T1_ISR(void)
{
	TMR1H = timer_value>>8;
	TMR1L = timer_value;
	PORTD = wave[i];
	PORTC = wave[j];
	i++;
	j++;
	if(i == 180)
	i=0;
	if(j == 180)
	j = 0;
	PIR1bits.TMR1IF = 0;	//Clear the Timer-1 Flag Bit	
}

void Phase_ISR()
{
	if(PORTBbits.RB6 == 1)
	{
		offset = offset + 1;
	}
	else
	{
		offset = offset - 1;
	}

	if(offset < 0)
	{
	   j = 180 + offset;
	}
	else
	{
   		j = offset;
	}
	INTCONbits.RBIF = 0;
}
 

bigdogguru

Administrator
Joined
Mar 12, 2010
Messages
9,831
Helped
2,348
Reputation
4,690
Reaction score
2,274
Trophy points
1,413
Location
Southwest, USA
Activity points
62,510
Instead of a POT we have to use two push buttons..
One is for Up and Another for Down..

Up Button Increases the Phase Shift..
Down Button Decreases the Phase Shift..


So i have decided to use another interrupt for this purpose..
i.e whenever someone presses the button my controller gets interrupt and service that routine...

But my PIC has only Interrupt Pin and i can't change my controller...
Thats Why i had designed a circuit , so that i can process multiple interrupts using a Single Interrupt pin..

While it is certainly possible to implement an external interrupt circuit like the one you have posted, it is not the only option.

Reference: PIC16F87XA Datasheet, Section: 4.2 PORTB and the TRISB Register, pg 44

Four of the PORTB pins, RB7:RB4, have an interrupton-
change feature. Only pins configured as inputs can
cause this interrupt to occur (i.e., any RB7:RB4 pin
configured as an output is excluded from the interrupton-
change comparison). The input pins (of RB7:RB4)
are compared with the old value latched on the last
read of PORTB. The “mismatch” outputs of RB7:RB4
are OR’ed together to generate the RB port change
interrupt with flag bit RBIF (INTCON<0>).

This interrupt can wake the device from Sleep. The
user, in the Interrupt Service Routine, can clear the
interrupt in the following manner:

a) Any read or write of PORTB. This will end the
mismatch condition.
b) Clear flag bit RBIF.

A mismatch condition will continue to set flag bit RBIF.
Reading PORTB will end the mismatch condition and
allow flag bit RBIF to be cleared.

The interrupt-on-change feature is recommended for
wake-up on key depression operation and operations
where PORTB is only used for the interrupt-on-change
feature. Polling of PORTB is not recommended while
using the interrupt-on-change feature.

This interrupt-on-mismatch feature, together with software
configurable pull-ups on these four pins, allow
easy interface to a keypad and make it possible for
wake-up on key depression. Refer to the application
note, AN552, “Implementing Wake-up on Key Stroke”
(DS00552).

RB0/INT is an external interrupt input pin and is
configured using the INTEDG bit (OPTION_REG<6>).
RB0/INT is discussed in detail in Section 14.11.1 “INT
Interrupt”.

By using the four PORTB pins, RB7:RB4, an interrupt on-change can be generated with the closure of a button or switch, thereby voiding any requirement of external interrupt circuitry.

As a side note, I would remove the 10K ohm pull up resister from the RB0 pin as I do not believe it is necessary and maybe the cause of the issue you describe.

I will post my comments concerning your current code after I've had a chance to review it.

BigDog
 

xpress_embedo

Advanced Member level 4
Joined
Jul 5, 2011
Messages
1,165
Helped
161
Reputation
396
Reaction score
191
Trophy points
1,353
Location
India
Activity points
10,573
Thanks BigDogGuru...

I had tried to implement my circuit in that way...
But has failed due to some thing known as PORTB mismatch Problem...

Could able to solve the problem occurring due to that..
and Thats why i have decided to implement it in this way...

I had removed 10k resistance and same thing happens..

Pls reply me after u review my code and circuit..
Thanks alot waiting for your reply
 

xpress_embedo

Advanced Member level 4
Joined
Jul 5, 2011
Messages
1,165
Helped
161
Reputation
396
Reaction score
191
Trophy points
1,353
Location
India
Activity points
10,573
The Problem with my code is that..
I am not able to come out of the interrupt when i am servicing the External Interrupt Service Routine...

Don't know why..

I my above code i just forget to place a line..

Code:
INTCONbits.INTE = 1;
//Enabling the External Interrupt

Despite of adding that line my code is not working...

It never comes out of the ISR
 

xpress_embedo

Advanced Member level 4
Joined
Jul 5, 2011
Messages
1,165
Helped
161
Reputation
396
Reaction score
191
Trophy points
1,353
Location
India
Activity points
10,573
Hello!!! BigDogGuru..

Actually i want to say sorry to you.. as i am always doing big mistakes in my code and stuck there for number of days..

In my code i am using RB0/INT external interrupt ..
But in my code i am using This interrupt enabling this interrupt but clearing the PORTB Change Interrupt Bit..


Code:
//I am using this in my code
INTCONbits.RBIF = 0;

//But i have to use this
INTCONbits.INTF = 0;

Right now i am testing my project...
And will report the Incidence soon
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top