Jump to content

ra68gi

EstablishedMember
  • Content Count

    229
  • Joined

  • Last visited

Everything posted by ra68gi

  1. Read data sheet on how to set Porta analog pins to digital mode. If your chip is 16F series &has got adc multiplexed with porta pin include adcon1 = 7; if it has analog comparators then write comcon = 7 ; Regards Raghunathan.
  2. Yes, it should work. I have not tried it. The data sheet says that the data EEPROM and Flash program memory is readable & writable during normal operation. The EEPROM data memory allows single-byte read and write. The flash program memory allows single-word reads and four-word block writes. program memory write operations automatically performs an erase-before write on blocks of four words. A byte write in data EEPROM memory automatically erases the location & writes the new data(erase-before-write). One other aspect while designing would be the erase/ write cycles of your memory. Typical values of erase/write for PIC16F8xx series is.. Flash program memory---100,000 erase/write cycle. EEPROM--------------------1,000,000 erase/write cycle. I hope you wouldn't exceed the 100,000 cycle of the flash. Regards Raghunathan.
  3. Rom objects can't be modified using C. The only option to do this is to use inline assembly (on targets that support run time flash write). Regards, Pavel Hi DavidT, Are you talking about the eeprom or the program flash memory? You can store & retrive your array using eeprom_read & eeprom_write function any where in your program. At this point i am a bit confused with what Pavel has mentioned. Does the flash_read , flash_loadbuffer, flash_write not work with data flash memory chips when invoked in a c program? I think i need to know what is what. eeprom?, program memory? or data flash memory? Raghunathan.
  4. Hi emte, I think the cost of C30 compiler from MicroChip for PIC24 & dspic is around $750. Regards Raghunathan.
  5. Hi Dave & Pavel, Is there any plans of coming out with a compiler for the 16 bit / dsp PIC micros? Regards Raghunathan
  6. Give a couple of days time & i will post a example program with circuit schematics in my thread. Regards Raghunathan
  7. Hi guys, I am using the hwusart of PIC16877 to send two data to a PC. The the two datas are the load value(from load cell) from an external adc chip and a positional value reading from a quadrature encoder. Lets say the variables are int load_value = 198 ; & int encoder_value = -65 ; I will be sending the characters in the following format.. #00198,-00065 I am using the sprintf function to convert the var to string & then display.For the radix i use "%05u". But when i receive it on the terminal screen, this is what i get.. #00198.,-00065. I am getting this extra dot, i don't know why. How do i get rid of it? I don't wish to use any other format as this is the most suited for me . my code.. #pragma CLOCK_FREQ 20000000 #include <system.h> #include "stdio.h" // you have to include this for your sprintf to compile. #pragma DATA _CONFIG, _HS_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF // PIC16F87x defaults for hardware USART support #define TX_PORT 0x07 #define TX_TRIS 0x87 #define TX_BIT 6 #define RX_PORT 0x07 #define RX_TRIS 0x87 #define RX_BIT 7 #define e_SPBRG 0x99 #define e_RCREG 0x1a #define e_TXREG 0x019 #define e_TXSTA 0x98 #define e_RCSTA 0x18 #define e_TXIF_PIR 0x0c #define e_RCIF_PIR 0x0c #define e_TXIF_BIT 4 #define e_RCIF_BIT 5 #define MODE (USART_reset_wdt | USART_HW) // specify that we are using hwuart #define bit_time 520 //260 though not required for hwuart needs to be there for the lib to work. #include <rs232_driver_modified.h> void convert_to_string_tx (unsigned int x) { char buff [ 5 ]; sprintf(buff,"%05u",x); puts_no_cr(buff); // puts without carriage return / line feed. } void sign_plus(void) { putc(43); } void sign_minus(void) { putc(45); } void main() { // clock speed used 20mhz// 129 for 9600 baud uart_init(1,129); trisc = 255; // config rc.6 & rc.7 as tx & rx bits.(set trisc.6 & trisc.7). unsigned char b0; unsigned char b1; signed int load_value; signed int encoder_value; /* the data format to be sent is #+load_value,-encoder_value#-load...repeats. So we need to convert load_value & encoder_value to string & then transmit.Lets use the sprintf command to convert decimal int to string. Lets give some EXAMPLE values and check it... */ load_value = 198; encoder_value = -65; putc(35); // for # sign if(!(load_value < 0)) //check for sign { sign_plus(); //if positive send ascii of + } else { sign_minus(); load_value = -1 * load_value; } convert_to_string_tx (load_value); putc(44); // ascii for comma "," if(!(encoder_value < 0)) { sign_plus(); } else { sign_minus(); encoder_value = -1 * encoder_value; } convert_to_string_tx (encoder_value); cr_lf(); // function for carriage return line feed. while(1); } Raghunathan
  8. Hi Laurence, For a quick start try this thread.."PIC micro programming in BoostC for beginners" As far as printf command is concerned you have lprintf used only with LCD. See page 78 of BoostC manual. for serial communication you can use serial_printf command available in the folder named lika.be( i don't know if it comes with the source boost ide down load or whether i down loaded it from his website)lika.be Regards Raghunathan.
  9. I think you can enable the watch dog timer. The #define MODE (USART_reset_wdt | USART_HW) will automatically clear your wdt before it resets. I think you might be facing some other problem & not related to wdt. See if your Rx buffers are overflowing and so receive disabled.
  10. Hi DavidT, It may be difficult to work with interrupts in your case ( due to key bouncing). Why don't you try some thing like this.. Lets say you have connected the switch to portb.0 & based on the duration you have pressed you decide what activity to do. if(portb.0==0) { delay_ms(100); // wait for the key to settle down. if(portb.0==0) { for(x=1;x<1000;x++) { y=x; delay_ms(1); if(portb.0==1) { break; } } if(y<=500) { write to eeprom; } if((y>500)&&(y<750)) { light 12 leds; } if((y>750)&&(y<999)) { do some thing else; } y=0; x=0; } } hope this would be useful. Regards Raghunathan.
  11. Hi guys, In my project I am using 3 interrupt sources, they are tmr0, RB0/INT, ccp( capture interrupt) all as external interrupt on pulse. I have a problem with the ccp interrupt. The problem is every time there is some noise ( electrical disturbance from power line etc) the ccp interrupt gets disabled. I need to reset the system to get it to work again. I found that such noise ( as found in my present circuit setup) does not have any effect on the tmr0 or RB0/int interrupts. Right now i can do away with this problem by simply changing the interrupt source to tmr1 but my future projects may require more sources & so i would need a way to use them(ccp) reliably. Has any one faced similar problems ? Can any one suggest some techique to use the ccp interrupt reliably? Regards Raghunathan
  12. You didn't mention if you used a debugger. When you use the ICD2 you must always include the icd2.h header: #include <system.h> #include <icd2.h> The compiler then protects the file registers used by the icd2 firmware. This might explain your unexpected changes in values. /Mark No, i haven't used a debugger, just direct load onto target board & check. I solved the problem by just declaring all the arrays with 6 elements. There is one small error in my ISR code. I initially had just 2 interrupt sources & hence used if else command. Latter i added one more interrupt source, so the ISR should look more like this.. void interrupt( void ) { if(intcon.2) //tmr0if (rising edge)busy signal from icl7135 { strobe_pulse_counter = 4; // reset counter tmr0 = 255; //tmr0 as pulse counter intcon.2 = 0; // clear tmr0if } if(intcon.1) //RB0/int(rising edge signal from 7135 strobe pulse) { adc_sign_flag = portc.0; bcd_value[strobe_pulse_counter] = porta & 0b00001111; strobe_pulse_counter --; if (strobe_pulse_counter == 0) { adc_update_flag = 1; } intcon.1 = 0; //clear intf } if(pir1.2) //ccp1if for rotary encoder. { encoder_update_flag = 1; if(portc.5 == 0) // read the quadrature pulse. { counter ++; } else { counter --; } pir1.2 = 0; } } I will try putting in more details(schematics) & pictures of this interesting project here on this thread. Thanks Raghunathan.
  13. Hi ryeg, First try it on portb, see if it works then use porta. What chip are you using ? chips such as PIC12C67x, PIC16C7xx, PIC16F87x porta pins will come up as analog pins. to use as digital write adcon1 = 7; Some chips like 16C620, 621, 16F627,628, have analog comparators on porta & you need to disable them to use them as digital pins, so use comcon = 7; Regards Raghunathan.
  14. Hi guys, I have already said this in my previous thread, yet.. I am currently working on a project in which the pic is made to read adc values from an external adc chip. The adc chip outs the data in a bcd format (-20,000 to +20,000 counts) & it generates 5 strobe pulses during which it outs the 5 digits of its adc result. Using ext interrupts i load these value into the pic. Simultaneously I am reading a rotary positional encoders output again thro' ccp interrupts . The value of the adc or the encoder is displayed on to 6 no. of 7-segment led display which are multiplexed on to 8 i/o pins. I have three arrays namely, unsigned char bcd_value[5]; unsigned char bcd_value1[5]; unsigned char digit[6];. The five elements of the array "digit" gets loaded either with the "bcd_value1" array which contains the bcd values of the adc converter icl7135 or the bcd values derived from counter1(encoder value)value. Now when i actually test the circuit, initially it displays fine, but slowly the segment value changes, when it should not ( my encoder is not rotated). The value changes slowly & the values are random and occurs in all segment. again on slightly changing the encoder position it gets back to the right value. The program is written in such a way that only if there is a change in encoder value or adc value the old value gets updated for display or else it is supposed to display the old ram values, i do this with an update flag. I realse that the value stored in this array(digit[6]) gets lost some how after a short time. I don't know why. Can any one tell me if its a flaw in my C code or that of the compilers. code.. #include <system.h> // Set clock frequency to 20MHz. #pragma CLOCK_FREQ 20000000 //set configuration fuse. #pragma DATA _CONFIG, _HS_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF & _LVP_OFF signed long counter; unsigned long counter1; unsigned char strobe_pulse_counter; bit encoder_update_flag; bit encoder_display_flag; bit encoder_sign_flag; bit adc_update_flag; bit adc_display_flag; bit adc_sign_flag; bit digit_sign_flag; unsigned char bcd_value[5]; unsigned char bcd_value1[5]; unsigned char digit[6]; /*Interrupt service routine (ISR).On ccp capture interrupt or on RB0/int program will jump to this code location. */ void interrupt( void ) { if(intcon.2) //tmr0if (rising edge)busy signal from icl7135 { strobe_pulse_counter = 4; // reset counter tmr0 = 255; //tmr0 as pulse counter intcon.2 = 0; // clear tmr0if } else if(intcon.1) //RB0/int(rising edge signal from 7135 strobe pulse) { adc_sign_flag = portc.0; bcd_value[strobe_pulse_counter] = porta & 0b00001111; strobe_pulse_counter --; if (strobe_pulse_counter == 0) { adc_update_flag = 1; } intcon.1 = 0; //clear intf } else if(pir1.2) //ccp1if for rotary encoder. { encoder_update_flag = 1; if(portc.5 == 0) // read the quadrature pulse. { counter ++; } else { counter --; } pir1.2 = 0; } } //lookup table for the segment values. unsigned char get_value(unsigned char y) { unsigned char segments[12]={0xDE,0x50,0xE6,0xF4,0x78,0xBC,0xBE,0x54,0xFE,0xFC,0x20,0x6E}; return segments[y]; } // function to fire the leds in the segment. void led(void) { unsigned char z; for(z=0;z<10;z++) { portb = get_value(digit[5]); portd.0 = 1; delay_us(5); portd.0 = 0; portb = get_value(digit[4]); portd.1 = 1; delay_us(5); portd.1 = 0; portb = get_value(digit[3]); portd.2 = 1; delay_us(5); portd.2 = 0; portb = get_value(digit[2]); portd.3 = 1; delay_us(5); portd.3 = 0; portb = get_value(digit[1]); portd.4 = 1; delay_us(5); portd.4 = 0; portb = get_value(digit[0]); portd.5 = 1; delay_us(5); portd.5 = 0; } encoder_display_flag = 0; adc_display_flag = 0; } //function converts to bcd value for display. void encoder_bcd (void) { digit[4] = counter1 / 10000; digit[3] = (counter1 % 10000) / 1000; digit[2] = (counter1 % 1000) / 100; digit[1] = (counter1 % 100) / 10; digit[0] = counter1 % 10; } //function loads the adc value from icl7135 void adc_bcd (void) { unsigned char x; for(x=0;x<5;x++) { digit[x] = bcd_value1[x]; } } void display(void) { if (encoder_display_flag) { if (encoder_sign_flag == 0) { digit[5] = 10; //will display - on segment } else { digit[5] = 11; //will display "P" on segment } led(); } else if (adc_display_flag) { if(digit_sign_flag == 0) { digit[5] = 10; } else { digit[5] = 11; } led(); } } // The main program starts here. void main() { unsigned char a; bit display_refresh_flag; trisa = 255; // porta as inputs. adcon1 = 7; //make digital i/o. trisb = 1; /* rc0-polarity check,rc1&rc2-ccp pins,rc4-over voltage check, rc5-quadrature pulse of encoder,rc6-7 as tx & rx */ trisc = 0b11110111; trisd = 0b01000000; //switch connected to rd.6 trise = 0; //configure option register bits //portb pull-ups(rbpu)(disable)...bit7 //interrupt on rising edge(RB0/int)(intedg)...bit6 //tmr0 clk source(tocs)is transition on RA4..bit5=1(we are using tmr0) //tmr0 source edge select(tose) is low to hi transition...bit4=0 //bit3-bit0...don't care. //SO we use option_reg = 0b11101111; option_reg = 0b11101111; // enable interrupts: interrupt control register. // intcon.6=1; enable peripheral interrupts // intcon.7=1; enable global interrupt // intcon.5=1; enable tmr0 overflow interrupt. // intcon.4=1; enable inte (RB0/int) // intcon.3=0; disable rbie (rb port change interrupt) // intcon.2=0; tmr0if // intcon.1=0; intf ( RB0/int flag) // intcon.0=0; rbif // intcon = 0b11110000; //i will enable RB0/int along with ccp1 interrupt. //peripheral interrupt enable register 1. pie1.2 = 1; //enable ccp1(rc2) interrupt. /*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 0101 in our project. to get less count use 0110( divide by 4). or 0111 for divide by 16. ccp1con = 0b00000101; //set capture mode in rising edge. */ // yet to config eeprom read/write and hardware rs232 port pins. counter = 0; encoder_update_flag = 1; adc_update_flag = 1; tmr0 = 255; intcon = 0b11110000; ccp1con = 0b00000101; while (1) { if (portd.6 == 0) //check switch position for display. { encoder_display_flag = 1; if (encoder_update_flag == 1) { encoder_update_flag = 0; if( counter < 0 ) { counter1 = (-1)*counter; encoder_sign_flag = 0; } else { encoder_sign_flag = 1; counter1 = counter; } encoder_bcd(); } if(display_refresh_flag == 0) { encoder_bcd(); } display_refresh_flag = 1; display(); } else { adc_display_flag = 1; if(adc_update_flag == 1) { adc_update_flag = 0; digit_sign_flag = adc_sign_flag; for(a=0;a<5;a++) { bcd_value1[a] = bcd_value[a]; } adc_bcd(); } if(display_refresh_flag == 1) { adc_bcd(); } display_refresh_flag = 0; display(); } } } Upon changing all arrays with 5 elements the problem got solved, but i am unable to display the sign bit. I can use a different method to impliment sign, but i want to know why there should be a problem in changing values from one array to another of different size. compiler version used- 6.7 Regards Raghunathan
  15. No priority interrupts, I am using pic16f877. I am talking about software usart and so it does not generate any interrupt ( for that matter i think even the hw uart lib of source boost does not generate interrupt, but does a software polling of the interrupt or status flags( the rx & tx interrupt enable bits are cleared). I don't want to use my own routine. If i use the SB lib i have the advantage of handling strings ,ascii etc with ease( i suppose, i haven't tried). Regards Raghunathan.
  16. I am currently working on a project in which the pic is made to read adc values from an external adc chip. The adc chip outs the data in a bcd format (-20,000 to +20,000 counts) & it generates 5 strobe pulses during which it outs the 5 digits of its adc result. Using ext interrupts i load these value into the pic. Simultaneously I am reading a rotary positional encoders output again thro' ccp interrupts . The value of the adc or the encoder is displayed on to 6 no. of 7-segment led display which are multiplexed on to 8 i/o pins. Now i also need to transmit the adc and encoder values thro' rs232 to a PC. As you can see my interrupt routine is heavily loaded. What i need to know is if i use the emulated(software) usart will the transmitted data get corrupted due to extended soft ware delay(due to interrupts), which is used to generate the baud rate ? Regards Raghunathan.
  17. I don't see an issue here, msb indicates the sign when a negative number is stored as 2's complement. Don't known quite what you are talking about. Regards Dave Hi Dave, I am using an encoder & the result is stored in a variable which can take any value positive or negative,which i don't know. If i knew that my result is negative then what you say is right, the last bit becomes the sign bit. I just wanted to know if there was a easier way of knowing if my variable was positive or negative just by reading some bits. Regards Raghunathan
  18. emte, this sign conversion is confusing. The signed values are stored in two's compliments.Say we have a signed char x;, both -1 and 255 will be stored in a similar way & only the compiler seem to know if its -1 or 255, because when i use the simulator to display portb = -1 ; it displays all lit leds or value 255. or if i try to read it, the value turns out to be 255. The only way i can check is to write if(x<0).I have not tried what you have mentioned above, but could you explain. If there is a way to avoid duplicating the display code i would be happy. note: The signed character x is stored as (x - 256) for x > 127. example: 128 is represented as (128 -256) = -128. regards Raghunathan.
  19. Hi guys, I want to display a signed variable on a seven segment display. Right now i am checking if its a negative value if so converting it into positive value by multiplying it with -1 and then displaying it. Is this the only way to do it ? Part of the code... while (1) { if (portd.6 == 0) { encoder_display_flag = 1; if (encoder_update_flag == 1) { encoder_update_flag = 0; if( counter < 0 ) { counter1 = (-1)*counter; // signed long counter; & unsigned long counter1; encoder_sign_flag = 0; digit[4] = counter1 / 10000; digit[3] = (counter1 % 10000) / 1000; digit[2] = (counter1 % 1000) / 100; digit[1] = (counter1 % 100) / 10; digit[0] = counter1 % 10; } else { encoder_sign_flag = 1; digit[4] = counter / 10000; digit[3] = (counter % 10000) / 1000; digit[2] = (counter % 1000) / 100; digit[1] = (counter % 100) / 10; digit[0] = counter % 10; } } display(); } else { adc_display_flag = 1; if(adc_update_flag == 1) { adc_update_flag = 0; digit_sign_flag = adc_sign_flag; for(x=0;x<5;x++) { digit[x] = bcd_value[x]; } } display(); } } } Raghunathan.
  20. Hi, How is the sign bit in a variable stored ? Can i access the sign bit directly in boostC like i address the individual bits through dot operator? Raghunathan.
  21. You could also declared a union to do the job. typedef union { unsigned int val; struct { char hi; char lo; }byte; } HL; void main() { HL hl; hl.val = 0x1234; char hi = hl.byte.hi; char lo = hl.byte.lo; while( 1 ) } Regards Dave <{POST_SNAPBACK}> I checked the code on the simulator and found that the lo byte value & hi byte value are interchanged. I suppose the struct should be declared as... typedef union { unsigned int val; struct { char lo; // first the lower byte char hi; //then the next byte of data. }byte; } HL; Regards Raghunathan.
  22. Hi emte, Its just today that i started to read the data sheet of 16f8xx on the USART module. I realize that the flag rcif can't be cleared in software. Its cleared only in hardware & this happens when you read the rcreg register. I think upon reading the rcreg, it automatically gets cleared (gets empty). And since rcreg is a double buffered, capable of storing 2 bytes of data it may probably take 2 reads before you can clear the rcreg register and rcif flag. The only way to disable the interrupt is to clear the rcie enable bit. Am i write ? can you add some more information to improve my understanding. I have changed your code a bit. Is it o.k? while (rcif ==1) { rxHolder[rxCount] = rcreg; /* read data into array to handle in main when count max is reached */ rxCount++; /* increment count */ } Regards Raghunathan.
  23. Hi Guys, I know i should ask the microchip guys this doubt, & i did register it. I thougtht i would get a quicker response from here. I have a chip marked 16F877A-I/P. From page DS39582B-page231 of your data sheet the chip's operational frequency is written as 10Mhz. So, does that mean i can't use a 20MHZ crystal. IF so what should the chip be marked to operate at 20mhz. Any idea? Regards Raghunathan
  24. You could also declared a union to do the job. typedef union { unsigned int val; struct { char hi; char lo; }byte; } HL; void main() { HL hl; hl.val = 0x1234; char hi = hl.byte.hi; char lo = hl.byte.lo; while( 1 ) } Regards Dave <{POST_SNAPBACK}> For those who are new to C programming this bit of information may be useful. Dave, please tell if i am wrong. The above is a very good example of using union & struct not available in BoostC user manual. the syntax for using the struct is as follows.. struct { char hi; char lo; }byte; // byte is the name given to the struct. typedef union { }HL; // HL is the name of the new data type( like we say int x or char x). // Data types of your choice can be created using typedef. In the main we have... void main() { HL hl; // hl is the new variable with data type declared as HL. hl.val = 0x1234; //hl.val becomes the 16 bit integer. char high_byte = hl.byte.hi; //hl.byte.hi will get us the higher order bits into var high_byte. char low_byte = hl.byte.lo; //hl.byte.lo will get us the low order bits into var low_byte. while( 1 ) } I suppose the properties of union makes it possible to write the below expression. hl.val = 0x1234; Dave, am i right ? Also see that i have changed the variable char hi in the main() in your program to char high_byte. Is this wrong ? Regards Raghunathan.
×
×
  • Create New...