Jump to content

ra68gi

EstablishedMember
  • Content Count

    229
  • Joined

  • Last visited

Everything posted by ra68gi

  1. Hi runep, Basic stamp is very good for beginners and hobbiest not for serious professional. Now that you have a feel of the microcontrollers try the power of source boost C compiler. Its compact code resulting in much less program memory space and improved speed are some of the major advantages over B.S. Down load a free version of source boost, with which you can write code upto 2k that too on any PIC microcontroller of your choice. The source Boost ide has got a beautiful simulator, very useful for beginners to check if your code is functioning properly. If you wish you can integrate the source boost compiler with microchips mplab ide. As far as your PULSIN & PULSOUT & other commands are concerned, you can create your own macros that too at a much more compact code. The most difficult thing is to get started, but once you learn it i bet you would'nt use B.S any more. Follow this thread and it will help you get started with BoostC... pic micro programming in boostc for beginners Regards Raghunathan.
  2. I have never used extern in my programming so far. But i think you should have No problem defining the bits of a global character variable. Just remove "extern char error_flag;" in your functions. Declare the error_flag as global by writing them outside the functions. char error_flag; #define BCD_fail error_flag.0 Pls let me know if your program is working properly & if the flag bits work as expected. Regards, Raghunathan.
  3. There seems to be a lot of people wanting to use PWM module to control their servos. I think i should make a project and post it on my thread. Regards, Raghunathan.
  4. You definitely can call it PWM signal. A PWM signal has a period value and a duty cycle value. In the case of servo the period is 20ms and to generate this period you need to load the PR2 register with the appropriate value given by the formula in the data sheet [(PR2)+1]*4*Tosc*(TMR2 prescaler value). Similarly the duty cycle for the servo can vary from 1ms to 2ms & this value is calculated as a 10 bit value from the formula (CCPR1L:CCP1CON<5:4>)*Tosc*(TMR2 prescaler). You will see that the percentage of ON time & OFF time is controlled or changed by changing the dutycycle value but the period( frequency )remains the same. You can also see that to generate signal with 20ms period you need to use crystal freq less then 1Mhz, so i have used an RC oscillator( of less then 1mhz) to generate signal at this period. Raghunathan.
  5. Yes, As cac says, servo motors can't be used for precise angle measurements. You can use stepper motors for such applications. You can experiment with your servo by varying the pulse width from 1ms -2ms and verifying the postion/ angle. repeat the experiment several times to see if your servo behaves the same always. If its consistent and satisfies your purpose, use it. Stepper motors have higher torque and a very precise angular movement. The only draw back being the complex drive circuitry. Servos has no such problems. regards Raghunathan.
  6. robomaker, This subject has been discussed in an earlier threadservo motor control Here i have given examples using the delay commands of compiler. If you still wish to generate your pulses using PWM module, you can't use a crystal larger then 1.25mhz to generate 50 hz pulses. I have a sightly different program which generates 100hz pwm for inverter application, but you can modify it for 50 hz. you can change the duty cycle value for the various sero positions. PWM generation for low frequency regards Raghunathan.
  7. I understand that you are using int0 or interrupt on RB0(INTE) to read the pulse, but where is the option register config bits? YOU need to set the edge trigger bit INTEDG of option register (rising edge or falling edge). Regards. Raghunathan
  8. Measuring the number of pulses for 1sec(RPS) & then multiplying with 60 to get RPM will result in a lot of error especially when the RPM of the motor gets low, say 300 RPM. Let's say we get 50 RPS on one occasion & 51 RPS in the next then your RPM meter will jump from 300RPM to 360 RPM which is unacceptable. To get a precise RPM reading you need to determine the time between two pulses. Once you have this time t, frecuency can be calculated using f=1/t. If this results in floating point calculation then make it 1000000/t or try using the fp library available as down load. You can use tmr0 in counter mode to count pulses and tmr1 in timer mode to time the interval between pulses. Regards Raghunathan.
  9. Hi guys, Some more progress in the inverter project. I have included the adc module, adc is performed on the battery supply, the adc value is checked for low battery, annunciation is done by switching portb pins. If the the battery voltage gets too low, the inverter is switched off & a trip flag is set, which gets cleared only on resetting the micro. adc is also done on inverter feed back voltage. The initial (minimum) pulse width is made 3ms. As the inverter feed back voltage drops( due to loading or drop in battery voltage) the adc value will also drop. The difference in the drop between NO-load (255 -adc) and with load (x-adc) is the error feed back, which we multiply by 44/10( determined from the 10 bit duty cycle formula). This error is added to 188( which is the duty_cycle value for 3ms). The duty_cycle is controlled in the range of 3ms to 9ms, giving a dead band of about 1ms, which is safe for the mosfets commutation. Some more test need to be performed. #include <system.h> // Set clock frequency to 1MHz. #pragma CLOCK_FREQ 1000000 //set configuration fuse. #pragma DATA _CONFIG, _RC_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF int duty_cycle; //global variable unsigned char adc; /*Interrupt service routine (ISR).On timer2 interrupt, program will jump to this code location. */ void interrupt( void ) { char pulse; /*generate two 50hz 180 degree out of phase pulses & externally AND it with the 100Hz pwm pin to get a modulated 50Hz to drive mosfets connected to a transformer in a push-pull configuration. A/D conversion of the the output voltage can act as feed back to adjust the duty-cycle ( not yet implemented in this code). */ pulse = portb; pulse.0 = ~ pulse.0; pulse.1 = ~ pulse.1; portb = pulse; pir1.1=0; //clear TMR2 to pr2 match interrupt flag } void load_duty_cycle(void) { ccpr1l.7 = duty_cycle.9; ccpr1l.6 = duty_cycle.8; ccpr1l.5 = duty_cycle.7; ccpr1l.4 = duty_cycle.6; ccpr1l.3 = duty_cycle.5; ccpr1l.2 = duty_cycle.4; ccpr1l.1 = duty_cycle.3; ccpr1l.0 = duty_cycle.2; ccp1con.5 = duty_cycle.1; ccp1con.4 = duty_cycle.0; } void a_d(void) //adc routine. { adc=0; adcon0.2=1; //start ad conversion. while(adcon0.2==1) //check if conversion is complete. { } adc=adres; //if conversion is over, load adc value. } // The main code configures the pwm registers void main() { trisa = 255; trisb = 0; //configure port B as output trisc = 0; // portc as out put portb = 1; //set port B to 1 portc = 0; //clear portc /* make RA0,RA1,RA2 pins as analog inputs & RA3 as +ref.*/ adcon1=1; /*choose Fosc/2,RA0/AN0 as channel(0),go/done=0,adon=1.*/ adcon0=0b00000001; //we use Fosc/2 bec' we have chosen 1Mhz clk. // enable interrupts intcon.6=1; //enable peripheral interrupt intcon.7=1; //enable global interrupt pie1.1=1; //tmr2 to pr2 match interrupt //configure the ccp1con register to enable PWM module. /*ccpxm3:ccpxm0: mode select bits<3:0> 11xx = for PWM mode. */ ccp1con=0b00001100; // //PWM period=[(PR2)+1]*4*Tosc*(TMR2 prescaler value) /*our pmw period is 10ms(100Hz),Tosc is 1/1000,000Hz & prescaler is 16.For which PR2+1 works out to 156.25. Lets round it to 156 & make PR2 to 155. */ //load the period value into pr2 register. pr2 = 155; /*timer2 control register we have selected bit6-3...(0000) 1:1 for post scaler bit2.....(1) timer2 on bit1-0...(11) prescaler is 16 */ t2con = 0b00000111; /*PWM duty cycle = (ccpr1l:ccp1con<5:4>)*Tosc*(TMR2 prescaler value) Here i have taken 2ms as an example value for duty cycle, Tosc & pre- scaler are same as above.We will get 10 bit values when we work with larger duty cycle but for our example we get the value as 125. */ //load the duty cycle values duty_cycle = 188; load_duty_cycle(); unsigned int sample; //sample var holds the adc sample value. unsigned char b0; //for loop var. unsigned char battery_adc; unsigned char inverter_adc; unsigned char error_adc; bit low_bat_flag; bit low_bat_trip_flag; while( 1 ) { adcon0=0b00000001; //choose channel 0 check_battery: sample=0; //initialize the sample to zero. for(b0=0;b0<10;b0++) //take 10 adc samples. { a_d(); //call function a_d(). sample += adc; } battery_adc=sample/10; //take average of 10 samples. if((battery_adc<202)&&(low_bat_flag == 0)) { portb.3=1; low_bat_flag=1; } else if((battery_adc>219)&&(low_bat_flag == 1)) { portb.3=0; low_bat_flag=0; } if((battery_adc<192)&&(low_bat_trip_flag == 0)) { portb.2=1; //shut down the mosfets/inverter low_bat_trip_flag=1; } while(low_bat_trip_flag == 1); //do nothing until reset. check_inverter: adcon0=0b00001001; //choose channel 1(RA1) sample=0; //initialize the sample to zero. for(b0=0;b0<10;b0++) //take 10 adc samples. { a_d(); //call function a_d(). sample += adc; } inverter_adc=sample/10; //take average of 10 samples. if(inverter_adc < 255) { error_adc = 255 - inverter_adc; //error feed back value duty_cycle = (error_adc*44)/10 + 188; load_duty_cycle(); //load the new duty cycle value } } } Any suggestion is appreciated. Regards Raghunathan
  10. Now you raise the bar to what he wants: The only issue left is do you believe that the code does what he described? You should be able to figure this one out yourself. I am happy to accept any conclusion you honestly arrive at. <{POST_SNAPBACK}> O.K cac, I will keep my word. Send me your contact thro' a personal mail. I will not promise any time frame. But cash definitely will reach you. Regards, Raghunathan.
  11. hmmm, Where are you? you are the only one who can save me from losing a $100. Is this what you want? Raghunathan.
  12. Only after testing it fully will i post it. When i post my project i definitely will warn them of dangerous voltages and precaution they need to take. Regards Raghunathan.
  13. Programming is not difficult. You write your code and post it, we will help you debug it. This forum is a very friendly one & iam sure there will be many people to help you. If you are a beginner in programming then see this thread.."pic micro programming in boostc for beginners". Its got examples on using PIC's adc. Regards Raghunathan.
  14. manasir, You have asked to many questions at one go. But let me try answering it one by one. I have a scheme for IR object detection. See if its useful. If you feel you need to use your IR receiver which gives analog output then you need to use the adc. 1. What IR transmitter_receiver are you using? I guess 38 khz must be the carrier frequency for IR communication. This carrier frequency has to be modulated with data signal. I have used a simple 555 timer ic to generate the 38Khz for Driving an IR LED( you should get an IR LED that has max sensitivity in this freq range, others may work but the detection range may vary). Next you need a IR receiver. I had used TSOP1738 IR receiver. This receiver from Vishay electronics is sensitive only to 38khz IR signal. It has three pins, two for supply and the third pin(output pin) is connected to the micro. If it receives a IR signal the output pin goes high & you should read it with your micro. TX: Generally the IR led is also fired from the micro. How is this done? The 38khz output from the 555 is connected to the anode of the IR LED, the catode of the LED is connected to the collector of a transistor say BC547(NPN) via a 47 ohms resistor. The emitter of the transistor is connected to ground. The base of the transistor is driven from the i/o port pin of the micro via 1k resistor. You can not send a data (say high or 1) continiously. TSOP will consider it as noise and reject it. So you need to switch ON the transmitter only for a Brief duration (how brief? Say less then 200ms for worst case but 1 ms is good enough).See data sheet of TSOP to determine the max data stream length. This is how you detect the object: Switch on the IR led, immediately start reading the the TSOP for reflected signal and then switch off the IR LED. If you read a 1 you have detected an object else no object detected. If you are using analog signal as your receiver. 2. Don't confuse yourself with the microcontrollers crystal frequency(20mhz your using) and the IR carrier frequency(38khz). For the adc you need to be concerned only with the crystal freq of the microcontroller. Read the micro chips data sheet for more information on a to d converter. Regards Raghunathan.
  15. I need $50.00.Which will get what they need sooner? <{POST_SNAPBACK}> cac001, I will give you $100.00 if you write a code from what he has described. Raghunathan.
  16. Hi guys, Its working! I forgot to configure the ccp1con register to PWM mode. The modified code is written below. The ccp module is a superb hardware function with which we can obtain true multi tasking feature or call it parallel processing. With built-in adc & PWM modules one can construct wonderful automatic feed back control systems. This project is a design of an inverter which will convert 12v dc to 230v, 50Hz ac using iron core transformer similar to the APC UPS( uninterrupted power supply) that powers the computers. Now i have successfully produced the 50Hz 180 degree out of phase pulses on portb.0 & portb.1 in the interrupt service routine. We will then AND the 50Hz pulses with the 100hz PWM pulse generated on pin RC2(pwm pin). The ANDing is done externally using simple transistor circuits to keep cost low. The ANDed output will drive the mosfet connected to a iron core tx in a push pull configuration. By sensing the voltage from the tx & using the built-in adc of the PIC we can cange the duty cycle value to give a constant voltage at the output of the tx. This is in a nut shell. But there is more to it, like checking battery voltage short circuit protection, annunciations etc. This product is nothing new, but will be a wonderful project for my thread "pic micro programming in Boostc for begginners". One more thing with regards to the clock. To genrate a PWM for 100Hz you need to use oscillators less then 1.5Mhz. I have used an RC oscillator & the R value is around 10K & the capacitor value is 68pf. This value generates around 1MHz. For our project RC will do the job( the cost of 1Mhz crystal is 4 times the cost of the micro in my place). #include <system.h> // Set clock frequency to 1MHz. #pragma CLOCK_FREQ 1000000 //set configuration fuse. #pragma DATA _CONFIG, _RC_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF /*Interrupt service routine (ISR).On timer2 interrupt, program will jump to this code location. */ void interrupt( void ) { char pulse; /*generate two 50hz 180 degree out of phase pulses & externally AND it with the 100Hz pwm pin to get a modulated 50Hz to drive mosfets connected to a transformer in a push-pull configuration. A/D conversion of the the output voltage can act as feed back to adjust the duty-cycle ( not yet implemented in this code). */ pulse = portb; pulse.0 = ~ pulse.0; pulse.1 = ~ pulse.1; portb = pulse; pir1.1=0; //clear TMR2 to pr2 match interrupt flag } // The main code configures the pwm registers void main() { trisa = 255; trisb = 0; //configure port B as output trisc = 0; // portc as out put portb = 1; //set port B to 1 portc = 0; //clear portc // enable interrupts intcon.6=1; //enable peripheral interrupt intcon.7=1; //enable global interrupt pie1.1=1; //tmr2 to pr2 match interrupt //configure the ccp1con register to enable PWM module. /*ccpxm3:ccpxm0: mode select bits<3:0> 11xx = for PWM mode. */ ccp1con=0b00001100; //pwm mode //PWM period=[(PR2)+1]*4*Tosc*(TMR2 prescaler value) /*our pmw period is 10ms(100Hz),Tosc is 1/1000,000Hz & prescaler is 16.For which PR2+1 works out to 156.25. Lets round it to 156 & make PR2 to 155. */ //load the period value into pr2 register. pr2 = 155; /*PWM duty cycle = (ccpr1l:ccp1con<5:4>)*Tosc*(TMR2 prescaler value) Here i have taken 2ms as an example value for duty cycle, Tosc & pre- scaler are same as above.We will get 10 bit values when we work with larger duty cycle but for our example we get the value as 125. */ //load the duty cycle value int duty_cycle; duty_cycle = 125; //duty cycle is for 2ms ccpr1l.7 = duty_cycle.9; ccpr1l.6 = duty_cycle.8; ccpr1l.5 = duty_cycle.7; ccpr1l.4 = duty_cycle.6; ccpr1l.3 = duty_cycle.5; ccpr1l.2 = duty_cycle.4; ccpr1l.1 = duty_cycle.3; ccpr1l.0 = duty_cycle.2; ccp1con.5 = duty_cycle.1; ccp1con.4 = duty_cycle.0; /*timer2 control register we have selected bit6-3...(0000) 1:1 for post scaler bit2.....(1) timer2 on bit1-0...(11) prescaler is 16 */ t2con = 0b00000111; while( 1 ); //do nothing & wait for tmr2 interrupt. } Regards Raghunathan.
  17. Hi guys, Is it possible to view or see the state of pwm pin( RC2) on the source boost simulator? I have a sample code written for PIC16F72 at 1Mhz. When i built the code i didn't see the the change on the simulator. Have i missed any thing in the code? #include <system.h> // Set clock frequency to 1MHz. #pragma CLOCK_FREQ 1000000 //set configuration fuse. #pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF /*Interrupt service routine (ISR).On timer2 interrupt, program will jump to this code location. */ void interrupt( void ) { char pulse; /*generate two 50hz 180 degree out of phase pulses & externally AND it with the 100Hz pwm pin to get a modulated 50Hz to drive mosfets connected to a transformer in a push-pull configuration. A/D conversion of the the output voltage can act as feed back to adjust the duty-cycle ( not yet implemented in this code). */ pulse = portb; pulse.0 = ~ pulse.0; pulse.1 = ~ pulse.1; portb = pulse; pir1.1=0; //clear TMR2 to pr2 match interrupt flag } // The main code configures the pwm registers void main() { trisa = 255; trisb = 0; //configure port B as output trisc = 0; // portc as out put portb = 1; //set port B to 1 portc = 0; //clear portc // enable interrupts intcon.6=1; //enable peripheral interrupt intcon.7=1; //enable global interrupt pie1.1=1; //tmr2 to pr2 match interrupt //PWM period=[(PR2)+1]*4*Tosc*(TMR2 prescaler value) /*our pmw period is 10ms(100Hz),Tosc is 1/1000,000Hz & prescaler is 16.For which PR2+1 works out to 156.25. Lets round it to 156 & make PR2 to 155. */ //load the period value into pr2 register. pr2 = 155; /*PWM duty cycle = (ccpr1l:ccp1con<5:4>)*Tosc*(TMR2 prescaler value) Here i have taken 2ms as an example value for duty cycle, Tosc & pre- scaler are same as above.We will get 10 bit values when we work with larger duty cycle but for our example we get the value as 125. */ //load the duty cycle value int duty_cycle; duty_cycle = 125; //duty cycle is for 2ms ccpr1l.7 = duty_cycle.9; ccpr1l.6 = duty_cycle.8; ccpr1l.5 = duty_cycle.7; ccpr1l.4 = duty_cycle.6; ccpr1l.3 = duty_cycle.5; ccpr1l.2 = duty_cycle.4; ccpr1l.1 = duty_cycle.3; ccpr1l.0 = duty_cycle.2; ccp1con.5 = duty_cycle.1; ccp1con.4 = duty_cycle.0; /*timer2 control register we have selected bit6-3...(0000) 1:1 for post scaler bit2.....(1) timer2 on bit1-0...(11) prescaler is 16 */ t2con = 0b00000111; while( 1 ); //do nothing & wait for tmr2 interrupt. } Raghunathan.
  18. Sorry Elvis75, My code is for PIC16f series of micro & not 18f. I have not used the 18 series, so can't help. Please look into the microchip data sheet & set the bits associated with INT2. Looks like int2 works on RB2 which is also an anolog input. So make sure to configure it to digital mode before you use it. On seeing the data sheet this is what i found. The registers and bits associated with int2 are.. 1. rcon- & the bit rcon.7 has to be cleared 2. intcon- & the bit(gie) intcon.7 has to be set. 3. intcon2- & the bit(intedg2) intcon2.4 ( make your choice for edge) 4. intcon3- & the bit(int2ie) intcon3.4 has to be set to enable interrupt. 5. intcon3-& the bit(int2if) intcon3.1 is a flag that you need to clear in the ISR. Hope this helps. Raghunathan.
  19. Elvis75, As far as i know we have got external interrupt on only one pin ie. RB0/INT pin & its edge triggered( either rising edge or falling edge decided by option_reg.6. This interrupt can be enabled by setting the INTE bit(intcon.4).The associated interrupt flag for this is INTF or intcon.1, which should be cleared in the interrupt service routine before re-enabling the interrupt. Next we have got portb input change interrupt. This can happen only on portb pins 7,6,5, & 4. So a change in state of RB2 will not cause an interrupt to occur. To use this interrupt you need to enable it by setting bit RBIE(intcon.3) Lets use this for your example.. code.. void interrupt (void) { portb.1=~portb.1; //toggle led // wait for some time to see led before we get another interrupt delay_ms(250); intcon.0=0; //clear the flag to receive the next interrupt } void main () { trisb = 0b11111101; // only RB1 is made output to light the led. //connect a switch to any portb pins <7:4> intcon.7=1; //enable global interrupt intcon.3=1; //enable RB port change interrupt while(1); //wait until a key is pressed for an interrupt } If you wish, you can make just one of the 4 portb pins(<7:4>) as input( in which you connect your switch) & the rest can be made as output pin by changing the trisb value. Raghunathan.
  20. Instead of using macros why don't you try direct bit access. Its much more easy and universal. You can use it on any compiler. say you want to set RB port change interrupt enable bit (RBIE), simply write.. intcon.3 = 1; say you want to clear the RB port change interrupt flag bit in your ISR then.. intcon.0 = 0; will do the job. you want to enable the global interrupt enable.. intcon.7 = 1; You dont need to use the tmr0 interrupt flag in your code if you are generating an interrupt only by a switch ( or change in portb state).
  21. /* timer0_interrupt.c In this project we make the timer0 of the PIC microcontroller to measure a time interval of 250 micro seconds.The timer0(tmr0) is made to generate an interrupt every 250us.We then count 4000 of such interrupts to get a precise 1 second interval. We change the state of an LED once we finish counting 4000. So the LED will be lit for a duration of 1sec & off for the next 1sec & it keeps switching on & off. The idea behind this project is to help you understand as to how the tmr0 can be set to generate an accurate 1sec interval.This code will turn out to be the building block of our next project a digital clock, which will display hours,minutes & seconds. What's an interrupt? Anything that interrupts our normal course of activity (or program) can be considered an interrupt.Suppose we are doing our normal house hold activity of cleaning our house & all of a sudden we hear the calling bell ringing, you can then consider the ringing of the bell as an interrupt. What do we do? We immediately stop the current activity of cleaning & attend to the person who rang the calling bell. In a similar fashion the main program in the microcontroller gets interrupted by what we call hardware interrupts. Note,here the word main in the main program is not suggestive of the importance of the program. Hardware interrupts will cause the microcontroller to halt the execution of the current code & jump to a location in the program memory where the more important task or program also called interrupt service routine (ISR) is stored.After executing the ISR it gets back to the main program from where it had abruptly left. When an interrupt occurs the first thing the microcontroller does before it jumps to the ISR is to save the contents of the files.ie. the status register, w register,port setting etc so that when it returns back from the ISR it can restore these settings & carry on with its actvity from the setting in which it had left. Interrupt sources on PIC16F84 1.External interrupt RB0/INT pin. 2.TMR0 overflow interrupt. 3.PORTB change interrupts(pins RB7:RB4) 4.Data EEPROM write complete interrupt See the microcontroller data sheet for more information on interrupts. In our project we will be using the tmr0 interrupt. Now i will show you how to set the tmr0 interrupt. The timer0 module. The timer0 module timer/counter has the following fearutes: 1.8-bit timer/counter 2.Readable & writable 3.Internal or external clock select 4.Edge select for external clock 5.8-bit software programmable prescaler 6.Interrupt-on-overflow from 255 to 0 First we need to know the various registers associated with tmr0. They are.. 1.tmr0 module register This register is a counter that can display values 0 to 255 so its a 8bit counter.If the prescaler assignment bit(in the option register) is set to 1 & t0cs( tmr0 clock source select bit) bit in the option register is set to 0 then tmr0 counter value increments itself every instruction cycle. 2.option register(option_reg)(address 0x81) note:In the older chips, data sheet call them option_reg, but in the new ones they call it just option.The SB compiler recognizes only option_reg. The names of these register can be seen from the .h files in the include folder,which in itself are in the SB folder. In this project we are only concerned with the t0cs(tmr0 clock source select bit) & the psa(prescaler assignment bit) of the option_reg. bit5....t0cs: tmr0 clock source select bit 1 = transition on RA4/TOCKI pin 0 = internal instruction cycle clock.(we will use this mode for our proj- ect, so make option_reg.5=0) bit3....psa: prescaler assignment bit 1 = prescaler assigned to WDT. ( we use this mode for our project) 0 = prescaler assigned to tmr0 module so we make option_reg.3=1 bit2-0....ps2:ps0: prescaler rate select bits I have made all three bits as 0 & have chosen 1:1 for the WDT. This setting is not going to be important to us since we have disabled the WDT through our pragma directive(configuration word). To learn more about prescaler see data sheet. Now our option_reg is configured to the value.. option_reg = 0b00001000; //or option_reg=8; 3.intcon register(interrupt controller register)(address 0x0b)(its also mirrored onto all other banks of the chip). Here we are only concerned with three control bits they are.. bit7....gie: global interrupt enable bit 1 = enable all unmasked interrupts.(we choose this bit to enable interrupt) 0 = disable all interrupts. bit5....toie: tmr0 overflow interrupt enable bit. bit2....t0if: tmr0 overflow interrupt flag bit. 1 = tmr0 register has overflowed.(we clear this flag in the ISR so that we can enable the next interrupt) 0 = tmr0 has not overflowed. Circuit connection: Device PIC16F84 pin4- MCLR pin to +5v via 4.7K resistor pin15-16 4mhz crystal(across pin 15 & 16) connect 22pf capacitors( between pin15 & gnd, pin16 & gnd) pin6-RB0-connect LED to pin6 via 470 ohms. Cathode of LED to gnd. Buid this program & step thro' the code using the source boost simulator. See how the micro spends most of its time in while loop and jumps to the ISR every time the tmr0 rolls over from 255 to 0.Since we have connected a 4MHz crystal the internal clock frequency is Fosc/4 = 1MHz & so the tmr0 increments its self every instuction cycle which in our case is 1us.We have set the tmr0 in such a way as to count 250us for an interrupt to occur.This we do by writing tmr0+=9; in the ISR.We count 4000 of such interrupts which will result in 4000*250us = 1000000us or 1second and we change the state of the led to indicate this. */ #include <system.h> // Set clock frequency to 4MHz. #pragma CLOCK_FREQ 4000000 //set configuration fuse. #pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF /*Interrupt service routine (ISR).On timer0 interrupt, program will jump to this code location. */ void interrupt( void ) { unsigned char tick; unsigned char tick1; // writing 9 onto tmr0 will generate interrupts at 250us interval. tmr0 +=9; tick++; //increment variable tick. if(tick>19) //if tick equals 20, increment tick1 & reset tick. { tick=0; tick1++; //if tick1 equals 200,we have counted 4000 ticks if(tick1>199) //in total, which equals 1 second(4000*250us). { tick1=0; //reset tick1. portb.0=~portb.0; //toggle the led to show that 1sec has elapsed. } } intcon.2=0; //clear TMR0 overflow flag } // The main code configures the option & intcon registers. void main() { trisb = 0; //configure port B portb = 0; //clear port B option_reg = 8; //no prescaler & start tmr0 // enable interrupts intcon.5=1; //enable tmr0 overflow interrupt intcon.7=1; //enable global interrupt /*simply write 6 to tmr0 counter value.This line will not alter the accuracy of the clock, so it can be removed if you wish. */ tmr0=6; while( 1 ); //do nothing & wait for tmr0 interrupt. } /* To check the accuracy of the timer interrupt code we have written you can use the stop watch in the mplab simulator. For this you need to integrate the boostC compiler with mplab ide. Look into the BoostC com- iler reference manual for information on integrating with mplab. */
  22. Thanks Andrew, for that nice bit of information. Regards Raghunathan
  23. I believe 1 us at 4 MHz is 1 cycle, so if you wanted to be safe, you could put a nop there instead. I don't see the purpose either, so it would still be fine to run at other frequencies. <{POST_SNAPBACK}> Yes. I did see the 1us delay in the code. I will try replacing it with a nop and see if it works. Regards Raghunathan,
  24. To change the delays in rs232_driver.h file is a very difficult task for me. Since i haven't understood the code completely. I will sit back and wait for the release of v6.70. Mean while i will keep working with 20Mhz chips. At this stage i think its going to be good form me see some asm program examples(Microcontrol'n Apps written by David Benson & serial communication by Roger Stevens) ) Regards Raghunathan.
  25. The above code builds when i changed the clock frequency to 20MHz. Does that mean i wouldn't be able to implement SB's suart or huart lib on PICs operating on less than 20MHz ? Is there anyway i can get it to work with a 4MHz clock ? Raghunathan
×
×
  • Create New...