// hvwdefines // build 004, engines forward/reverse swapped // build 005, explanation comment added /* Question: Why is this long include file needed? Answer: The Asuro programming examples use something like this: #define FWD (1 << PB5) If I like to create a new program or modify any of my own existing programs if find it difficult to understand what all of this ment to be. So I need to re-read the Atmega8 pdf documentation I develooped my own way of setting, clearing and reading bits from various registers in such a way that I easily could understand my own programs at a later time when I all forgot about my program. -----o----- I use a lot of 'defines'. For example: #define PB5_L (0x20<<8) this converts PB5_L (a bit that must be cleared) into hex value 0x2000 (shifts it to the high byte part) #define PB5_H (0x20) this converts PB5_H (a bit that must be set ) into hex value 0x0020 (low byte part) -----o----- Now my 'defined' SFRX function (defined near the end of this file) may be written like SFRX ( PORTB , PB4_L | PB5_H | PB1_L ) ; This function will set bit 4 and bit 1 to LOW and bit 5 to HIGH in port PORTB. This function is executed by the preprocessor and therefore will NOT create more microcontroller code as when using the ASURO way of programming. -----o----- Port PB5 controls the right Asuro engine, when LOW it enables the right engine to move reverse and PB4 must be HIGH. #define PB5_L (0x20<<8) setting PortB bit5 low is converted to hex 0x2000 (high byte part of 16-bit integer) (PORTB) #define PB5_H (0x20) setting PortB bit5 high is converted to hex 0x0020 (low byte part of 16-bit integer) (PORTB) #define PB5_I PB5_L setting a bit as (I)nput equals setting that bit (in DDRB, not PORTB) to (L)ow #define PB5_O PB5_H setting a bit as (O)utput equals setting that bit (in DDRB, not PORTB) to (H)igh #define REV_RGT_L PB5_L activate reversing right engine (remember that active = LOW in case of engine control) (PORTB) #define REV_RGT_H PB5_H inactivate reversing right engine (remember that inactive = HIGH in case of engine control) (PORTB) #define REV_RGT_I PB5_L setting right engine microcontroller pin as (I)nput (DDRB) #define REV_RGT_O PB5_H setting right engine microcontroller pin as (O)utput (DDRB) #define REV_RGT_N PB5_L deselection (N)one/(N)eutral pull-up resistor at right engine microcontroller pin (PORTB) #define REV_RGT_P PB5_H selection (P)ull-up pull-up resistor at right engine microcontroller pin (PORTB) if you like to use PORT bitnames you may use PB5_n bitnaming and if you like to use port-related Asuro-names you may use REV_RGT_n bit naming. Both do the same. -----o----- If I want to switch left engine to (output and) forward I may program: (bit 5 must be low and bit 4 must be high) SFRX ( DDRB , PB5_O | PB4_O ) ; //switch ports pb4 and pb5 as outputs SFRX ( PORTB , PB5_L | PB4_H ) ; //switch port pb5 low and pb4 high or SFRX ( DDRB , REV_RGT_O | FWD_RGT_O ) ; //swithc ports pb4 and pb5 as outputs SFRX ( PORTB , REV_RGT_L | FWD_RGT_H ) ; //switch port pb5 low and pb4 high the bit position in the SFRX function is irrelevant, see below. SFRX ( PORTB , PB5_L | PB4_H ) ; //switch port pb5 low and pb4 high SFRX ( PORTB , PB4_H | PB5_L ) ; //switch port pb5 low and pb4 high -----o----- This way of programming is not watertide (I know) and may be confusing, for example: SFRX ( DDRB , REV_RGT_L ) ; will set Port PB5 to INPUT and not to LOW because REV_RGT_L is ment to be used with PORTB and not with DDRB! No compiler warning or whatsoever is given. -----o----- */ #ifndef _HVW_DEFINES_H_ #define _HVW_DEFINES_H_ 1 #include #include #include #define FALSE 0 #define TRUE 1 /* _BV(b) equals (1<>8))|(Msk)) // - a Mask (Msk) is 16 bits wide // - the left 8 bits represents the bits to be cleared (each 1-bit means that corresponding registerbit must be cleared) // - the right 8 bits represents the bits to be set (each 1-bit means that corresponding registerbit must be set ) // a Msk example: // 7654 3210 7654 3210 (bitnumbers) // 0010 0000 0000 0100 // x bit 6 must be cleared // x bit 2 must be set // p = previous result // ((Msk)>>8) => shift clear-bits from the high-byte to the low-byte (1-bits means that corresponding bit must be cleared) // ~(p) => invert clear-bits, meaning, bits that must be cleared are now '0' and must not be cleared are now '1' in low-byte // Sfr&p => get register data and 'and' it with 'p' so: // 1. reg 0 and clr 0 => reg 0 (a cleared bit that must be cleared stays cleared) // 2. reg 1 and clr 0 => reg 0 (a set bit that must be cleared is cleared) // 3. reg 0 and clr 1 => reg 0 (an cleared bit that must not be cleared stays cleared) // 4. reg 1 and clr 1 => reg 1 (an set bit that must not be cleared stays set) // p|(Msk) => to-be-set bits in low-byte are just prepaired to be set in register // Sfr=p => execute settings //Write Special Function Register byte #define SFRW(Sfr,Msk) (Sfr=(Msk)) //Test on mask bits 1 being set and mask bits 0 being cleared // (Msk)>>8) => shift 'clr' mask 8 bits to the right // | ((Msk)&0xFF) => 'Or' shifted 'clr' mask with 'set' mask: now all 'clr' and 'set' bits are set to '1' // & Sfr => Retrieve all 'clr' and 'set' bits from Sfr // ^((Msk&0xFF)) => Get 'set' bitmask, force all 'set' masked '1' bits from Sfr to go '0', leaving errornous bits resulting as '1' // ! => invert (any '1' bit is error = boolean pass) to (any '1' bit is error = boolean fail) #define SFRQ(Sfr,Msk) (!((((((Msk)>>8)|((Msk)&0xFF)) ) & Sfr)^((Msk)&0xFF))) //werkt! //================================================================================ //#define SFRQ(Sfr,Msk) (((Msk)^Sfr) | ((~((Msk)>>8))&Sfr)) #define SET_FRONT_LED_OUTPUT (SFRX(DDRD, TRK_LED_O)) #define SET_FRONT_LED_ON (SFRX(PORTD,TRK_LED_H)) #define SET_FRONT_LED_OFF (SFRX(PORTD,TRK_LED_L)) #define CHK_FRONT_LED_ON (SFRT(PORTD,TRK_LED_H)) #define SET_LEFT_BRAKE_LED_ON (SFRX(PORTC,BOD_LFT_H)) #define SET_LEFT_BRAKE_LED_OFF (SFRX(PORTC,BOD_LFT_L)) #define SET_RGHT_BRAKE_LED_ON (SFRX(PORTC,BOD_RGT_H)) #define SET_RGHT_BRAKE_LED_OFF (SFRX(PORTC,BOD_RGT_L)) #define CHK_LEFT_BRAKE_LED_ON (SFRT(PORTC,BOD_LFT_H)) #define CHK_LEFT_BRAKE_LED_OFF (!SFRT(PORTC,BOD_LFT_H)) #define CHK_RGHT_BRAKE_LED_ON (SFRT(PORTC,BOD_RGT_H)) #define CHK_RGHT_BRAKE_LED_OFF (!SFRT(PORTC,BOD_RGT_H)) #define SFR_TST(Sfr,Msk) (Sfr&Msk) #define SFRT(Sfr,Msk) (Sfr&Msk) #define TST_FRONT_LED_ON (SFR_TST(PORTD,PD6_H)) #define SET_RED_SYSTM_LED_ON (SFRX(PORTD,SLD_RED_H)) #define SET_RED_SYSTM_LED_OFF (SFRX(PORTD,SLD_RED_L)) #define SET_GRN_SYSTM_LED_ON (SFRX(PORTB,SLD_GRN_H)) #define SET_GRN_SYSTM_LED_OFF (SFRX(PORTB,SLD_GRN_L)) //Set and Clear Bits in Byte #define BYTE_BIT(Byt,Bit) (Byt=(Byt&~((Bit)>>8))|(Bit)) #define SET_BYTE_BITS(Byt,Bit) (Byt=(Byt|Bit)) #define SET_BYTE_BIT(Byt,Bit) (Byt=(Byt|Bit)) #define CLR_BYTE_BITS(Byt,Bit) (Byt=(Byt&~(Bit))) #define CLR_BYTE_BIT(Byt,Bit) (Byt=(Byt&~(Bit))) #define CHK_BYTE_BIT_SET(Byt,Bit) (Byt&Bit) #define CHK_BYTE_BIT_CLR(Byt,Bit) (~(Byt&Bit)) // Byt&(Bit) selects bit, #define byte unsigned char #define SFR_ADMUX_MUX_ADC_LEFT_TRACK_SENSOR (MUX2_H|MUX1_H) //mux3 #define SFR_ADMUX_MUX_ADC_RGHT_TRACK_SENSOR (MUX1_H) //mux2 #define SET_LEFT_ENGINE_DIRECTION_TO_FORWARD SFRX(PORTD,PD4_L|PD5_H) #define SET_LEFT_ENGINE_DIRECTION_TO_REVERSE SFRX(PORTD,PD4_H|PD5_L) #define SET_RGHT_ENGINE_DIRECTION_TO_FORWARD SFRX(PORTB,PB4_L|PB5_H) #define SET_RGHT_ENGINE_DIRECTION_TO_REVERSE SFRX(PORTB,PB4_H|PB5_L) #define SET_LEFT_ENGINE_SPEED(LftEngSpd) (OCR1A=LftEngSpd) #define SET_RGHT_ENGINE_SPEED(RgtEngSpd) (OCR1B=RgtEngSpd) #endif //_MY_DEFINES_H_