¿Pasando el parámetro en ATMEGA128?

-1

No entiendo el parámetro de paso en ATMEGA128 y AVR Studio 6, He probado esta función y encontrar trabajo

lcd_cmd()
{
            PORTD = 0xFF;
            _delay_ms(100);
            PORTD = 0x00;
            _delay_ms(100);

            en=0;
            _delay_ms(100);
            en=1;
            _delay_ms(100);
            rs=0;
            _delay_ms(100);
            rs=1;
            _delay_ms(100);
            rw=0;
            _delay_ms(100);
            rw=1;
            _delay_ms(100);    
}
main()
{
 lcd_cmd();
}

D0-D4 están apareciendo [ingrese la descripción de la imagen aquí] [1] pero cuando pongo el parámetro a pasar, no funciona

lcd_cmd(unsigned char data_cmd)
{
            PORTD = data_cmd;
            _delay_ms(100);
            PORTD = data_cmd;
            _delay_ms(100);

            en=0;
            _delay_ms(100);
            en=1;
            _delay_ms(100);
            rs=0;
            _delay_ms(100);
            rs=1;
            _delay_ms(100);
            rw=0;
            _delay_ms(100);
            rw=1;
            _delay_ms(100);
}

main() {
   while(1) {
     lcd_cmd(0xFF);
     _delay_ms(100);
     lcd_cmd(0x00);
   }
}

como se puede ver, faltan D0-D4 pero rw, rs y en están funcionando ! [ingrese la descripción de la imagen aquí] [2]

¿Qué me pierdo aquí? Es muy extraño para mi ... Cualquier experiencia, intercambio o conocimiento será muy apreciado,

Aquí está el código completo, por favor, hágamelo saber. ¿Qué extraño aquí?

    #include <avr/io.h>
#include <util/delay.h>

// structure to allow bit field operations, name conversions: PORTA.0 -> PORT_A.b0  PORTB.7 -> PORT_B.b7
typedef struct{ uint8_t b0:1;
                uint8_t b1:1;
                uint8_t b2:1;
                uint8_t b3:1;
                uint8_t b4:1;
                uint8_t b5:1;
                uint8_t b6:1;
                uint8_t b7:1; } bits;

// define all the ports of your microcontroller, add more ports depending on the available mcu ports
#define PORT_A (* (volatile bits *) &PORTA)
#define PIN_A (* (volatile bits *) &PINA)
#define DDR_A (* (volatile bits *) &DDRA)

#define PORT_B (* (volatile bits *) &PORTB)
#define PIN_B (* (volatile bits *) &PINB)
#define DDR_B (* (volatile bits *) &DDRB)

//Mention Clock frequency here
#define _XTAL_FREQ 8000000 

#define lcd_data_pin PORTD

#define en PORT_A.b0
#define rs PORT_A.b1
#define rw PORT_A.b2




void lcd_init();
void lcd_data(unsigned char data1);
void lcd_cmd(unsigned char cmd);
void lcd_control(unsigned char cmdordata);
void lcd_string(unsigned char *str);


void lcd_init(){

    lcd_cmd(0x02);      
    lcd_cmd(0x28);      
    lcd_cmd(0x0C);
    lcd_cmd(0x06);
    lcd_cmd(0x80);

}

void lcd_data(unsigned char data1)
{

    lcd_data_pin = data1;
    lcd_control(2);


}

void lcd_cmd(unsigned char cmd){

    lcd_data_pin = cmd & 0xF0;
    lcd_control(1);

    lcd_data_pin = (cmd << 4) & 0xF0;
    lcd_control(1);


}

void lcd_control(unsigned char cmdordata){

    if(cmdordata == 1){
        en=1;
        rs=0;
        rw=0;
        _delay_ms(1);       
        en=0;
    }
    else if(cmdordata == 2){
        en=1;
        rs=1;
        rw=0;
        _delay_ms(1);
        en=0;
    }
}

void lcd_string(unsigned char *str){

    while(*str){
        lcd_data(*str++);       
    }

}




int main(){

    DDRA = 0xFF;
    DDRD = 0xFF;

    lcd_init();
    lcd_data('A');


    while(1){

        lcd_string("Working?");

    }

    return (0);
}

entonces el correcto será:

void lcd_data(unsigned char data1)
{

    lcd_data_pin = data1 & 0xF0;;
    lcd_control(2);

    lcd_data_pin = (data1<< 4) & 0xF0;
    lcd_control(2);


}

void lcd_cmd(unsigned char cmd){

    lcd_data_pin = cmd & 0xF0;
    lcd_control(1);

    lcd_data_pin = (cmd << 4) & 0xF0;
    lcd_control(1);

}

Probé en ATMEGA32, y está bien, ¿está relacionado con la configuración de ATMEGA128? Código más reciente:

 #include <avr/io.h>
#include <util/delay.h>

// structure to allow bit field operations, name conversions: PORTA.0 -> PORT_A.b0  PORTB.7 -> PORT_B.b7
typedef struct{ uint8_t b0:1;
                uint8_t b1:1;
                uint8_t b2:1;
                uint8_t b3:1;
                uint8_t b4:1;
                uint8_t b5:1;
                uint8_t b6:1;
                uint8_t b7:1; } bits;

// define all the ports of your microcontroller, add more ports depending on the available mcu ports
#define PORT_D (* (volatile bits *) &PORTD)
#define PIN_D (* (volatile bits *) &PIND)
#define DDR_D (* (volatile bits *) &DDRD)

#define PORT_G (* (volatile bits *) &PORTG)
#define PIN_G (* (volatile bits *) &PING)
#define DDR_G (* (volatile bits *) &DDRG)

//Mention Clock frequency here
//#define _XTAL_FREQ 8000000 

#define lcd_data_pin PORTA

#define en PORT_D.b0
#define rs PORT_D.b1
#define rw PORT_D.b2


void lcd_init();
void lcd_data(unsigned char data1);
void lcd_cmd(unsigned char cmd);
void lcd_control(unsigned char cmdordata);
void lcd_string(unsigned char *str);


void lcd_init(){

    lcd_cmd(0x30);
    _delay_ms(100);      
    lcd_cmd(0x38);
    _delay_ms(100);      
    lcd_cmd(0x0F);
    _delay_ms(100);
    lcd_cmd(0x80);
    _delay_ms(100);

}

void lcd_data(unsigned char data1)
{


    lcd_data_pin = data1;// & 0x0F;
        en=1;
        rs=1;
        rw=0;
        _delay_ms(10);
        en=0;

}

void lcd_cmd(unsigned char cmd){
    lcd_data_pin = cmd ;
        en=1;
        rs=0;
        rw=0;
        _delay_ms(10);       
        en=0;

}



void lcd_string(unsigned char *str){

    while(*str){
        lcd_data(*str++);       
    }

}




int main(){

    DDR_D.b0 = 1;
    DDR_D.b1 = 1;
    DDR_D.b2 = 1;
    DDRA = 0xFF;

    lcd_init();


    while(1){
      _delay_ms (200);
        lcd_cmd(0x80);//put the cursor into the first row
        _delay_ms (300);
        lcd_cmd(0x01);//Clear display
        _delay_ms (300);
        lcd_cmd(0xC0);//goto second row
        _delay_ms (300); 
       lcd_cmd(0x01); //Clear display

       lcd_string("HELLO ATMEGA32");

    }

    return (0);
}

Utilicé este código y puedo mostrarlo hasta el inicio pero no puedo mostrar el carácter A Video: enlace El código (no paso ningún parámetro y funciona):

#include <avr/io.h>
#include <util/delay.h>

// structure to allow bit field operations, name conversions: PORTA.0 -> PORT_A.b0  PORTB.7 -> PORT_B.b7
typedef struct{ uint8_t b0:1;
                uint8_t b1:1;
                uint8_t b2:1;
                uint8_t b3:1;
                uint8_t b4:1;
                uint8_t b5:1;
                uint8_t b6:1;
                uint8_t b7:1; } bits;

// define all the ports of your microcontroller, add more ports depending on the available mcu ports
#define PORT_D (* (volatile bits *) &PORTD)
#define PIN_D (* (volatile bits *) &PIND)
#define DDR_D (* (volatile bits *) &DDRD)

#define PORT_G (* (volatile bits *) &PORTG)
#define PIN_G (* (volatile bits *) &PING)
#define DDR_G (* (volatile bits *) &DDRG)

//Mention Clock frequency here
#define _XTAL_FREQ 8000000 

#define lcd_data_pin PORTA

#define en PORT_D.b0
#define rs PORT_D.b1
#define rw PORT_D.b2





lcd_init()
{
      lcd_data_pin = 0x30;

       en = 1;
       rs = 0;
       rw = 0;
       _delay_ms(10);
      en = 0;

//next command
       _delay_ms(100);

      lcd_data_pin = 0x38;

       en = 1;
       rs = 0;
       rw = 0;
       _delay_ms(10);
      en = 0;
    _delay_ms(100);

      lcd_data_pin = 0x0F;

       en = 1;
       rs = 0;
       rw = 0;
       _delay_ms(10);
      en = 0;

//next command
       _delay_ms(100);

      lcd_data_pin = 0x80;

       en = 1;
       rs = 0;
       rw = 0;
       _delay_ms(10);
      en = 0;

      } 
  lcd_clear()
{
    lcd_data_pin = 0x80;//put the cursor into the first row
     en = 1;
       rs = 0;
       rw = 0;
       _delay_ms(10);
      en = 0;
        _delay_ms (300);

    lcd_data_pin = 0xC0;//put the cursor into the first row
     en = 1;
       rs = 0;
       rw = 0;
       _delay_ms(10);
      en = 0;
        _delay_ms (300);

}
void lcd_data()
{

       lcd_data_pin = 0x41;// & 0x0F;
        en=1;
        rs=1;
        rw=0;
        _delay_ms(10);
        en=0;

}



int main(){

    DDR_D.b0 = 1;
    DDR_D.b1 = 1;
    DDR_D.b2 = 1;
    DDRA = 0xFF;



    lcd_init();

    while(1){
        lcd_clear();
        lcd_data();
        _delay_ms(1000); 

    }

    return (0);
}
    
pregunta Rick Ant

3 respuestas

1

Esto es lo que debo hacer para que su código se compile (en avr-gcc) y sea funcional:

#include <avr/io.h>
#include <util/delay.h>

bool en;
bool rs;
bool rw;

void lcd_cmd(unsigned char data_cmd)
{
        PORTD = data_cmd;
        _delay_ms(100);
        PORTD = data_cmd;
        _delay_ms(100);

        en=0;
        _delay_ms(100);
        en=1;
        _delay_ms(100);
        rs=0;
        _delay_ms(100);
        rs=1;
        _delay_ms(100);
        rw=0;
        _delay_ms(100);
        rw=1;
        _delay_ms(100);
}

int main() {
   DDRD = 0xFF;
   while(1) {
     lcd_cmd(0xFF);
     _delay_ms(100);
     lcd_cmd(0x00);
   }
}

Sin embargo, el siguiente programa hace exactamente lo mismo que su código (en la medida en que lo compartió con nosotros), pero es mucho más corto:

#include <avr/io.h>
#include <util/delay.h>

void lcd_cmd(unsigned char data_cmd)
{
        PORTD = data_cmd;
        _delay_ms(800);
}

int main() {
   DDRD = 0xFF;
   while(1) {
     lcd_cmd(0xFF);
     _delay_ms(100);
     lcd_cmd(0x00);
   }
}
    
respondido por el jippie
0

Su problema está en lcd_command ()

lcd_data_pin = cmd & 0xF0;

Siempre pondrá d0-d3 en cero, al igual que

lcd_data_pin = (cmd << 4) & 0xF0;

porque & 0xF0 siempre da como resultado un byte con los cuatro bits más bajos despejados: d0 es el bit menos significativo del puerto, d7 el más significativo.

Es posible que hayas querido escribir:

lcd_data_pin = cmd & 0x0f; // send the low four bits

y

lcd_data_pin = (cmd >> 4) & 0x0f; // send the high four bits in the low four bits of D (the '&' is unnecessary as cmd is unsigned)

Mi código anterior también establece d4-d7 en cero, lo que no creo que importe en tu aplicación.

    
respondido por el Tom Davies
-1

Establezca el bit de fusible M103C en el programador ISP en 0 y solucionará el problema,

gracias por cualquier respuesta.

    
respondido por el Rick Ant

Lea otras preguntas en las etiquetas