Я тут недавно с удивлением обнаружил, что разработанной когда-то по моей просьбе библиотекой DigitalPins пользуюсь не я один. Потому решил выложить сделанные сегодня изменения.
Изменение позволяет использовать пины XTAL1, XTAL2 и RESET как обычные GPIO в ATmega328 (раньше они не поддерживались).
Только прошу правильно понять. Выкладываю исключительно потому, что увидел её в «Проектах». Факт выкладывания не означает, что она стала «поставляться». Она по-прежнему является внутренней поделкой для внутреннего пользования. Использовать или не использовать её Вы можете только на собственный страх и риск.
001 | ///////////////////////////////////////////////////////////////////////////////// |
041 | ///////////////////////////////////////// |
051 | #define lowByte(w) ((uint8_t) ((w) & 0xff)) |
052 | #define highByte(w) ((uint8_t) ((w) >> 8)) |
053 | #define bit(b) (1UL << (b)) |
064 | #define INPUT_PULLUP 0x2 |
065 | #endif // !INPUT_PULLUP |
075 | #define __AVR_ATtinyDetected__ (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)) |
077 | #if (!__AVR_ATtinyDetected__) && (!defined(__AVR_ATmega328P__)) |
078 | #ifndef IGNORE_CPU_CHECK |
079 | #error The library has been well tested for ATmega328P and ATtiny25/45/85 only. Define IGNORE_CPU_CHECK option to ignore this check. |
080 | #endif // !IGNORE_CPU_CHECK |
081 | #endif // (!__AVR_ATtinyDetected__) && (!defined(__AVR_ATmega328P__)) |
085 | ////////////////////////////////////////////////////////////// |
089 | #define __orMask2(m1,m2) ((unsigned char)((m1) | (m2))) |
090 | #define __orMask3(m1,m2,m3) ((unsigned char)(__orMask2(m1,m2) | (m3))) |
091 | #define __orMask4(m1,m2,m3,m4) ((unsigned char)(__orMask3(m1,m2,m3) | (m4))) |
092 | #define __orMask5(m1,m2,m3,m4,m5) ((unsigned char)(__orMask4(m1,m2,m3,m4) | (m5))) |
093 | #define __orMask6(m1,m2,m3,m4,m5,m6) ((unsigned char)(__orMask5(m1,m2,m3,m4,m5) | (m6))) |
094 | #define __orMask7(m1,m2,m3,m4,m5,m6,m7) ((unsigned char)(__orMask6(m1,m2,m3,m4,m5,m6) | (m7))) |
095 | #define __orMask8(m1,m2,m3,m4,m5,m6,m7,m8) ((unsigned char)(__orMask7(m1,m2,m3,m4,m5,m6,m7) | (m8))) |
100 | #if __AVR_ATtinyDetected__ |
102 | ////////////////////////////////////////////////////////////// |
107 | #define __pin2Port(pin) (PORTB) |
108 | #define __pin2DirectionPort(pin) (DDRB) |
109 | #define __pin2InputPort(pin) (PINB) |
110 | #define __pin2PortBit(pin) (pin) |
112 | #else // Не __AVR_ATtinyDetected__ |
127 | #define EXT_PORTB_PINN(pin) (((pin) == XTAL1_PIN || (pin) == XTAL2_PIN) ? ((pin)-(XTAL1_PIN-6)) : |
128 | #define EXT_PORTB_PINS(pin) || ((pin) == XTAL1_PIN) || ((pin) == XTAL2_PIN) |
130 | #define EXT_PORTB_PINS(pin) |
131 | #define EXT_PORTB_PINN(pin) ( |
138 | #define EXT_PORTC_PIN(pin) || ((pin) == RESET_PIN) |
139 | #define EXT_PORTC_PINN(pin) (((pin) == RESET_PIN) ? 6 : |
141 | #define EXT_PORTC_PIN(pin) |
142 | #define EXT_PORTC_PINN(pin) ( |
146 | ////////////////////////////////////////////////////////////// |
150 | #define ERROR_PORT _SFR_IO8(255) |
152 | #define ___pin2Port(pin, portD, portB, portC) \ |
153 | (((pin) < 8) ? (portD) : \ |
154 | (((pin) >= 8 && (pin) < 14) EXT_PORTB_PINS(pin) ? (portB) : \ |
155 | (((pin) >= A0 && (pin) <= A5) EXT_PORTC_PIN(pin) ? (portC) : ERROR_PORT))) |
157 | #define __pin2Port(pin) ___pin2Port(pin, PORTD, PORTB, PORTC) |
158 | #define __pin2DirectionPort(pin) ___pin2Port(pin, DDRD, DDRB, DDRC) |
159 | #define __pin2InputPort(pin) ___pin2Port(pin,PIND,PINB,PINC) |
161 | #define __pin2PortBit(pin) \ |
162 | (((pin) < 8) ? (pin) : \ |
163 | (((pin) >= 8 && (pin) < 14) ? ((pin)-8) : \ |
166 | (((pin) >= A0 && (pin) <= A5) ? ((pin)-A0) : ERROR_BIT))))) |
168 | #endif // __AVR_ATtinyDetected__ |
170 | ////////////////////////////////////////////////////////////// |
174 | #define __pin2Mask(pin) (1 << __pin2PortBit(pin)) |
175 | #define __orPin2(p1,p2) __orMask2(__pin2Mask(p1),__pin2Mask(p2)) |
176 | #define __orPin3(p1,p2,p3) __orMask3(__pin2Mask(p1),__pin2Mask(p2),__pin2Mask(p3)) |
177 | #define __orPin4(p1,p2,p3,p4) __orMask4(__pin2Mask(p1),__pin2Mask(p2),__pin2Mask(p3),__pin2Mask(p4)) |
178 | #define __orPin5(p1,p2,p3,p4,p5) __orMask5(__pin2Mask(p1),__pin2Mask(p2),__pin2Mask(p3),__pin2Mask(p4),__pin2Mask(p5)) |
179 | #define __orPin6(p1,p2,p3,p4,p5,p6) __orMask6(__pin2Mask(p1),__pin2Mask(p2),__pin2Mask(p3),__pin2Mask(p4),__pin2Mask(p5),__pin2Mask(p6)) |
180 | #define __orPin7(p1,p2,p3,p4,p5,p6,p7) __orMask7(__pin2Mask(p1),__pin2Mask(p2),__pin2Mask(p3),__pin2Mask(p4),__pin2Mask(p5),__pin2Mask(p6),__pin2Mask(p7)) |
181 | #define __orPin8(p1,p2,p3,p4,p5,p6,p7,p8) __orMask8(__pin2Mask(p1),__pin2Mask(p2),__pin2Mask(p3),__pin2Mask(p4),__pin2Mask(p5),__pin2Mask(p6),__pin2Mask(p7),__pin2Mask(p8)) |
183 | ////////////////////////////////////////////////////////////// |
187 | #define __pinHigh(port,mask) ((port) |= (mask)) |
188 | #define __pinLow(port,mask) ((port) &= ~(mask)) |
189 | #define __digitalWrite(port,mask,val) (((val)!=LOW) ? (__pinHigh(port,mask)) : (__pinLow(port,mask))) |
190 | #define __pinInvert(port,mask) ((port) |= (mask)) |
191 | #define __pinModeOutput(dirport,mask) ((dirport) |= (mask)) |
192 | #define __pinModeInput(dirport, mask) ((dirport) &= ~(mask)) |
193 | #define __pinModeInputPullUp(port,dirport,mask) { unsigned char oldSREG = SREG; cli(); (dirport) &= ~(mask); (port) |= (mask); SREG = oldSREG; } |
194 | #define __pinMode(pin,state,mask) ((state) == INPUT) ? (__pinModeInput(__pin2DirectionPort(pin), mask)) : \ |
195 | ((state) == INPUT_PULLUP) ? (__pinModeInputPullUp(__pin2Port(pin), __pin2DirectionPort(pin), mask)) : \ |
196 | ((state) == OUTPUT) ? (__pinModeOutput(__pin2DirectionPort(pin), mask)) : (__pinModeOutput(__pin2DirectionPort(pin),0)) |
199 | ////////////////////////////////////////////////////////////// |
203 | #define _pinMode(pin,state) __pinMode(pin,state,__pin2Mask(pin)) |
204 | #define _digitalWrite(pin,val) __digitalWrite(__pin2Port(pin),__pin2Mask(pin),val) |
205 | #define _digitalRead(pin) (((__pin2InputPort(pin)) & (__pin2Mask(pin))) ? HIGH : LOW) |
206 | #define _pulseHigh(pin) do { unsigned char oldSREG = SREG; cli(); _digitalWrite(pin,HIGH); _digitalWrite(pin,LOW); SREG = oldSREG; } while(false) |
207 | #define _pulseLow(pin) do { unsigned char oldSREG = SREG; cli(); _digitalWrite(pin,LOW); _digitalWrite(pin,HIGH); SREG = oldSREG; } while(false) |
208 | #define _pinPulse(pin) do { unsigned char oldSREG = SREG; cli(); _pinInvert(pin); _pinInvert(pin); SREG = oldSREG; } while(false) |
209 | #define _pinInvert(pin) __pinInvert(__pin2InputPort(pin),__pin2Mask(pin)) |
212 | #if defined(GROUP_OPERATIONS) |
214 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
215 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
216 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
223 | #define __pulseLow(port,mask) \ |
225 | "in __tmp_reg__,__SREG__ \n\t" \ |
234 | "out __SREG__,__tmp_reg__ \n\t" \ |
235 | : : "I" (_SFR_IO_ADDR(port)), "r" ((mask)) : "r24" , "r23" \ |
238 | ////////////////////////////////////////////////////////////// |
242 | #define __pulseHigh(port,mask) \ |
244 | "in __tmp_reg__,__SREG__ \n\t" \ |
253 | "out __SREG__,__tmp_reg__ \n\t" \ |
254 | : : "I" (_SFR_IO_ADDR(port)), "r" ((mask)) : "r24" , "r23" \ |
257 | ////////////////////////////////////////////////////////////// |
261 | #define __Invert(port,mask) \ |
263 | "in __tmp_reg__,__SREG__ \n\t" \ |
268 | "out __SREG__,__tmp_reg__ \n\t" \ |
269 | : : "I" (_SFR_IO_ADDR(port)), "r" ((mask)) : "r24" \ |
272 | ////////////////////////////////////////////////////////////// |
276 | #define __2Invert(port,mask) \ |
278 | "in __tmp_reg__,__SREG__ \n\t" \ |
284 | "out __SREG__,__tmp_reg__ \n\t" \ |
285 | : : "I" (_SFR_IO_ADDR(port)), "r" ((mask)) : "r24" \ |
289 | ////////////////////////////////////////////////////////////// |
293 | #define _digitalWrite2(p1,p2,val) __digitalWrite(__pin2Port(p1),__orPin2(p1,p2),val) |
294 | #define _digitalWrite3(p1,p2,p3,val) __digitalWrite(__pin2Port(p1),__orPin3(p1,p2,p3),val) |
295 | #define _digitalWrite4(p1,p2,p3,p4,val) __digitalWrite(__pin2Port(p1),__orPin4(p1,p2,p3,p4),val) |
296 | #define _digitalWrite5(p1,p2,p3,p4,p5,val) __digitalWrite(__pin2Port(p1),__orPin5(p1,p2,p3,p4,p5),val) |
297 | #define _digitalWrite6(p1,p2,p3,p4,p5,p6,val) __digitalWrite(__pin2Port(p1),__orPin6(p1,p2,p3,p4,p5,p6),val) |
298 | #if !__AVR_ATtinyDetected__ |
299 | #define _digitalWrite7(p1,p2,p3,p4,p5,p6,p7,val) __digitalWrite(__pin2Port(p1),__orPin7(p1,p2,p3,p4,p5,p6,p7),val) |
300 | #define _digitalWrite8(p1,p2,p3,p4,p5,p6,p7,p8,val) __digitalWrite(__pin2Port(p1),__orPin8(p1,p2,p3,p4,p5,p6,p7,p8),val) |
301 | #endif // __AVR_ATtinyDetected__ |
303 | ////////////////////////////////////////////////////////////// |
307 | #define _pulseHigh2(p1,p2) __pulseHigh(__pin2Port(p1),__orPin2(p1,p2)) |
308 | #define _pulseHigh3(p1,p2,p3) __pulseHigh(__pin2Port(p1),__orPin3(p1,p2,p3)) |
309 | #define _pulseHigh4(p1,p2,p3,p4) __pulseHigh(__pin2Port(p1),__orPin4(p1,p2,p3,p4)) |
310 | #define _pulseHigh5(p1,p2,p3,p4,p5) __pulseHigh(__pin2Port(p1),__orPin5(p1,p2,p3, p4, p5)) |
311 | #define _pulseHigh6(p1,p2,p3,p4,p5,p6) __pulseHigh(__pin2Port(p1),__orPin6(p1,p2, p3, p4, p5, p6)) |
312 | #if !__AVR_ATtinyDetected__ |
313 | #define _pulseHigh7(p1,p2,p3,p4,p5,p6,p7) __pulseHigh(__pin2Port(p1),__orPin7(p1, p2, p3, p4, p5, p6, p7)) |
314 | #define _pulseHigh8(p1,p2,p3,p4,p5,p6,p7,p8) __pulseHigh(__pin2Port(p1),__orPin8(p1, p2, p3, p4, p5, p6, p7, p8)) |
315 | #endif // __AVR_ATtinyDetected__ |
317 | ////////////////////////////////////////////////////////////// |
321 | #define _pulseLow2(p1,p2) __pulseLow(__pin2Port(p1),__orPin2(p1,p2)) |
322 | #define _pulseLow3(p1,p2,p3) __pulseLow(__pin2Port(p1),__orPin3(p1,p2,p3)) |
323 | #define _pulseLow4(p1,p2,p3,p4) __pulseLow(__pin2Port(p1),__orPin4(p1,p2,p3,p4)) |
324 | #define _pulseLow5(p1,p2,p3,p4,p5) __pulseLow(__pin2Port(p1),__orPin5(p1,p2,p3, p4, p5)) |
325 | #define _pulseLow6(p1,p2,p3,p4,p5,p6) __pulseLow(__pin2Port(p1),__orPin6(p1,p2, p3, p4, p5, p6)) |
326 | #if !__AVR_ATtinyDetected__ |
327 | #define _pulseLow7(p1,p2,p3,p4,p5,p6,p7) __pulseLow(__pin2Port(p1),__orPin7(p1, p2, p3, p4, p5, p6, p7)) |
328 | #define _pulseLow8(p1,p2,p3,p4,p5,p6,p7,p8) __pulseLow(__pin2Port(p1),__orPin8(p1, p2, p3, p4, p5, p6, p7, p8)) |
329 | #endif // __AVR_ATtinyDetected__ |
331 | ////////////////////////////////////////////////////////////// |
335 | #define _pinInvert2(p1,p2) __Invert(__pin2InputPort(p1),__orPin2(p1,p2)) |
336 | #define _pinInvert3(p1,p2,p3) __Invert(__pin2InputPort(p1),__orPin3(p1,p2,p3)) |
337 | #define _pinInvert4(p1,p2,p3,p4) __Invert(__pin2InputPort(p1),__orPin4(p1,p2,p3, p4)) |
338 | #define _pinInvert5(p1,p2,p3,p4,p5) __Invert(__pin2InputPort(p1),__orPin5(p1,p2, p3, p4, p5)) |
339 | #define _pinInvert6(p1,p2,p3,p4,p5,p6) __Invert(__pin2InputPort(p1),__orPin6(p1, p2, p3, p4, p5, p6)) |
340 | #if !__AVR_ATtinyDetected__ |
341 | #define _pinInvert7(p1,p2,p3,p4,p5,p6,p7) __Invert(__pin2InputPort(p1),__orPin7(p1, p2, p3, p4, p5, p6, p7)) |
342 | #define _pinInvert8(p1,p2,p3,p4,p5,p6,p7,p8) __Invert(__pin2InputPort(p1),__orPin8(p1, p2, p3, p4, p5, p6, p7, p8)) |
343 | #endif // __AVR_ATtinyDetected__ |
345 | ////////////////////////////////////////////////////////////// |
349 | #define _pinPulse2(p1,p2) __2Invert(__pin2InputPort(p1),__orPin2(p1,p2)) |
350 | #define _pinPulse3(p1,p2,p3) __2Invert(__pin2InputPort(p1),__orPin3(p1,p2,p3)) |
351 | #define _pinPulse4(p1,p2,p3,p4) __2Invert(__pin2InputPort(p1),__orPin4(p1,p2,p3, p4)) |
352 | #define _pinPulse5(p1,p2,p3,p4,p5) __2Invert(__pin2InputPort(p1),__orPin5(p1,p2, p3, p4, p5)) |
353 | #define _pinPulse6(p1,p2,p3,p4,p5,p6) __2Invert(__pin2InputPort(p1),__orPin6(p1, p2, p3, p4, p5, p6)) |
354 | #if !__AVR_ATtinyDetected__ |
355 | #define _pinPulse7(p1,p2,p3,p4,p5,p6,p7) __2Invert(__pin2InputPort(p1),__orPin7(p1, p2, p3, p4, p5, p6, p7)) |
356 | #define _pinPulse8(p1,p2,p3,p4,p5,p6,p7,p8) __2Invert(__pin2InputPort(p1),__orPin8(p1, p2, p3, p4, p5, p6, p7, p8)) |
357 | #endif // __AVR_ATtinyDetected__ |
359 | ////////////////////////////////////////////////////////////// |
363 | #define __read(port, mask) ((port) & (mask)) |
364 | #define _digitalRead2(p1,p2) __read(__pin2InputPort(p1),__orPin2(p1,p2)) |
365 | #define _digitalRead3(p1,p2,p3) __read(__pin2InputPort(p1),__orPin3(p1,p2,p3)) |
366 | #define _digitalRead4(p1,p2,p3,p4) __read(__pin2InputPort(p1),__orPin4(p1,p2,p3,p4)) |
367 | #define _digitalRead5(p1,p2,p3,p4,p5) __read(__pin2InputPort(p1),__orPin5(p1,p2,p3,p4,p5)) |
368 | #define _digitalRead6(p1,p2,p3,p4,p5,p6) __read(__pin2InputPort(p1),__orPin6(p1,p2,p3,p4,p5,p6)) |
369 | #if !__AVR_ATtinyDetected__ |
370 | #define _digitalRead7(p1,p2,p3,p4,p5,p6,p7) __read(__pin2InputPort(p1),__orPin7(p1,p2,p3,p4,p5,p6,p7)) |
371 | #define _digitalRead8(p1,p2,p3,p4,p5,p6,p7,p8) __read(__pin2InputPort(p1),__orPin8(p1,p2,p3,p4,p5,p6,p7,p8)) |
372 | #endif // __AVR_ATtinyDetected__ |
374 | ////////////////////////////////////////////////////////////// |
378 | #define _pin0 __pin2Mask(0) |
379 | #define _pin1 __pin2Mask(1) |
380 | #define _pin2 __pin2Mask(2) |
381 | #define _pin3 __pin2Mask(3) |
382 | #define _pin4 __pin2Mask(4) |
383 | #define _pin5 __pin2Mask(5) |
384 | #if !__AVR_ATtinyDetected__ |
385 | #define _pin6 __pin2Mask(6) |
386 | #define _pin7 __pin2Mask(7) |
387 | #define _pin8 __pin2Mask(8) |
388 | #define _pin9 __pin2Mask(9) |
389 | #define _pin10 __pin2Mask(10) |
390 | #define _pin11 __pin2Mask(11) |
391 | #define _pin12 __pin2Mask(12) |
392 | #define _pin13 __pin2Mask(13) |
393 | #define _pinA0 __pin2Mask(A0) |
394 | #define _pinA1 __pin2Mask(A1) |
395 | #define _pinA2 __pin2Mask(A2) |
396 | #define _pinA3 __pin2Mask(A3) |
397 | #define _pinA4 __pin2Mask(A4) |
398 | #define _pinA5 __pin2Mask(A5) |
399 | #endif // !__AVR_ATtinyDetected__ |
401 | #endif // defined(GROUP_OPERATIONS) |
404 | #endif // DigitalPins_h |
А маски для трёх новых пинов? Те, что в строках 378-399? Забыл? Или не посчитал нужным?
А ещё бы инверсию одной командой.
А маски для трёх новых пинов? Те, что в строках 378-399? Забыл? Или не посчитал нужным?
Забыл.
Вставьте, если не в лом, а то мне не до сук сегодня.
А ещё бы инверсию одной командой.
Это есть (и было давно, с самого начала) - _pinInvert(pin)
Вставьте, если не в лом
Не вопрос
001
/////////////////////////////////////////////////////////////////////////////////
002
//
003
// Только ATmega328P и ATtiny25/45/85
004
//
005
// 1. Не является универсальной библиотекой и не предназначена для распространения
006
//
007
// 2. Групповые операции доступны только если оперелить #define GROUP_OPERATIONS
008
// 2.1 РИСК групповых операций - они НЕ ПРОВЕРЯЮТ, что все пины от одного и того
009
// же порта, просто берут порт первого пина и сичтают, что остальные пины там же
010
// 2.2 БЕНЕФИТ групповых операций. Они сделаны так, что все пины изменяются
011
// точно одновременно - ОДНОЙ командой процессора. Иногда это важно, например,
012
// если нужно, чтобы два сигнала шли точно в одинаковой фазе. В этих
013
// случаях лучше воспользоваться digitalWrite на два пина, чем двумя по пину,
014
// хотя последнее и эффективнее. Потому, кстати, нет никакого смысла в
015
// мультипортовых групповых операциях - два порта одной командой не изменишь.
016
//
017
// 3. Если этот текст как-то попал к Вам, это Ваши проблемы. Автор не несёт никаких
018
// обязательств ни перед кем, ни в каком случае.
019
// Текст исключительно для внутреннего использования.
020
//
021
// Используем операции с одним подчерком. Операции с большим количество подчерков - внутренняя кухня
022
//
023
// Перечень операций
024
//
025
// _pinMode(pin,state)
026
// _digitalWrite(pin,val)
027
// _digitalRead(pin)
028
// _pinInvert(pin) // Инвертирование пина
029
// _pinPulse(pin) // Инвертируется на 1 такт
030
// _pulseHigh(pin) // Высокий импульс в 1 такт
031
// _pulseLow(pin) // Низкий импульс в 1 такт
032
//
033
// Групповые операции N - 2-8
034
// _digitalWriteN(p1,...,pN,val)
035
// _pulseHighN(p1,...,pN)
036
// _pulseLowN(p1,...,pN)
037
// _pinInvertN(p1,...,pN)
038
// _pinPulseN(p1,...,pN)
039
// _digitalReadN(p1,...,pN) // выдаёт байт, пины можно снимать битовой маской
040
//
041
/////////////////////////////////////////
042
043
044
045
#ifndef DigitalPins_h
046
#define DigitalPins_h
047
048
#define USE_XTAL_PINS
049
#define USE_RESET_PIN
050
051
#define lowByte(w) ((uint8_t) ((w) & 0xff))
052
#define highByte(w) ((uint8_t) ((w) >> 8))
053
#define bit(b) (1UL << (b))
054
055
#ifndef INPUT
056
#define INPUT 0x0
057
#endif // !INPUT
058
059
#ifndef OUTPUT
060
#define OUTPUT 0x1
061
#endif // !OUTPUT
062
063
#ifndef INPUT_PULLUP
064
#define INPUT_PULLUP 0x2
065
#endif // !INPUT_PULLUP
066
067
#ifndef HIGH
068
#define HIGH 0x1
069
#endif // !HIGH
070
071
#ifndef LOW
072
#define LOW 0x0
073
#endif // !LOW
074
075
#define __AVR_ATtinyDetected__ (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__))
076
077
#if (!__AVR_ATtinyDetected__) && (!defined(__AVR_ATmega328P__))
078
#ifndef IGNORE_CPU_CHECK
079
#error The library has been well tested for ATmega328P and ATtiny25/45/85 only. Define IGNORE_CPU_CHECK option to ignore this check.
080
#endif // !IGNORE_CPU_CHECK
081
#endif // (!__AVR_ATtinyDetected__) && (!defined(__AVR_ATmega328P__))
082
083
084
085
//////////////////////////////////////////////////////////////
086
//
087
// Маски для битов групповых операций
088
//
089
#define __orMask2(m1,m2) ((unsigned char)((m1) | (m2)))
090
#define __orMask3(m1,m2,m3) ((unsigned char)(__orMask2(m1,m2) | (m3)))
091
#define __orMask4(m1,m2,m3,m4) ((unsigned char)(__orMask3(m1,m2,m3) | (m4)))
092
#define __orMask5(m1,m2,m3,m4,m5) ((unsigned char)(__orMask4(m1,m2,m3,m4) | (m5)))
093
#define __orMask6(m1,m2,m3,m4,m5,m6) ((unsigned char)(__orMask5(m1,m2,m3,m4,m5) | (m6)))
094
#define __orMask7(m1,m2,m3,m4,m5,m6,m7) ((unsigned char)(__orMask6(m1,m2,m3,m4,m5,m6) | (m7)))
095
#define __orMask8(m1,m2,m3,m4,m5,m6,m7,m8) ((unsigned char)(__orMask7(m1,m2,m3,m4,m5,m6,m7) | (m8)))
096
097
098
#define ERROR_BIT 255
099
100
#if __AVR_ATtinyDetected__
101
102
//////////////////////////////////////////////////////////////
103
//
104
// У ATtiny есть единственный порт B,
105
// а номера пинов совпадают с номерами битов
106
//
107
#define __pin2Port(pin) (PORTB)
108
#define __pin2DirectionPort(pin) (DDRB)
109
#define __pin2InputPort(pin) (PINB)
110
#define __pin2PortBit(pin) (pin)
111
112
#else // Не __AVR_ATtinyDetected__
113
114
#define A0 14
115
#define A1 15
116
#define A2 16
117
#define A3 17
118
#define A4 18
119
#define A5 19
120
121
#ifdef USE_XTAL_PINS
122
// (PCINT6/XTAL1/TOSC1) PB6
123
// (PCINT7/XTAL2/TOSC2) PB7
124
#define XTAL1_PIN 20
125
#define XTAL2_PIN 21
126
127
#define EXT_PORTB_PINN(pin) (((pin) == XTAL1_PIN || (pin) == XTAL2_PIN) ? ((pin)-(XTAL1_PIN-6)) :
128
#define EXT_PORTB_PINS(pin) || ((pin) == XTAL1_PIN) || ((pin) == XTAL2_PIN)
129
#else
130
#define EXT_PORTB_PINS(pin)
131
#define EXT_PORTB_PINN(pin) (
132
#endif
133
134
#ifdef USE_RESET_PIN
135
// (PCINT14/RESET) PC6
136
#define RESET_PIN 22
137
138
#define EXT_PORTC_PIN(pin) || ((pin) == RESET_PIN)
139
#define EXT_PORTC_PINN(pin) (((pin) == RESET_PIN) ? 6 :
140
#else
141
#define EXT_PORTC_PIN(pin)
142
#define EXT_PORTC_PINN(pin) (
143
#endif
144
145
146
//////////////////////////////////////////////////////////////
147
//
148
// Выбор порта и бита по пину для ATmega328
149
//
150
#define ERROR_PORT _SFR_IO8(255)
151
152
#define ___pin2Port(pin, portD, portB, portC) \
153
(((pin) < 8) ? (portD) : \
154
(((pin) >= 8 && (pin) < 14) EXT_PORTB_PINS(pin) ? (portB) : \
155
(((pin) >= A0 && (pin) <= A5) EXT_PORTC_PIN(pin) ? (portC) : ERROR_PORT)))
156
157
#define __pin2Port(pin) ___pin2Port(pin, PORTD, PORTB, PORTC)
158
#define __pin2DirectionPort(pin) ___pin2Port(pin, DDRD, DDRB, DDRC)
159
#define __pin2InputPort(pin) ___pin2Port(pin,PIND,PINB,PINC)
160
161
#define __pin2PortBit(pin) \
162
(((pin) < 8) ? (pin) : \
163
(((pin) >= 8 && (pin) < 14) ? ((pin)-8) : \
164
EXT_PORTB_PINN(pin) \
165
EXT_PORTC_PINN(pin) \
166
(((pin) >= A0 && (pin) <= A5) ? ((pin)-A0) : ERROR_BIT)))))
167
168
#endif // __AVR_ATtinyDetected__
169
170
//////////////////////////////////////////////////////////////
171
//
172
// Битовые маски из номеров пинов
173
//
174
#define __pin2Mask(pin) (1 << __pin2PortBit(pin))
175
#define __orPin2(p1,p2) __orMask2(__pin2Mask(p1),__pin2Mask(p2))
176
#define __orPin3(p1,p2,p3) __orMask3(__pin2Mask(p1),__pin2Mask(p2),__pin2Mask(p3))
177
#define __orPin4(p1,p2,p3,p4) __orMask4(__pin2Mask(p1),__pin2Mask(p2),__pin2Mask(p3),__pin2Mask(p4))
178
#define __orPin5(p1,p2,p3,p4,p5) __orMask5(__pin2Mask(p1),__pin2Mask(p2),__pin2Mask(p3),__pin2Mask(p4),__pin2Mask(p5))
179
#define __orPin6(p1,p2,p3,p4,p5,p6) __orMask6(__pin2Mask(p1),__pin2Mask(p2),__pin2Mask(p3),__pin2Mask(p4),__pin2Mask(p5),__pin2Mask(p6))
180
#define __orPin7(p1,p2,p3,p4,p5,p6,p7) __orMask7(__pin2Mask(p1),__pin2Mask(p2),__pin2Mask(p3),__pin2Mask(p4),__pin2Mask(p5),__pin2Mask(p6),__pin2Mask(p7))
181
#define __orPin8(p1,p2,p3,p4,p5,p6,p7,p8) __orMask8(__pin2Mask(p1),__pin2Mask(p2),__pin2Mask(p3),__pin2Mask(p4),__pin2Mask(p5),__pin2Mask(p6),__pin2Mask(p7),__pin2Mask(p8))
182
183
//////////////////////////////////////////////////////////////
184
//
185
// Внутренняя реализация основных операций
186
//
187
#define __pinHigh(port,mask) ((port) |= (mask))
188
#define __pinLow(port,mask) ((port) &= ~(mask))
189
#define __digitalWrite(port,mask,val) (((val)!=LOW) ? (__pinHigh(port,mask)) : (__pinLow(port,mask)))
190
#define __pinInvert(port,mask) ((port) |= (mask))
191
#define __pinModeOutput(dirport,mask) ((dirport) |= (mask))
192
#define __pinModeInput(dirport, mask) ((dirport) &= ~(mask))
193
#define __pinModeInputPullUp(port,dirport,mask) { unsigned char oldSREG = SREG; cli(); (dirport) &= ~(mask); (port) |= (mask); SREG = oldSREG; }
194
#define __pinMode(pin,state,mask) ((state) == INPUT) ? (__pinModeInput(__pin2DirectionPort(pin), mask)) : \
195
((state) == INPUT_PULLUP) ? (__pinModeInputPullUp(__pin2Port(pin), __pin2DirectionPort(pin), mask)) : \
196
((state) == OUTPUT) ? (__pinModeOutput(__pin2DirectionPort(pin), mask)) : (__pinModeOutput(__pin2DirectionPort(pin),0))
197
198
199
//////////////////////////////////////////////////////////////
200
//
201
// Основные операции с единичным пином
202
//
203
#define _pinMode(pin,state) __pinMode(pin,state,__pin2Mask(pin))
204
#define _digitalWrite(pin,val) __digitalWrite(__pin2Port(pin),__pin2Mask(pin),val)
205
#define _digitalRead(pin) (((__pin2InputPort(pin)) & (__pin2Mask(pin))) ? HIGH : LOW)
206
#define _pulseHigh(pin) do { unsigned char oldSREG = SREG; cli(); _digitalWrite(pin,HIGH); _digitalWrite(pin,LOW); SREG = oldSREG; } while(false)
207
#define _pulseLow(pin) do { unsigned char oldSREG = SREG; cli(); _digitalWrite(pin,LOW); _digitalWrite(pin,HIGH); SREG = oldSREG; } while(false)
208
#define _pinPulse(pin) do { unsigned char oldSREG = SREG; cli(); _pinInvert(pin); _pinInvert(pin); SREG = oldSREG; } while(false)
209
#define _pinInvert(pin) __pinInvert(__pin2InputPort(pin),__pin2Mask(pin))
210
211
212
#if defined(GROUP_OPERATIONS)
213
214
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
215
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
216
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
217
//
218
// ГРУППОВЫЕ ОРПЕРАЦИИ
219
//
220
//
221
// Групповой pulseLow по маске (внутренняя операция)
222
//
223
#define __pulseLow(port,mask) \
224
asm volatile ( \
225
"in __tmp_reg__,__SREG__ \n\t"
\
226
"cli \n\t"
\
227
"in r24,%0 \n\t"
\
228
"mov r23,r24 \n\t"
\
229
"or r24,%1 \n\t"
\
230
"com %1 \n\t"
\
231
"and r23,%1 \n\t"
\
232
"out %0,r23 \n\t"
\
233
"out %0,r24 \n\t"
\
234
"out __SREG__,__tmp_reg__ \n\t"
\
235
: :
"I"
(_SFR_IO_ADDR(port)),
"r"
((mask)) :
"r24"
,
"r23"
\
236
)
237
238
//////////////////////////////////////////////////////////////
239
//
240
// Групповой pulseHigh по маске (внутренняя операция)
241
//
242
#define __pulseHigh(port,mask) \
243
asm volatile ( \
244
"in __tmp_reg__,__SREG__ \n\t"
\
245
"cli \n\t"
\
246
"in r24,%0 \n\t"
\
247
"mov r23,r24 \n\t"
\
248
"or r24,%1 \n\t"
\
249
"com %1 \n\t"
\
250
"and r23,%1 \n\t"
\
251
"out %0,r24 \n\t"
\
252
"out %0,r23 \n\t"
\
253
"out __SREG__,__tmp_reg__ \n\t"
\
254
: :
"I"
(_SFR_IO_ADDR(port)),
"r"
((mask)) :
"r24"
,
"r23"
\
255
)
256
257
//////////////////////////////////////////////////////////////
258
//
259
// Групповой Invert по маске (внутренняя операция)
260
//
261
#define __Invert(port,mask) \
262
asm volatile ( \
263
"in __tmp_reg__,__SREG__ \n\t"
\
264
"cli \n\t"
\
265
"in r24,%0 \n\t"
\
266
"or r24,%1 \n\t"
\
267
"out %0,r24 \n\t"
\
268
"out __SREG__,__tmp_reg__ \n\t"
\
269
: :
"I"
(_SFR_IO_ADDR(port)),
"r"
((mask)) :
"r24"
\
270
)
271
272
//////////////////////////////////////////////////////////////
273
//
274
// Групповой двойной Invert по маске (внутренняя операция)
275
//
276
#define __2Invert(port,mask) \
277
asm volatile ( \
278
"in __tmp_reg__,__SREG__ \n\t"
\
279
"cli \n\t"
\
280
"in r24,%0 \n\t"
\
281
"or r24,%1 \n\t"
\
282
"out %0,r24 \n\t"
\
283
"out %0,r24 \n\t"
\
284
"out __SREG__,__tmp_reg__ \n\t"
\
285
: :
"I"
(_SFR_IO_ADDR(port)),
"r"
((mask)) :
"r24"
\
286
)
287
288
289
//////////////////////////////////////////////////////////////
290
//
291
// Групповой _digitalWrite
292
//
293
#define _digitalWrite2(p1,p2,val) __digitalWrite(__pin2Port(p1),__orPin2(p1,p2),val)
294
#define _digitalWrite3(p1,p2,p3,val) __digitalWrite(__pin2Port(p1),__orPin3(p1,p2,p3),val)
295
#define _digitalWrite4(p1,p2,p3,p4,val) __digitalWrite(__pin2Port(p1),__orPin4(p1,p2,p3,p4),val)
296
#define _digitalWrite5(p1,p2,p3,p4,p5,val) __digitalWrite(__pin2Port(p1),__orPin5(p1,p2,p3,p4,p5),val)
297
#define _digitalWrite6(p1,p2,p3,p4,p5,p6,val) __digitalWrite(__pin2Port(p1),__orPin6(p1,p2,p3,p4,p5,p6),val)
298
#if !__AVR_ATtinyDetected__
299
#define _digitalWrite7(p1,p2,p3,p4,p5,p6,p7,val) __digitalWrite(__pin2Port(p1),__orPin7(p1,p2,p3,p4,p5,p6,p7),val)
300
#define _digitalWrite8(p1,p2,p3,p4,p5,p6,p7,p8,val) __digitalWrite(__pin2Port(p1),__orPin8(p1,p2,p3,p4,p5,p6,p7,p8),val)
301
#endif // __AVR_ATtinyDetected__
302
303
//////////////////////////////////////////////////////////////
304
//
305
// Групповой _pulseHigh
306
//
307
#define _pulseHigh2(p1,p2) __pulseHigh(__pin2Port(p1),__orPin2(p1,p2))
308
#define _pulseHigh3(p1,p2,p3) __pulseHigh(__pin2Port(p1),__orPin3(p1,p2,p3))
309
#define _pulseHigh4(p1,p2,p3,p4) __pulseHigh(__pin2Port(p1),__orPin4(p1,p2,p3,p4))
310
#define _pulseHigh5(p1,p2,p3,p4,p5) __pulseHigh(__pin2Port(p1),__orPin5(p1,p2,p3, p4, p5))
311
#define _pulseHigh6(p1,p2,p3,p4,p5,p6) __pulseHigh(__pin2Port(p1),__orPin6(p1,p2, p3, p4, p5, p6))
312
#if !__AVR_ATtinyDetected__
313
#define _pulseHigh7(p1,p2,p3,p4,p5,p6,p7) __pulseHigh(__pin2Port(p1),__orPin7(p1, p2, p3, p4, p5, p6, p7))
314
#define _pulseHigh8(p1,p2,p3,p4,p5,p6,p7,p8) __pulseHigh(__pin2Port(p1),__orPin8(p1, p2, p3, p4, p5, p6, p7, p8))
315
#endif // __AVR_ATtinyDetected__
316
317
//////////////////////////////////////////////////////////////
318
//
319
// Групповой _pulseLow
320
//
321
#define _pulseLow2(p1,p2) __pulseLow(__pin2Port(p1),__orPin2(p1,p2))
322
#define _pulseLow3(p1,p2,p3) __pulseLow(__pin2Port(p1),__orPin3(p1,p2,p3))
323
#define _pulseLow4(p1,p2,p3,p4) __pulseLow(__pin2Port(p1),__orPin4(p1,p2,p3,p4))
324
#define _pulseLow5(p1,p2,p3,p4,p5) __pulseLow(__pin2Port(p1),__orPin5(p1,p2,p3, p4, p5))
325
#define _pulseLow6(p1,p2,p3,p4,p5,p6) __pulseLow(__pin2Port(p1),__orPin6(p1,p2, p3, p4, p5, p6))
326
#if !__AVR_ATtinyDetected__
327
#define _pulseLow7(p1,p2,p3,p4,p5,p6,p7) __pulseLow(__pin2Port(p1),__orPin7(p1, p2, p3, p4, p5, p6, p7))
328
#define _pulseLow8(p1,p2,p3,p4,p5,p6,p7,p8) __pulseLow(__pin2Port(p1),__orPin8(p1, p2, p3, p4, p5, p6, p7, p8))
329
#endif // __AVR_ATtinyDetected__
330
331
//////////////////////////////////////////////////////////////
332
//
333
// Групповой _pinInvert
334
//
335
#define _pinInvert2(p1,p2) __Invert(__pin2InputPort(p1),__orPin2(p1,p2))
336
#define _pinInvert3(p1,p2,p3) __Invert(__pin2InputPort(p1),__orPin3(p1,p2,p3))
337
#define _pinInvert4(p1,p2,p3,p4) __Invert(__pin2InputPort(p1),__orPin4(p1,p2,p3, p4))
338
#define _pinInvert5(p1,p2,p3,p4,p5) __Invert(__pin2InputPort(p1),__orPin5(p1,p2, p3, p4, p5))
339
#define _pinInvert6(p1,p2,p3,p4,p5,p6) __Invert(__pin2InputPort(p1),__orPin6(p1, p2, p3, p4, p5, p6))
340
#if !__AVR_ATtinyDetected__
341
#define _pinInvert7(p1,p2,p3,p4,p5,p6,p7) __Invert(__pin2InputPort(p1),__orPin7(p1, p2, p3, p4, p5, p6, p7))
342
#define _pinInvert8(p1,p2,p3,p4,p5,p6,p7,p8) __Invert(__pin2InputPort(p1),__orPin8(p1, p2, p3, p4, p5, p6, p7, p8))
343
#endif // __AVR_ATtinyDetected__
344
345
//////////////////////////////////////////////////////////////
346
//
347
// Групповой _pinPulse
348
//
349
#define _pinPulse2(p1,p2) __2Invert(__pin2InputPort(p1),__orPin2(p1,p2))
350
#define _pinPulse3(p1,p2,p3) __2Invert(__pin2InputPort(p1),__orPin3(p1,p2,p3))
351
#define _pinPulse4(p1,p2,p3,p4) __2Invert(__pin2InputPort(p1),__orPin4(p1,p2,p3, p4))
352
#define _pinPulse5(p1,p2,p3,p4,p5) __2Invert(__pin2InputPort(p1),__orPin5(p1,p2, p3, p4, p5))
353
#define _pinPulse6(p1,p2,p3,p4,p5,p6) __2Invert(__pin2InputPort(p1),__orPin6(p1, p2, p3, p4, p5, p6))
354
#if !__AVR_ATtinyDetected__
355
#define _pinPulse7(p1,p2,p3,p4,p5,p6,p7) __2Invert(__pin2InputPort(p1),__orPin7(p1, p2, p3, p4, p5, p6, p7))
356
#define _pinPulse8(p1,p2,p3,p4,p5,p6,p7,p8) __2Invert(__pin2InputPort(p1),__orPin8(p1, p2, p3, p4, p5, p6, p7, p8))
357
#endif // __AVR_ATtinyDetected__
358
359
//////////////////////////////////////////////////////////////
360
//
361
// Групповой _digitalRead
362
//
363
#define __read(port, mask) ((port) & (mask))
364
#define _digitalRead2(p1,p2) __read(__pin2InputPort(p1),__orPin2(p1,p2))
365
#define _digitalRead3(p1,p2,p3) __read(__pin2InputPort(p1),__orPin3(p1,p2,p3))
366
#define _digitalRead4(p1,p2,p3,p4) __read(__pin2InputPort(p1),__orPin4(p1,p2,p3,p4))
367
#define _digitalRead5(p1,p2,p3,p4,p5) __read(__pin2InputPort(p1),__orPin5(p1,p2,p3,p4,p5))
368
#define _digitalRead6(p1,p2,p3,p4,p5,p6) __read(__pin2InputPort(p1),__orPin6(p1,p2,p3,p4,p5,p6))
369
#if !__AVR_ATtinyDetected__
370
#define _digitalRead7(p1,p2,p3,p4,p5,p6,p7) __read(__pin2InputPort(p1),__orPin7(p1,p2,p3,p4,p5,p6,p7))
371
#define _digitalRead8(p1,p2,p3,p4,p5,p6,p7,p8) __read(__pin2InputPort(p1),__orPin8(p1,p2,p3,p4,p5,p6,p7,p8))
372
#endif // __AVR_ATtinyDetected__
373
374
//////////////////////////////////////////////////////////////
375
//
376
// Маски для проверки отдельных битов после группового _digitalRead
377
//
378
#define _pin0 __pin2Mask(0)
379
#define _pin1 __pin2Mask(1)
380
#define _pin2 __pin2Mask(2)
381
#define _pin3 __pin2Mask(3)
382
#define _pin4 __pin2Mask(4)
383
#define _pin5 __pin2Mask(5)
384
#if !__AVR_ATtinyDetected__
385
#define _pin6 __pin2Mask(6)
386
#define _pin7 __pin2Mask(7)
387
#define _pin8 __pin2Mask(8)
388
#define _pin9 __pin2Mask(9)
389
#define _pin10 __pin2Mask(10)
390
#define _pin11 __pin2Mask(11)
391
#define _pin12 __pin2Mask(12)
392
#define _pin13 __pin2Mask(13)
393
#define _pinA0 __pin2Mask(A0)
394
#define _pinA1 __pin2Mask(A1)
395
#define _pinA2 __pin2Mask(A2)
396
#define _pinA3 __pin2Mask(A3)
397
#define _pinA4 __pin2Mask(A4)
398
#define _pinA5 __pin2Mask(A5)
399
400
#ifdef USE_XTAL_PINS
401
#define _pinXTAL1 __pin2Mask(XTAL1_PIN)
402
#define _pinXTAL2 __pin2Mask(XTAL2_PIN)
403
#endif
404
405
#ifdef USE_RESET_PIN
406
#define _pinRESET __pin2Mask(RESET_PIN)
407
#endif
408
409
#endif // !__AVR_ATtinyDetected__
410
#endif // defined(GROUP_OPERATIONS)
411
#endif // DigitalPins_h
Меня смущает
#define __pinInvert(port,mask) ((port) |= (mask))
так же как и
#define __Invert(port,mask) \
1
asm volatile ( \
2
"in __tmp_reg__,__SREG__ \n\t"
\
3
"cli \n\t"
\
4
"in r24,%0 \n\t"
\
5
"or r24,%1 \n\t"
\
6
"out %0,r24 \n\t"
\
7
"out __SREG__,__tmp_reg__ \n\t"
\
8
: :
"I"
(_SFR_IO_ADDR(port)),
"r"
((mask)) :
"r24"
\
9
)
...сичтают...
У меня тоже, когда выпью, одна рука опережает другую.)
Не, извиняюсь, это не тот случай - тут одна рука.)
Меня смущает
Читайте строки №№ 17-19. Этот текст НЕ является универсальной библиотекой, НЕ поддерживается и НЕ сопровожадется. Это домашняя вещь для домашнего использования. Я просто увидел, что она как-то расползлась и даже появилась у нас в одном из проектов в соответсвующем разделе. Потому и решил выложить изменения, о чём уже жалею.
В любом случае, я не консультирую по этому коду и не помогаю решать связанные с ним вопросы. Сейчас сделаю исключение, но впредь, имейте в виду.
Что до Вашего смущения, Вы полезли в групповые операции. Они не делаются одной командой по определению. Однокомандное инвертирование возможно для одиночного пина - _pinInvert(pin). Видимо, Ваш вопрос связан с тем, почему групповое инвертирование не сделано записью в PINx, как это сделано для единичного пина. Так при такой записи, туда (в PINx) полезут не только единицы "куда надо", но и нули "во все остальные биты". Вы уверены. что это будет нормально восприниматься?
Да, я уверен (хотя верить нельзя никому), потому что только запись 1-цы влияет на инверсию порта, не более. 0 не влияет ни на что. Ни на PIN, ни на PORT.
Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn.
Плюс этого варианта ещё в том, что операция атомарна.
Да, я уверен ... только запись 1-цы влияет на инверсию порта, не более. 0 не влияет ни на что.
Ну, в даташите этого не написано, а вопросы веры мы тут обсуждать точно не будем. Мне жаль что тот кусок оскорбил Ваши чувства верующего, но обсуждение прекращаем. Как я уже сказал, библиотека не поддерживается а тот мой ответ был исключением.
Да ради бога. Я не пытался вам что то доказать, я просто обратил ваше внимание.)
ЕвгенийП, на самом деле классная библиотека.) Может Вам копирайт какой то следовало поставить? Пусть даже чисто символически.)
Если позволите - тоже влезу. Я такое вот у себя пользую для того, чтобы значения на "защищаемых" пинах не портить (во всяком случае так полагаю):
01
#include <util/atomic.h>
02
03
uint8_t writeToPort(
const
uint8_t _port,
const
uint8_t _value,
const
uint8_t _protectMask = B00000000)
04
{
05
volatile uint8_t *portRegister;
06
07
portRegister = portOutputRegister(_port);
08
if
(NOT_A_PORT == portRegister)
return
false
;
09
// Port write transaction
10
// Use protection mask when write to port to save some pins state
11
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
12
*portRegister = (*portRegister & _protectMask) | (_value & ~_protectMask);
13
}
14
return
true
;
15
}
В _protectMask '1' препятствует изменению пина, '0' - разрешает изменение.
может и мне когда-нибудь пригодится!
Я такое вот у себя пользую...
С виду норм. Только тип возвращаемого значения желательно bool, по красивому.)