Jump to content

ra68gi

EstablishedMember
  • Content Count

    229
  • Joined

  • Last visited

Everything posted by ra68gi

  1. Hi, I think we need to know how you generate the zero cross pulse. Try to use a full wave rectifier ckt with a center-tap transformer in which case you use only 2 diodes to do the rectification. Use a low drop diode like germanium instead of silicon diode. Silicon diodes create a 0.7v drop. Generate a narrow pulse with comparator setup. you can use the rising edge to activate the interrupt. Make sure your sine signal is symmetrical on both the +ve & -ve cycle. See if using rising edge for one & falling edge for the next as interrupt triggers solves your problem. Regards Raghunathan
  2. See in Thermometer1.c Programming PIC micro for beginners Regards Raghunathan Where's the SPI in that file? Dan, I recommend you read the data sheet for your device because it walks you through the steps to take for SPI and it's fairly easy. The functions you might need to write are very simple. Easier than implementing I2C. Post again if you have problems and we'll help you out. Hi, SPI or serial peripheral interface is a communication protocol. Its a synchronous communication protocol, because it uses a clock to send or receive data. This is unlike the RS232 communication also called asynchronous comm. or USART where the datas are not clocked, but the TX & RX accept upon a common speed of data transfer also called the baud rate. The main pins in a SPI device are SDI(serial data in) SDO(serial data out) and a clock. There are various mode like slave, master etc.. but the concept is simple. The one which gives out the clock pulse is the master & the other slave. Some PICs may have dedicated pins & registers for for hardware SPI. If this is what you need to config and use, may be SourceBoost doesn't have LIB for it. You need to do it your self or find other compilers that may have one. You can set your own software SPI comm. like this... Copied from the example.. PLS see data sheet of the respectve device to get more info regarding SPI data transfer. void clk(void) //The clock routine. { porta.4=1; //Make porta.4 high. porta.4=0; //Make porta.4 low. } void serial_adc(void) //serial_adc routine. { adc=0; porta.3=0; // bring chip select low to start adc. adc.7=portb.0; //load the most significant bit of adc. clk(); //send clock pulse to get the next adc bit. adc.6=portb.0; //load it onto the next significant bit. clk(); // & so on until the last adc bit. adc.5=portb.0; clk(); adc.4=portb.0; clk(); adc.3=portb.0; clk(); adc.2=portb.0; clk(); adc.1=portb.0; clk(); adc.0=portb.0; clk(); porta.3=1; } This may not be an efficient coding but clearly explains the concept of clocking the data(may be receive or transmit). Regards Raghunathan
  3. See in Thermometer1.c Programming PIC micro for beginners Regards Raghunathan
  4. I couldn't find anything. But SPI is so simple with the device itself that you really don't need it. It's easier than I2C. Maybe some other users could provide links to threads in this forum or elsewhere to sample code. The search feature is useless for this (and many other things) because of the 4 letter minimum search terms. I did a bit of research and found some info that suggested that SPI and I2C are very similar, to the extent that an SPI device can actually reside on an I2C bus, as long as you provide an additional enable line. A little more work needs to be done to confirm this. I have been surprised at the lack of coverage in the BoostC documentation for this, and the 4 character site limitation for searching is a bit silly. If Pavel or Dave could comment, that would good. Dan Hi Dan, The example projects that I have written contains a thermometer project which uses TI's TLC549 ADC. It uses SPI. See if its useful. Regards Raghunathan.
  5. Sree, You can build this program in the sourceboost IDE and check how the code gets executed using the debugger/simulator. You can also see the Special function reg- gisters & their values change while stepping thro' the code. Especially watch the tmr0 register and intcon register. 1) The register that contols tmr0 is the option register. learn more about it by down loading the datasheet of your chip from microchip.com 2) Its interrupts are controlled by the bits 5 & 7 of the intcon register(also in datasheet). 3) Its interrupt flag is activated by bit 2 of intcon register. 4) while(1); is infinite loop where the micro does nothing. It sits here waiting for the next interrupt flag to go hi. 5)The beginner program also has a clock program to display hours minutes & seconds. You can use the same as template & modify it to suit your need. Its good practice to initialize variables, but if it does not affect the outcome you needn't write those extra code. Regards Raghunathan.
  6. Apostal, Generally the output of the IR RX would be a series of pulses rather then a high or low. Its best recommended to measure the number of low( assuming the output of the IR receiver goes low on detecting an object) This can avoid false triggers & providing a sort of hysterisis to the circuit. So its better to do a software polling. The polling can be done for just a brief period by switching on the ir tx and then switching it off. Just a burst of pulses will do. A continuous pulse train from the IR LED(TX) will be viewed as noise by your RX and it shuts down. You can use an interrupt like RB0/int external interrupt soucre to detect the falling edge of the IR RX, count the no. of interrut pulses and decide to stop. It can be done this way void interrupt(void) { if(pir1.6) // assuming this is your ADIF flag bit { ....... ...... pir1.6 = 0; } if(intcon.4) // assuming this is the RB0/INTE { counter++; if(counter==30) { counter = 0; object_detected_flag = 1; } intcon.4 = 0; } } In the main check for the object_detected_flag & give the appropriate (i guess 1ms pulse train) pulse to stop your servo motor. Make sure to config the appropriate interrupt enable bits in the main. I hope this helps. Regards Raghunathan
  7. Thats great news! I would definitely buy it. Regards Raghunathan.
  8. Hi Dave & Pavel, Its been a long time since the introduction of FP in BoostC. When will we have trignometric functions, exp, log, sqrt, pi ...etc in boostc ? Regards Raghunathan.
  9. How much does it cost or is it free ? Regards Raghunathan.
  10. Dave & Pavel How long do we have to wait for a usb lib? Regards Raghunathan.
  11. Are you talking about rs232 communication? Source boost user manual has got lots of string handling functions. have a look at them Regards Raghunathan
  12. I have used the PWM in PIC16F72. You may have to sightly modify for the PIC18. It generates a 38khz for IR communication as carrier frequency. #include <system.h> #pragma CLOCK_FREQ 20000000 // config clock to 20mhz. // Set configuration fuse. #pragma DATA _CONFIG, _HS_OSC & _WDT_ON & _CP_OFF & _PWRTE_OFF void main(void) { trisa = 255; trisb = 0; trisc=0; //set all portc pins as output pins. portc=0; //make all portc pins low. option_reg = 0b11111111; // using 1:32 prescaler for wtd. //wtd will awaken from sleep mode.wtd uses internal rc for its clock. //wtd gives a min of 7ms typ of 18ms or 33ms of max time out period. /*lets configure the pwm module for 38khz. formula for pwm period = [(pw2)+1].4.tosc.(tmr2 prescaler value) lets take tosc as 20mhz as it will result in better resolution then 4mhz. tosc = 1/20000000; pwm period = 1/38000; therefore pr2 +1 = 132; with pr2 as 131 the generated pwm freq is = 37.8787khz. ******************************* we choose pr2 = 131; * ******************************* duty cycle = (ccpr1l:ccp1con<5:4)*tosc*(tmr2 prescale value) lets assume 50% duty cycle.ie. 50% on time 50% off time. duty cycle = (1/37878)/2 = 1.32*10^-5. which is = ccp_duty_value/20,000000 **************************************** ccp_duty_value = (1.32*10^-5)*20000000 * = 264; * **************************************** note:ccpr1l contains MSB & ccp1con contains the LSB total of 10bits. ****************************** so load ccpr1l = 0b01000010; ****************************** the two bits of ccp1con is not required to be filled. */ pr2 = 131; ccpr1l = 0b01000010; //for a duty cycle value of 264. ccp1con = 0b00001100; //11xx=pwm mode /*timer2 control register we have selected bit7.....unimplemented.read as 0. bit6-3...(0000) 1:1 for post scaler, not used in pwm. but can be used as servo feed back. bit2.....(1) timer2 on bit1-0...(00) prescaler is 1. */ t2con = 0b00000100; while(1); } Leave the WDT alone as its got nothing to do with the PWM. Regards Raghunathan
  13. could be syntax problem with your rom char array statement. I have made programs for digital sine wave generation. have a look at the program. with a r-2r ladder (dac) connected to portb you can generate a sine wave.Hope it helps. #include <system.h> #pragma CLOCK_FREQ 4000000 // config clock to 4mhz. // Set configuration fuse. #pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF unsigned char get_sine_value(unsigned char x) { rom char *sine_array = {0,2,3,5,6,8,9,11,12,14,16,17,19,20,22,23,25,26,28,30,31,33,34,36,37,39,40,42,43 ,45,46,48,49,50,52,53,55,56,57,60,60,62,63,64,66,67,68,70,71,72,74,75,76,77,79,80 ,81,82,83,85,86,87,88,89,90,91,93,94,95,96,97,98,99,100,101,102,103,103,104,105,1 06,107,108,109,109,110,111,112,112,113,114,115,115,116,117,117,118,118,119,119,12 0,120,121,121,122,122,123,123,123,124,124,125,125,125,125,126,126,126,126,126,127 ,127,127,127,127,127,127,127}; return sine_array[x]; } void main(void) { trisb = 0; portb = 0; unsigned char y; while(1) { for(y=0;y<129;y++) { portb = (get_sine_value(y) + 128) ; } for(y=128;y>-1;y--) { portb = (get_sine_value(y) +128); } for(y=0;y<129;y++) { portb = (127 - get_sine_value(y)); } for(y=128;y>-1;y--) { portb = (get_sine_value(y) - 127); } } } Regards Raghunathan
  14. Many a times we need to read a SPI device(serial pheripheral interface) by giving clk pulses and receiving the data serially. We would store it in some variable. I have written a program to access 20bits from a serial ADC ads1230. The section of the code looks like this.. void interrupt( void ) { unsigned char b; //data ready interrupt from ads1230 if(intcon.1) //RB0/int(falling edge signal from ads1230 drdy pin) { l_adc_counter = 0; l_clk(); l_adc_sign_flag = portb.0; // 20th bit(MSB) is the sign bit. for(b=0;b<17;b++) { l_clk(); l_adc_counter |= portb.0; //load the 19 - 4th most significant bit. l_adc_counter <<= 1; } l_clk(); // the last bit is loaded without bit shifting. l_adc_counter |= portb.0; // we will load only 18 bits. // we will discard the rest of the bits. for(b=0;b<2;b++) { l_clk(); // 20th & 21st clock pulses. //the 21st clock will push the DRDY/Dout pin of ads1230 high. } if(l_cal == 1) //if calibration switch is ON. { for(b=0;b<5;b++) { l_clk(); // 22nd thro' 26th clk pulses. } l_cal = 0; } else { l_adc_update_flag = 1; } intcon.1 = 0; //clear intf } hope this helps.
  15. Hi John, If i understand it right, I think you are wanting to measure the frequency of a square wave signal. There are many ways to do it. You could use the ccp module in the capture mode to captue the tmr1 value every time a rising edge is received in your ccp pin. If your time period is larger than the 16 bit timer counter then you need to also count the tmr1 over flow interrupt. I have done a similar program using timer1 & ccp pin, but i have used the ccp pin only as a pin to detect the external pulse interrupt & not in the capture mode. Sorry, I don't have time to explain my code. #include <system.h> #include "lcd_driver.h" // Set clock frequency to 4MHz. #pragma CLOCK_FREQ 4000000 //set configuration fuse. #pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF #define LCD_ARGS 2, /* Interface type: mode 0 = 8bit, 1 = 4bit(low nibble), 2 = 4bit(upper nibble) */ \ 0, /* Use busy signal: 1 = use busy, 0 = use time delays */\ PORTC, TRISC, /* Data port and data port tris register */ \ PORTB, TRISB, /* Control port and control port tris register */ \ 2, /* Bit number of control port is connected to RS */ \ 7, /* Bit number of control port is connected to RW */ \ 3 /* Bit number of control port is connected to Enable */ unsigned char tick; unsigned int value1; bit frequency_update_flag; /*Interrupt service routine (ISR).On timer0 interrupt, program will jump to this code location. */ void interrupt( void ) { unsigned char capture_count; if(pir1.0 == 1) //tmr1 overflow flag(tmr1if). { tick++; // count the number of tmr1 interrupts. if(tick > 15) //if frequency is too low { ccp1con = 0; t1con = 0; tmr1l = 0; tmr1h = 0; tick = 0; value1 = 0; capture_count = 0; frequency_update_flag = 1; } pir1.0 = 0; //clear tmr1if } else if(pir1.2 == 1) //ccp interrupt flag(ccp1if). { capture_count ++; if(capture_count > 1) { t1con = 0; ccp1con = 0; //switch off capture mode. value1 = tmr1l + (tmr1h * 256); capture_count = 0; frequency_update_flag = 1; } else //The first ccp interrupt resets tmr1 & starts it. { t1con = 0; tick = 0; tmr1l = 0; tmr1h = 0; t1con = 1; } pir1.2 = 0; //clear ccp flag. } } /* function to display RPM. */ void display (unsigned int x) { lcd_clear(); lprintf("RPM="); lprintf("%u",x); delay_s(2); } /* The main code configures the intcon, pie1, t1con & ccpcon1 registers.*/ void main() { trisb = 0; //configure port B portb = 0; //clear port B trisc = 0b00000100; //RC2/ccp1 pin as input. // enable interrupts: interrupt control register. intcon.6=1; //enable peripheral interrupts intcon.7=1; //enable global interrupt //peripheral interrupt enable register 1. pie1.2 = 1; //enable ccp1 interrupt. pie1.0 = 1; //enables tmr1 overflow interrupt. /* timer1 control register: t1ckps1:t1ckps0: input prescaler bit5-4.....select 00= 1:1 prescale tmr1cs: timer1 clock source select bit. bit1...select 0 = internal clock (Fosc/4) tmr1on: timer1 on bit bit0......1 = enable timer1 bit0......0 = stop timer1 we are not concerned about the other bits of t1con. */ //set t1con t1con = 0b00000000; //tmr1 not yet enabled. /*ccpcon1: capture/compare/pwm control register1. bit3-0.....ccpxm3:ccpxm0: ccpx mode select bits. we will use... 0100 = capture mode, every falling edge. 0101 = capture mode, every rising edge. we can choose any one of the above mode. but we will use 0100 in our project. */ /* print " RPM = " in the first line of LCD */ lcd_setup(); unsigned long count; while (1) { frequency_update_flag = 0; ccp1con = 0b00000101; //set capture mode. t1con = 1; //start timer1. while (frequency_update_flag == 0); count = (tick*65536) + value1; if(count == 0) //if frequency is too low. { display(count); } else { count = 100000000/count; //to find frequency. count *= 60; //for cycles per minute. count /= 100; //divide by 100 to get actual RPM. display(count); } } } Regards Raghunathan
  16. Hi emte, Infact one can generate any odd Baud rate using the formula Baudrate = Fosc/16(x+1); where x is the spbrg value or divisor value, but we would like to use baud rate that are supported by the com ports in our PC. 33.6kb is not supported my hyper Nor my VB supports it nor does the terminal of source boost ide. Regards Raghunathan.
  17. Hi Guys, I am using the huart of the 16F877A with a 20Mhz crystal. I wish to use the transmission with the highest baud rate possible supported by the hyper terminals com port at the same time want a very reliable transmission. I also know that only for certain baud rates the divisor value creates minimum percentage error as can be seen in data sheet. So I am using it at 19200 bauds with a percentage error of 0.16. What would be the maximum recommended or worst case error value for reliable communication? At 38400 baud the divisor of 31 generates an error of 1.6%. At 57,600 with a divisor of 20 its 3.5%. Regards Raghunathan.
  18. Hi Ettore, Yes, as you say 7135 chip is quite a old chip but looking at the cost(less than a dollar in my place) performance & ease of interfacing ( DIP package) its still worth it. There are a lots of delta sigma adcs with 24 bit resolution & nearly 1k plus samples thro' put available at low price especially from cirrus logic. I started with 7135 because its relatively easy. I have right now developed the same circuit with ADS1230 20 bit adc from texas instrument. This has a thro'put of 80 samples per second.These chips have builtin amplifiers and come in smd pack making the whole ckt really small. Project... The clock for the 7135 is derived from a 4011 nand gate chip. in the schematic i have shown component value of a clk freq of around 100khz. With 100Khz you can get only 2.5 samples per second. For my use(UTM) i have selected components for 350Khz which will give you around 8 samples per second. Have a look at the schematics. I have a very tight schedule, my business & my post graduation course, is just not giving me enough time to compile all the related stuff and post it. I need to explain how the code works else you wouldn't understand. Pleeeease wait for a couple of days & i will post it all. Regards Raghunathan Differential_amplifier_circuit_for_load_cell.bmp ICL7135_to_PIC16F877A_interface_circuit.bmp ICL7135_to_PIC16F877A_interface_circuit2.bmp Interfacing_Power_supply_to_Load_cell_sensor___Instrument_amplifier.bmp load_cell___instrument_amplifier_power_supply.bmp
  19. Hi David, I have not used this chip, but looks like this chip has got a lot of oscillator options. Your option in the pragma statements shows that you have chosen internal RC oscillator mode and no pin is made to out the clock,ie. to say both osc1 & osc2 pins are made as i/o pins. I think you need to set the osccon register for it to function. Look into the data sheet & load the appropriate bits on to the osccon. osccon = 0b???????? ; regards Raghunathan.
  20. Hi emte, Nice to see you back in the forum after a small gap. Well, i suppose you are not impressed with my project . Hey man.. atleast give me a word of motivation. I am not going for a competition nor am I trying to sell some thing, I am only sharing my experience in constructing this project. Let me see if you would change your mind once i have posted all the project stuff. I had gathered these information with great difficulty & I am sure its going to benifit many. note: The project has got nothing to do with pogo pins. Info on UTM:UTM Zwick UTMs Regards Raghunathan.
  21. Dear friends, At last my project is ready to be posted on this forum. I made this project for my UTM(universal testing machine). An UTM is used for materials testing. Its used in several industries, especially in automobile industry( to test materials like springs, axles, cables. etc) for their durability. This project is fairly large & so I will divide it into many sections or parts. Though a difficult project for a beginner, I have made all efforts to furnish all the required details of the project so that it will be easy for any one to reproduce. This project will not only be interesting to a beginner but to a professional as well. Salient features of the project( what shall we call it?..Hmmm.. UTM project should be fine). 1. Uses PIC16F877A at 20Mhz. 2. How to interface a load cell ( a transducer for load or force measurement) to the microcontroller via operation amplifier(OP07) as instrument amplifier. I will furnish the schematics for the analog circuit along with tracking power supply used. 3. How to interface the instrument amp to the +20,000 count to -20,000 count low cost high resolution ADC ICL7135. 4. How to interface ADC ICL7135 with 16F877A. 5. How to interface a optical positional encoder to the microcontroller. 6. How to interface 6, 7-segment led display to display the encoder & adc values along with sign. 7. Uses the HUART with rs232 interface chip to connect to your PC. 8. Drives 5 relays through control from PC using husart. 9. Displays the load cell & encoder values on the terminal screen. 10. All the required schematic for the above. 11. Last but not the least, we use BoostC to write our code. 12. Will show how these values can be plotted as a graph using visual basic.( source code for the vb will not be given). As you can see the micro will be fully loaded with activity. This forum is a great place & its here i learnt my first C programme. Looking at the number of hits my thread has received i feel a bit excited & like to contribute more to this forum in the form of projects. Regards Raghunathan.
  22. Thanks, Picxie for clearing my doubt. Raghunathan.
  23. I am working with the husart lib functions of the BoostC. The section of the header file rs232_driver.h looks like this... if (T_MODE & USART_HW) { while (!KBHIT<_USART_TEMPL_ARGS>()) // wait for a character if (T_MODE & USART_reset_wdt) clear_wdt(); return(l_rcreg); } I have generally used the while function ending with a semicolon like this.. while (!KBHIT<_USART_TEMPL_ARGS>()); // wait for a character or if you have some statement to execute.. while (!KBHIT<_USART_TEMPL_ARGS>()) // wait for a character { .... .... } I don't see the semi colon or the closed paranthesis in the header file. Can anyone explain how it functions? In my project i don't want the micro to simply sit & wait for a character to be received, i want it to carry on executing other instructions & if it sees a character i then want it to execute specific task using switch case function. Is there a way to modify the lib to do this while retaining all other functionality of the lib. Regards Raghunathan.
  24. I am sorry, for PIC16F690 you need to use the ansel register to set or clear analog functions on porta pins. For chips like 16C620,621,16F627 & 628 use comcon = 7 ; to use porta pins in digital mode. For chips like PIC12C67x, 16C7xx, 16F87x use adcon1 = 7 ; to use porta pins in digital mode. Regards Raghunathan.
  25. RAM is volatile ie. the data gets erased when power is gone. Not the one you are looking for i guess. external eeprom is the most economical option using I2C interface. Regards Raghunatahan.
×
×
  • Create New...