Jump to content

TimC

EstablishedMember
  • Content Count

    26
  • Joined

  • Last visited

Community Reputation

0 Neutral

About TimC

  • Rank
    Regular

Profile Information

  • Gender
    Male
  • Location
    Boston MA
  1. Sourceboost is a great product. I just think the 8-bit micro's are not as interesting as they used to be but I still like them because they are easy to work with. Take a look at Google trends and you will see a downward slope for search terms such as Microchip, Atmel, mplab and so forth.
  2. Hi all, Here is a batch file I have been using to program my pic chips within the IDE. Before I was not able to program using the ICD3 because of the character space between the parm "F" and the hex file name. The ICD3 command line software would report back saying "enter hex file name". A separate batch file seems like a lot of work to just get rid of a single space so I added some functionality to make it more worthwhile. Enjoy Tim C =================== Batch file follows ======================== @echo off @setlocal ::Version 0.9 Boost Programmer assistant ::This bat file sits in the base of your source code projects directory like D:\PIC\BOOSTC so you only need to maintain one copy ::The first parm (%1) is the Programmer code name like ICD3 ::The Pic chip name is the second parm (%2) within BoostC it is %shorttarget%. If you need to, just add "PIC" in front of your chip parm. ::The third (%3) and last parm is the hex file name like Debug\main.hex ::TODO: Adjust the programmer command lines for path and parms. Set echo off to debug :: :: Example BoostC programmer line: ..\BoostBurn.bat ICD3 %shorttarget% :: ::Advantages: ::More flexability for programmer command lines ::One batch file to maintain ::Easier to manage and see the IDE tools programmer line ::I could not get ICD3 to work before, now I can. ::Add different configurations for the same programmer ::Ability to do further processing if /i %1 == ICD3e "C:\Program Files\Microchip\MPLAB IDE\Programmer Utilities\ICD3\ICD3CMD.exe" -P%2 -E -F%3 -M -L if /i %1 == ICD3 "C:\Program Files\Microchip\MPLAB IDE\Programmer Utilities\ICD3\ICD3CMD.exe" -P%2 -F%3 -M -L if /i %1 == CCS "C:\Program Files\PICC\CCSLoad.exe" DEVICE=PIC%2 /T%3 if /i %1 == MELABS "C:\Program Files\Pic\melabs Programmer\meProg.exe" -n -X -DPIC%2 -e -P -q1 %3 if /i %1 == MICRO "C:\Program Files\Pic\Mikroelektronika\mikroProg Suite For PIC\mikroProg Suite For PIC.exe" -w -q -pPIC%2 %3 if /i %1 == EZ "C:\Program Files\Pic\BoostC\EZDownloader.exe" -p 1 %3 if /i %1 == WARP "C:\Program Files\PIC\Warp13\WARP13.EXE" %3 -PIC%2 IF %ERRORLEVEL% GTR 0 goto BurnError echo ===== Clean Programmer Download, Now Running ====== goto exit :BurnError echo ==== Programmer Error ===== rem echo Error Level = %ERRORLEVEL% goto exit :exit
  3. Ted, You have done an amazing job recreating the old 1802. It really shows your talents! Also your work with the 1802 C compiler probably got me more interested in that chip than anything. Yup call me an old fart. Tim
  4. TimC

    External Editor Brought Up In Ide V7.0!

    What is going on here?? origional post I feel very weird. I don't power up my PC quite so early in the morning. Still TimC I think
  5. TimC

    External Editor Brought Up In Ide V7.0

    Thank you works for me too.
  6. Hi, Is there a way to stop the new V7.0 IDE from bringing up my external editor when I click on a file in the workspace view? The V6.97 IDE does not do this. I have *.c and *.h files associated with ultraedit for many years and has not caused problems with my other IDE/compilers. Thanks TimC
  7. Thank you Pavel for answering my question. This really is a huge advancement for small memory devices! Lots of examples will help your users understand how to use this feature and give you a competitive advantage. I have already rewritten the LCD template so that the control pins can all be on different ports but I have much more to learn.
  8. Thank You It's a start. I am looking for a software based SPI, but I could back step a little more and try this on hardware SPI platform then modify to software bit bang. One question I have yet to figure out. How do I use the templates to define more than one? For example what does code look like for using 2 LCD's (lcd_driver.h) or 2 Serial ports (rs232_driver.h) or two I2C devices (i2c_driver.h) TimC
  9. I have 3 SPI devices on an X1 micro Engineering board, DS1620 Temp, DS1302 clock and a 25LS640 EEProm. Being used for a Temperature recording project. My problem is how to reuse a software SPI.h and SPI.c files which contain all the shift in and shift out calls. Currently the calls are designed so the header file points to one device at a time. ------------------------------------------------ //#define CS_TRIS TRISA // ds1302, spi eeprom //#define CS_PORT PORTA // ds1302, spi eeprom #define CS_TRIS TRISC // ds1620 #define CS_PORT PORTC // ds1620 //#define CS_PIN 2 //ds1302 //#define CS_PIN 5 //spi eeprom #define CS_PIN 0 //ds1620 ------------------------------------------------ I have looked at using templates and I do not see how to create multiple definitions like 2 LCD’s or 2 serial ports. It all looks like define once and use that one instance. To me what would make the most sense would be creating a SPI class that defines an instance/device. But all I have seen so far is comments stating you can not efficiently pass port names. What would look so nice and be maintainable would be: //create new SPI instance for DS1302 using CLK @ PORTA.1, I/O @ PORTB.2 and Select @ PORTB,3 SPI *DS1302 = new SPI(PORTA,1,PORTB,2,PORTB,3); And just for reference this is what the simple Basic interpreter can do. ------------------------------------------------ ReadRtcBurst: 'read all time keeping in one burst HIGH Rtccs SHIFTOUT Dta, Clk, LSBFIRST,[%1\1,BrstReg\5,%10\2] SHIFTIN Dta, Clk, LSBPRE,[seconds,Minutes,Hours,Date,Month,Day,Year] 'debug cr,"Burst read ",hex2 Month,"/",hex2 Day,"/",hex2 Year," ",hex2 Hours,":",hex2 Minutes," ",hex2 Seconds LOW Rtccs RETURN ------------------------------------------------ Ok basic has a ton of problems like no call stack but they can pass the port names Maybe shiftout and shiftin should each be a template and SPI.c and SPI.h is on top of that? Oh and code portability I don’t think I am asking for too much am I? Thank You TimC
  10. The mikroelectronika dev boards are great and getting better. I have the EasyPic4 here. Sad to say you are going to have to change your .H files. One idea is to make a multi-board header file like this: Regards Tim C // Define the LCD connections for the EasyPic4 board here // these names are defined using the Settings-->options-->compiler // and then adding the compiler option -d boardname #ifdef EASYPIC4 #define LCD_LOW_SPEED 1 // 1 if not using RW and input in data pin 7 #define LCD_E_PORT PORTD #define LCD_RS_PORT PORTD #define LCD_RW_PORT PORTD #define LCD_DATA4_PORT PORTD #define LCD_DATA5_PORT PORTD #define LCD_DATA6_PORT PORTD #define LCD_DATA7_PORT PORTD #define LCD_E_TRIS TRISD #define LCD_RS_TRIS TRISD #define LCD_RW_TRIS TRISD #define LCD_DATA4_TRIS TRISD #define LCD_DATA5_TRIS TRISD #define LCD_DATA6_TRIS TRISD #define LCD_DATA7_TRIS TRISD #define LCD_E_PIN 3 #define LCD_RS_PIN 2 #define LCD_RW_PIN 1 #define LCD_DATA4_PIN 4 #define LCD_DATA5_PIN 5 #define LCD_DATA6_PIN 6 #define LCD_DATA7_PIN 7 #define LCD_BOARD_DEFINED #endif // Define the LCD for the ETT CP-PIC V4 board (then add the compiler option -d boardname) #ifdef ETTCPV4 #define LCD_LOW_SPEED 1 // 1 if not using RW and input in data pin 7 #define LCD_E_PORT PORTA #define LCD_RS_PORT PORTC #define LCD_RW_PORT PORTD // dummy not real could move #define LCD_DATA4_PORT PORTD #define LCD_DATA5_PORT PORTD #define LCD_DATA6_PORT PORTD #define LCD_DATA7_PORT PORTD #define LCD_E_TRIS TRISA #define LCD_RS_TRIS TRISC #define LCD_RW_TRIS TRISD // dummy not real #define LCD_DATA4_TRIS TRISD #define LCD_DATA5_TRIS TRISD #define LCD_DATA6_TRIS TRISD #define LCD_DATA7_TRIS TRISD #define LCD_E_PIN 4 #define LCD_RS_PIN 0 #define LCD_RW_PIN 7 // dummy not real #define LCD_DATA4_PIN 4 #define LCD_DATA5_PIN 5 #define LCD_DATA6_PIN 6 #define LCD_DATA7_PIN 7 #define LCD_BOARD_DEFINED #endif // Define the LCD for the x1 board #ifdef X1BOARD #define LCD_E_PORT PORTE #define LCD_RS_PORT PORTE #define LCD_RW_PORT PORTE #define LCD_DATA4_PORT PORTD #define LCD_DATA5_PORT PORTD #define LCD_DATA6_PORT PORTD #define LCD_DATA7_PORT PORTD #define LCD_E_TRIS TRISE #define LCD_RS_TRIS TRISE #define LCD_RW_TRIS TRISE #define LCD_DATA4_TRIS TRISD #define LCD_DATA5_TRIS TRISD #define LCD_DATA6_TRIS TRISD #define LCD_DATA7_TRIS TRISD #define LCD_E_PIN 1 #define LCD_RS_PIN 0 #define LCD_RW_PIN 2 #define LCD_DATA4_PIN 4 #define LCD_DATA5_PIN 5 #define LCD_DATA6_PIN 6 #define LCD_DATA7_PIN 7 #define LCD_BOARD_DEFINED #endif #ifndef LCD_BOARD_DEFINED #error "You must define a ~development board name~ using the compiler option -d on the command line" #endif
  11. TimC

    Spi Interface & Boostc++

    The SPI interface can be handled using software or hardware and by interrupts as well. Mikrobasic as I recall does not have all the options one might need. Since I am not sure what you want, here is some software bit bang driven SPI code that will work in the most situations. Also see the bottom for a link to some One Wire code. Also look for Lieven Hollevoet's code at http://boostc.lika.be Regards Tim FIRST THE H FILE #ifndef _SOFTSPI_H_ #define _SOFTSPI_H_ #include <system.h> #define INPUT 1 #define OUTPUT 0 #define SET 1 #define CLEAR 0 #define DISABLE 0 #define ENABLE 1 #define HIGH 1 #define LOW 0 // clock #define CLK_TRIS TRISC // trisa, trisb or trisc #define CLK_PORT PORTC #define CLK_PIN 3 // chip select #define CS_TRIS TRISC #define CS_PORT PORTC #define CS_PIN 0 // chip select polarity (Comment out the wrong one) //#define CS_POSITIVE #define CS_NEGATIVE // data i #define DATAI_TRIS TRISC #define DATAI_PORT PORTC #define DATAI_PIN 4 // data o #define DATAO_TRIS TRISC #define DATAO_PORT PORTC #define DATAO_PIN 5 //------------- Configure pins above this line ----------- /////////////////////////////////////////////////////////// // Don't change below this line // The TRIS register bits volatile bit spi_clk_dir @ CLK_TRIS . CLK_PIN; //volatile bit spi_data_dir @ DATA_TRIS . DATA_PIN; volatile bit spi_cs_dir @ CS_TRIS . CS_PIN; volatile bit spi_datai_dir @ DATAI_TRIS . DATAI_PIN; volatile bit spi_datao_dir @ DATAO_TRIS . DATAO_PIN; // another example of defining a pin //volatile bit pinB1@0x6.1; //declare bit variable mapped to pin 1, port B // The chip select of the device connected to the port volatile bit spi_cs @ CS_PORT . CS_PIN; #ifdef CS_NEGATIVE #define spi_enable spi_cs = 0; delay_us(5); #define spi_disable spi_cs = 1; delay_us(5); #else #define spi_enable spi_cs = 1; delay_us(5); #define spi_disable spi_cs = 0; delay_us(5); #endif volatile bit spi_clock @ CLK_PORT . CLK_PIN; #define clock_high spi_clock = 1; delay_us(5); #define clock_low spi_clock = 0; delay_us(5); #define clock_high_low spi_clock = 1; delay_us(5); spi_clock = 0; delay_us(5); //volatile bit spi_data @ DATA_PORT . DATA_PIN; //#define data_high spi_data = 1; delay_us(5); //#define data_low spi_data = 0; delay_us(5); volatile bit spi_datai @ DATAI_PORT . DATAI_PIN; //#define datai_high spi_datai = 1; delay_us(5); //#define datai_low spi_datai = 0; delay_us(5); volatile bit spi_datao @ DATAO_PORT . DATAO_PIN; //#define datao_high spi_datao = 1; delay_us(5); //#define datao_low spi_datao = 0; delay_us(5); void spi_init(); void spi_write_lsbfirst(unsigned char cmd); unsigned char spi_read_lsbpre(); unsigned char spi_xfer_lsb(unsigned char cmd); unsigned char spi_xfer_lsb(unsigned char cmd, unsigned char data1, unsigned char data2); void spi_write_lsb(unsigned char data); void spi_write_lsb(unsigned char cmd,unsigned char data); void spi_write_lsb(unsigned char cmd, unsigned char data, unsigned char data2); void spi_write_msbfirst(unsigned char cmd); unsigned char spi_read_msbpre(); unsigned char spi_xfer_msb(unsigned char cmd); unsigned char spi_xfer_msb(unsigned char cmd, unsigned char data1, unsigned char data2); // these are the ones we mainly call void spi_write_msb(unsigned char data); void spi_write_msb(unsigned char cmd,unsigned char data); void spi_write_msb(unsigned char cmd, unsigned char data, unsigned char data2); void spi_write_msb(unsigned char cmd, unsigned char data, unsigned char data2, unsigned char data3); #endif //_SPI_H_ NOW THE C FILE // TIMS SPI FACTORY THIS WORKS SO WE ARE HAPPY #include <system.h> #include "softspi.h" //#include "timtest.h" void spi_init() { unsigned char x; spi_cs_dir = OUTPUT; spi_disable spi_clk_dir = OUTPUT; spi_clock = LOW; spi_datao_dir = OUTPUT; spi_datai_dir = INPUT; } /* ----------------------------------------------------------------------- */ /* write byte ------- */ /* ----------------------------------------------------------------------- */ void spi_write_lsbfirst(unsigned char cmd) { unsigned char i; bool z; spi_datao_dir = OUTPUT; for(i=0;i<=7;i++) { z = test_bit(cmd,i); spi_datao = z; clock_high_low } } /* ----------------------------------------------------------------------- */ /* write byte ------- */ /* ----------------------------------------------------------------------- */ void spi_write_msbfirst(unsigned char cmd) { unsigned char i; bool z; spi_datao_dir = OUTPUT; for(i=8;i>0;i--) { z = test_bit(cmd,(i-1)); spi_datao = z; clock_high_low } } /* ----------------------------------------------------------------------- */ /* write 1 byte ------- */ /* ----------------------------------------------------------------------- */ void spi_write_lsb(unsigned char data) { spi_enable spi_write_lsbfirst(data); spi_disable } /* ----------------------------------------------------------------------- */ /* write 1 byte ------- */ /* ----------------------------------------------------------------------- */ void spi_write_msb(unsigned char data) { spi_enable spi_write_msbfirst(data); spi_disable } /* ----------------------------------------------------------------------- */ /* write 2 bytes ------- */ /* ----------------------------------------------------------------------- */ void spi_write_lsb(unsigned char cmd, unsigned char data) { spi_enable spi_write_lsbfirst(cmd); spi_write_lsbfirst(data); spi_disable } /* ----------------------------------------------------------------------- */ /* write 2 bytes ------- */ /* ----------------------------------------------------------------------- */ void spi_write_msb(unsigned char cmd, unsigned char data) { spi_enable spi_write_msbfirst(cmd); spi_write_msbfirst(data); spi_disable } /* ----------------------------------------------------------------------- */ /* write 3 bytes ------- */ /* ----------------------------------------------------------------------- */ void spi_write_lsb(unsigned char cmd, unsigned char data, unsigned char data2) { spi_enable spi_write_lsbfirst(cmd); spi_write_lsbfirst(data); spi_write_lsbfirst(data2); spi_disable } /* ----------------------------------------------------------------------- */ /* write 3 bytes ------- */ /* ----------------------------------------------------------------------- */ void spi_write_msb(unsigned char cmd, unsigned char data, unsigned char data2) { spi_enable spi_write_msbfirst(cmd); spi_write_msbfirst(data); spi_write_msbfirst(data2); spi_disable } /* ----------------------------------------------------------------------- */ /* write 4 bytes ------- */ /* ----------------------------------------------------------------------- */ void spi_write_msb(unsigned char cmd, unsigned char data, unsigned char data2, unsigned char data3) { spi_enable spi_write_msbfirst(cmd); spi_write_msbfirst(data); spi_write_msbfirst(data2); spi_write_msbfirst(data3); spi_disable } /* ----------------------------------------------------------------------- */ /* read byte ------- */ /* ----------------------------------------------------------------------- */ unsigned char spi_read_lsbpre() { unsigned char i,x,data=0; spi_datai_dir = INPUT; for(i=0;i<=7;++i) { data = data >> 1; x = spi_datai; if (x) data |= 0x80; clock_high_low } return(data); } /* ----------------------------------------------------------------------- */ /* read byte ------- */ /* ----------------------------------------------------------------------- */ unsigned char spi_read_msbpre() { unsigned char i,x,data=0; spi_datai_dir = INPUT; for(i=0;i<=7;++i) { data = data << 1; x = spi_datai; if (x) data |= 0x01; clock_high_low } return(data); } /* ----------------------------------------------------------------------- */ /* xfer byte ------- */ /* ----------------------------------------------------------------------- */ unsigned char spi_xfer_lsb(unsigned char cmd) { unsigned char data=0; spi_enable spi_write_lsbfirst(cmd); data = spi_read_lsbpre(); spi_disable return(data); } /* ----------------------------------------------------------------------- */ /* xfer byte ------- */ /* ----------------------------------------------------------------------- */ unsigned char spi_xfer_msb(unsigned char cmd) { unsigned char data=0; spi_enable spi_write_msbfirst(cmd); data = spi_read_msbpre(); spi_disable return(data); } /* ----------------------------------------------------------------------- */ /* New xfer byte ------- */ /* ----------------------------------------------------------------------- */ unsigned char spi_xfer_lsb(unsigned char cmd, unsigned char data1, unsigned char data2) { unsigned char data=0; spi_enable spi_write_lsbfirst(cmd); spi_write_lsbfirst(data1); spi_write_lsbfirst(data2); data = spi_read_lsbpre(); spi_disable return(data); } /* ----------------------------------------------------------------------- */ /* New xfer byte ------- */ /* ----------------------------------------------------------------------- */ unsigned char spi_xfer_msb(unsigned char cmd, unsigned char data1, unsigned char data2) { unsigned char data=0; spi_enable spi_write_msbfirst(cmd); spi_write_msbfirst(data1); spi_write_msbfirst(data2); data = spi_read_msbpre(); spi_disable return(data); } For your last question here is a one wire sample One wire for DS18S20
  12. Pic to Pic one wire would be a real challenge. however you could take a look at this code: One Wire Regards Tim
  13. Hi, I have always had to go through several of the settings when changing a chip or starting a new test project. Problem is I can never remember where everything is. Like I think the menu item should say chip or uCPU but it says target, Toolsuite to me should say Compiler, Options Tools sounds like Toolsuite but means something different. Renaming some of these items might cause an uproar I think it might be much better to bring them together on one or two screens so you can see if your project is set up right, mainly if something is not working and you need to check more than your code. In addition is there a way to better edit the contents of the programmer drop down? Programmer parms and paths can be so long and the edit box is very short. Is it safe to delete them in the registry? Thanks Tim
  14. TimC

    Max Size Of A Class?

    Pavel, Your new version 6.91 works perfectly. I do not see any of the problems I was having before. I have about 50 more bytes to play with inside the class now. I am so pleased thank you for your work Regards Tim
  15. Hi All, I have been working on a general utility that would help me with many of the one wire devices. This routine is a start and it should work with any speed uP but I have only been testing it with 20mhz devices. When using the routines with just ground and data connected I am getting about 80% success rate with crc. When using the routines with 3 wires it's 100% no bad packets for days. A simple test harness would go sort of like this: oo_tx(0xcc,0x44); delay_s(1); // give time to make temperature oo_tx(0xcc,0xbe); for(x=0; x<8; x++) { ow_temp_reading[x] = oo_rx_byte(); } x =oo_rx_byte(); //last time get the crc oo_busreset(); Regards TimC FIRST THE H FILE: #ifndef _ONEWIRE_H_ #define _ONEWIRE_H_ #include <system.h> // One wire port configure #define OO_PORT PORTC #define OO_TRIS TRISC #define OO_PIN 0 // --------------------------------- #define oo_readmode oo_bus_tris = 1 #define oo_writemode oo_bus_tris = 0 volatile bit oo_bus @ OO_PORT . OO_PIN; volatile bit oo_bus_tris @ OO_TRIS . OO_PIN; unsigned char oo_busreset(); void oo_tx_byte(unsigned char data); unsigned char oo_rx_byte(); void oo_tx(unsigned char data); void oo_tx(unsigned char data, unsigned char data2); unsigned char oo_powered(); unsigned char onewire_init(); #endif // _ONEWIRE_H_ AND HERE IS THE C FILE #include "onewire.h" // Remember to change h file for one wire pin define //////////////////////////////////////////////////////////// // oo_busreset() // Returns: 0 if a presence pulse was detected // 1 if no device was detected //////////////////////////////////////////////////////////// char oo_busreset(){ oo_bus = 0; // Send the reset pulse oo_writemode; // therefore, make port low delay_10us(60); // Wait for 600 µs, this is the reset pulse oo_readmode; // Release bus delay_10us(10); // Wait 60 us (release) + 40 us (let device drive the bus) // Now sample, if there is a sensor on the bus, the line should be low if (oo_bus){ return 1; // no devices } delay_10us(40); // Wait another 400 us to complete the reset sequence return 0; } //////////////////////////////////////////////////////////// // oo_tx_bit(bit value) // // Transmits a single bit over the bus //////////////////////////////////////////////////////////// void oo_tx_bit(bit value){ // Pull bus low oo_writemode; oo_bus = 0; // Start the write slot delay_us(2); if (value == 0){ delay_10us(6); // Write a '0' (hold the bus for another 60 us) oo_readmode; // Release the bus } else { oo_readmode; // Release the bus delay_10us(6); // Write a '1' using pullup } delay_us(2); // Final wait for the bus to calm down new 11/13 (was 10us) return; } //////////////////////////////////////////////////////////// // char oo_rx_bit() // // Receives a single bit from the bus //////////////////////////////////////////////////////////// unsigned char oo_rx_bit(){ char value = 0; // Bus low oo_writemode; oo_bus = 0; delay_us(2); // Release bus oo_readmode; delay_us(8); value = oo_bus; // Wait for the end of the read time slot delay_10us(12); // new on 11/13 (was 50us) return value; } //////////////////////////////////////////////////////////// // oo_tx_byte(char data) // // Transmits a single byte from the bus //////////////////////////////////////////////////////////// void oo_tx_byte(unsigned char data) { char counter = 0; while (counter < 8){ if (data & 0x01){ oo_tx_bit(1); } else { oo_tx_bit(0); } data = data >> 1; counter++; } // leave Power on Bus oo_writemode; oo_bus = 1; } //////////////////////////////////////////////////////////// // oo_tx(char data) // // Transmits a single byte from the bus //////////////////////////////////////////////////////////// void oo_tx(unsigned char data) { oo_busreset(); oo_tx_byte(data); } //////////////////////////////////////////////////////////// // oo_tx(char data) // // Transmits a 2 bytes from the bus //////////////////////////////////////////////////////////// void oo_tx(unsigned char data, unsigned char data2) { oo_busreset(); oo_tx_byte(data); oo_tx_byte(data2); } //////////////////////////////////////////////////////////// // oo_powered() // // Transmits 2 bytes requesting if device is powered //////////////////////////////////////////////////////////// unsigned char oo_powered() { unsigned char i=55; oo_busreset(); oo_tx_byte(0xcc); oo_tx_byte(0xb4); i = oo_rx_bit(); oo_busreset(); return i; } //////////////////////////////////////////////////////////// // char oo_rx_byte() // // Receives a single byte from the bus //////////////////////////////////////////////////////////// unsigned char oo_rx_byte() { char counter = 0; char data = 0; bit oo_bit = 0; while (counter < 8){ // Rx bit oo_bit = test_bit(oo_rx_bit(),0); // maybe have a function that returns a bit? // Shift and add one depending on the value of the bus data = data >> 1; if (oo_bit){ data |= 0x80; } counter++; } return data; }
×