zdravím, chci se zeptat jestli někdo nemáte nějakou jednoduchou knihovnu pro ovládání tohoto displaye : gme.cz/lcd-alfanumericky-dis … t-p513-227 má ovladač ST7066 , podle toho co jsem četl je zpětně kompatibilní s HD44780, co jsem hledal knihovnu tak nikde sem pro toto rozlišení displaye 20x4 nic nenašel, nebo asi špatně hledám. Programovat v Céčku se teprve učím, ve škole nás učili jenom v assembleru, jinak bych si knihovnu napsal svojí.
Díky
Jo, něco jsem našel. Není to sice nic extra, ale pro začátek by ti to mohlo stačit.
44780.h
#ifndef __DRIVERS_HD44780_H
#define __DRIVERS_HD44780_H
#define Radku 4
#define Sloupcu 20
#define CLRSCR 0x01
#define HOME 0x02
#define MOD 0x04
#define MODR 0x02
#define MODS 0x01
#define DISON 0x0C
#define DISOFF 0x08
#define CURON 0x0E
#define CURBLIK 0x0F
#define CURHIDE 0x0C
#define MOVCURLEFT 0x10
#define MOVCURRIGHT 0x14
#define FUN4BIT 0x28
#define FUN8BIT 0x38
#define FONT2 0x04
#define SETCGRAM 0x40
#define SETDDRAM 0x80
#define FIRSTLINE 0x00
#define SECLINE 0x40
#define THIRDLINE 0x14
#define FOURTHLINE 0x54
#define LCDport PORTC
#define LCDddr DDRC
#define DDRwrite 0xFF
#define DDRread 0x7F
#define RSpin PC0
#define RWpin PC1
#define Epin PC2
#define LCD_data LCDport |= _BV(RSpin)
#define LCD_cmd LCDport &= ~_BV(RSpin)
#define LCD_reading LCDport |= _BV(RWpin)
#define LCD_writing LCDport &= ~_BV(RWpin)
#define E_UP LCDport |= _BV(Epin)
#define E_DOWN LCDport &= ~_BV(Epin)
unsigned char DisplayTexts[Radku][Sloupcu];
void DispInit(void);
void Write_command (unsigned char cmd);
void Write_data (unsigned char cmd);
void gotoXY (unsigned char x, unsigned char y);
void Write_screen (void);
void Write_string (unsigned char *string);
#endif /* __DRIVERS_HD44780_H */
44780.c
#if !defined (F_CPU)
#define F_CPU 4000000
#endif
#include <avr/io.h>
#include <util/delay.h>
#include "HD44780.h"
#define sleep() asm volatile ("nop")
void Write_string (unsigned char *string)
{
unsigned char pom;
for (pom=0; pom<Sloupcu; pom++)
if (string[pom]) Write_data(string[pom]);
else break;
}
void Write_screen (void)
{
Write_command(CLRSCR); //Vymazání displeje
_delay_ms(1);
Write_command(SETDDRAM | FIRSTLINE ); //Začátek druhého řádku
_delay_us(40);
Write_string (&DisplayTexts[0][0]);
Write_command(SETDDRAM | SECLINE ); //Začátek druhého řádku
_delay_us(40);
Write_string (&DisplayTexts[1][0]);
Write_command(SETDDRAM | THIRDLINE); //Začátek třetího řádku
_delay_us(40);
Write_string (&DisplayTexts[2][0]);
Write_command(SETDDRAM | FOURTHLINE ); //Začátek čtvrtého řádku
_delay_us(40);
Write_string (&DisplayTexts[3][0]);
}
void Write_half_cmd (unsigned char cmd)
{
LCD_cmd;
_delay_us(40);
LCD_writing;
_delay_us(40);
E_UP;
LCDport = (LCDport & 0x0F) | (cmd<<4);
_delay_us(40);
E_DOWN;
}
void Write_command (unsigned char cmd)
{
Write_half_cmd (cmd >> 4);
_delay_us(40);
Write_half_cmd (cmd & 0x0F);
_delay_us(100);
}
void Write_half_data (unsigned char cmd)
{
LCD_data;
_delay_us(40);
LCD_writing;
_delay_us(40);
E_UP;
LCDport = (LCDport & 0x0F) | (cmd<<4);
_delay_us(40);
E_DOWN;
}
void Write_data (unsigned char cmd)
{
Write_half_data (cmd >> 4);
_delay_us(40);
Write_half_data (cmd & 0x0F);
_delay_us(100);
}
void gotoXY (unsigned char x, unsigned char y)
{
unsigned char pom;
if (x>Sloupcu) pom=0;
else pom=x;
switch (y)
{
case 1: Write_command((SETDDRAM | SECLINE )+ pom);
break;
case 2: Write_command((SETDDRAM | THIRDLINE )+ pom);
break;
case 3: Write_command((SETDDRAM | FOURTHLINE )+ pom);
break;
default: Write_command((SETDDRAM | FIRSTLINE )+ pom);
break;
}
}
void DispInit(void)
{
LCDddr = DDRwrite;
_delay_ms(20); //Čas potřebný pro ustálení a náběh LCD
Write_half_cmd(3);
_delay_ms(5);
Write_half_cmd(3);
_delay_ms(1);
Write_half_cmd(3);
_delay_ms(1);
Write_half_cmd(2);
_delay_ms(1);
Write_command(FUN4BIT);
Write_command(DISOFF);
Write_command(DISON); //Zapnout displej bez kurzoru
Write_command(MOD | MODR); //Posuv kurzoru vpravo
Write_command(CLRSCR); //Vymazání displeje
Write_command(HOME); //kurzor to HOME
_delay_ms(10);
}
main.c
#if !defined (F_CPU)
#define F_CPU 4000000
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <string.h>
#include <util/delay.h>
#include "hd44780.h"
int main()
{
DispInit();
strcpy((char*)&DisplayTexts[0][0]," Zobrazovany ");
strcpy((char*)&DisplayTexts[1][0]," text ");
strcpy((char*)&DisplayTexts[2][0]," pres vsechny ");
strcpy((char*)&DisplayTexts[3][0]," radky ");
Write_screen ();
return 0;
}
mno zkusil sem to přeložit, a teda nesedí názvy použitých knihoven a v tom main.c není ani ten soubor 44780.c vloženej, tak to sem si tam všechno dodělal, ale nějak sem nepochopil na jaký piny mam připojit datový vodiče, ty řídící sem tam našel jsou to PC0 až PC3 ale ty datový kam ? a pracuje to jako 4 nebo 8mi bitová linka ?
V tomhle případě jde o 4bit. Datové linky jsou nad těmi řídícími na portu PORTC.
Jinak řečeno:
PC7 = dat3
PC6 = dat2
PC5 = dat1
PC4 = dat0
PC3 = nepoužito
PC2 = E
PC1 = RW
PC0 = RS
data 0-3 ? myslel sem že pro 4bit se používaj 4-7, no a vyzkoušel sem oboje, vždycky zbývající datové vodiče sem připojil na zem, a nic na displeji svítí furt dva řádky kostičkama, první a třetí, svítí celá matice v celém řádku, zajímavé je že když odpojim všechno nechám jenom připojený + a - a kontrast na mínusu tak to svítí taky takže si myslím že je problém v SW v inicializaci nebo v HW v propojení
nebo doufám že není KO display…
Soubory .c se do souborů .c nevkládají.
Jenom se přidají do “Source files” v AvrStudiu.
nevím jestli to myslíš takhle, ale teda holí zdroják mam takhle:
[code]#if !defined (F_CPU)
#define F_CPU 16000000
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <string.h>
#include <util/delay.h>
#include “D:\PRS\testmyho\LCDTEST/hd44780.h”
#include “D:\PRS\testmyho\LCDTEST/hd44780.c”
int main()
{
DispInit();
strcpy((char*)&DisplayTexts[0][0]," Zobrazovany “);
strcpy((char*)&DisplayTexts[1][0],” text “);
strcpy((char*)&DisplayTexts[2][0],” pres vsechny “);
strcpy((char*)&DisplayTexts[3][0],” radky ");
Write_screen ();
}
[/code]
Stačí takto:
[code]#if !defined (F_CPU)
#define F_CPU 16000000
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <string.h>
#include <util/delay.h>
#include “hd44780.h”
int main()
{
DispInit();
strcpy((char*)&DisplayTexts[0][0]," Zobrazovany “);
strcpy((char*)&DisplayTexts[1][0],” text “);
strcpy((char*)&DisplayTexts[2][0],” pres vsechny “);
strcpy((char*)&DisplayTexts[3][0],” radky ");
Write_screen ();
} [/code]
Když je soubor v uvozovkách, hledá linker v tom samém adresáři, kde se nachází main.c.
P.S. Jen doufám, že máš ty soubory hd44780.h a hd44780.c importovány v projektu.
importované ??? já myslel že pomocí include se tam přidaj, jinak by to nešlo přeložit né ? popř. jak je mam importovat do toho projektu ? sorry za možná tak triviální otázky, ale v céčku dělám fakt poprvé, dělal jsem jenom v C++ programy pro PC a to je uplně o něčem jinym
edit: už jsem na to přišel, takže pokud sem to pochopil správně, do include se píšou pouze hlavičkový soubory, a zdrojové kody se dávaj vedle na pravo do toho okna tam je seznam zdrojáků použitý v tom projektu, tak tam sem dal ten hd78.c a teď to du skusit naprogramovat…
Vyřešeno !! vzal sem led diodu a jel po jednotlivých pinech a sledoval jak dioda bliká, a na nějakých jenom slabě svítila, na některých silně svítivě blikala, tak jsem knihovnu předělal na port D a ejhle najednou to chodí, akorát teda 4tý řádek na displayi je takový slabě viditelný, asi je to způsobeno nižším napětím 4,8V -> nepřesný stabilizátor, i tak děkuji za knihovnu, tahle je celkem jednoduchá tak pro mě půjde lehce použít. Proč ale display nešel na portu C ? Odprásklej by neměl bejt, ještě jsem k němu nic kromě displaye nepřipojil.
Edit: posláblí jas na konci displaye je vedlejší vliv rychlého přepisování, stačí dát do smyčky zpoždění a je to OK…
Gratuluji. Na to, že to byl tvůj první projekt, jsi to vyřešil docela rychle.
Hodně štěstí v dalším bastlení.
Nepises aky mcu pouzivas, ale na C-cku to mohlo neist preto, lebo si si pravdepodobne nezakazal JTAG interface. AK by si si ho v poistkach vypol, potom by to asi slo aj na tom C-cku.
mno používám Atmega32-16PU, kouknu na to, protože v těch pojistkách jsem jenom navolil externí krystal, na nic dalšího sem nešahal, je možný že ten JTAG bude aktivní…
edit: opravdu, vypnul jsem Jtag a už display chodí na portu C vpohodě, díky za radu
ještě se chci zeptat jak převedu int na string ? chci zobrazit obsah OCR1A na displayi ale ta rutina bere jenom string, díky.
nech je cislo v rozsahu 0-255
//...
uint8_t znak[3], cislo, pom_prem;
pom_prem = cislo/100;
znak[0] = pom_prem + "0";
cislo = cislo - pom_prem * 100;
pom_prem = cislo / 10;
cislo = cislo - pom_prem * 10;
znak[1] = pom_prem + "0";
znak[2] = cislo + "0";
//...
/*
ak bude hodnota cisla 167
znak[0] = "1";
znak[1] = "6";
znak[2] = "7";
tieto potom postupne posles na display. Program som pisal z hlavy a netestoval som ho. Mozno sa to spravit aj inak, ale tomu rozkladu v zasade neujdes.
alebo mozes pouzit aj funkciu z avr-lib itoa() alebo utoa(), ale to uz budes musiet vediet ako tak pouzivat ukazatele
*/
// cislo moze by int16 alebo uint16
//...
#include <stdlib.h>
uint8_t znak[5], cislo, pom_prem;
// funkcia Ti naplni pole znakmi, ktore interpretuju cislo v danej ciselnej sustave. Program bude samozrejme vacsi, kedze sa vklada funkcia ktora vie kde co vsetko, dokonca zobrazit cislo v 18, alebo 36-tkovej ciselnej sustave
utoa((uint16_t)cislo,(char *)&znak[0],(uint8_t)10);
// alebo aj pre znamienko
itoa((int16_t)cislo,(char *)&znak[0],(uint8_t)10);
//...
jj díky už sem to vyřešil právě přes funkci itoa
ještě sem se chtěl zeptat, jak se řeší desetinná místa když chci měřit napětí ? použil jsem datový typ float, jenže ten zase nevezme display, je třeba ho převést, když použiju funkci sprintf jak se píše všude na internetu tak mi to na displayi ukáže otazník. Co s tím ?
Díky
co skusit pouzit dtostrf
popis je na nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga060c998e77fb5fc0d3168b3ce8771d42
díky moc funguje to
nevíte někdo, jak přepínat mezi adc kanálama ? přepnu je v ADMUX, potom pustim převod, všechno jde, jeden kanál mi funguje, ale jakmile začnu přepínat na další tak se to začne nějak tlouct a ve výsledku to ukazuje nesmysly všude, nevadí že pokaždý výsledek převodu dám do stejný proměnný ? mam v úmyslu měřit 3 teploty + napětí sítě, termistory mam NTC 10K, s pullup rezistorem 10K. Termistory PA0 - PA2 napětí PA7
je tam nějaká záludnost nebo mám chybu v programu ? díky