textový string v XC8

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
Jeejda_teda_puvodne
Příspěvky: 142
Registrován: 08 dub 2012, 02:00

#16 Příspěvek od Jeejda_teda_puvodne »

Naposledy upravil(a) Jeejda_teda_puvodne dne 25 říj 2016, 19:42, celkem upraveno 1 x.

Uživatelský avatar
Ladin
Příspěvky: 32
Registrován: 07 dub 2015, 02:00

#17 Příspěvek od Ladin »

Omlouvám se za opožděnou reakci, konečně jsem se dostal k dalším pokusům a je to tak :o ... prototyp funkce s textovým řetězcem pro ostatni které by to zajímalo v MPLAB X IDE, XC8 je:

Kód: Vybrat vše

void writetxt(char* text, size_t size, unsigned int x1,unsigned int y1);
resp.

Kód: Vybrat vše

void writetxt(char* text);
text se vkládá elegantně v main:

Kód: Vybrat vše

writetxt("AHOJ\0");
nic se neseká, vypisuje to jak má, další tuning, který se tu řešil ještě musím vyzkoušet

ZATÍM DÍKY!
:D

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#18 Příspěvek od mtajovsky »

Ladin píše:

Kód: Vybrat vše

writetxt("AHOJ\0");
Mělo by stačit i writetxt("AHOJ");
Překladač C stringy automaticky ukončuje nulovým znakem.

Uživatelský avatar
Ladin
Příspěvky: 32
Registrován: 07 dub 2015, 02:00

#19 Příspěvek od Ladin »

Máte pravdu, funguje to i bez "\0"... :)

pár hodin se snažím překopat ten switch bite1,2,3,4,5 do pole s ukazatelem nebo _progmem_ jak psal Jeejda, ale bezuspěšně...
Jediné co se mi uspěšně povedlo, tak postupně pomocí switch tam naházet 5 bytů do pole byte[5]... (zjednodušil jsem to na znaky 0 a 1)
Kdyby ještě byla chuť se tím zabívat, tady je kod:

Kód: Vybrat vše

void writetxt(char* text, size_t size, unsigned int x1,unsigned int y1){
    colmod16();
    switch (size){
        case 1:
           frame(x1,319,y1,y1+7);
            break;
        }
    data();
    unsigned char byte[5];
    
    unsigned char bit0;
    unsigned char bit1;
    unsigned char bit2;
    unsigned char bit3;
    unsigned char bit4;
    unsigned char bit5;
    unsigned char bit6;
    unsigned char bit7;

    for (long i2=0;i2 < strlen(text);i2++){
        switch (text[i2]){
// CISLOVKY
            case '0':
                byte[0] = 0x3E;
                byte[1] = 0x51;
                byte[2] = 0x49;
                byte[3] = 0x45;
                byte[4] = 0x3E;
                break;
            case '1':
                byte[0] = 0x00;
                byte[1] = 0x42;
                byte[2] = 0x7F;
                byte[3] = 0x40;
                byte[4] = 0x00;
                break;
        }
                     
    for (long i=0;i < 5;i++){

    bit0 = (byte[i] & 0b00000001)*255;       // & je AND .. 0 AND 1 = 0 a 1 AND 1 = 1
    bit1 = ((byte[i] & 0b00000010)>>1)*255;  // >>1 p?esune bity o 1 místo vpravo
    bit2 = ((byte[i] & 0b00000100)>>2)*255;
    bit3 = ((byte[i] & 0b00001000)>>3)*255;
    bit4 = ((byte[i] & 0b00010000)>>4)*255;
    bit5 = ((byte[i] & 0b00100000)>>5)*255;
    bit6 = ((byte[i] & 0b01000000)>>6)*255;
    bit7 = ((byte[i] & 0b10000000)>>7)*255;  // >>7 p?esune bity o 7 míst vpravo

    switch (size){
        case 1:
            putcSPI(bit0);    putcSPI(bit0);    putcSPI(bit1);    putcSPI(bit1);    putcSPI(bit2);    putcSPI(bit2);    putcSPI(bit3);    putcSPI(bit3);
            putcSPI(bit4);    putcSPI(bit4);    putcSPI(bit5);    putcSPI(bit5);    putcSPI(bit6);    putcSPI(bit6);    putcSPI(bit7);    putcSPI(bit7);
            break;
    }

    }
    // Mezera mezi písmeny
        for (int i3=0; i3 < 16*size; i3++){
        putcSPI(0);
    }
    }
    CS = 1;
}

// *** MAIN ***
void main(void) {
   
// INICIALIZACE LCD
    CS = 1;
    RST = 1;
    __delay_ms(10);
    DC = 0;
    CS = 0;
    putcSPI(0b00010001);
    CS = 1;

    dispon();
    
    writetxt("10111010",1,0,100);
   }

Uživatelský avatar
MiloPS3
Příspěvky: 259
Registrován: 07 srp 2010, 02:00

#20 Příspěvek od MiloPS3 »

vubec netusim kterej switch mislis a ani nevim co to ma vsechno delat, tak kdyby si nam to trochu upresnil

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#21 Příspěvek od mtajovsky »

Když zůstaneme u znaků '0' a '1', tak to pole bude mít 2 x 5 byte:

Kód: Vybrat vše

unsigned char data[2][5] =
{
    {0x3e, 0x51, 0x49, 0x45, 0x3e},      // predlohy pro '0'
    {0x00, 0x42, 0x7f, 0x40, 0x00}       // predlohy pro '1'
};

unsigned char byte[5];               // pole plnenych byte

for(long i2=0; i2 < strlen(text); ++i2)
{
    int radek = text[i2] - '0';
    for(int sloupec = 0; sloupec < sizeof(byte)/sizeof(unsigned char); ++sloupec)
    {
        byte[sloupec] = data[radek][sloupec];
    }

    for (long i=0;i < 5;i++){
    bit0 = (byte[i] & 0b00000001)*255;
// dalsi zpracovani ...

}
Předlohy znaků jsou v poli data. Pro každý znak text[i2] se v cyklu naplní byte[0] - byte[4] z pole data. Index řádku je odvozen ze znaku:

Kód: Vybrat vše

text[i2] - '0'
tohle platí pro číslovky. Pro velká písmena se to musí odvodit podobně odečtením hodnoty znaku 'A'. Předpokládá se kódování ASCII nebo jiné, kde kódy pro číslovky i písmena tvoří souvislou vzrůstající řadu. Index sloupce se mění 0-4 podle proměnné cyklu index.

Píši to od boku, odlaďte si to na překladači pro tuto verzi v RAM. Až to bude fungovat, zaměňte uložení pole data do PROGMEM. Pak taky budete muset modifikovat řádek:

Kód: Vybrat vše

byte[sloupec] = data[radek][sloupec];
užitím funkcí pro čtení z programové paměti. Data do programové paměti zkuste uložit takto (viz http://www.microchip.com/forums/m166493.aspx ):

Kód: Vybrat vše

// nekde na zacatku programu nebo v headeru
#define PROGMEM __attribute__((space(prog)))

// definice pole 5 byte do progr. pameti
const char x[] PROGMEM = {8,9,10,11,12};
A nakonec - změňte název proměnné byte. Tohle slovo se většinou používá jako zástupný název typu pro unsigned char:

Kód: Vybrat vše

typedef unsigned char byte;
Když to použijete pro název proměnné, může docházet k nedorozumění. Také si nejprve do nějaké pomocné proměnné uložte délku strlen(text), aby se to v cyklu nemuselo znovu a znovu vyčíslovat. Pochybuji, že to kompilátor optimalizuje, to by musel spolehlivě detekovat, že se za žádných okolností nezměnil řetězec text a to ani v žádném vnořeném volání funkce nebo nějakým side-efektem.

PS.: nevzdávejte to, já zkoušením a tápáním proseděl u překladače tisíce hodin.

Uživatelský avatar
Ladin
Příspěvky: 32
Registrován: 07 dub 2015, 02:00

#22 Příspěvek od Ladin »

Když to napíšu zjednodušeně tak řadič ILI9341 funguje tak, že pro jeden obrazový bod musím poslat buď 3 bajty (3 barvy BGR) nebo 2 bajty (3 barvy BGR takto 0bBBBBBGGG, 0bGGGRRRRR), pak se da použít ještě nižší rozlišení, je rychlejší, ale nepraktické, používám pouze při vykreslování ploch.
Takže když chci vykreslit jeden bílý bod, musím poslat dva bajty 255, takže 0b11111111, 0b11111111.
A ta funkce writetxt jednoduše překládá body písmen (jeden znak 8x5 bitů=40 bodů) na dva bajty, které se odešlou do LCD a ten zobrazí jeden bílý bod. Pokud chci vykreslit černý bod, pak je to dvakrát 0b00000000.
Samozřejmě nepíšu další části kodu jako např.funkci frame, která vytvoří na lcd rámec do kterého se vykreslují body(nutné pro text).
Dnes zkusím přepsat kod podle p. mtajovskeho aby se těch 40 bitů pro každý znak uložilo do 2D pole programové paměti. Funguje to i bez toho, ale pro začátečníka je to příležitost jak se něco naučit a za to díky.. Až to bude, můžu sem dát hotový kod, ptže ten display je za 2stovky a má rozlišení 320x240bodů s dostatečnou barevnou hloubkou. Někomu by se to mohlo třeba hodit.

Uživatelský avatar
Ladin
Příspěvky: 32
Registrován: 07 dub 2015, 02:00

#23 Příspěvek od Ladin »

Ještě jeden asi uplně blbej dotaz.

Proč "Céčkařum" vadí vůbec switch? 8-)

Když to nedám do 2D pole, ale do toho switche takže takto:

Kód: Vybrat vše

for (long i2=0;i2 < strlen(text);++i2){
        switch (text[i2]){
// CISLOVKY
            case '0':byte[0]=0x3E;byte[1]=0x51;byte[2]=0x49;byte[3]=0x45;byte[4]=0x3E;break;
            case '1':byte[0]=0x00;byte[1]=0x42;byte[2]=0x7F;byte[3]=0x40;byte[4]=0x00;break;
tak se přeci, ram také nezaplní předem nebo ano?

Mě to jen nejde do hlavy co mi uniká...

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#24 Příspěvek od mtajovsky »

Switch nevadí, pokud se používá rozumně. Srovnejte si přehlednost toho switche a spotřebu kódové paměti na něj s variantou s polem předloh a jednoduchým cyklem.
A dále, když je potřeba udělat nějakou změnu, třeba vyměnit znakovou sadu, tak se se switchem upíšete nebo seknete snadno nějakou chybu. Ve variantě s polem předloh jen přepíšete data v poli přehledně na jednom místě. Dokonce je možno mít současně více polí předloh pro různé znakové sady a ty podle potřeb za běhu jednoduše přepínat tím, které pole se použije. Nebo mít to pole předloh v samostatném souboru např.: charset.c, a jeho výměnou v projektu měnit znakovou sadu. Nebo mít ta pole v RAM a při inicializaci aplikace předlohy načíst z disku, z SD karty, po síti a tak dále, tvořivosti se meze nekladou.

Zkrátka, vždy se snažte oddělit data a kód. Kód udělat univerzální a konkrétní obsah vhodně strukturovaných dat udělá z aplikace patřičnou její variantu.

Podívejte se na přiložený soubor pro zobrazování obsahu LCD. Data pro texty a formátování obrazovky jsou data mimo kód uložená v programové paměti (ale to teď není podstatné). Pole cursor_placement
určuje pozice kursoru na LCD při pohybu kursorem šipkami - používá se v jiném modulu. Funkce void displayScreen(CCP_STATUS status) vypisuje sestavené obrazovky podle stavu aplikace 'status' a vyjma reference na pole obrazovek a délky dat neobsahuje nic z konkrétních textů zobrazovaných na LCD.

Kód: Vybrat vše

// --------------------------------------------------------
//                        DISPLAY.C
//
// Module for LCD processing.
// --------------------------------------------------------


// ---------------- include files -------------------------

#include <avr/pgmspace.h>
#include "global.h"
#include <util/delay.h>
#include "lcdapi/lcdapi.h"
#include "ccp.h"
#include "display.h"
#include "config.h"


// ------------------- static strings ---------------------

static char welcome_text1[] PROGMEM = "\7\0MT9851";
static char welcome_text2[] PROGMEM = "\2\1SWEEP GENERATOR";
static char welcome_text3[] PROGMEM = "\6\2""0-50 MHz";
static char welcome_text4[] PROGMEM = "\0\3Welcome to machine!!";
static char cf_heading[]    PROGMEM = "\1\0CONSTANT FREQUENCY\2";
static char am_heading[]    PROGMEM = "\1\0\3AMPLTD MODULATION\2";
static char swp_heading[]   PROGMEM = "\1\0\3SWEEP GENERATOR\2";
static char af_heading[]    PROGMEM = "\1\0\3ACOUSTIC FRQ.SWEEP";
static char fmod_value[]    PROGMEM = "\1\2Fmod: .    Hz";
static char frq_value[]     PROGMEM = "\1\1Freq:  .   .    Hz";
static char af_value[]      PROGMEM = "\1\1Freq:10-100.000 Hz";
static char mrk_value[]     PROGMEM = "\1\2Mark:  .   .    Hz";
static char v_out[]         PROGMEM = "\1\3Vout:    mV";
static char swp_value[]     PROGMEM = "\15\3\6f:  %";


// -------------------- cursor placement ------------------

u08 placement_matrix[4][3][10] PROGMEM =
{
    {
        {0, 6, 7, 9, 10, 11, 13, 14, 15, 255}, {0, 255, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 255, 0, 0, 0, 0, 0, 0, 0, 0},
    },
    {
        {0, 6, 7, 9, 10, 11, 13, 14, 15, 255}, {0, 6, 8, 9, 10, 255, 0, 0, 0, 0}, {0, 255, 0, 0, 0, 0, 0, 0, 0, 0},
    },
    {
        {0, 6, 7, 9, 10, 11, 13, 14, 15, 255}, {0, 6, 7, 9, 10, 11, 13, 14, 15, 255}, {0, 16, 17, 255, 0, 0, 0, 0, 0, 0}
    },
    {
        {0, 255, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 15, 255, 0, 0, 0, 0, 0, 0, 0}, {0, 255, 0, 0, 0, 0, 0, 0, 0, 0}
    }
};


// --------------- screens for individual status ----------

static prog_char* welcome_screen[] PROGMEM =
{
    welcome_text1,
    welcome_text2,
    welcome_text3,
    welcome_text4
};

static prog_char* cf_screen[] PROGMEM =
{
    cf_heading,
    frq_value,
    v_out
};

static prog_char* am_screen[] PROGMEM =
{
    am_heading,
    frq_value,
    fmod_value,
    v_out
};

static prog_char* swp_screen[] PROGMEM =
{
    swp_heading,
    frq_value,
    mrk_value,
    v_out,
    swp_value   
};

static prog_char* afsw_screen[] PROGMEM =
{
    af_heading,
    af_value,
    mrk_value,
    v_out
};


// ------------------ all screens array -------------------

static prog_char** screens[] PROGMEM =
{
    welcome_screen,
    cf_screen,
    am_screen,
    swp_screen,
    afsw_screen
};


// --- number of displayed items for individual status ----

static u08 screen_len[] PROGMEM = {4, 3, 4, 5, 4};


// ----------------- initDisplay --------------------------
// Function initializes LCD and displays invitation message.
void initDisplay(void)
{
    LCD_init();
    LCD_cust_chars_init();
    displayScreen(INTRO);
    _delay_ms(1000);

// ------------- front panel LEDS test --------------------

	LCD_CTRL_PORT |= ERROR_LED | MARKER_LED;
	BUTTON_PORT |= REMOTE_LED;
    _delay_ms(600);
	LCD_CTRL_PORT &= ~(ERROR_LED | MARKER_LED);
	BUTTON_PORT &= ~REMOTE_LED;
    _delay_ms(300);
}


// ---------------- displayScreen -------------------------
// Function displays screen according to given state.
void displayScreen(CCP_STATUS status)
{
    LCD_clear();                                           // erase old screen content
    prog_char** screen = (prog_char**)pgm_read_word(screens + status); // load screen table addres
    u08 table_len = pgm_read_byte(screen_len + status);    // load screen table length
    for(u08 i = 0; i < table_len; ++i)                     // for all string in table
    {
        prog_char* string = (prog_char*)pgm_read_word(screen + i); // load string from table
        LCD_putstrxy_P(string);
    }
    if(status != INTRO)
    {
        markLine((u08)0);
    }
}


// -------------------- markLine --------------------------
// Function marks the actual line.
void markLine(u08 line)
{
    if(line >= (u08)0 && line <= (u08)3)
    {
        LCD_xy(0, line); 
        LCD_send_1('\0');
    }
}


// -------------------- unmarkLine ------------------------
// Function unmarks the actual line.
void unmarkLine(u08 line)
{
    if(line >= (u08)0 && line <= (u08)3)
    {
        LCD_xy(0, line); 
        LCD_send_1(' ');
    }
}

Uživatelský avatar
Ladin
Příspěvky: 32
Registrován: 07 dub 2015, 02:00

#25 Příspěvek od Ladin »

JJ máte pravdu, je lepší se rovnou učit programovat tak, aby se kod dal používat co neuniverzálněji, navíc přístup do předem daného pole je zřejmě rychlejší než pokaždé přepisovat proměnné...

Takže zpátky k původnímu, všechny uvedené úpravy co jste poradil se povedly, přidal jsem všechny základní znaky od mezery(32) po malé z
Výsledek sem dávám pro případ, že by si chtěl někdo displej pořídit a něco zkusit naprogramovat jako já. 8-)

P.MTAJOVSKY mnohokrát díky!!!

jedná se o tento displej:
http://www.dx.com/p/2-2-serial-spi-tft- ... S6h1JPs1Ko
nebo:
http://www.easyduino.cz/LCD-displej-2-2 ... o-d103.htm
tady video pro představu(doba krmení, omluvte pozadí):
https://www.youtube.com/watch?v=zjPq2On ... e=youtu.be

celý kod pro PIC 18F14k22 v prostředí MPLAB X IDE, komp.XC8:

Kód: Vybrat vše

#include <spi.h>
#include <string.h>
#include <stdlib.h>
#include <htc.h>
#include <p18f14k22.h>

#define _XTAL_FREQ 64000000   //Used by the compiler for the delay_ms(x) macro

// PIC Configuration bits
#define SDI     PORTCbits.RC7
#define SCK     PORTBbits.RB6
#define CS      PORTBbits.RB7
#define DC      PORTBbits.RB5
#define RST     PORTCbits.RC6

//config bits that are part-specific for the PIC18F14K22
__CONFIG(1, FOSC_IRC & PLLEN_OFF & FCMEN_OFF);
__CONFIG(2, PWRTEN_OFF & BOREN_OFF & WDTEN_OFF);
__CONFIG(3, HFOFST_OFF & MCLRE_OFF);
__CONFIG(4, STVREN_ON & LVP_OFF & DEBUG_OFF);
__CONFIG(5, CP0_OFF & CP1_OFF & CPB_OFF & CPD_OFF);
__CONFIG(6, WRT0_OFF & WRT1_OFF & WRTC_OFF & WRTB_OFF & WRTD_OFF);
__CONFIG(7, EBTR0_OFF & EBTR1_OFF & EBTRB_OFF);

const unsigned char asci[91][5] =
{

{0x00, 0x00, 0x00, 0x00, 0x00},            // Code for char
{0x00, 0x00, 0x5F, 0x00, 0x00},            // Code for char !
{0x00, 0x03, 0x00, 0x03, 0x00},            // Code for char "
{0x14, 0x7F, 0x14, 0x7F, 0x14},            // Code for char #
{0x24, 0x2A, 0x7F, 0x2A, 0x12},            // Code for char $
{0x23, 0x13, 0x08, 0x64, 0x62},            // Code for char %
{0x36, 0x49, 0x55, 0x22, 0x50},            // Code for char &
{0x00, 0x05, 0x03, 0x00, 0x00},            // Code for char '
{0x00, 0x1C, 0x22, 0x41, 0x00},            // Code for char (
{0x00, 0x41, 0x22, 0x1C, 0x00},            // Code for char }
{0x14, 0x08, 0x3E, 0x08, 0x14},            // Code for char *
{0x08, 0x08, 0x3E, 0x08, 0x08},            // Code for char +
{0x00, 0xA0, 0x60, 0x00, 0x00},            // Code for char ,
{0x08, 0x08, 0x08, 0x08, 0x08},            // Code for char -
{0x00, 0x60, 0x60, 0x00, 0x00},            // Code for char .
{0x20, 0x10, 0x08, 0x04, 0x02},            // Code for char /
{0x3E, 0x51, 0x49, 0x45, 0x3E},            // Code for char 0
{0x00, 0x42, 0x7F, 0x40, 0x00},            // Code for char 1
{0x42, 0x61, 0x51, 0x49, 0x46},            // Code for char 2
{0x21, 0x41, 0x45, 0x4B, 0x31},            // Code for char 3
{0x18, 0x14, 0x12, 0x7F, 0x10},            // Code for char 4
{0x27, 0x45, 0x45, 0x45, 0x39},            // Code for char 5
{0x3C, 0x4A, 0x49, 0x49, 0x30},            // Code for char 6
{0x01, 0x71, 0x09, 0x05, 0x03},            // Code for char 7
{0x36, 0x49, 0x49, 0x49, 0x36},            // Code for char 8
{0x06, 0x49, 0x49, 0x29, 0x1E},            // Code for char 9
{0x00, 0x36, 0x36, 0x00, 0x00},            // Code for char :
{0x00, 0x56, 0x36, 0x00, 0x00},            // Code for char //
{0x08, 0x14, 0x22, 0x41, 0x00},            // Code for char <
{0x14, 0x14, 0x14, 0x14, 0x14},            // Code for char =
{0x41, 0x22, 0x14, 0x08, 0x00},            // Code for char >
{0x02, 0x01, 0x51, 0x09, 0x06},            // Code for char ?
{0x32, 0x49, 0x79, 0x41, 0x3E},            // Code for char @
{0x7E, 0x09, 0x09, 0x09, 0x7E},            // Code for char A
{0x7F, 0x49, 0x49, 0x49, 0x36},            // Code for char B
{0x3E, 0x41, 0x41, 0x41, 0x22},            // Code for char C
{0x7F, 0x41, 0x41, 0x41, 0x3E},            // Code for char D
{0x7F, 0x49, 0x49, 0x41, 0x41},            // Code for char E
{0x7F, 0x09, 0x09, 0x01, 0x01},            // Code for char F
{0x3E, 0x41, 0x49, 0x49, 0x3A},            // Code for char G
{0x7F, 0x08, 0x08, 0x08, 0x7F},            // Code for char H
{0x00, 0x00, 0x7F, 0x00, 0x00},            // Code for char I
{0x31, 0x41, 0x41, 0x41, 0x3F},            // Code for char J
{0x7F, 0x08, 0x14, 0x22, 0x41},            // Code for char K
{0x7F, 0x40, 0x40, 0x40, 0x40},            // Code for char L
{0x7F, 0x02, 0x04, 0x02, 0x7F},            // Code for char M
{0x7F, 0x04, 0x08, 0x10, 0x7F},            // Code for char N
{0x3E, 0x41, 0x41, 0x41, 0x3E},            // Code for char O
{0x7F, 0x09, 0x09, 0x09, 0x06},            // Code for char P
{0x3E, 0x41, 0x51, 0x21, 0x5E},            // Code for char Q
{0x7F, 0x09, 0x19, 0x29, 0x46},            // Code for char R
{0x26, 0x49, 0x49, 0x49, 0x32},            // Code for char S
{0x01, 0x01, 0x7F, 0x01, 0x01},            // Code for char T
{0x3F, 0x40, 0x40, 0x40, 0x3F},            // Code for char U
{0x1F, 0x20, 0x40, 0x20, 0x1F},            // Code for char V
{0x3F, 0x40, 0x30, 0x40, 0x3F},            // Code for char W
{0x63, 0x14, 0x08, 0x14, 0x63},            // Code for char X
{0x03, 0x04, 0x78, 0x04, 0x03},            // Code for char Y
{0x61, 0x51, 0x49, 0x45, 0x43},            // Code for char Z
{0x00, 0x7F, 0x41, 0x41, 0x00},            // Code for char [
{0x02, 0x04, 0x08, 0x10, 0x20},            // Code for char BackSlash
{0x00, 0x41, 0x41, 0x7F, 0x00},            // Code for char ]
{0x00, 0x02, 0x01, 0x02, 0x00},            // Code for char ^
{0x00, 0x40, 0x40, 0x40, 0x00},            // Code for char _
{0x00, 0x03, 0x03, 0x00, 0x00},            // Code for char `
{0x20, 0x54, 0x54, 0x54, 0x78},            // Code for char a
{0x7F, 0x48, 0x44, 0x44, 0x38},            // Code for char b
{0x38, 0x44, 0x44, 0x44, 0x20},            // Code for char c
{0x38, 0x44, 0x44, 0x48, 0x7F},            // Code for char d
{0x38, 0x54, 0x54, 0x54, 0x18},            // Code for char e
{0x08, 0x7E, 0x09, 0x01, 0x02},            // Code for char f
{0x08, 0x54, 0x54, 0x54, 0x3C},            // Code for char g
{0x7F, 0x08, 0x04, 0x04, 0x78},            // Code for char h
{0x00, 0x44, 0x7D, 0x40, 0x00},            // Code for char i
{0x20, 0x40, 0x44, 0x3D, 0x00},            // Code for char j
{0x7F, 0x10, 0x28, 0x44, 0x00},            // Code for char k
{0x00, 0x41, 0x7F, 0x40, 0x00},            // Code for char l
{0x7C, 0x04, 0x78, 0x04, 0x78},            // Code for char m
{0x7C, 0x08, 0x04, 0x04, 0x78},            // Code for char n
{0x38, 0x44, 0x44, 0x44, 0x38},            // Code for char o
{0x7C, 0x14, 0x14, 0x14, 0x08},            // Code for char p
{0x08, 0x14, 0x14, 0x14, 0x7C},            // Code for char q
{0x7C, 0x08, 0x04, 0x04, 0x08},            // Code for char r
{0x48, 0x54, 0x54, 0x54, 0x20},            // Code for char s
{0x02, 0x3F, 0x42, 0x40, 0x20},            // Code for char t
{0x3C, 0x40, 0x40, 0x20, 0x7C},            // Code for char u
{0x1C, 0x20, 0x40, 0x20, 0x1C},            // Code for char v
{0x3C, 0x40, 0x30, 0x40, 0x3C},            // Code for char w
{0x44, 0x28, 0x10, 0x28, 0x44},            // Code for char x
{0x0C, 0x50, 0x50, 0x50, 0x3C},            // Code for char y
{0x44, 0x64, 0x54, 0x4C, 0x44}            // Code for char z
};
void wait(int w){
    for (int d2=0;d2<w;d2++)
    for (int d=0;d<100;d++)
         __delay_ms(10);
}
void pause(int p){
    for (int d=0;d<p;d++)
         __delay_ms(1);
}
// DISPON
void dispon(){
    DC = 0;
    CS = 0;
    putcSPI(0b00101001);
    CS = 1;
    }
// DISPOFF
void dispoff(){
    DC = 0;
    CS = 0;
    putcSPI(0b00101000);
    CS = 1;
    }
// 12ti BITOVÉ BAREVNÉ ROZLI?ENÍ
void colmod12(){
    DC = 0;
    CS = 0;
    putcSPI(0b00111010);
    DC = 1;
    putcSPI(0b00000011);
    CS = 1;
    }
// 16ti BITOVÉ BAREVNÉ ROZLI?ENÍ
void colmod16(){
    DC = 0;
    CS = 0;
    putcSPI(0b00111010);
    DC = 1;
    putcSPI(0b01010101);
    CS = 1;
    }
// NORMAL
void normal(){
    DC = 0;
    CS = 0;
    putcSPI(0b00010011);
    CS = 1;
    }
// INVERT ON
void invon(){
    DC = 0;
    CS = 0;
    putcSPI(0b00100001);
    CS = 1;
    }
// INVERT OFF
void invoff(){
    DC = 0;
    CS = 0;
    putcSPI(0b00100000);
    CS = 1;
    }
// DATA TO LCD
void data(){
    DC = 0;
    CS = 0;
    putcSPI(0b00101100);
    DC = 1;
    }
// SCROLLING
void scrl(unsigned short int X){
    DC = 0;
    CS = 0;
    putcSPI(X);
    CS = 1;
    }
void frame(int x1, int x2, char y1, char y2){
    // X adresses
    DC = 0;
    CS = 0;
    putcSPI(0x2B);
    DC = 1;
    char x1a;
    if (x1>255){
        x1a = 255;
        x1 = (char)x1 - 256;
    }
    else x1a = 0;
    putcSPI(x1a);
    putcSPI(x1);
    char x2a;
    if (x2>255){
        x2a = 255;
        x2 = (char)x2 - 256;
    }
    else x2a = 0;
    putcSPI(x2a);
    putcSPI(x2);
    CS = 1;
    // Y adresses
    DC = 0;
    CS = 0;
    putcSPI(0x2A);
    DC = 1;
    putcSPI(0x00);
    putcSPI(y1);
    putcSPI(0x00);
    putcSPI(y2);
    CS = 1;
    }
void box (int x1, int x2, char y1, char y2,char color){
    colmod12();
    ++x2;
    ++y2;
    long i2 = ((((long)x2-(long)x1) * ((long)y2-(long)y1))/2)+1;
    --x2;
    --y2;
    frame(x1,x2,y1,y2);
    
    char col1,col2,col3;

    switch (color) {
        case 0: col1 = 0b00000000; col2 = 0b00000000; col3 = 0b00000000; break; //?erná
        case 1: col1 = 0b11111111; col2 = 0b11111111; col3 = 0b11111111; break; //bílá
        case 2: col1 = 0b00000000; col2 = 0b11110000; col3 = 0b00001111; break; //?ervená
        case 3: col1 = 0b00001111; col2 = 0b00000000; col3 = 0b11110000; break; //zelená
        case 4: col1 = 0b11110000; col2 = 0b00001111; col3 = 0b00000000; break; //modrá
        case 5: col1 = 0b00001111; col2 = 0b11110000; col3 = 0b11111111; break; //?lutá
        case 6: col1 = 0b11111111; col2 = 0b00001111; col3 = 0b11110000; break; //azurová
        case 7: col1 = 0b11110000; col2 = 0b11111111; col3 = 0b00001111; break; //purpurová
        case 8: col1 = 0b00000011; col2 = 0b01110000; col3 = 0b00110111; break; //hn?dá
    }
    data();
    while (i2){
        putcSPI(col1);                           // POSLI BYT PREZ SPI
        putcSPI(col2);
        putcSPI(col3);
        i2 = i2 -1;
    }
}

//void writetxt (char text[],char size, unsigned int x1,unsigned int y1){
void writetxt(char* text, size_t size, unsigned int x1,unsigned int y1){
    colmod16();
    switch (size){
        case 1: frame(x1,319,y1,y1+7);  break;
        case 2: frame(x1,319,y1,y1+15); break;
        case 3: frame(x1,319,y1,y1+23); break;
        case 4: frame(x1,319,y1,y1+31); break;
        case 10:frame(x1,319,y1,y1+79); break;
    }
    data();
    
    unsigned char bajt[5];
    unsigned char bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7;

// TUNING OD MTAJOVSKEHO
    for (long i2=0;i2 < strlen(text);++i2){
    int radek = text[i2] - 32;
          for(int sloupec = 0; sloupec < 5; ++sloupec)    //místo 5 .. sizeof(bajt)/sizeof(unsigned char)
    {
        bajt[sloupec] = asci[radek][sloupec];
    }

    for (long i=0;i < 5;i++){

    bit0 = (bajt[i] & 0b00000001)*255;
    bit1 = ((bajt[i] & 0b00000010)>>1)*255;
    bit2 = ((bajt[i] & 0b00000100)>>2)*255;
    bit3 = ((bajt[i] & 0b00001000)>>3)*255;
    bit4 = ((bajt[i] & 0b00010000)>>4)*255;
    bit5 = ((bajt[i] & 0b00100000)>>5)*255;
    bit6 = ((bajt[i] & 0b01000000)>>6)*255;
    bit7 = ((bajt[i] & 0b10000000)>>7)*255;

    switch (size){
        case 1:
            putcSPI(bit0);putcSPI(bit0);putcSPI(bit1);putcSPI(bit1);putcSPI(bit2);putcSPI(bit2);putcSPI(bit3);putcSPI(bit3);
            putcSPI(bit4);putcSPI(bit4);putcSPI(bit5);putcSPI(bit5);putcSPI(bit6);putcSPI(bit6);putcSPI(bit7);putcSPI(bit7);
            break;
        case 2:
            for (char iii=0;iii<2;iii++){
            for (char ii=0;ii < 4;ii++){putcSPI(bit0);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit1);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit2);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit3);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit4);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit5);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit6);}
            for (char ii=0;ii < 4;ii++){putcSPI(bit7);}
            }
            break;
        case 3:
            for (char iii=0;iii<3;iii++){
            for (char ii=0;ii < 6;ii++){putcSPI(bit0);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit1);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit2);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit3);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit4);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit5);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit6);}
            for (char ii=0;ii < 6;ii++){putcSPI(bit7);}
            }
            break;
        case 4:
            for (char iii=0;iii<4;iii++){
            for (char ii=0;ii < 8;ii++){putcSPI(bit0);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit1);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit2);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit3);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit4);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit5);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit6);}
            for (char ii=0;ii < 8;ii++){putcSPI(bit7);}
            }
            break;
        case 10:
            for (char iii=0;iii<8;iii++){
            for (char ii=0;ii < 20;ii++){putcSPI(bit0);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit1);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit2);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit3);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit4);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit5);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit6);}
            for (char ii=0;ii < 20;ii++){putcSPI(bit7);}
            }
            break;
    }

    }
    for (int i4=0; i4 < size; i4++){
        for (int i3=0; i3 < 16*size; i3++){
        putcSPI(0);
    }
    }
    }
    CS = 1;
}
void writenum (unsigned int cislo,unsigned int size, unsigned int x1, unsigned int y1){
     char buf[10];
     utoa(buf, cislo, 10);
     writetxt(buf,size,x1,y1);
}

// *** MAIN ***
void main(void) {

    // NASTAVENI FREKVENCE OSCILATORU
    OSCCON = 112 ;              //16MHZ clock speed based on internal oscillator block
    OSCCON2 = 0 ;
    OSCTUNE = 64 ;              //PLLx4 coz je 16x4=64

    wait(1);

    OpenSPI(SPI_FOSC_16, MODE_00, SMPEND);   // NASTAVENI SPI
    TRISC = 0;
    TRISCbits.TRISC7 = 0;           //using pin as output
    TRISBbits.TRISB6 = 0;           //using pin as output
    TRISBbits.TRISB7 = 0;           //using pin as output
    TRISBbits.TRISB5 = 0;           //using pin as output
    TRISCbits.TRISC6 = 0;           //using pin as output
    TRISAbits.TRISA4 = 1;           //potenciometr
    ANSELbits.ANS3 = 1;                  //analog input - different than pic16 syntax
    ADCON0 = 0b00001101;            //select RA4 as source of ADC, which is AN3, and enable the module
    ADCON2 = 0b00111110;            // fosc/64
    
// INICIALIZACE LCD
    CS = 1;
    RST = 1;
    __delay_ms(10);
    DC = 0;
    CS = 0;
    putcSPI(0b00010001);
    CS = 1;       
    pause(120);

    dispon();

    box (0,319,0,239,0);

    writetxt(" ** 2,2\" LCD ILI9341 :) **",2,0,0);

    wait(2);

    writetxt("!\"#$%&´()*+,-./0123456789",1,0,30);
    writetxt(":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ",1,0,38);
    writetxt("[\\]^_'abcdefghijklmnopqrstuvwxyz",1,0,46);

    writetxt("!\"#$%&´()*+,-./",2,0,60);
    writetxt("0123456789:;<=>?@",2,0,76);
    writetxt("ABCDEFGHIJKLMNOPQRSTUVWXYZ",2,0,92);
    writetxt("[\\]^_'",2,0,108);
    writetxt("abcdefghijklmnopqrstuvwxyz",2,0,124);

    wait(5);
    box (0,319,0,239,0);
    box (10,310,10,230,1);
    box (20,300,20,220,2);
    box (30,290,30,210,3);
    box (40,280,40,200,4);
    box (50,270,50,190,5);
    box (60,260,60,180,6);
    box (70,250,70,170,7);
    box (80,240,80,160,0);
    writetxt("Size1",1,150,120);
    wait(2);
    box (80,240,80,160,0);
    writetxt("Size2",2,140,110);
    wait(2);
    box (80,240,80,160,0);
    writetxt("Size3",3,120,100);
    wait(2);
    box (80,240,80,160,0);
    writetxt("Size4",4,110,90);
    wait(2);
    box (0,320,70,170,0);
    writetxt("Size10",10,10,85);
    wait(2);
    invon();
    wait(1);
    invoff();
    wait(1);
    invon();
    box (0,320,70,170,0);
    while (1){
        __delay_us(5);
        GO = 1;
        while (GO) continue;
        writenum (ADRESH,10,100,85);
        }
}
Naposledy upravil(a) Ladin dne 20 dub 2015, 09:00, celkem upraveno 1 x.

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#26 Příspěvek od mtajovsky »

No výborně, ještě by to chtělo něco podobného udělat se switchem pro color.

Malou poznámku bych měl k řádku

Kód: Vybrat vše

for(int sloupec = 0; sloupec < 5; ++sloupec)    //místo 5 .. sizeof(bajt)/sizeof(unsigned char) 
Když se dělá v cyklu iterace přes pole, tak můžete určit horní mez cyklu jako:

Kód: Vybrat vše

for(int sloupec = 0; sloupec < 5; ++sloupec)
nebo

Kód: Vybrat vše

for(int sloupec = 0; sloupec < sizeof(bajt)/sizeof(unsigned char); ++sloupec)
První způsob v sobě nese nebezpečí, že při změně velikosti pole se zapomene změnit horní mez cyklu. Funkce sizeof() je jako jedna z mála funkcí přímo zabudována v překladači a vyhodnocuje se jen v době překladu. Na rozdíl např. od od run-time funkce strlen(), která se vyhodnocuje až v době běhu programu. sizeof(), která dává velikost nějakého objektu (třeba pole) nebo datového typu v bytech, tak nezatěžuje za běhu nijak procesor, protože se při překladu nahradí konstantou.
Jestliže máme

Kód: Vybrat vše

float array[4];

int x = sizeof(array) / sizeof(float);
tak při překladu se vyhodnotí celková velikost pole array a podělí se velikostí uloženého prvku float. Tím se vypočte konstanta udávající dimenzi pole. Když se potom při ladění programu velikost pole změní, tak se automaticky všude v programu, kde se takto vypočítala délka pole, při překladu nově přepočítá a máme zaručeno, že všechny cykly, které toto pole iterují budou mít správnou horní mez.

Uživatelský avatar
rnbw
Příspěvky: 32312
Registrován: 21 bře 2006, 01:00
Bydliště: Bratislava

#27 Příspěvek od rnbw »

Vhodne je zadefinovat si na to makro:

Kód: Vybrat vše

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

Uživatelský avatar
Ladin
Příspěvky: 32
Registrován: 07 dub 2015, 02:00

#28 Příspěvek od Ladin »

Barvy a strlen upravím, zamýšlel jsem to udělat uplně jinak, zadávat barvy přímo do funkce, ale to už asi je další téma...

K původnímu problému, nevšiml jsem si při překladu hlášky warning a překladač uvedenou definici PROGMEM nerozpozná a ignoruje, takže by mělo stačit napsat pole pouze takto:

Kód: Vybrat vše

const unsigned char asci[91][5] ={};
Dočítám se, že const sám o sobě znamená, že pole bude pouze pro čtení a uložené v programové paměti.

Dyštak mě někdo opravte jestli to tak není...

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#29 Příspěvek od mtajovsky »

Tak to si nejsem jist, const znamená něco jiného, ledaže by XC8 to speiálně interpretoval. const se může vyskytovat v následujících konstrukcích:

Kód: Vybrat vše

const int x = 300;                // C++ nahrada za: #define x (300)

const int x = y;                   // inicializace konstatní hodnoty, která je dále neměnitelná

const char* cpch;                // ukazatel na konstatni proměnnou

char* const pchc;              // konstatni ukazatel na proměnnou

const char cch = 'A';
const char* const pch4 = &cch;   // konstantni ukazatel na konstatni proměnnou

float function(const int x);  // prototyp funkce, která nemůže měnit dodaný parametr

const char function1(void);  // funkce vrací hodnotu, kterou lze inicializovat jen konstantní hodnotu:
const char ch = function1();

class C
{
...

    int getInteger(void) const;    // konstatní metoda, nemůže měnit žádnou hodnotu ve třídě C, getter je typický příklad

    const int method(const char c) const;  // kombinace - metoda nemůže měnit svůj parametr ani nic jiného ve třídě C a vrací konstantní hodnotu, která nemůže být později měněna.
...
};
Všechna vyjmenovaná const slouží pro ochranu dat na úrovni překladače, primárně to nemá nic co do činění s uložením do kódové paměti.

Uživatelský avatar
Jeejda_teda_puvodne
Příspěvky: 142
Registrován: 08 dub 2012, 02:00

#30 Příspěvek od Jeejda_teda_puvodne »

Naposledy upravil(a) Jeejda_teda_puvodne dne 25 říj 2016, 19:43, celkem upraveno 1 x.

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“