Jump to content

trossin

Moderator
  • Content Count

    243
  • Joined

  • Last visited

Posts posted by trossin


  1. Side question:

     

    Why is it that most people use 9600 baud for their serial connections? I've had plenty of luck over the years with 115K baud but use a 20MHz crystal. Even at 10MHz 56K would work fine (115K is possible also but there may not be enough cycles left for the PIC to do any work between bytes coming in). 9600 baud is less than 1K byte/second.

     

    Back to the real question:

     

    You could transmit the data as a hex string with something like this:

     

    void SendAdcValue(unsigned int AdcValue)
    {
       unsigned char Buf[7];
    
       Buf[0] = '0';  Buf[1] = 'x';
       Buf[2] = (AdcValue>>12) & 0xf);
       Buf[2] += ((Buf[2]>9) ? ('a'-10) : '0');
       Buf[3] = (AdcValue>>8) & 0xf);
       Buf[3] += ((Buf[3]>9) ? ('a'-10) : '0');
       Buf[4] = (AdcValue>>4) & 0xf);
       Buf[4] += ((Buf[4]>9) ? ('a'-10) : '0');
       Buf[5] = (AdcValue>>0) & 0xf);
       Buf[5] += ((Buf[5]>9) ? ('a'-10) : '0');
       Buf[6] = 0;
       puts(Buf);
    }

     

    Then, on the PC side you could use sscanf(Buf,"%x",&AdcValue) to recover your data.

     

    Or, if you want to conserve bandwidth of the RS-232 port your could just send two bytes:

     

    putc(AdcValue>>8);
    putc(AdcValue&0xff);

     

    On the PC side just put the 16-bit value back together again:

     

    AdcValue = (getc()<<8);

    AdcValue |= getc();


  2. Here is some code I wrote last night. I've only tested transmitting at 115K baud but the code is based on some assembler I wrote a few years back. To use it, just call

     

    RS232Init(RS232_10MHZ_BAUD_9600);

     

    Then read/write bytes with RS232putch(unsigned char Val) or RS232getch().

     

    I hope this helps.

     

    serial.c

     

    #include <system.h>
    
    void RS232putch(unsigned char ByteVal)
    {
       /*
          // should work but I have not tested
       while(!(test_bit(pir1,4)));
       txreg = ByteVal;
      */
       asm{
             WaitSendByte:
                  btfss	_pir1,4
      goto	WaitSendByte
    movwf	_txreg
       }
    }
    
    unsigned char RS232getch(void)
    {
       /*
          // should work but I have not tested
       while(!(test_bit(pir1,5)));
       clear_bit(pir1,5);
       return(rcreg);
      */
       asm{
             WaitGetByte:
    btfss	_pir1,5; Wait for byte to show up.	
                     goto	WaitGetByte
    bcf	_pir1,5; Clear the recieved data flag
       }
       return(rcreg);
    }
    
    unsigned char RS232peekch(void)
    {
       if(test_bit(pir1,5)) return(1);
       return(0);
    }
    
    /* Set up serial port to run at 115200 baud */
    
    void RS232Init(unsigned char BaudRate)
    {
    set_bit(trisc,7);	// PORTC[RX] is Input
    clear_bit(trisc,6); // PORTC[TX] is Output
    spbrg = BaudRate;	// Set baud to see header file
    txsta = 0x24;		// Set TXEN and BRGH to 1
    rcsta = 0x90;		// Set SPEN and CREN to 1
    }

     

    serial.h

     

    void RS232Init(unsigned char BaudRate);
    void RS232putch(unsigned char ByteVal);
    char RS232getch(void);
    unsigned char RS232peekch(void);
    
    #define RS232_20MHZ_BAUD_115000		10
    #define RS232_20MHZ_BAUD_57600		20
    #define RS232_20MHZ_BAUD_28800		42
    #define RS232_20MHZ_BAUD_19200		64
    #define RS232_20MHZ_BAUD_9600		129
    
    #define RS232_16MHZ_BAUD_115000		8
    #define RS232_16MHZ_BAUD_57600		16
    #define RS232_16MHZ_BAUD_28800		33
    #define RS232_16MHZ_BAUD_19200		51
    #define RS232_16MHZ_BAUD_9600		103
    
    #define RS232_10MHZ_BAUD_115000		4
    #define RS232_10MHZ_BAUD_57600		10
    #define RS232_10MHZ_BAUD_28800		21
    #define RS232_10MHZ_BAUD_19200		31
    #define RS232_10MHZ_BAUD_9600 		64


  3. When I was younger I would add the following:

     

    org 0x2100

    de 0x12,0x34,0xe2,0xf8

     

    to my assembler source file to get this data into the hex file that my programmer and other's programmers could pick up and initialize the EEPROM to default values. This can not be done at run time as it would overwrite settings that the use may want to retain between power cycles.

     

    Is there a way to tell SourceBoost to do this. I found the rom data type but did not find a eeprom data type.

     

    Currently I'm forced to hand edit the .hex file to add the "factory defaults".

     

    P.S. the eeprom_write and eeprom_read routines are a nice addition.


  4. Thanks Dave. Hidden in that boot loader code I found the answer.

     

        // Jump to 0x1f02
    asm{
           movlw   0x1f
           movwf   _pclath
           movlw   0x02
           movwf   _pcl
    }

     

    I'm still not sure why I can't use my original code but I'm guessing that the linker would get confused. Anyway, this will allow me to use my bootloader that is already programmed into every PIC processor I own and allows me to use my own downloader software that uses binary instead of ASCII as well as only programs locations that have changed to improve programming time. My code also runs at 115K baud and support A versions of the parts that have to be programmed in blocks of 4 words.

     

    http://www.geocities.com/ted_rossin/Electr...ot%20Programmer


  5. I have a 16F8xx bootloader that I place in the range 0x1f00 to 0x1fff for 8K devices and 0x0f00 to 0x0fff in 4K devices. What I would like to do is have my main application jump to location 0x1f02 (the bootloader entry point) when a "Update Firmware" command is recieved. I tried:

     

    asm{
             bsf	_pclath,4
             bsf	_pclath,3
             goto 0x702
    }

     

    I had no luck with this. I tried using a symbol and an org statement and a label but it does not like the org statement. Is there a way to specify and external function and absolute address and then jump or call the function?


  6. Before the net we had to have a lot a patience and trial and error attitude. The design of experiments to trouble shoot problems was also an art praticed. Magazines and data sheets were all we had. So lots of double checking and sanity experiments were the key to sucess.

     

    I soldered up my first computer using perf-board and point-to-point wire armed with a $20 logic probe, RCA 1802 data, CMOS and TTL data books and a Popular Electronics magazine back in 1977! It took nearly a month but I got it working.


  7. Bug description:

    When array address math used inside a function using a function parameter, the compiler generates code that uses an uninitialized variable.

     

    This small program:

     

    #include <system.h>
    
    void Junky(char *s)
    {
    }
    
    void FunTime(char *s)
    {
       Junky(&s[1]);  // Generates bad code
    }
    
    void main()
    {
       char s[10];
       
       s[0] = '-';
       FunTime(&s[1]);  // Generates good code
    
    
       while(1);
    }

     

    produces the following code that adds the uninitialized CompTempVar53 to the address of s instead of 1 in the function FunTime at address 8. Here is the output of BoostC.

     

    ;/////////////////////////////////////////////////////////////////////////////////
    ;// Code Generator: BoostC Compiler - http://www.sourceboost.com
    ;// Version       : 6.35
    ;// License Type  : Full License
    ;// Limitations   : PIC12,PIC16 max code size:Unlimited, max RAM banks:Unlimited, Non commercial use only
    ;/////////////////////////////////////////////////////////////////////////////////
    
    ORG 0x00000003
    0003  281A 	 GOTO	_startup
    ORG 0x00000006
    0006        Junky_00000
    ; { Junky; function begin
    0006  0008 	 RETURN
    ; } Junky function end
    
    ORG 0x00000007
    0007        FunTime_00000
    ; { FunTime; function begin
    0007  082A 	 MOVF FunTime_00000_arg_s, W
    0008  072E 	 ADDWF CompTempVar53, W
    0009  00AC 	 MOVWF Junky_00000_arg_s
    000A  082B 	 MOVF FunTime_00000_arg_s+D'1', W
    000B  00AD 	 MOVWF Junky_00000_arg_s+D'1'
    000C  1803 	 BTFSC STATUS,C
    000D  0AAD 	 INCF Junky_00000_arg_s+D'1', F
    000E  2006 	 CALL Junky_00000
    000F  0008 	 RETURN
    ; } FunTime function end
    
    ORG 0x00000010
    0010        main
    ; { main; function begin
    0010  302D 	 MOVLW 0x2D
    0011  1283 	 BCF STATUS, RP0
    0012  1303 	 BCF STATUS, RP1
    0013  00A0 	 MOVWF main_1_s
    0014  3000 	 MOVLW HIGH(main_1_s+D'1')
    0015  00AB 	 MOVWF FunTime_00000_arg_s+D'1'
    0016  3021 	 MOVLW LOW(main_1_s+D'1')
    0017  00AA 	 MOVWF FunTime_00000_arg_s
    0018  2007 	 CALL FunTime_00000
    0019        label268436513
    0019  2819 	 GOTO	label268436513
    ; } main function end
    
    ORG 0x0000001A
    001A        _startup
    001A  118A 	 BCF PCLATH,3
    001B  120A 	 BCF PCLATH,4
    001C  2810 	 GOTO	main

     

    Steps to reproduce:

    Using a 16F873 target for this case but also fails for 16F876A. Just need to do the same in any subroutine but must use a call paramter of the subroutine to get it to fail.

     

    Expected behaviour:

    Should use s+1 insead of s+random_value in the FunTime subroutine.

     

    Is the problem 100% reproduceable:

    Yes

     

    IDE version: 6.35

    Compiler: BoostC

    Compiler version: 6.35

    Target device: PIC16F873

    OS: WinXp

     

    Comments:

    I was able to work around the problem by changing:

     

    Junky(&s[1]);

     

    to

     

    Junky(s+1);


  8. trossin,

     

    I'm using version 6.35 and when I tab over and type a line of text:

     

    if(I_dont_want_auto_indent){

     

    Instead of the cursor going to column 1 (like I like) it goes to column 4. This happens no matter what I have the Editor Settings dialog box "Smart Indentation" set to.

    Try changing tab size to 1.

     

    Regards

    Dave

     

    No that didn't work but I apologize for not doing a preview before submitting my post as I wanted the line indented by 4 spaces. I'll try again. Assume that bbbb is 4 spaces or 1 tab:

     

    bbbbif(I_dont_want_auto_indent){

     

    What I want to know is why when I turn off (leave off) "Smart Indentation" does the insert point after I hit enter show up in column 5 (under the i in if) instead of column 1. In the unix editor vi I would do a :set noai to turn this off.

     

    It seems that "Smart Indentation" is always turned on. Or I do not know what it means. I checked the IDE user manual and there was no data on the subject.


  9. Sorry for the confusion. I was looking at the assembler output instead of using my head. I've only been using a trial of BoostC and doing experiments before I send in the money and add a link on my web site. So far, everything looks great. It would be nice if you included a real printf like the other guys but for $930 less money I'll live without it.

     

    It does not seem possible to create a real "void printf(char *Format, ...)" function as BoostC does not seem to support variable argument lists. Even if the code had to have an assembler interface, I'm not sure how I would pick off the parameters.

     

    I've seen the LCD printf like functions but they only take one parameter which gets the job done but they are a bit of a pain as users have to recode them to be more general for their needs. The other guys have their printf call a user supplied putch function so that printf can be wired up to a serial port, LCD, papertape punch or whatever. I'm just making a single variable sprintf and tossing it into a library.


  10. When I compile a simple function like below without an asm block and use Val1 and return something it looks like I should use Lcd2WriteCo_00013_arg_Val1 to refrence Val1 within my asm block. When I try this, the compiler tells me that this symbol does not exist (with or without an _).

     

    unsigned char LcdWriteCommand(unsigned char Val1)
    {
       return(Val1 + 3);
    }
    
    output:
    
    0006        LcdWriteCo_00013
    ; { LcdWriteCommand; function begin
    0006  3003 	 MOVLW 0x03
    0007  0721 	 ADDWF LcdWriteCo_00013_arg_Val1, W
    0008  00A0 	 MOVWF CompTempVarRet0
    0009  0008 	 RETURN

     

    Is the only answer:

     

    unsigned char LcdWriteCommand(unsigned char Val1)
    {
       unsigned char Param1=Val1, ReturnVal;
    
       asm{
            movlw 3
            addwf _Param1,W
            movwf _ReturnVal
       }
       return(ReturnVal);
    }

     

    or is there something more efficient that can be done?


  11. I've been playing around with PIC microcontrollers for a few years now but am new to SourceBoost.

     

    Here is a link to some of my PIC projects:

     

    http://www.geocities.com/ted_rossin/Electronics/Pic/Pic.html

     

    One of my projects is a boot loader for 87x(A) parts. I used to use the HI-TECH compiler and they always left the first 3 locations free and did the jump at location 3 to the start of code. This way I could use the first three locations to set both PCLATH bit and then jump to my bootloader that I placed at the last 256 words of ROM space. The bootloader then jumps to location 3 on exit. All is cool.

     

    HI-TECH recently changed this and they now put their jump at location 2 but I'm able to deal with this by moving the jump to location 3 and all is fine.

     

    SourceBoost puts the jump at location 0 so I just detect the jump in any of the first 3 locations and put it at location 3 and all is fine. This works fine until I generate code without an interrupt handler. In this case SourceBoost does no jump and just puts linear code from location 0 to N. This makes it impossible for the bootloader to work.

     

    My work-around to this problem is to always include an interrupt handler so that location 4 has to be jumped around.

     

    Is it possible to tell BoostC to not use location 3 and put a jump within the first 3 instructions to the real start of the program?

     

    P.S. I've been quite happy with the compiler so far and after a little more work I will reference it on my web page.

×
×
  • Create New...