I don't understand on passing parameter on ATMEGA128 and AVR Studio 6, I tested this function and working find
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 are appearing ![enter image description here][1] but by the time I put parameter to be passed, it doesn't work
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);
}
}
as you can see D0-D4 are missing but rw,rs,and en are working ![enter image description here][2]
What do I miss here ? It's very strange for me.... Any experiences , shares or knowledges will be very appreciated,
Here's the complete code, please let me know what I miss here ???
#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);
}
so the right one will be:
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);
}
I tested on ATMEGA32, and it's allright, is it related with ATMEGA128 configuration ??? Latest code :
#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);
}
I used this code and can display until init but can not display character A Video : http://www.youtube.com/watch?v=BbL6GBVkWuU The code (I'm not passing parameter at all and it works ):
#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);
}
PORTD
,PORTB
,PORTC
, etc), and the port is passed as a parameter to such function. You are trying to pass the value to write to the port. Like others have said, make sure thatDDRD
is set correctly (for instanceDDRD=0xFF;
). Also, even when relevant, it doesn't help to paste entire sections of FAQs: better to just link to those. Especially when such text lacks any formatting in the answer. \$\endgroup\$