Alot of compilers have demo versions that are limited by lines of code or by compiled code size.
HITech C has a good ANSI C compiler limited by chip type and hex code size.
Proton Basic has an excellent, easy to use, IDE + demo that is limited to 31 lines of code and certain processes. I would definately use Proton Basic to do something like this saying it can probably be done in less than 31 lines of code.
Microchip has a free student edition of their C18 compiler for the PIC18 series.
There are alot of other free compilers, but those are most of the popular ones. Search on google and you should be able to get download links for them quite easily.
basic code what am I missing? IF ADC is => increase PWM
Hard to believe what I was asking of you guys/gals. Two months later and 4-500 lines of code in a 16f877 and I have the program running. I had no idea it would be this involved and admire each and every one of you'all who even VENTURE into someone elses coding project knowing what's involved in completing the program. I thank you all for not telling me that I'm dreaming if I think I can program this thing! I have two ADC's, three opto isolated relays, and an LCD telling me what's happening and the ability to serial program it all for under $50 for all of the hardware. Thank you all again for your support and humility. I owe you all a debt of gratitude. Emmett
PicBasicPro to Codevision "C"
Well I'm back with a little less hair and on the verge of a cardiac arrest, no just kidding. The PIC code works well and I am happy with it but need to move everything over to Atmel. Codevision has a utility to set up the three timers but I have no clue how to code in "c". How would I begin to set up the three timers and one adc channel on this Mega48 to
1. read the adc
2. pause 30 seconds or so (I might be able to figure this part out)
3. Read the ADC again and if it is lower than the first reading then raise the frequency of all three timers 10 Hz, and if it is higher than the first reading then lower the frequency 10 Hz.
That's the basics of the program but when it comes to all of the
>><<{{}} in "C" I obviously don't know beans about it. I have bought a C programming book that don't help me much! Anyhow after all the hours invested programming the 16F877 PIC I know what I am asking and I don't expect you all to drop everything and figure this out but if there is any code samples or ? that might point me in the right direction I would so much appreciate it. Thank you'all so much! Emmett
This is the basic pic code to do what I need (without the defines and stuff).
BEGIN:
For PWMFREQ = 150 To 300 Step 10
TIMER0,DUTY,PWMFREQ
ADCIN 0, CNTRL
PAUSE 60
ADCIN 0, TST
IF TST < CNTRL THEN PWMFREQ=PWMFREQ +10
PAUSE 60
ADCIN 0, TST
if TST >= CNTRL THEN PWMFREQ=PWMFREQ -10
NEXT PWMFREQ
goto BEGIN:
end
This is the setup generated by Codevision for the three timers to put out both non-inverted and inverted outputs
Project : three pwm's six outputs
Chip type : ATmega48
Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
}
// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Place your code here
}
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
// Place your code here
}
#define ADC_VREF_TYPE 0x00
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=In
// State7=T State6=T State5=T State4=T State3=0 State2=0 State1=0 State0=T
PORTB=0x00;
DDRB=0x0E;
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=0 State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x08;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 62.500 kHz
// Mode: Fast PWM top=FFh
// OC0A output: Non-Inverted PWM
// OC0B output: Inverted PWM
TCCR0A=0xB3;
TCCR0B=0x03;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 15.625 kHz
// Mode: Fast PWM top=01FFh
// OC1A output: Non-Inv.
// OC1B output: Inverted
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xB2;
TCCR1B=0x0C;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 15.625 kHz
// Mode: Fast PWM top=OCR0A
// OC2A output: Non-Inverted PWM
// OC2B output: Inverted PWM
ASSR=0x00;
TCCR2A=0xB3;
TCCR2B=0x0E;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x01;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x01;
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x01;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;
// ADC initialization
// ADC Clock frequency: 1000.000 kHz
// ADC Voltage Reference: AREF pin
// ADC Auto Trigger Source: None
// Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
// ADC4: On, ADC5: On
DIDR0=0x00;
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x82;
// Global enable interrupts
#asm("sei")
while (1)
{
// Place your code here
};
1. read the adc
2. pause 30 seconds or so (I might be able to figure this part out)
3. Read the ADC again and if it is lower than the first reading then raise the frequency of all three timers 10 Hz, and if it is higher than the first reading then lower the frequency 10 Hz.
That's the basics of the program but when it comes to all of the
>><<{{}} in "C" I obviously don't know beans about it. I have bought a C programming book that don't help me much! Anyhow after all the hours invested programming the 16F877 PIC I know what I am asking and I don't expect you all to drop everything and figure this out but if there is any code samples or ? that might point me in the right direction I would so much appreciate it. Thank you'all so much! Emmett
This is the basic pic code to do what I need (without the defines and stuff).
BEGIN:
For PWMFREQ = 150 To 300 Step 10
TIMER0,DUTY,PWMFREQ
ADCIN 0, CNTRL
PAUSE 60
ADCIN 0, TST
IF TST < CNTRL THEN PWMFREQ=PWMFREQ +10
PAUSE 60
ADCIN 0, TST
if TST >= CNTRL THEN PWMFREQ=PWMFREQ -10
NEXT PWMFREQ
goto BEGIN:
end
This is the setup generated by Codevision for the three timers to put out both non-inverted and inverted outputs
Project : three pwm's six outputs
Chip type : ATmega48
Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
}
// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Place your code here
}
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
// Place your code here
}
#define ADC_VREF_TYPE 0x00
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=In
// State7=T State6=T State5=T State4=T State3=0 State2=0 State1=0 State0=T
PORTB=0x00;
DDRB=0x0E;
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=0 State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x08;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 62.500 kHz
// Mode: Fast PWM top=FFh
// OC0A output: Non-Inverted PWM
// OC0B output: Inverted PWM
TCCR0A=0xB3;
TCCR0B=0x03;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 15.625 kHz
// Mode: Fast PWM top=01FFh
// OC1A output: Non-Inv.
// OC1B output: Inverted
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xB2;
TCCR1B=0x0C;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 15.625 kHz
// Mode: Fast PWM top=OCR0A
// OC2A output: Non-Inverted PWM
// OC2B output: Inverted PWM
ASSR=0x00;
TCCR2A=0xB3;
TCCR2B=0x0E;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x01;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x01;
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x01;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;
// ADC initialization
// ADC Clock frequency: 1000.000 kHz
// ADC Voltage Reference: AREF pin
// ADC Auto Trigger Source: None
// Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
// ADC4: On, ADC5: On
DIDR0=0x00;
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x82;
// Global enable interrupts
#asm("sei")
while (1)
{
// Place your code here
};
To be really useful, you'll need to check your 'C' compilers library of inbuilt functions that may well do all that you want in a fashion that you're used to.cwaugs wrote: ADCIN 0, any variable name1
pause 60 seconds
ADCIN 0, any variable name2
One of the problems with autocode dooflunkies is that they can be difficult to decipher.
The first thing I'd suggest is to delete most things that appear between /* */ these are comments or commented out sections of code. Delete also // these are single line comments.
In 'C' so that the compiler knows when an end to a code line is reached you have to bung in a semicolon.
Sections of code are demarcated by the { } brackets.
Your For statement will become For (PWMFREQ = 150;PWMFREQ <= 300; PWMFREQ = PWMFREQ + 10)
{
code here will depend upon how your internal libraries work
}
You might need to do some experiments here, for example my 'C' compiler for Pics gives better ASM if I have a For statment as For (PWMFREQ = 300;PWMFREQ; PWMFREQ = PWMFREQ - 10), though in this case that might not be helpful.
I've just realised that much of what you want is already in the code you posted - I'll play about with it to make it more readable and see if that helps.
Colin
On a clear disk you can seek forever.
OK here is a slightly tidied up version.
With 'C' if you want to be able to follow it in the same way that basic starts at the top and works down to the bottom, you'll need to put function prototypes under the DOT H file, then you can put all your functions in any order underneath the MAIN one.
Colin
Project : three pwm's six outputs
Chip type : ATmega48
Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
#define ADC_VREF_TYPE 0x00
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
}
// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
}
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
}
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE; // Start the AD conversion
ADCSRA|=0x40; // Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
/* Setup initialises all ports and hardware such as ADC, PWM etc */
void setup(void)
{
/* Input/Output Ports initialization **
** Port B initialization. To make pin an input clear the bit, to make output set the bit
**
** Pins 7 6 5 4 3 2 1 0
** 0 0 0 0 1 1 1 0
********************************************************************/
PORTB=0x00;
DDRB=0x0E;
/* Port C initialization */
PORTC=0x00;
DDRC=0x00;
/* Port D initialization */
PORTD=0x00;
DDRD=0x08;
/* Timer/Counter 0 initialization **
**
** Clock source: System Clock
** Clock value: 62.500 kHz
** Mode: Fast PWM top=FFh
** OC0A output: Non-Inverted PWM
** OC0B output: Inverted PWM
******************************************************************/
TCCR0A=0xB3;
TCCR0B=0x03;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
/* Timer/Counter 1 initialization **
**
** Clock source: System Clock
** Clock value: 15.625 kHz
** Mode: Fast PWM top=01FFh
** OC1A output: Non-Inv. OC1B output: Inverted
** Noise Canceler: Off
** Input Capture on Falling Edge, Input Capture Interrupt: Off
** Timer 1 Overflow Interrupt: On
** Compare A Match Interrupt: Off , Compare B Match Interrupt: Off
***************************************************************/
TCCR1A=0xB2;
TCCR1B=0x0C;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
/* Timer/Counter 2 initialization **
**
** Clock source: System Clock
** Clock value: 15.625 kHz
** Mode: Fast PWM top=OCR0A
** OC2A output: Non-Inverted PWM , OC2B output: Inverted PWM
****************************************************************/
ASSR=0x00;
TCCR2A=0xB3;
TCCR2B=0x0E;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;
/* External Interrupt(s) initialization **
**
** INT0: Off , INT1: Off
** Interrupt on any change on pins PCINT0-7: Off
** Interrupt on any change on pins PCINT8-14: Off
** Interrupt on any change on pins PCINT16-23: Off
**************************************************************/
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;
TIMSK0=0x01; // Timer/Counter 0 Interrupt(s) initialization
TIMSK1=0x01; // Timer/Counter 1 Interrupt(s) initialization
TIMSK2=0x01; // Timer/Counter 2 Interrupt(s) initialization
/* Analog Comparator initialization **
**
** Analog Comparator: Off
** Analog Comparator Input Capture by Timer/Counter 1: Off
************************************************************/
ACSR=0x80;
ADCSRB=0x00;
** ADC initialization **
**
** ADC Clock frequency: 1000.000 kHz
** ADC Voltage Reference: AREF pin
** ADC Auto Trigger Source: None
** Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On ADC4: On, ADC5: On
***********************************************************/
DIDR0=0x00;
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x82;
// Global enable interrupts
#asm("sei")
}
void main(void)
{
setup(); // call the initialisation function
while (1)
{
// Place your code here
};
With 'C' if you want to be able to follow it in the same way that basic starts at the top and works down to the bottom, you'll need to put function prototypes under the DOT H file, then you can put all your functions in any order underneath the MAIN one.
Colin
Project : three pwm's six outputs
Chip type : ATmega48
Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
#define ADC_VREF_TYPE 0x00
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
}
// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
}
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
}
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE; // Start the AD conversion
ADCSRA|=0x40; // Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
/* Setup initialises all ports and hardware such as ADC, PWM etc */
void setup(void)
{
/* Input/Output Ports initialization **
** Port B initialization. To make pin an input clear the bit, to make output set the bit
**
** Pins 7 6 5 4 3 2 1 0
** 0 0 0 0 1 1 1 0
********************************************************************/
PORTB=0x00;
DDRB=0x0E;
/* Port C initialization */
PORTC=0x00;
DDRC=0x00;
/* Port D initialization */
PORTD=0x00;
DDRD=0x08;
/* Timer/Counter 0 initialization **
**
** Clock source: System Clock
** Clock value: 62.500 kHz
** Mode: Fast PWM top=FFh
** OC0A output: Non-Inverted PWM
** OC0B output: Inverted PWM
******************************************************************/
TCCR0A=0xB3;
TCCR0B=0x03;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
/* Timer/Counter 1 initialization **
**
** Clock source: System Clock
** Clock value: 15.625 kHz
** Mode: Fast PWM top=01FFh
** OC1A output: Non-Inv. OC1B output: Inverted
** Noise Canceler: Off
** Input Capture on Falling Edge, Input Capture Interrupt: Off
** Timer 1 Overflow Interrupt: On
** Compare A Match Interrupt: Off , Compare B Match Interrupt: Off
***************************************************************/
TCCR1A=0xB2;
TCCR1B=0x0C;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
/* Timer/Counter 2 initialization **
**
** Clock source: System Clock
** Clock value: 15.625 kHz
** Mode: Fast PWM top=OCR0A
** OC2A output: Non-Inverted PWM , OC2B output: Inverted PWM
****************************************************************/
ASSR=0x00;
TCCR2A=0xB3;
TCCR2B=0x0E;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;
/* External Interrupt(s) initialization **
**
** INT0: Off , INT1: Off
** Interrupt on any change on pins PCINT0-7: Off
** Interrupt on any change on pins PCINT8-14: Off
** Interrupt on any change on pins PCINT16-23: Off
**************************************************************/
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;
TIMSK0=0x01; // Timer/Counter 0 Interrupt(s) initialization
TIMSK1=0x01; // Timer/Counter 1 Interrupt(s) initialization
TIMSK2=0x01; // Timer/Counter 2 Interrupt(s) initialization
/* Analog Comparator initialization **
**
** Analog Comparator: Off
** Analog Comparator Input Capture by Timer/Counter 1: Off
************************************************************/
ACSR=0x80;
ADCSRB=0x00;
** ADC initialization **
**
** ADC Clock frequency: 1000.000 kHz
** ADC Voltage Reference: AREF pin
** ADC Auto Trigger Source: None
** Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On ADC4: On, ADC5: On
***********************************************************/
DIDR0=0x00;
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x82;
// Global enable interrupts
#asm("sei")
}
void main(void)
{
setup(); // call the initialisation function
while (1)
{
// Place your code here
};
On a clear disk you can seek forever.
To make the above program into a basic type flow - do the following. I've added in the call to the ADC as well in this version. For long delays you would probably use one of the Timer interrupts to delay a second and then call the ADC.
The adc stuff could either be in the interrupt after checking for the interrupt flag, or, if the rest of your program is time sensitive, you'd set a flag variable in the interrupt and check this in MAIN which would then call the adc.
Chip type : ATmega48
Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
unsigned int read_adc(unsigned char adc_input);
void setup();
#define ADC_VREF_TYPE 0x00
void main(void)
{
unsigned char ADC_var;
setup(); // call the initialisation function
while (1)
{
adc_var =read_adc(0);
delay(60seconds); //Note your compiler will have a library file for delays.
adc_var = read_adc(0);
};
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
}
// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
}
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
}
/* Setup initialises all ports and hardware such as ADC, PWM etc */
void setup(void)
{
/* Input/Output Ports initialization **
** Port B initialization. To make pin an input clear the bit, to make output set the bit
**
** Pins 7 6 5 4 3 2 1 0
** 0 0 0 0 1 1 1 0
********************************************************************/
PORTB=0x00;
DDRB=0x0E;
/* Port C initialization */
PORTC=0x00;
DDRC=0x00;
/* Port D initialization */
PORTD=0x00;
DDRD=0x08;
/* Timer/Counter 0 initialization **
**
** Clock source: System Clock
** Clock value: 62.500 kHz
** Mode: Fast PWM top=FFh
** OC0A output: Non-Inverted PWM
** OC0B output: Inverted PWM
******************************************************************/
TCCR0A=0xB3;
TCCR0B=0x03;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
/* Timer/Counter 1 initialization **
**
** Clock source: System Clock
** Clock value: 15.625 kHz
** Mode: Fast PWM top=01FFh
** OC1A output: Non-Inv. OC1B output: Inverted
** Noise Canceler: Off
** Input Capture on Falling Edge, Input Capture Interrupt: Off
** Timer 1 Overflow Interrupt: On
** Compare A Match Interrupt: Off , Compare B Match Interrupt: Off
***************************************************************/
TCCR1A=0xB2;
TCCR1B=0x0C;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
/* Timer/Counter 2 initialization **
**
** Clock source: System Clock
** Clock value: 15.625 kHz
** Mode: Fast PWM top=OCR0A
** OC2A output: Non-Inverted PWM , OC2B output: Inverted PWM
****************************************************************/
ASSR=0x00;
TCCR2A=0xB3;
TCCR2B=0x0E;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;
/* External Interrupt(s) initialization **
**
** INT0: Off , INT1: Off
** Interrupt on any change on pins PCINT0-7: Off
** Interrupt on any change on pins PCINT8-14: Off
** Interrupt on any change on pins PCINT16-23: Off
**************************************************************/
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;
TIMSK0=0x01; // Timer/Counter 0 Interrupt(s) initialization
TIMSK1=0x01; // Timer/Counter 1 Interrupt(s) initialization
TIMSK2=0x01; // Timer/Counter 2 Interrupt(s) initialization
/* Analog Comparator initialization **
**
** Analog Comparator: Off
** Analog Comparator Input Capture by Timer/Counter 1: Off
************************************************************/
ACSR=0x80;
ADCSRB=0x00;
** ADC initialization **
**
** ADC Clock frequency: 1000.000 kHz
** ADC Voltage Reference: AREF pin
** ADC Auto Trigger Source: None
** Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On ADC4: On, ADC5: On
***********************************************************/
DIDR0=0x00;
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x82;
// Global enable interrupts
#asm("sei")
}
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE; // Start the AD conversion
ADCSRA|=0x40; // Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
The adc stuff could either be in the interrupt after checking for the interrupt flag, or, if the rest of your program is time sensitive, you'd set a flag variable in the interrupt and check this in MAIN which would then call the adc.
Chip type : ATmega48
Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/
#include <mega48.h>
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
unsigned int read_adc(unsigned char adc_input);
void setup();
#define ADC_VREF_TYPE 0x00
void main(void)
{
unsigned char ADC_var;
setup(); // call the initialisation function
while (1)
{
adc_var =read_adc(0);
delay(60seconds); //Note your compiler will have a library file for delays.
adc_var = read_adc(0);
};
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
}
// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
}
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
}
/* Setup initialises all ports and hardware such as ADC, PWM etc */
void setup(void)
{
/* Input/Output Ports initialization **
** Port B initialization. To make pin an input clear the bit, to make output set the bit
**
** Pins 7 6 5 4 3 2 1 0
** 0 0 0 0 1 1 1 0
********************************************************************/
PORTB=0x00;
DDRB=0x0E;
/* Port C initialization */
PORTC=0x00;
DDRC=0x00;
/* Port D initialization */
PORTD=0x00;
DDRD=0x08;
/* Timer/Counter 0 initialization **
**
** Clock source: System Clock
** Clock value: 62.500 kHz
** Mode: Fast PWM top=FFh
** OC0A output: Non-Inverted PWM
** OC0B output: Inverted PWM
******************************************************************/
TCCR0A=0xB3;
TCCR0B=0x03;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
/* Timer/Counter 1 initialization **
**
** Clock source: System Clock
** Clock value: 15.625 kHz
** Mode: Fast PWM top=01FFh
** OC1A output: Non-Inv. OC1B output: Inverted
** Noise Canceler: Off
** Input Capture on Falling Edge, Input Capture Interrupt: Off
** Timer 1 Overflow Interrupt: On
** Compare A Match Interrupt: Off , Compare B Match Interrupt: Off
***************************************************************/
TCCR1A=0xB2;
TCCR1B=0x0C;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
/* Timer/Counter 2 initialization **
**
** Clock source: System Clock
** Clock value: 15.625 kHz
** Mode: Fast PWM top=OCR0A
** OC2A output: Non-Inverted PWM , OC2B output: Inverted PWM
****************************************************************/
ASSR=0x00;
TCCR2A=0xB3;
TCCR2B=0x0E;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;
/* External Interrupt(s) initialization **
**
** INT0: Off , INT1: Off
** Interrupt on any change on pins PCINT0-7: Off
** Interrupt on any change on pins PCINT8-14: Off
** Interrupt on any change on pins PCINT16-23: Off
**************************************************************/
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;
TIMSK0=0x01; // Timer/Counter 0 Interrupt(s) initialization
TIMSK1=0x01; // Timer/Counter 1 Interrupt(s) initialization
TIMSK2=0x01; // Timer/Counter 2 Interrupt(s) initialization
/* Analog Comparator initialization **
**
** Analog Comparator: Off
** Analog Comparator Input Capture by Timer/Counter 1: Off
************************************************************/
ACSR=0x80;
ADCSRB=0x00;
** ADC initialization **
**
** ADC Clock frequency: 1000.000 kHz
** ADC Voltage Reference: AREF pin
** ADC Auto Trigger Source: None
** Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On ADC4: On, ADC5: On
***********************************************************/
DIDR0=0x00;
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x82;
// Global enable interrupts
#asm("sei")
}
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE; // Start the AD conversion
ADCSRA|=0x40; // Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
On a clear disk you can seek forever.
A flag is a variable that you declare and then make some of its bits 1 or 0 as you choose.
So make the variable global (declare it outside the MAIN function)
unsigned char my_system_flag;
Then in whichever timer you can use for long delays.
while(!Timer_bit_flag)
{
Timer_bit_flag = 0; //The name of this will be in the hardware register file of your compiler
my_system_flag |= my_system _flag |=(1<<bit2); // set bit 2 of flag byte
}
In MAIN
void main()
{
setup;
while(1)
{
while(my_system_flag)
{
my_system_flag = my_system_flag &~(1<<bit2); //clear bit 2 of flag
adc_var = read_adc(0);
}
}
Hope that helps
Colin
So make the variable global (declare it outside the MAIN function)
unsigned char my_system_flag;
Then in whichever timer you can use for long delays.
while(!Timer_bit_flag)
{
Timer_bit_flag = 0; //The name of this will be in the hardware register file of your compiler
my_system_flag |= my_system _flag |=(1<<bit2); // set bit 2 of flag byte
}
In MAIN
void main()
{
setup;
while(1)
{
while(my_system_flag)
{
my_system_flag = my_system_flag &~(1<<bit2); //clear bit 2 of flag
adc_var = read_adc(0);
}
}
Hope that helps
Colin
On a clear disk you can seek forever.
I would do this differently in C.cwaugs wrote:Tried it, but not user freindly enough for a dumb butt like myself.
O.K. I'm thinkin' start small. In "C" what would the code be for these
three lines?
ADCIN 0, any variable name1
pause 60 seconds
ADCIN 0, any variable name2
I'm just at a loss as to all of the punctuation marks.
Thanks again Emmett
First off, I'd use a timer interrupt to create a "clock". typically, I set up a 50 uS timer interrupt rate. inside the timer ISR, I have something like this:
Code: Select all
void timer_ISR(void) {
if( tcnt1mS-- ) {
tcnt1mS = 20; // for a 50 uS clock
// put 1 mS events here
if( tcnt10mS--) { // 10 mS section
tcnt10mS = 10; // reload 10 mS counter
// put 10 mS events here (like switch debounce stuff)
if(tcnt1S--) { // 1 Second section
tcnt1S = 100; // reload seconds counter
// read ADC value, start next sample going
}
}
}
}
Now, you'll need to figure out how to select var 1 or var 2 though i would do is a little differently (move the old value to var 2 and read new value in var 1).
Who is online
Users browsing this forum: No registered users and 27 guests