xpress_embedo
Advanced Member level 4
You have given me a method to generate the variable frequency wave...
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:
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:-
Kindly ignore my comments.....
and this code works fine for me
My main logic is as follow:-
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
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