Как правильно расставить биты
- Войдите на сайт для отправки комментариев
Вс, 12/06/2016 - 19:17
хочу в библиотеку для дисплея добавить шилд на меге128, все работает как надо, но выход в PB1 в 128 это sck, хочу передвинуть PB0 PB1 на PB4 PB5, уже весь мозг сломал
//#define USE_SPECIAL //check for custom drivers //#if defined(USE_SPECIAL) //#include "mcufriend_special.h" //#if !defined(USE_SPECIAL_FAIL) //#warning WE ARE USING A SPECIAL CUSTOM DRIVER //#endif //#endif //#if !defined(USE_SPECIAL) || defined (USE_SPECIAL_FAIL) #if 0 #elif defined(__AVR_ATmega328P__) //regular UNO shield on UNO #define RD_PORT PORTC #define RD_PIN 0 #define WR_PORT PORTC #define WR_PIN 1 #define CD_PORT PORTC #define CD_PIN 2 #define CS_PORT PORTC #define CS_PIN 3 #define RESET_PORT PORTC #define RESET_PIN 6 #define DMASK 0x03 #define NMASK ~DMASK #define write_8(x) { PORTB = (PORTB & NMASK) | ((x) & DMASK); PORTD = (PORTD & DMASK) | ((x) & NMASK); } #define read_8() ( (PINB & DMASK) | (PIND & NMASK) ) #define setWriteDir() { DDRB = (DDRB & NMASK) | DMASK; DDRD = (DDRD & DMASK) | NMASK; } #define setReadDir() { DDRB = (DDRB & NMASK) & NMASK; DDRD = (DDRD & DMASK) & DMASK; } #define write8(x) { write_8(x); WR_STROBE; } #define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } #define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } #define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } #define PIN_LOW(p, b) (p) &= ~(1<<(b)) #define PIN_HIGH(p, b) (p) |= (1<<(b)) #define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) #elif defined(__AVR_ATmega128__) //ATmega128 #define RD_PORT PORTF #define RD_PIN 0 #define WR_PORT PORTF #define WR_PIN 1 #define CD_PORT PORTF #define CD_PIN 2 #define CS_PORT PORTF #define CS_PIN 3 #define RESET_PORT PORTF #define RESET_PIN 4 #define EMASK 0x03 //B00000011 // ~DMASK //B11111100 #define BMASK 0x30 //B00110000 PB5,PB4,PE7,PE6,PE5,PE4,PE3,PE2 //~BMASK //B11001111 #define write_8(x) { PORTB = (PORTB & ~BMASK) | ((x) & BMASK); PORTE = (PORTE & EMASK) | ((x) & ~EMASK); } #define read_8() ( (PINB & BMASK) | (PINE & ~EMASK) ) #define setWriteDir() { DDRB = (DDRB & ~BMASK) | BMASK; DDRE = (DDRE & EMASK) | ~EMASK; } #define setReadDir() { DDRB = (DDRB & ~BMASK) & ~BMASK; DDRE = (DDRE & EMASK) & EMASK; } #define write8(x) { write_8(x); WR_STROBE; } #define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } #define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } #define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } #define PIN_LOW(p, b) (p) &= ~(1<<(b)) #define PIN_HIGH(p, b) (p) |= (1<<(b)) #define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) #elif defined(__AVR_ATmega2560__) //regular UNO shield on MEGA2560 #define RD_PORT PORTF #define RD_PIN 0 #define WR_PORT PORTF #define WR_PIN 1 #define CD_PORT PORTF #define CD_PIN 2 #define CS_PORT PORTF #define CS_PIN 3 #define RESET_PORT PORTF #define RESET_PIN 4 #define EMASK 0x38 // B00111000 #define GMASK 0x20 // B00100000 #define HMASK 0x78 // B01111000 // PH6,PH5,PH4,PH3,PE3,PG5,PE5,PE4 #define write_8(x) { PORTH &= ~HMASK; PORTG &= ~GMASK; PORTE &= ~EMASK; \ PORTH |= (((x) & (3<<0)) << 5); \ PORTE |= (((x) & (3<<2)) << 2); \ PORTG |= (((x) & (1<<4)) << 1); \ PORTE |= (((x) & (1<<5)) >> 2); \ PORTH |= (((x) & (3<<6)) >> 3); \ } #define read_8() ( ((PINH & (3<<5)) >> 5)\ | ((PINE & (3<<4)) >> 2)\ | ((PING & (1<<5)) >> 1)\ | ((PINE & (1<<3)) << 2)\ | ((PINH & (3<<3)) << 3)\ ) #define setWriteDir() { DDRH |= HMASK; DDRG |= GMASK; DDRE |= EMASK; } #define setReadDir() { DDRH &= ~HMASK; DDRG &= ~GMASK; DDRE &= ~EMASK; } #define write8(x) { write_8(x); WR_STROBE; } #define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } #define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } #define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } #define PIN_LOW(p, b) (p) &= ~(1<<(b)) #define PIN_HIGH(p, b) (p) |= (1<<(b)) #define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) #elif defined(__SAMD21G18A__) //regular UNO shield on ZERO or M0_PRO #include "sam.h" // configure macros for the control pins #define RD_PORT PORT->Group[0] #define RD_PIN 2 #define WR_PORT PORT->Group[1] #define WR_PIN 8 #define CD_PORT PORT->Group[1] #define CD_PIN 9 #define CS_PORT PORT->Group[0] #define CS_PIN 4 #define RESET_PORT PORT->Group[0] #define RESET_PIN 5 // configure macros for data bus #define DMASK 0x0030C3C0 // #define write_8(x) PORT->Group[0].OUT.reg = (PORT->Group[0].OUT.reg & ~DMASK)|(((x) & 0x0F) << 6)|(((x) & 0x30) << 10)|(((x) & 0xC0)<<14) #if defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_ZERO) // American ZERO #define write_8(x) {\ PORT->Group[0].OUTCLR.reg = DMASK;\ PORT->Group[0].OUTSET.reg = (((x) & 0x0B) << 6)\ |(((x) & (1<<2)) << 12)\ |(((x) & (1<<4)) << 4)\ |(((x) & (1<<5)) << 10)\ |(((x) & 0xC0) << 14);\ } #define read_8() (((PORT->Group[0].IN.reg >> 6) & 0x0B)\ |((PORT->Group[0].IN.reg >> 12) & (1<<2))\ |((PORT->Group[0].IN.reg >> 4) & (1<<4))\ |((PORT->Group[0].IN.reg >> 10) & (1<<5))\ |((PORT->Group[0].IN.reg >> 14) & 0xC0)) #else //default to an M0_PRO on v1.6.5 or 1.7.6 #define write_8(x) {\ PORT->Group[0].OUTCLR.reg = DMASK;\ PORT->Group[0].OUTSET.reg = (((x) & 0x0F) << 6)\ |(((x) & 0x30) << 10)\ |(((x) & 0xC0) << 14);\ } #define read_8() (((PORT->Group[0].IN.reg >> 6) & 0x0F)|((PORT->Group[0].IN.reg >> 10) & 0x30)|((PORT->Group[0].IN.reg >> 14) & 0xC0)) #endif #define setWriteDir() { PORT->Group[0].DIRSET.reg = DMASK; \ PORT->Group[0].WRCONFIG.reg = (DMASK & 0xFFFF) | (0<<22) | (1<<28) | (1<<30); \ PORT->Group[0].WRCONFIG.reg = (DMASK>>16) | (0<<22) | (1<<28) | (1<<30) | (1<<31); \ } #define setReadDir() { PORT->Group[0].DIRCLR.reg = DMASK; \ PORT->Group[0].WRCONFIG.reg = (DMASK & 0xFFFF) | (1<<17) | (1<<28) | (1<<30); \ PORT->Group[0].WRCONFIG.reg = (DMASK>>16) | (1<<17) | (1<<28) | (1<<30) | (1<<31); \ } #define write8(x) { write_8(x); WR_STROBE; } #define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } #define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } #define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } // Shield Control macros. #define PIN_LOW(port, pin) (port).OUTCLR.reg = (1<<(pin)) #define PIN_HIGH(port, pin) (port).OUTSET.reg = (1<<(pin)) #define PIN_OUTPUT(port, pin) (port).DIR.reg |= (1<<(pin)) #elif defined(__SAM3X8E__) //regular UNO shield on DUE // configure macros for the control pins #define RD_PORT PIOA #define RD_PIN 16 #define WR_PORT PIOA #define WR_PIN 24 #define CD_PORT PIOA #define CD_PIN 23 #define CS_PORT PIOA #define CS_PIN 22 #define RESET_PORT PIOA #define RESET_PIN 6 // configure macros for data bus #define BMASK (1<<25) #define CMASK (0xBF << 21) #define write_8(x) { PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; \ PIOC->PIO_SODR = (((x) & (1<<0)) << 22); \ PIOC->PIO_SODR = (((x) & (1<<1)) << 20); \ PIOB->PIO_SODR = (((x) & (1<<2)) << 23); \ PIOC->PIO_SODR = (((x) & (1<<3)) << 25); \ PIOC->PIO_SODR = (((x) & (1<<4)) << 22); \ PIOC->PIO_SODR = (((x) & (1<<5)) << 20); \ PIOC->PIO_SODR = (((x) & (1<<6)) << 18); \ PIOC->PIO_SODR = (((x) & (1<<7)) << 16); \ } #define read_8() ( ((PIOC->PIO_PDSR & (1<<22)) >> 22)\ | ((PIOC->PIO_PDSR & (1<<21)) >> 20)\ | ((PIOB->PIO_PDSR & (1<<25)) >> 23)\ | ((PIOC->PIO_PDSR & (1<<28)) >> 25)\ | ((PIOC->PIO_PDSR & (1<<26)) >> 22)\ | ((PIOC->PIO_PDSR & (1<<25)) >> 20)\ | ((PIOC->PIO_PDSR & (1<<24)) >> 18)\ | ((PIOC->PIO_PDSR & (1<<23)) >> 16)\ ) #define setWriteDir() { PIOB->PIO_OER = BMASK; PIOC->PIO_OER = CMASK; } #define setReadDir() { \ PMC->PMC_PCER0 = (1 << ID_PIOB)|(1 << ID_PIOC);\ PIOB->PIO_ODR = BMASK; PIOC->PIO_ODR = CMASK;\ } #define write8(x) { write_8(x); WR_ACTIVE; WR_STROBE; WR_IDLE; } #define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } #define READ_8(dst) { RD_STROBE; RD_ACTIVE; dst = read_8(); RD_IDLE; RD_IDLE; } #define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } // Shield Control macros. #define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin)) #define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin)) #define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin)) #elif defined(__AVR_ATmega32U4__) //regular UNO shield on Leonardo #define RD_PORT PORTF #define RD_PIN 7 #define WR_PORT PORTF #define WR_PIN 6 #define CD_PORT PORTF #define CD_PIN 5 #define CS_PORT PORTF #define CS_PIN 4 #define RESET_PORT PORTF #define RESET_PIN 1 #define BMASK (3<<4) #define CMASK (1<<6) #define DMASK ((1<<7)|(1<<4)|(3<<0)) #define EMASK (1<<6) static inline //hope we use r24 void write_8(uint8_t x) { PORTB &= ~BMASK; PORTC &= ~CMASK; PORTD &= ~DMASK; PORTE &= ~EMASK; PORTB |= (((x) & (3 << 0)) << 4); PORTD |= (((x) & (1 << 2)) >> 1); PORTD |= (((x) & (1 << 3)) >> 3); PORTD |= (((x) & (1 << 4)) << 0); PORTC |= (((x) & (1 << 5)) << 1); PORTD |= (((x) & (1 << 6)) << 1); PORTE |= (((x) & (1 << 7)) >> 1); } #define read_8() ( ((PINB & (3<<4)) >> 4)\ | ((PIND & (1<<1)) << 1)\ | ((PIND & (1<<0)) << 3)\ | ((PIND & (1<<4)) >> 0)\ | ((PINC & (1<<6)) >> 1)\ | ((PIND & (1<<7)) >> 1)\ | ((PINE & (1<<6)) << 1)\ ) #define setWriteDir() { DDRB |= BMASK; DDRC |= CMASK; DDRD |= DMASK; DDRE |= EMASK; } #define setReadDir() { DDRB &= ~BMASK; DDRC &= ~CMASK; DDRD &= ~DMASK; DDRE &= ~EMASK; } #define write8(x) { write_8(x); WR_STROBE; } #define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); } #define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; } #define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); } #define PIN_LOW(p, b) (p) &= ~(1<<(b)) #define PIN_HIGH(p, b) (p) |= (1<<(b)) #define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b)) #else #error MCU unsupported #endif // regular UNO shields on Arduino boards //#endif //!defined(USE_SPECIAL) || defined (USE_SPECIAL_FAIL) #define RD_ACTIVE PIN_LOW(RD_PORT, RD_PIN) #define RD_IDLE PIN_HIGH(RD_PORT, RD_PIN) #define RD_OUTPUT PIN_OUTPUT(RD_PORT, RD_PIN) #define WR_ACTIVE PIN_LOW(WR_PORT, WR_PIN) #define WR_IDLE PIN_HIGH(WR_PORT, WR_PIN) #define WR_OUTPUT PIN_OUTPUT(WR_PORT, WR_PIN) #define CD_COMMAND PIN_LOW(CD_PORT, CD_PIN) #define CD_DATA PIN_HIGH(CD_PORT, CD_PIN) #define CD_OUTPUT PIN_OUTPUT(CD_PORT, CD_PIN) #define CS_ACTIVE PIN_LOW(CS_PORT, CS_PIN) #define CS_IDLE PIN_HIGH(CS_PORT, CS_PIN) #define CS_OUTPUT PIN_OUTPUT(CS_PORT, CS_PIN) #define RESET_ACTIVE PIN_LOW(RESET_PORT, RESET_PIN) #define RESET_IDLE PIN_HIGH(RESET_PORT, RESET_PIN) #define RESET_OUTPUT PIN_OUTPUT(RESET_PORT, RESET_PIN) // General macros. IOCLR registers are 1 cycle when optimised. #define WR_STROBE { WR_ACTIVE; WR_IDLE; } //PWLW=TWRL=50ns #define RD_STROBE RD_IDLE, RD_ACTIVE, RD_ACTIVE, RD_ACTIVE //PWLR=TRDL=150ns, tDDR=100ns #define CTL_INIT() { RD_OUTPUT; WR_OUTPUT; CD_OUTPUT; CS_OUTPUT; RESET_OUTPUT; } #define WriteCmd(x) { CD_COMMAND; write16(x); } #define WriteData(x) { CD_DATA; write16(x); }
подскажите как правильно раставить биты чтоб получилось PB5,PB4,PE7,PE6,PE5,PE4,PE3,PE2
забыл что 1 пост нельзя редактировоать
128 c 38 строки, делал по аналогии как на 328 - PB1,PB0,PE7,PE6,PE5,PE4,PE3,PE2 все работает
подскажите как правильно раставить биты чтоб управлять портами PB5,PB4,PE7,PE6,PE5,PE4,PE3,PE2
не выходит аленький цветочек
Ну из того, что бросается в глаза 50 строчка должна быть такой : #define EMASK 0xFC //B11111100
не работает:(
с BMASK = 0x03 порты PB0 PB1 все работает но их надо освободить
Valera19701, дайте ссылку на оригинальный файл.
http://forum.arduino.cc/index.php?action=dlattach;topic=366304.0;attach=165912
file - mcufriend_shield.h
Valera19701, как я понял рабочий бит порта в маске - ноль, а единицами прикрывают остальные биты. Тогда 50 строка пусть как было (0x03), а 52 строка значит получается 0xCF //B11001111
И непонятно зачем вы сделали выборочно инверсию BMASK из 56-57 строках, в примере для 328 меги, по аналогии которой говорите делали -никаких инверсий маски нет, не считая "юмора" автора в 24 строке, наверное ему проще было нарисовать знак инверсии, хотя логичнее было бы написать 0xFC .
Valera19701, как я понял рабочий бит порта в маске - ноль, а единицами прикрывают остальные биты. Тогда 50 строка пусть как было (0x03), а 52 строка значит получается 0xCF //B11001111
И непонятно зачем вы сделали выборочно инверсию BMASK из 56-57 строках, в примере для 328 меги, по аналогии которой говорите делали -никаких инверсий маски нет, не считая "юмора" автора в 24 строке, наверное ему проще было нарисовать знак инверсии, хотя логичнее было бы написать 0xFC .
я за два дня что только не пробовал, и BMASK = 0xFC тоже, не работает
Должно заработать при правильных 55-57 строках. Сейчас там полная путаница.
Должно заработать при правильных 55-57 строках. Сейчас там полная путаница.
сделал чтобы не путаться
не работает :(
например строка #define read_8() ( (PINB & ~BMASK) | (PINE & ~EMASK) ) при слиянии
получается накладка PORTE - B11111100
PORTB - B00110000
я уже пробовал сдвигать вправо на4, тоже не работает
#define read_8() ( (PINB & ~BMASK)>>4 | (PINE & ~EMASK) )
Это ж копия того, что было. У вас все дефайны с ошибками. Делайте по примеру 328
#define write_8(x){ PORTB = (PORTB & BMASK) | ((x) & EMASK);
PORTD = (PORTE & EMASK) | ((x) & BMASK); }
и так далее..
так?
утро вечера мудренее. спать пора:)
Valera19701, да, я это имел ввиду. Но к сожалению так тоже не заработает, я только сейчас, на свежую голову понял всю сложность задачи. Нельзя просто так взять другие биты, нужно привести их вес к тому, который должен быть. В общем есть три варианта решения. Первый -самый простой. Выделить отдельный полный порт. Тогда макросы упростятся до вида: #define read_8() (PINB) #define write_8(x) (PORTB=x) и.т.п Второй способ -чуть сложнее, собссно это способ как для меги328. Биты могут быть из разных портов, но должны не пересекаться, к примеру если берём 5 и 4 бит из порта Б, то в порту Е мы берём 7,6,3,2,1,0. Тогда должны работать способы как в #12, и третий способ, - биты в разнобой ( как ваш текущий вариант). Придётся дополнительно передвигать взад-вперёд, это будет жуткий пинг-понг, аналогично например строкам 230-250.
да, придется делать 3 вариант, уже пытаюсь понять как, строка 81 и чувствую как мозг закипает :)