Jump to content

ra68gi

EstablishedMember
  • Content Count

    229
  • Joined

  • Last visited

Posts posted by ra68gi


  1. I just purchased the Microchip Pickit2 with the included LPC demo board.

    Since I did read the followed 'readme.txt' that I should be carefull about using the onboard switch SW1, I mounted a extra switch pulledup to Vdd and connected to portA bit 2.

    Now it comes.. whatever I do it seems that the PIC internal always read 0 = low level.

    Can some one give me a clue what I missed?

     

    Thanks - Jens

     

    #include <system.h>

     

    #pragma CLOCK_FREQ 4000000 //in Hz.

     

    // Set configuration fuse

    #pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF

     

    #define SW1 porta.3 // SW1 is alais for porta.3 = RA3

    #define SW2 porta.2 // SW2 is alais for porta.2 = RA2

    #define RP01 porta.0 // RP1 is alais for A/D on RA0

     

    #define DS1 portc.0 // DS1 is alais for RC0

    #define DS2 portc.1 // DS1 is alais for RC1

    #define DS3 portc.2 // DS1 is alais for RC2

    #define DS4 portc.3 // DS1 is alais for RC3

     

    int X = 0; // X is declared as global variable.

     

     

    void main(void)

    { // Program entry point.

    trisa = 4; // set porta pin2 as input.

    // trisb = 0; // set portb pins as output.

    // portb = 0; // set portb pins to low.

    trisc = 0; // set portc pins as output.

    portc = 0; // set portc pins to low.

     

     

    while(1) // infinite loop.

    {

    X++;

    delay_ms(200);

    if(SW2) /* RA2=1 */ // if SW2 button is not pressed, execute

    { // the following statements.

    portc = X;

    delay_ms(200); // pause for 200ms.

    if(X > 14)

    X=0;

    }

    else /* RA2=0 */ // else if porta.0 pin is low = pressed then

    { // execute the statements below.

    portc = 6;

    delay_ms(200);

    delay_ms(200);

    }

    }//end while

    }//END MAIN

     

    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. SD/MMC cards need 512byte buffers and most 16F's only go to 256 in EEPROM, some 368. So yes, Pavel understood me correctly. I did mean program memory.

     

    Thanks for pointing out the flash_ statements. Will these will work with any 'self-write' PIC in the 16F and 18F ranges or only the ones mentioned?

    David.

     

    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. Hi. I can create and read an array created with the rom char statement. Is it possible to write to this array from within the program to use as a temporary data logging store (before writing to SD card)?

     

    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 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


  5. I am trying to learn the basics of C on my PC first, using a public domain C compiler. Once I've got the hang of that, I'll move "down" to my PIC

     

    Laurence Wilkins

    www.MrNixie.com - see what I mean about the "non-standard output device? ;) )

     

    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.


  6. Sirs:

     

    I have been using the rs232_driver with a pic16f628 on a couple of projects. My question is about including the #define MODE (USART_reset_wdt | USART_HW).

     

    Is it a good idea to setup a wdt when using rs232? I had always just selected the USART_HW and let it go at that. But there have been a couple of times when my boxes would fail to respond and have to be rebooted. I have no idea what the problem was, as it only happened once or twice over months of use.

     

    Thank-you for any help

    Douglas

     

    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.


  7. Thanks, Richard. This interrupt will be an input state change triggered by a push-button so I don't have another on it's way if I debounce it adequately and disable interrupts while in the interrupt function itself. I would like to measure the button press duration to select modes, write to EEPROM, make 12 LED's flash in special patterns, etc. This quickly builds up into code of some substance.

     

    I will take another look at ra68qi's post; its been helpful before. Thanks for the prototyping example.

    David.

     

    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.


  8. 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


  9. Raghunathan,

     

    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..

     

    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.

     

    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.


  10. OK, I give up! I must have missed something in the manual and have this simple problem that I don't understand relating to writing to bits in a port.

     

    The code below works fine and shows a 100ms square wave on pin A0;

     

    void main()

    {

    trisa = 0;

    while( 1 )

    {

    porta.0=1;

    delay_ms(50);

    porta.0=0;

    delay_ms(50)

    ;

    }

    }

     

    The code below doesn't work and is making me crazy. Now I see is the squarewave on A1 and just short (us) pulses on A0.

     

    void main()

    {

    trisa = 0;

    while( 1 )

    {

    porta.0=1;

    porta.1=0; // I added this

    delay_ms(50);

    porta.0=0;

    porta.1=1; //and this

    delay_ms(50);

    }

    }

     

    It almost looks like the porta.1 operation is resetting A0.

     

    What am I missing? Is this part of the much feared read modify write beast? I am sure this is a common problem, but I haven't had much luck searching the forum --mostly because I can't seem to define the problem.

     

    In the larger problem, I have a mix of input and output pins on port a -- so I want to write to specific pins as well as read from specific pins.

     

    du-uh! :P

     

    Rye

     

    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.


  11. 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


  12. Not if you intelligently use priority interrupts or alternativly give NOVOS a spin.

     

    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.


  13. 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.


  14. emte,
    To sumarize, looking at the MSB to determine sign is not technically

    correct nore proper, but it is a noticable trait for determining signed vs unsigned number.

    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


  15. I have reduced the code to this..

    if( counter < 0 )

    {

    counter1 = (-1)*counter;

    encoder_sign_flag = 0 ;

    bcd();

     

    }

    else

    {

    encoder_sign_flag = 1 ;

    counter1 = counter ;

    bcd();

    }

    }

    display();

    }

     

    void 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 ;

    }


  16. (counter>>15)?sign=0x8:sign=0xFF; /* bar value or 0xFF marker for space */

    counter = variable & 0x7FFF; /* strip off signed

    {[/code]

     

    Even if you write a custom function you will still pretty much do the same thing since all you are

    actually doing is converting your values into segment locations.

     

    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.


  17. 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.


  18. DavidT,
    Hi. I'm wanting to select the lower 8 bits (and upper) from a 16bit variable. How do I do this with BoostC please? With CC5X I'm used to variable.low8 and .high8.

    Thanks, David.

     

    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

    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.


  19. Basic Hardware Uart usage

     

    /* bare min in interrupt for rx 
    *  * remember to clear out the holder fast enough, will start dumping after 3 bytes or use multi-dimension
    */
    if(rcif)
    {
      rxHolder[rxCount] = rcreg;  /* read data into array to handle in main when count max is reached */
      rxCount++;                            /* increment count */
      rcif = 0;                                   /* safety clear - SHOULD clear on rcreg read */
    }
    
    
    /* minimal non-blocking send 
       under timer trigger if critical 
       otherwise handled general in main
    */
    if(!txsta)   /* is last send done? skip if not */
    {
      txreg = dataToSend;
    }

     

    Thats about it other than setting up the registers.

     

    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.


  20. 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


  21. DavidT,
    Hi. I'm wanting to select the lower 8 bits (and upper) from a 16bit variable. How do I do this with BoostC please? With CC5X I'm used to variable.low8 and .high8.

    Thanks, David.

     

    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

     

    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...