
دوستان سلام
من که دیگه دیونه شدم از دست این .... چی بگم آخه ؟
دوستان مداری دارم که از نظر سخت افزاری ok هست . ( مدار برد AVR Ethernet Board ECA هست )
یه lcd 2*16 کاراکتری به میکرو من متصل شده Mega32A .
نکته جلب توجه این است که Hex ی که با کدویژن نوشتم رو وقتی داخلش میریزم lcd کار می کنه !
ولی وقتی برنامه ای که با Atmel Studio نوشتم رو داخل می ریزم lcd کار نمی کنه !
دوستان خیلی تنظیمات مختلف رو در کدم چک کردم به نتیجه نرسیدم . کد ها رو می زارم اگه ممکنه یه نگاهی بندازید ببینید متوجه اشکال میشید .
کمکم کنید ممنون . :biggrin:
کد main برنامه
کد:
#include <avr/io.h>
#include <stdlib.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <string.h>
#include <avr/pgmspace.h>
// HD44780 LCD Class
#include "HD44780.h"
#define F_CPU 8000000UL
#define True 1
#define False 0
#define Output 0xFF;
#define Input 0x00;
#define SW1 PINA4
#define SW2 PINA5
#define SW3 PINA6
#define SW4 PINA7
HD44780 lcd;
int main(void) {
PORTA=0xFC;
DDRA=0x0C;
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0x3C;
PORTD=0x00;
DDRD=0x00;
char Manaelectronic[16] = "Mana Electronic";
lcd.lcd_init(); // init the LCD screen
lcd.lcd_clrscr(); // initial screen cleanup
lcd.lcd_home();
lcd.lcd_string(Manaelectronic);
fcpu_delay_ms(1000);
while(1){
PORTA = 0x08;
fcpu_delay_ms(500);
PORTA = 0x04;
fcpu_delay_ms(500);
}
return (0);
}
کد هدر HD44780.h
کد:
// HD44780 LCD 4-bit IO mode Driver
// (C) 2009 - 2012 Radu Motisan , radu.motisan@gmail.com , www.pocketmagic.net
// All rights reserved.
//
// To be used with AVR Studio 5 (avr-g++.exe)
//
// HD44780.h: Definitions for LCD command instructions
// The constants define the various LCD controller instructions which can be passed to the
// function lcd_command(), see HD44780 data sheet for a complete description.
#pragma once
#include <stdio.h>
//--------------------------------CONFIGURE LCD------------------------------------------------------//
#define LCD_LINES 2 // number of visible lines of the display
#define LCD_DISP_LENGTH 16 // visibles characters per line of the display
#define LCD_START_LINE1 0x00 // DDRAM address of first char of line 1
#define LCD_START_LINE2 0x40 // DDRAM address of first char of line 2
#define LCD_START_LINE3 0x14 // DDRAM address of first char of line 3
#define LCD_START_LINE4 0x54 // DDRAM address of first char of line 4
//Purpose: work with a LCD display
#define LCD_4BIT_D4_PORT PORTD // port for 4bit data bit 0 //D5 poz:3 connector...[digits 0,1,...]
#define LCD_4BIT_D4_PIN 4 // pin for 4bit data bit 0
#define LCD_4BIT_D5_PORT PORTD // port for 4bit data bit 1 //D6
#define LCD_4BIT_D5_PIN 5 // pin for 4bit data bit 1
#define LCD_4BIT_D6_PORT PORTD // port for 4bit data bit 2 //D7
#define LCD_4BIT_D6_PIN 6 // pin for 4bit data bit 2
#define LCD_4BIT_D7_PORT PORTD // port for 4bit data bit 3 //B0
#define LCD_4BIT_D7_PIN 7 // pin for 4bit data bit 3
#define LCD_RS_PORT PORTB // port for RS line
#define LCD_RS_PIN 0 // pin for RS line
#define LCD_E_PORT PORTB // port for Enable line
#define LCD_E_PIN 2 // pin for Enable line
#define LCD_RW_PORT PORTB // port for RW line UNUSED - we only WRITE
#define LCD_RW_PIN 1 // pin for RW line UNUSED - we only WRITE
//---------------------------------------------------------------------------------------------------//
// instruction register bit positions, see HD44780U data sheet
#define LCD_CLR 0x0 // DB0: clear display
#define LCD_HOME 0x1 // DB1: return to home position
#define LCD_ENTRY_MODE 0x2 // DB2: set entry mode
#define LCD_ENTRY_INC 0x1 // DB1: 1=increment, 0=decrement
#define LCD_ENTRY_SHIFT 0x1 // DB2: 1=display shift on 0->1
#define LCD_ON 0x3 // DB3: turn lcd/cursor on
#define LCD_ON_DISPLAY 0x2 // DB2: turn display on
#define LCD_ON_CURSOR 0x1 // DB1: turn cursor on
#define LCD_ON_BLINK 0x0 // DB0: blinking cursor ?
#define LCD_MOVE 0x4 // DB4: move cursor/display
#define LCD_MOVE_DISP 0x3 // DB3: move display (0-> cursor) ?
#define LCD_MOVE_RIGHT 0x2 // DB2: move right (0-> left) ?
#define LCD_FUNCTION 0x5 // DB5: function set
#define LCD_FUNCTION_8BIT 0x0 // DB4: set 8BIT mode (0->4BIT mode) 4->0
#define LCD_FUNCTION_2LINES 0x1 // DB3: two lines (0->one line) 3->1
#define LCD_FUNCTION_10DOTS 0x0 // DB2: 5x10 font (0->5x7 font) 2->0
#define LCD_CGRAM 0x6 // DB6: set CG RAM address
#define LCD_DDRAM 0x7 // DB7: set DD RAM address
#define LCD_BUSY 0x7 // DB7: LCD is busy
// set entry mode: display shift on/off, dec/inc cursor move direction
#define LCD_ENTRY_DEC 0x04 // display shift off, dec cursor move dir
#define LCD_ENTRY_DEC_SHIFT 0x05 // display shift on, dec cursor move dir
#define LCD_ENTRY_INC_ 0x06 // display shift off, inc cursor move dir
#define LCD_ENTRY_INC_SHIFT 0x07 // display shift on, inc cursor move dir
// display on/off, cursor on/off, blinking char at cursor position
#define LCD_DISP_OFF 0x08 // display off
#define LCD_DISP_ON 0x0C // display on, cursor off
#define LCD_DISP_ON_BLINK 0x0D // display on, cursor off, blink char
#define LCD_DISP_ON_CURSOR 0x0E // display on, cursor on
#define LCD_DISP_ON_CURSOR_BLINK 0x0F // display on, cursor on, blink char
// move cursor/shift display
#define LCD_MOVE_CURSOR_LEFT 0x10 // move cursor left (decrement)
#define LCD_MOVE_CURSOR_RIGHT 0x14 // move cursor right (increment)
#define LCD_MOVE_DISP_LEFT 0x18 // shift display left
#define LCD_MOVE_DISP_RIGHT 0x1C // shift display right
// function set: set interface data length and number of display lines
#define LCD_FUNCTION_4BIT_1LINE 0x20 // 4-bit interface, single line, 5x7 dots
#define LCD_FUNCTION_4BIT_2LINES 0x28 // 4-bit interface, dual line, 5x7 dots
#define LCD_FUNCTION_8BIT_1LINE 0x30 // 8-bit interface, single line, 5x7 dots
#define LCD_FUNCTION_8BIT_2LINES 0x38 // 8-bit interface, dual line, 5x7 dots
//
#define LCD_MODE_DEFAULT ((1<<LCD_ENTRY_MODE) | (1<<LCD_ENTRY_INC) )
// address of data direction register of port x
#define LCD_DDR(x) (*(&x - 1))
class HD44780 {
private:
int g_nCurrentLine;
inline void lcd_e_high() { LCD_E_PORT |= _BV(LCD_E_PIN); }
inline void lcd_e_low() { LCD_E_PORT &= ~_BV(LCD_E_PIN); }
inline void lcd_rs_high() { LCD_RS_PORT |= _BV(LCD_RS_PIN); }
inline void lcd_rs_low() { LCD_RS_PORT &= ~_BV(LCD_RS_PIN); }
// flush channel E
void lcd_toggle_e(void);
// PURPOSE: send a character or an instruction to the LCD
void lcd_write(uint8_t data,uint8_t rs) ;
// PURPOSE: send an instruction to the LCD
void lcd_instr(uint8_t instr);
public:
// PURPOSE: Initialize LCD to 4 bit I/O mode
void lcd_init();
// PURPOSE: send a character to the LCD
void lcd_char(uint8_t data);
// PURPOSE: send a null terminated string to the LCD eg. char x[10]="hello!";
void lcd_string(char *text);
void lcd_string_format(char *szFormat, ...);
// PURPOSE: Set cursor to specified position
// Input: x horizontal position (0: left most position)
// y vertical position (0: first line)
void lcd_gotoxy(uint8_t x, uint8_t y);
// PURPOSE: Move cursor on specified line
void lcd_setline(uint8_t line);
// PURPOSE: Clear display and set cursor to home position
void lcd_clrscr(void);
// FUNCTION: lcd_home
// PURPOSE: Set cursor to home position
void lcd_home(void);
};
کد CPP هدر HD44780.cpp
کد:
// HD44780 LCD 4-bit IO mode Driver
// (C) 2009 - 2012 Radu Motisan , radu.motisan@gmail.com , www.pocketmagic.net
// All rights reserved.
//
// To be used with AVR Studio 5 (avr-g++.exe)
//
// HD44780.cpp: Definitions for LCD command instructions
// The constants define the various LCD controller instructions which can be passed to the
// function lcd_command(), see HD44780 data sheet for a complete description.
#include <avr/io.h>
#include "HD44780.h"
#include "aux_globals.h"
// PURPOSE: flush channel E
void HD44780::lcd_toggle_e(void)
{
lcd_e_high();
fcpu_delay_us(10);
lcd_e_low();
}
// PURPOSE: send a character or an instruction to the LCD
void HD44780::lcd_write(uint8_t data,uint8_t rs)
{
// we cannot check LCD status (no read available) , so we will assume a default delay to wait for lcd to be ready
fcpu_delay_us(500);
//check write type
if (rs)
lcd_rs_high(); //write data
else
lcd_rs_low(); //write instruciton
// configure data pins as output
LCD_DDR(LCD_4BIT_D4_PORT) |= _BV(LCD_4BIT_D4_PIN);
LCD_DDR(LCD_4BIT_D5_PORT) |= _BV(LCD_4BIT_D5_PIN);
LCD_DDR(LCD_4BIT_D6_PORT) |= _BV(LCD_4BIT_D6_PIN);
LCD_DDR(LCD_4BIT_D7_PORT) |= _BV(LCD_4BIT_D7_PIN);
// output high nibble first
LCD_4BIT_D7_PORT &= ~_BV(LCD_4BIT_D7_PIN);
LCD_4BIT_D6_PORT &= ~_BV(LCD_4BIT_D6_PIN);
LCD_4BIT_D5_PORT &= ~_BV(LCD_4BIT_D5_PIN);
LCD_4BIT_D4_PORT &= ~_BV(LCD_4BIT_D4_PIN);
if(data & 0x80) LCD_4BIT_D7_PORT |= _BV(LCD_4BIT_D7_PIN);
if(data & 0x40) LCD_4BIT_D6_PORT |= _BV(LCD_4BIT_D6_PIN);
if(data & 0x20) LCD_4BIT_D5_PORT |= _BV(LCD_4BIT_D5_PIN);
if(data & 0x10) LCD_4BIT_D4_PORT |= _BV(LCD_4BIT_D4_PIN);
lcd_toggle_e();
// output low nibble
LCD_4BIT_D7_PORT &= ~_BV(LCD_4BIT_D7_PIN);
LCD_4BIT_D6_PORT &= ~_BV(LCD_4BIT_D6_PIN);
LCD_4BIT_D5_PORT &= ~_BV(LCD_4BIT_D5_PIN);
LCD_4BIT_D4_PORT &= ~_BV(LCD_4BIT_D4_PIN);
if(data & 0x08) LCD_4BIT_D7_PORT |= _BV(LCD_4BIT_D7_PIN);
if(data & 0x04) LCD_4BIT_D6_PORT |= _BV(LCD_4BIT_D6_PIN);
if(data & 0x02) LCD_4BIT_D5_PORT |= _BV(LCD_4BIT_D5_PIN);
if(data & 0x01) LCD_4BIT_D4_PORT |= _BV(LCD_4BIT_D4_PIN);
lcd_toggle_e();
// all data pins high (inactive)
LCD_4BIT_D4_PORT |= _BV(LCD_4BIT_D4_PIN);
LCD_4BIT_D5_PORT |= _BV(LCD_4BIT_D5_PIN);
LCD_4BIT_D6_PORT |= _BV(LCD_4BIT_D6_PIN);
LCD_4BIT_D7_PORT |= _BV(LCD_4BIT_D7_PIN);
}
// PURPOSE: send an instruction to the LCD
void HD44780::lcd_instr(uint8_t instr)
{
lcd_write(instr,0);
}
// PURPOSE: Initialize LCD to 4 bit I/O mode
void HD44780::lcd_init()
{
// configure all port bits as output (LCD data and control lines on different ports
LCD_DDR(LCD_RS_PORT) |= _BV(LCD_RS_PIN);
LCD_DDR(LCD_E_PORT) |= _BV(LCD_E_PIN);
LCD_DDR(LCD_4BIT_D4_PORT) |= _BV(LCD_4BIT_D4_PIN);
LCD_DDR(LCD_4BIT_D5_PORT) |= _BV(LCD_4BIT_D5_PIN);
LCD_DDR(LCD_4BIT_D6_PORT) |= _BV(LCD_4BIT_D6_PIN);
LCD_DDR(LCD_4BIT_D7_PORT) |= _BV(LCD_4BIT_D7_PIN);
// wait 25ms or more after power-on
fcpu_delay_us(25000);
// initial write to lcd is 8bit
LCD_4BIT_D5_PORT |= _BV(LCD_4BIT_D5_PIN); // _BV(LCD_FUNCTION)>>4;
LCD_4BIT_D4_PORT |= _BV(LCD_4BIT_D4_PIN); // _BV(LCD_FUNCTION_8BIT)>>4;
lcd_toggle_e();
fcpu_delay_us(2000); //2000 // delay, busy flag can't be checked here
// repeat last command
lcd_toggle_e();
fcpu_delay_us(64); //64 // delay, busy flag can't be checked here
// now configure for 4bit mode
LCD_4BIT_D4_PORT &= ~_BV(LCD_4BIT_D4_PIN); // LCD_FUNCTION_4BIT_1LINE>>4
lcd_toggle_e();
fcpu_delay_us(2000); // some displays need this additional delay
// set 4 bit IO
lcd_instr(LCD_FUNCTION_4BIT_2LINES); // 4-bit interface, dual line, 5x7 dots
lcd_toggle_e();
fcpu_delay_us(2000); // some displays need this additional delay
lcd_instr(LCD_ENTRY_INC_);//cursor move right, no shift display
lcd_toggle_e();
fcpu_delay_us(2500); // some displays need this additional delay
lcd_instr(LCD_DISP_ON_CURSOR_BLINK);// display on, cursor on, blink char
lcd_toggle_e();
fcpu_delay_us(2500); // some displays need this additional delay
lcd_home();//set cursor to home and clear the cursor
}
// PURPOSE: send a character to the LCD
void HD44780::lcd_char(uint8_t data)
{
if (data=='\n')
{
if (g_nCurrentLine >= LCD_LINES - 1)
lcd_setline(0);
else
lcd_setline(g_nCurrentLine+1);
}
else
lcd_write(data,1);
}
// PURPOSE: send a null terminated string to the LCD eg. char x[10]="hello!";
void HD44780::lcd_string(char *text)
{
char c;
while ( (c = *text++) ) lcd_char(c);
}
void HD44780::lcd_string_format(char *szFormat, ...)
{
char szBuffer[256]; //in this buffer we form the message
int NUMCHARS = sizeof(szBuffer) / sizeof(szBuffer[0]);
int LASTCHAR = NUMCHARS - 1;
va_list pArgs;
va_start(pArgs, szFormat);
vsnprintf(szBuffer, NUMCHARS - 1, szFormat, pArgs);
va_end(pArgs);
lcd_string(szBuffer);
}
// PURPOSE: Set cursor to specified position
// Input: x horizontal position (0: left most position)
// y vertical position (0: first line)
void HD44780::lcd_gotoxy(uint8_t x, uint8_t y)
{
#if LCD_LINES==1
lcd_instr((1<<LCD_DDRAM)+LCD_START_LINE1+x);
#elif LCD_LINES==2
switch (y)
{
case 0:lcd_instr((1<<LCD_DDRAM)+LCD_START_LINE1+x);break;
case 1:lcd_instr((1<<LCD_DDRAM)+LCD_START_LINE2+x);break;
default: break;
}
#elif LCD_LINES==4
switch (y)
{
case 0:lcd_instr((1<<LCD_DDRAM)+LCD_START_LINE1+x);break;
case 1:lcd_instr((1<<LCD_DDRAM)+LCD_START_LINE2+x);break;
case 2:lcd_instr((1<<LCD_DDRAM)+LCD_START_LINE3+x);break;
case 3:lcd_instr((1<<LCD_DDRAM)+LCD_START_LINE4+x);break;
default: break;
}
#endif
}
// PURPOSE: Move cursor on specified line
void HD44780::lcd_setline(uint8_t line)
{
uint8_t addressCounter = 0;
switch(line)
{
case 0: addressCounter = LCD_START_LINE1; break;
case 1: addressCounter = LCD_START_LINE2; break;
case 2: addressCounter = LCD_START_LINE3; break;
case 3: addressCounter = LCD_START_LINE4; break;
default:addressCounter = LCD_START_LINE1; break;
}
g_nCurrentLine = line;
lcd_instr((1<<LCD_DDRAM)+addressCounter);
}
// PURPOSE: Clear display and set cursor to home position
void HD44780::lcd_clrscr(void)
{
g_nCurrentLine = 0;
lcd_instr(1<<LCD_CLR);
fcpu_delay_us(500);
}
// PURPOSE: Set cursor to home position
void HD44780::lcd_home(void)
{
g_nCurrentLine = 0;
lcd_instr(1<<LCD_HOME);
}
شماتیک مدار توی سایت اصلی ECA هست نمی دونم چطوری باید بزارمش اینجا ولی پایه های LCD رو می نویسم
B0 -> RS
B1 -> RW
B2 -> EN
D4 -> D4
D5 -> D5
D6 -> D6
D7 -> D7
ممنون





دیدگاه