- Labornetzteil AliExpress         
Ergebnis 1 bis 5 von 5

Thema: problem mit bitmanipulation

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.10.2006
    Ort
    Detmold
    Alter
    33
    Beiträge
    106

    problem mit bitmanipulation

    Anzeige

    LiFePo4 Akku selber bauen - Video
    hallo
    ich habe ein glcd an meinem mega32 hängen, das bis vorhin noch super lief. ein port war für die daten zuständig, einer als CTRL port. jetzt brauchte ich am Datenport (PORTC) die SDA und SCL leitung. also habe ich statt PC0&PC1 PB0&PB1 mit dem datenport des lcd verlötet, weil die noch frei waren. dann hab ich das programm umgeschrieben, bis ich dachte, so müsste es funktionieren. die lötverbindungen sind einwandfrei, aber es tut sich nix. ich glaube ich habe einen einfachen fehler bei der bitmanipulation in diesen zeilen gemacht, ich komm aber nich drauf was es ist.
    statt
    DATAPORT=command;
    steht jetzt
    Code:
    	DATAPORT &=(1<<0)|(1<<1);
    	DATAPORT |= command&(~((1<<0)|(1<<1)));	
    	DATAPORT2 &=~((1<<0)|(1<<1));
    	DATAPORT2 |= command&((1<<0)|(1<<1));
    wo ist der denkfehler, tut mir etwas leid wenn die frage total dumm ist aber ich hab nen brett vorm kopf.
    hier der komplette code:
    Code:
    #define DATAPORT		PORTC
    #define DATADDR		DDRC
    #define DATAPIN		PINC
    #define DATAPORT2	PORTB
    #define DATADDR2		DDRB
    #define DATAPIN2		PINB
    #define CTRLPORT		PORTB
    #define CTRLDDR		DDRB
    #define RS				2
    #define RW				3
    #define E				4
    
    #define	lcd_busy		_delay_us(2)
    
    void lcd_enable(void){
    	// Erzeugt eine fallende Flanke am Enable-Pin
    
    	CTRLPORT |= (1<<E);
    	lcd_busy;
    	CTRLPORT &= ~(1<<E);
    	lcd_busy;
    }
    
    void lcd_writecommand(uint8_t command) {
    	// Kommandobyte -> HD61830
     
    	lcd_busy;
    	CTRLPORT &= ~(1<<RW);		// R/W auf logisch 0 -> W 
    	CTRLPORT |= (1<<RS);			// RS auf logisch 1 -> aktiv
    	DATAPORT &=(1<<0)|(1<<1);
    	DATAPORT |= command&(~((1<<0)|(1<<1)));		// übergebenes Kommandobyte wird ausgegeben
    	DATAPORT2 &=~((1<<0)|(1<<1));
    	DATAPORT2 |= command&((1<<0)|(1<<1));		// übergebenes Kommandobyte wird ausgegeben
    	lcd_enable();
    }
     
    void lcd_writedata(uint8_t data) {
    	// Datenbyte -> HD61830
     
    	lcd_busy;
    	CTRLPORT &= ~(1<<RW);	// R/W auf logisch 0 -> W 
    	CTRLPORT &= ~(1<<RS);	// RS auf logisch 0 -> inaktiv
    	DATAPORT &=(1<<0)|(1<<1);
    	DATAPORT |= data&(~((1<<0)|(1<<1)));		// übergebenes Kommandobyte wird ausgegeben
    	DATAPORT2 &=~((1<<0)|(1<<1));
    	DATAPORT2 |= data&((1<<0)|(1<<1));		// übergebenes Kommandobyte wird ausgegeben
    	lcd_enable();
    }
    
    void lcd_send(uint8_t command, uint8_t data) {
    	// Kombination aus Kommando- und Datenbyte
    
    	lcd_writecommand(command);
    	lcd_writedata(data);
    }
    
    void lcd_init(unsigned char modus){
    	// Initialisiert das Display
    
    	DATADDR |= ~((1<<0)|(1<<1));				// Datenport wird als Ausgang deklariert
    	DATADDR2 |= (1<<0)|(1<<1);				// Datenport wird als Ausgang deklariert
    	CTRLDDR |= (1<<RW)|(1<<RS)|(1<<E);		// Kommandoport wird als Ausgang deklariert
    	
    	if(modus == 'c'){
    	// Charaktermodus
    	
    	lcd_send(0x00, 0x30);	// Mode Control
    	lcd_send(0x01, 0x75);	// Set Character Pitch
    	lcd_send(0x02, 0x27);	// Set Number of Characters
    	lcd_send(0x03, 0x80);	// Set Number of Time Divisions
    	lcd_send(0x04, 0x07);	// Set Cursor Position
    	}
    	else{
    	// Grafikmodus
    	
    	lcd_send(0x00, 0x32);	// Mode Control
    	lcd_send(0x01, 0x07);	// number of bits of 1-byte display data to be displayed
    	lcd_send(0x02, 0x1d);	// number of horizontal bytes
    	lcd_send(0x03, 0x80);	// Set Number of Time Divisions 
    	}
    	
    	lcd_send(0x08, 0x00);	// Set Display Start Low Order Address
    	lcd_send(0x09, 0x00);	// Set Display Start High Order Address
    	
    	lcd_clear(modus);
    }
    
    void lcd_clear(unsigned char modus){
    	// Löscht das Display
    
    	lcd_gotoxy(modus, 0, 0);		// Cursor an den Anfang setzen
    	
    	if(modus == 'c'){
    	// Charaktermodus
    	
    	for(uint16_t i=0; i<640; i++)		// Alle Chars durchlaufen und löschen
    		lcd_send(0x0c, 0x20);
    	}
    	else{
    	// Grafikmodus
    	
    	for(uint16_t i=0; i<3840; i++)	// Alle Bytes durchlaufen und löschen
    		lcd_send(0x0c, 0x00);
    	}
    
    	lcd_gotoxy(modus, 0, 0);		// Cursor an den Anfang setzen
    }
    
    void lcd_gotoxy(unsigned char modus, uint8_t x, uint8_t y){
    	// Setzt den Cursor an eine bestimmte Position
    	
    	uint16_t adress;
    	
    	if(modus == 'c'){
    	// Charaktermodus
    	adress = (y * 40) + x;
    	}
    	
    	else{
    	// Grafikmodus	
    	adress = (y * 30) + x;
    	}
    	
    	lcd_send(0x0a, (uint8_t)(adress));		// Set Cursor Address (Low Order)
    	lcd_send(0x0b, (uint8_t)(adress >> 8));	// Set Cursor Address (High Order)
    }
    
    void lcd_setdot(uint8_t x, uint8_t y){
    	// Setzt ein Pixel an einer bestimmten Position
    
    	lcd_gotoxy('g', (x >> 3), y);
    	lcd_send(0x0f, (x & 0x07));
    }
    
    void lcd_cleardot(uint8_t x, uint8_t y){
    	// Löscht ein Pixel an einer bestimmten Position
    
    	lcd_gotoxy('g', (x >> 3), y);
    	lcd_send(0x0e, (x & 0x07));
    }
    
    void lcd_putc(char c){
    	static char line=0;
    	if((c == 'ä') | ( c == 'Ä' ) ){
    		lcd_send(0x0c,0xE1);
    		}	
    	else if((c == 'ü') | ( c == 'Ü' ) ){
    		lcd_send(0x0c,0xF5);
    		}	
    	else if((c == 'ö') | ( c == 'Ö' ) ){
    		lcd_send(0x0c,0xEF);
    		}		
    	else if((c == '\n') | ( c == '\r' )){
    		line++;
    		if(line==16) line=0;
    		lcd_gotoxy('c',0,line);
    		}
    	else lcd_send(0x0c,c);
    }
    	
    void lcd_puts(char *string){
    	uint8_t i=0;
    	char c = string[0];
    	
    	while(c != 0) {
    		lcd_putc(c);
    		c = string[++i];	
    	}
    }
    
    char swapbits(char c){
    	char swap=0;
    	for(char bit=0;bit<8;bit++) if(c&(1<<bit)) swap|=(1<<(7-bit));
    	return swap;
    }
    
    void lcd_picture(char* byte){
    	for(short counter=0;counter<3840;counter++) {
    		lcd_send(0x0c,swapbits(pgm_read_byte(byte)));
    		byte++;
    		}
    }
    
    void glcd_puts(unsigned short x, unsigned short y, char *string){
    	uint8_t i=0;
    	char c = string[0];
    	unsigned short xpos=x, ypos=y;
    	
    	while(c != 0) {
    		glcd_putc(xpos,ypos,c);
    		xpos+=6;
    		if(c=='\n'){
    			xpos=x;
    			ypos+=8;
    			}
    		c = string[++i];	
    	}
    }
    
    void glcd_putc(unsigned short x, unsigned short y, char character) {
    	unsigned char fontIndex, i, j;
    
    	/* The 5x7 character set starts at the '!' character (ASCII index 
     	 * number 33) so we subtract 32 from the ASCII character to find the 
     	 * index in the 5x7 font table. */	
    	fontIndex = character-32;
    	/* If the index is out of bounds, bail out */
    	if (fontIndex > 94)
    		return;
    	
    	for (i = 0; i < FONT_WIDTH; i++) {
    		for (j = 0; j < FONT_HEIGHT; j++) {
    			/* Check if the bit/pixel is set, paint accoringly to 
     			 * the screen */
    			if (pgm_read_byte(&Font5x7[FONT_WIDTH*fontIndex+i] ) & (1<<j))
    				lcd_setdot(x, y+j);
    			else	
    				lcd_cleardot(x, y+j);
    		}
    		/* Move the LCD cursor through the font width as well */
    		x++;
    	}
    }
    danke schonmal

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    1. Der Zugriff ist nicht-atomar. Wenn einer der Ports auch per ISR verändert wird, kann das Probleme machen
    2. Während des Setzens können je nach Device ungültige Kommandos entstehen? Vorher änderten sich ja alle Pins mit einem Schlag, was jetzt nicht mehr der Fall ist. Das Problem wird vielleicht abgemildert durch

      Code:
      PORT = (PORT & 0b11)  | (command & ~0b11);
      weil dann im Gegensatz zu Deiner Lösung nur 1x gelesen und 1x geschrieben wird (bei Dir 2x).
    3. DDR ist gesetzt?
    Disclaimer: none. Sue me.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.10.2006
    Ort
    Detmold
    Alter
    33
    Beiträge
    106
    1. stimmt aber ich habe keine interrupts aktiviert
    2. ist egal da das ganze nur bei einem enable impuls übertragen wird
    3. DDR ist gesetzt
    danke trotzdem

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    15.11.2004
    Ort
    Aachen
    Alter
    39
    Beiträge
    246
    Also rein logisch gesehen ist das schon richtig was du gemacht hast, aber übersichtlicher ist es auf jeden Fall in der Weise wie SprinterSB es geschrieben hat. (wobei ich anstatt 0b11 lieber 0x3 schreiben würde, versteht der GCC die Schreibweise 0b... ?)

    Im Zweifelsfall, auch zum Testen der Verbindungen, kannst du ja einfach mal command = 0xFF anlegen und an allen Pins messen ob ein high Pegel anliegt..., vielleicht ist ja doch ne kalte Lötstelle oder sowas.

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.10.2006
    Ort
    Detmold
    Alter
    33
    Beiträge
    106
    hi
    der GCC versteht die schreibweise 0b...., ist aber nicht standardkonform deshalb mag ichs nicht mehr so gerne.

    das problem hat sich irgendwie von selbst gelöst. ich habe keine erklärung aber es geht jetzt.
    danke für eure hilfe.
    LG maddin

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen