In this project, LCD is used to display the frequency and PIC timer 1 to measure the input signal and Timer0 to generate an indication that one second has gone.
System software utilizes Timer-1 in the 16-bit counter mode to count the input signal and overflows of the counter are added to provide the aggregate count in multiples of 65536. Totaling the existing value of the counter at the conclusion provides the full count.
To get the events per second we need another timer which conveys the system that one second has elapsed. Timer0 is used for this service. Since the main clock is running at 10MHz then the processor clock (Fosc/4) is 2.5MHz which is the rate at which Timer0 operates using an internal clock.
we will use interrupts of both timers to accomplish our system software. Timer0 interrupts will indicate that one second has passed and at this point, we will accumulate the values of Timer1 which will be our events per seconds. The timer1 interrupt will increment our multiplier for each overflow of Timer1, keep in mind Timer1 is configured as a 16 bit counter.
From the above argument, we can realize that the part of interrupts in this project is very critical.
so first we will devote some time to understand the concept of interrupts and specifically interrupts of PIC18f4580 for Timer0 and Timer1.
Interrupts vs. polling
A single microcontroller is capable to serve many devices
by using two ways :interrupts or polling.
In the interrupt methodology, whenever any device desires the
microcontroller's service, the device notifies it by delivering a digital signal,
upon receiving interrupt signal, the microcontroller stops all routines
except ISR (interrupt service routine). The program related to the
interrupt is termed the (ISR)or interrupt handler.
In polling, the microcontroller unceasingly monitors
the logical condition of a given device; once the required condition
is met, it performs the service.
After that, it moves on to observe successive device till all is entertained.
Although polling will monitor the logical condition of many devices
and serve every of them as logical condition are true, it is not an effective
way to use controller .
The advantage of interrupts is that the microcontroller will serve several devices
(not all at an equivalent time, of course); every device will get the
eye of the microcontroller supported the priority assigned to
that.
The most vital reason that the interrupt methodology is preferred is
that the polling methodology wastes a lot of the
microcontroller's time by polling devices that don't want service.
for instance, in our last post associated with timers and
counters polling method was utilized:
while (INTCON.TMR0IF==0)
See
Previous Posts and simulations
Here while loop waited till the timer rolled over, we couldn't do anything
that's a waste of time . In contrast, if we tend to use
the interrupt methodology, the microcontroller will perform alternative tasks,
and once the TMR0IF flag is raised, the timer can interrupt
the microcontroller in no matter it's doing.
Interrupt service routine
For every interrupt, microcontroller needs a piece of code which is
known as ISR, whenever interrupt raised microcontroller executes ISR.
Generally, in most microprocessors, for each interrupt there's a hard
and fast location in memory that holds the address of it's ISR. The cluster of
memory locations put aside to carry the addresses of ISRs is termed the
interrupt vector table.
Upon initiation of an interrupt, the microcontroller goes through the
subsequent steps:
1. It finishes the instruction defined in ISR and saves the address of
succeeding instruction (program counter) on the stack.
2. It jumps to defined location in memory known as the interrupt
vector table. The interrupt vector table is designed
to hold addresses so it directs
the microcontroller to the address of the interrupt service routine (ISR).
3. The microcontroller gets the address of the ISR from the
interrupt vector table and jumps to that. It starts to execute the interrupt
service routine till it reaches the last instruction of the routine.
4. Upon accomplishing the instruction, the microcontroller
returns to the place wherever it had been interrupted. First, it gets the
program counter (PC) address from the stack by removing the highest bytes of
the stack into the Program counter register, Then execute code from that address.
To avail the interrupts, we have to take the later steps:
1. Bit 07 (GIE) of the INTCON register should be set to HIGH to
permit the interrupts to happen.
INTCON.GIE = 1;
//instruction will allow user to avail all available interrupts
2. If GIE = 1, every interrupt is permitted by setting to HIGH
the interrupt enable
(IE) flag bit for that interrupt. In microcontroller we have multiple
interrupts for different peripherals like for serial communication (UART),
analog to digital converter(ADC) and etc. In case of timer, we need to enable
Timer0(TMR0IE). It should be noted that if GIE = zero, no interrupt are going
to be active, although the corresponding interrupt bit is high.
NTCON.TMR0IE=1; //enable Timer 0 interrupt
3. PEIE also need to configure as logic high to avail Timer1
PIE1.TMR1IE = 1;//enable Timer1 interrupt
Rollover timer flag and interrupt
The timer flag is HIGH when the timer rolls over. In previous posts, we showed how to monitor the timer flag with the instruction
while (INTCON.TMR0IF==0); In polling TMR0IF, we have to wait until TMR0IF is raised.
we have already discussed the method that keep controller busy is not an efficient way, to resolve this issue and to optimize our code we utilize interrupt .
If the timer interrupt in the interrupt register is enabled, TMR0IF is raised whenever the timer rolls over and the microcontroller jumps to the interrupt vector table to service the ISR.
By using interrupt methodology microcontroller is free to perform other tasks until it is notified that the timer has rolled over.
In the case of Timer0, the INTCON register contains the TMR0IE bit, and PIEI (peripheral interrupt enable) holds the TMR1IE bit.
Frequency Counter Project Code using miKroC
T0CON = 0X5; see my Previous post of one second delay
TMR0H = 0x67;
TMR0L = 0x69;
T0CON.TMR0ON = 1;
T1CON=0x2 Timer1 configured as 16 bit counter with no prescaler
PIE1.TMR1IE = 1 Timer1 interrupt is enable
Line 68-81 is the start of definition main program you already know that when timer0 generates interrupt after one second we set flag, in the main prog we use this flag and when it is set we start our calculations ,we get the timer1 data from its registers and store it in tmr_1Val register then we calculate totlal count by multiply 65536( timer1 is configures 16 bit in counter mode) with addition of Timer low byte register.Since whole action is performed after one second elapsed so we got events per unit time which is frequency of events.
Frequency Counter Project Code using CSS
#include <flex_lcd.c>
int8 overnumber=1;
int16 count;
int8 datatest=126;
char Freq_txt[17];
int1 flag=0;
#INT_TIMER0
void T0_ISR(void)
{
flag=1;
disable_interrupts(INT_TIMER0);
disable_interrupts(GLOBAL);
set_timer0(0x6769);
}
#INT_TIMER1
void Tl_ISR (void)
{
set_timer1(0);
overnumber++;
}
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1|T1_EXTERNAL_SYNC);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
set_timer0(0x6769);
set_tris_c(0xff); // make porta as an input
set_timer1(0); //set count to zero
lcd_init(); // Always call this first.
lcd_gotoxy(2,1);
lcd_putc("\f Frequency = ");
delay_ms(2000);
while(1){
if (flag==1){
count = get_timer1()*overnumber; //calculate frequency
lcd_gotoxy(1,2);
printf(lcd_putc,"%Lu Hz", count);
set_timer1(0);
flag= 0;
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
}
}
}
HI i'm getting error in ( LongWordToStr(Freq,Freq_txt) ) this line.can you tell me which library file i need to choose from library manager in mickro c ,to correct this error.
ReplyDelete