Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
November 28, 2024, 10:44:55 22:44


Login with username, password and session length


Pages: [1]
Print
Author Topic: Code Samples for beginners...  (Read 9531 times)
0 Members and 1 Guest are viewing this topic.
Some Anon Guy
Junior Member
**
Offline Offline

Posts: 43

Thank You
-Given: 58
-Receive: 25



« on: September 05, 2013, 06:08:30 18:08 »

Here I will compile a list of some code examples for beginners. (as I figure out/learn interesting things that I think could help others)
These are in no way always the most efficient way of doing things, just they way I figured it out and wanted to share to help other beginners...


This is a simple function that will check whether a bit is a 1 or a 0 in a variable.
Pass it the variable and the bit position you want to check (0-7 0 being the LSB)
it will return 1 if set, or 0 if not...


int CHECK_BIT(int _var, int _pos){
    _var&=1<<_pos;
    if (_var !=0){
       return (1);
       }
    else{
       return (0);
       }
}
« Last Edit: September 05, 2013, 06:12:12 18:12 by Some Anon Guy » Logged
pablo2048
Active Member
***
Offline Offline

Posts: 113

Thank You
-Given: 136
-Receive: 86


« Reply #1 on: September 05, 2013, 06:29:59 18:29 »

Same function:
Code:
int CHECK_BIT(int _var, int _pos)
{

  return (_var & (1 << _pos))? 1:0;
}
Logged
Some Anon Guy
Junior Member
**
Offline Offline

Posts: 43

Thank You
-Given: 58
-Receive: 25



« Reply #2 on: September 06, 2013, 03:11:55 15:11 »

Here are 2 functions to read and write to an I2C EEProm with a 16Bit Data Address and 8Bit Data location.
It was written with MikroC Pro for Pic

Code:
char I2CEERE(char _devAdd, int _dataAdd){
     // _devAdd is the 7bit device address
     // The 8th bit is the Read/Write bit (RW).
     // This bit is set to 1 for Read and 0 for Write operations.
     char _return;
     char _dataAddHI, _dataAddLO;
     char _devWR = _devAdd << 1;
     char _devRE = _devAdd << 1 |0x01;
     _dataAddHI = _dataAdd >> 8;
     _dataAddLO = _dataAdd  & 0x00FF;
     I2C1_Start();            // issue I2C start signal
     I2C1_Wr(_devWR);         // send device address + Write bit
     I2C1_Wr(_dataAddHI);     // send HIGH data address byte
     I2C1_Wr(_dataAddLO);     // send LOW data address byte
     I2C1_Repeated_Start();   // issue I2C repeated start
     I2C1_Wr(_devRE);         // send device address + Read bit
     _return = I2C1_Rd(0);    // Read the data (NO acknowledge)
     I2C1_Stop();             // issue I2C stop
     return _return;
}

void I2CEEWR(char _data, char _devAdd, int _dataAdd){
    // _devAdd is the 7bit device address
    // The 8th bit is the Read/Write bit (RW).
    // This bit is set to 1 for Read and 0 for Write operations.
    char _dataAddHI, _dataAddLO;
    char _devWR = _devAdd << 1 |0x01;
    _dataAddHI = _dataAdd >> 8;
    _dataAddLO = _dataAdd  & 0x00FF;
    I2C1_Start();              // issue I2C start signal
    I2C1_Wr(_devWR);           // send device address + Write bit
    I2C1_Wr(_dataAddHI);       // send HIGH data address byte
    I2C1_Wr(_dataAddLO);       // send LOW data address byte
    I2C1_Wr(_data);            // send data (data to be written to EEprom)
    I2C1_Stop();               // issue I2C stop signal
}
Logged
pablo2048
Active Member
***
Offline Offline

Posts: 113

Thank You
-Given: 136
-Receive: 86


« Reply #3 on: September 06, 2013, 04:25:11 16:25 »

I think, this can be more readable: (only I2CEERE, same way in WR method)
Code:
uint8_t I2CEERE(uint8_t _devAdd, uint16_t _dataAdd){
     // _devAdd is the 7bit device address
     // The 8th bit is the Read/Write bit (RW).
     // This bit is set to 1 for Read and 0 for Write operations.

     uint8_t _return;
     uint8_t _devWR = _devAdd << 1;

     I2C1_Start();            // issue I2C start signal
     I2C1_Wr(_devWR);         // send device address + Write bit
     I2C1_Wr(_dataAdd >> 8);     // send HIGH data address byte
     I2C1_Wr((uint8_t) _dataAdd);// send LOW data address byte
     I2C1_Repeated_Start();   // issue I2C repeated start
     I2C1_Wr(_devWR | 0x01);  // send device address + Read bit
     _return = I2C1_Rd(0);    // Read the data (NO acknowledge)
     I2C1_Stop();             // issue I2C stop
     return _return;
}
there is no need to compute both addresses and MSB & LSB bytes... Save the RAM memory even if it's local (aka stack) variable or register...  Smiley
Logged
hate
Hero Member
*****
Offline Offline

Posts: 555

Thank You
-Given: 156
-Receive: 355


« Reply #4 on: September 06, 2013, 04:33:05 16:33 »

In the case where the bit checking result will be treated as 'bool', it can be accomplished by a macro too. This will also be faster and compile into 1 or 2 native assembly instruction in most architectures.
Code:
#define btest(_var, _pos) (_var& (1<< _pos))

One should remember that 'define's are not type-safe in general.
Logged

Regards...
pablo2048
Active Member
***
Offline Offline

Posts: 113

Thank You
-Given: 136
-Receive: 86


« Reply #5 on: September 06, 2013, 05:07:31 17:07 »

In the case where the bit checking result will be treated as 'bool', it can be accomplished by a macro too. This will also be faster and compile into 1 or 2 native assembly instruction in most architectures.
Code:
#define btest(_var, _pos) (_var& (1<< _pos))

One should remember that 'define's are not type-safe in general.

Indeed, but he wants (int) 0/1 output...
Logged
Make_Pic
Junior Member
**
Offline Offline

Posts: 55

Thank You
-Given: 3
-Receive: 9


« Reply #6 on: September 21, 2013, 02:06:25 02:06 »

Hi all
Why do you use an underline before a variable? For example: _var
Where can I read about it?

regards
Logged
Brosske
Active Member
***
Offline Offline

Posts: 105

Thank You
-Given: 75
-Receive: 292



« Reply #7 on: September 21, 2013, 07:16:35 07:16 »

Hi all,

The underscore is simply a convention; nothing more. As such, its use is always somewhat different to each person. Here's how I understand them : an underscore usually indicates a private member (or local) variable.



greetz
Logged

Do or do not - there is no try
hate
Hero Member
*****
Offline Offline

Posts: 555

Thank You
-Given: 156
-Receive: 355


« Reply #8 on: September 21, 2013, 01:52:18 13:52 »

Preceding underscore(s) is/are usually used by compiler/system specific defines which are not to be modified by the inexperienced and the following underscore(s) is/are usually appended to member variables in C++. But it's a matter of convention really as Brosske said. They can be freely used unless one doesn't interfere with a critical variable/definition.
Logged

Regards...
odessa
Newbie
*
Offline Offline

Posts: 22

Thank You
-Given: 101
-Receive: 16


« Reply #9 on: September 21, 2013, 11:40:37 23:40 »

Heres a full set of bitwise routines I use :

Code:
#define bitSet(var,bitno) (var|=1<<bitno)
#define bitClr(var,bitno) (var&=~(1<<bitno))        
#define bitTest(var, bitno)  ((var) & (1 << (bitno)))
#define bitToggle(var,bitno) ((var&(1<<bitno))!=0) ? (var &= ~(1<<bitno)) : (var |= (1<<bitno))

Hope they help someone
Logged
hate
Hero Member
*****
Offline Offline

Posts: 555

Thank You
-Given: 156
-Receive: 355


« Reply #10 on: September 22, 2013, 11:16:05 11:16 »

Heres a full set of bitwise routines I use :

Code:
#define bitToggle(var,bitno) ((var&(1<<bitno))!=0) ? (var &= ~(1<<bitno)) : (var |= (1<<bitno))

A better and much faster bit toggle is
Code:
#define bitToggle(var, bitno) (var^= (1<<bitno))
Logged

Regards...
odessa
Newbie
*
Offline Offline

Posts: 22

Thank You
-Given: 101
-Receive: 16


« Reply #11 on: September 23, 2013, 09:53:10 09:53 »

Hi Hate,

I tried that but it doesn't work ...

edit: well not in C18, does in HiTEch C ... Smiley
« Last Edit: September 23, 2013, 09:59:33 09:59 by odessa » Logged
germanium
Newbie
*
Offline Offline

Posts: 13

Thank You
-Given: 6
-Receive: 64


« Reply #12 on: January 10, 2014, 05:27:28 05:27 »

Something that's bitten me before is if you do something like PORT |= or PORT ^= on a pin whose tristate registers aren't setup as inputs, it'll throw you for a loop. :-)

I'll add a serial port class that I've used in a lot of projects.  Bit long, but it's handy and only requires tweaks to the first couple functions for the hardware-specific changes. 

Code:
/// CPU clock speed in Hz
#define PIC_CLK 32000000

/// desired serial baud rate
#define BAUD 9600

/// calculate the baud rate generator divider
#define DIVIDER ((PIC_CLK/(16UL * BAUD) -1))

/// defines whether to use high speed baud rates or not (setting 0 changes the divider calc)
#define HIGH_SPEED 1

static unsigned char dummy;

/**
 * Initializes the onboard serial port hardware
 */
void SerialInit(void) {
    SPBRG = DIVIDER;    //using the baudrate generator in 8-bit mode
    BRGH  = HIGH_SPEED; //data rate for sending
    SYNC  = 0; //asynchronous
    SPEN  = 1; //enable serial port pins
    CREN  = 1; //enable reception
    TXIE  = 0; //disable tx interrupts
    RCIE  = 1; //enable rx interrupts
    TX9   = 0;  //8-bit transmission
    RX9   = 0;  //8-bit reception
    TXEN  = 0; //reset transmitter
    TXEN  = 1; //enable the transmitter
}

/// macro for clearing any UART errors
#define clear_usart_errors_inline    \
if (OERR)                \
{                        \
    TXEN=0;              \
    TXEN=1;              \
    CREN=0;              \
    CREN=1;              \
}                        \
if (FERR)                \
{                        \
    dummy=RCREG;         \
    TXEN=0;              \
    TXEN=1;              \
}

/**
 * Write a character to the serial port (necessary to use embedded printf calls).
 *
 * @param c character to write
 */
void putch(unsigned char c) {
    while (!TXIF); //set when register is empty
    {
        clear_usart_errors_inline;
        CLRWDT();
    }
    TXREG = c;
    _delay(240);
}

/**
 * Get a character from the serial port without timeout (neccessary to use
 * embedded scanf calls).
 *
 * @return character received from the UART
 */
unsigned char getch(void) {
    while (!RCIF) {
        CLRWDT();
        clear_usart_errors_inline;
    }
    return RCREG;
}

/**
 * Public function for clearing any framing or overrun errors from the serial
 * port hardware.
 */
void SerialClearErrors(void) {
    clear_usart_errors_inline;
}


/**
 * Write a character to the serial port in hex.
 *
 * @param c 8 bit value to output in hex
 */
void SerialPutCharHex(unsigned char c) {
    unsigned char temp;

    // transmits in hex
    temp = c;

    c = (c >> 4);
    if (c < 10) c += 48;
    else c += 55;
    putch(c);

    c = temp;

    c = (c & 0x0F);
    if (c < 10) c += 48;
    else c += 55;
    putch(c);
}

/**
 * Write an integer (16 bit) out to the serial port in hex.
 *
 * @param c Integer value to be written
 */
void SerialPutIntHex(unsigned int c) {
#define ramuint(x)              (*((unsigned int *) (x)))
#define ramuint_hibyte(x)       (*(((unsigned char *)&x)+1))
#define ramuint_lobyte(x)       (*(((unsigned char *)&x)+0))
#define ramuchar(x)             (*((unsigned char *) (x)))

    SerialPutCharHex(ramuint_hibyte(c));
    SerialPutCharHex(ramuint_lobyte(c));

#undef ramuint(x)
#undef ramuint_hibyte(x)
#undef ramuint_lobyte(x)
#undef ramuchar(x)
}


/**
 * Write an 8 bit value to the serial port in decimal form
 *
 * @param c 8 bit value to be output.
 */
void SerialPutCharDec(unsigned char c) {
    unsigned char temp;

    temp = c;
    //hundreds
    if ((c / 100) > 0) putch((c / 100) + '0');
    c -= (c / 100)*100;

    //tens
    if (((temp / 10) > 0) || ((temp / 100) > 0)) putch((c / 10) + '0');
    c -= (c / 10)*10;

    //ones
    putch((c / 1) + '0');
}

/**
 * Write a string to the serial port.
 * @param str String to be written. 
 */
void SerialPutst(register const char *str) {
    while ((*str) != 0) {
        putch(*str);
        if (*str == 13) putch(10);
        if (*str == 10) putch(13);
        str++;
    }
}
Logged
hate
Hero Member
*****
Offline Offline

Posts: 555

Thank You
-Given: 156
-Receive: 355


« Reply #13 on: January 10, 2014, 12:23:34 12:23 »

Something that's bitten me before is if you do something like PORT |= or PORT ^= on a pin whose tristate registers aren't setup as inputs, it'll throw you for a loop. :-)
Can you evaluate this a little further pls? What kind of a loop? The only use I can think of for changing the state of an input pin is to enable/disable the pull-up resistors on AVRs and I've never experienced any strange behavior with "PORT&=", "PORT^=" etc... on any output of any mcu architecture I've used. PICs have the output latching problem though if you were talking about that but that's unfortunately a design issue which none of the PIC18s or later have.
Logged

Regards...
germanium
Newbie
*
Offline Offline

Posts: 13

Thank You
-Given: 6
-Receive: 64


« Reply #14 on: January 11, 2014, 06:11:59 06:11 »

Sorry, by 'throwing for a loop' I just meant it can be confusing. The situation is if you don't set the port's tristate register as an input (and configure it as a digital input if that's applicable) then doing something like

PORTC ^= 0x08 will not behave as you expect since it'll always read the pin in as a logic high. Simple once you realize what's gong on, but I pulled some hair out over it when I was starting Smiley
Logged
hate
Hero Member
*****
Offline Offline

Posts: 555

Thank You
-Given: 156
-Receive: 355


« Reply #15 on: January 11, 2014, 12:53:04 12:53 »

Hmm, if you don't set the tristate register as input then it's set as output and to configure it as a digital input I understand it's done externally (by hardware). So you have a pin set as output and connected to an external input say a button. In that case you are mostly likely to fry the pin (ie. button is connected from pin to gnd and the pin set to high or vice versa). And the code 'PORT^=0x08' doesn't read any pins, it just toggles the 3rd pin of the PORT. The code to read the 3rd pin of a port should be something like 'some_variable=PORT&0x08', did you mean that?

Or are you trying to say that if a pin is set as output, the value read is what the pin is set at (high, low) regardless of the state of the external input as in the case above. Well that's quite obvious imo as it's been documented in datasheets and I still don't get what extraordinary problem you may have experienced with that.
Logged

Regards...
germanium
Newbie
*
Offline Offline

Posts: 13

Thank You
-Given: 6
-Receive: 64


« Reply #16 on: January 16, 2014, 05:07:34 05:07 »

I mean the latter; if it's set as an output, you read whatever the pin is set to regardless of actual state of the input.  There is no extraordinary problem, just a 'gotcha'.  :-)
Logged
Pages: [1]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC