Uživatel:Hullatom

Z MAM wiki

Přejít na: navigace, hledání

ovladani sedmisegmentoveho displaye

-moznost pridavat volny pocet mist

-vyuziti posuvných registrů 74HCT595

display.c

/*

Display.c

funkce pro ovladani sedmi segmentoveho displaye

kazda pozice je pripojena pres posuvny registr, potrebujici 4 vystupy, 
pro dynamicke diplaye jsou tri spolecne CS,DATA,CLK , pro staticke 1 EN

je mozne pridat jakekoli mnozstvi pozic, do tech pak jednotlive zapisovat


*/

#include <stdlib.h>
#include "pin.h"
#include "display.h"


/*struktura displayovych mist pro vytvoreni spojoveho seznamu */
typedef struct _MISTA MISTA;

struct _MISTA
{

    unsigned char CS;
	unsigned char DATA;
	unsigned char CLK;
	unsigned char EN;
	
	volatile unsigned char *brana;
	volatile unsigned char *branaEN;

	unsigned char data; //pro pripadne pouziti dynamickych disp.

    MISTA *next;
};

//funkcni prototypy
void zapisByte(unsigned char data,MISTA *misto);

/*spojovy seznam vytvorenych mist displaye */
MISTA *mista;
/*pocet vytvorenych mist v seznamu*/
short pocet = 0;


short vratPocet(){

return pocet;

}
/*
priklad na portu B je pripojen spolecnej enable pin vsech mist na pin 5
na portu A je pripojen posuvny registr na kterem je pripojen display ten je na pinech 3 4 5

pridejMisto(PINA, PINB, 5, 3, 4, 5);

pro dalsi misto proste staci zavolat tuto fci znova s prislusnymy hodnotami


*/

void pridejMisto(volatile unsigned char *branaRegPin, volatile unsigned char *branaEnablePin, unsigned char enablePin, 
					unsigned char csPin, unsigned char dataPin, unsigned char clkPin){

	/*vytvoreni nove struktury s displayem*/
    MISTA *misto;
    
	misto = (MISTA *) malloc (sizeof(MISTA)); //prideleni pameti nove strukture
    
	
	misto->CS = csPin;
	misto->DATA = dataPin;
	misto->CLK = clkPin;
	misto->EN  = enablePin;     
	
	misto->brana = branaRegPin;
	misto->branaEN = branaRegPin;

	misto->next = mista; /*predani adresy na predchozi misto */
	mista = misto; /*ukazatel mist je na tomto poslednim */
	

	
	/*nastaveni prislusnych pinu jako vystupnich 
	PREDPOKLAD DDR register je o jeden pod PORT*/
	volatile unsigned char *DDR;
	DDR = (misto->branaEN)+1;
	*DDR = misto->EN;


	DDR = (misto->brana)+1;
	*DDR = (misto->DATA)|(misto->CLK)|(misto->CS);

	pocet++;


}


/*vrati pole char na kazdou pozici jedna cislice */
unsigned char * vratPole(){

unsigned char *pole;

pole = (unsigned char *) malloc (pocet * sizeof(unsigned char));

return pole;

}

/* aktivuje display
* 
*/
/*TODO rizeni dynamyckeho disp*/
void aktivujDisp(){
	
	
	MISTA *misto;
	
	misto = mista;

    for (; misto; misto = misto->next)		/* projed cely spojovy seznam */
    {
        
		 setVybranyPinyHigh(misto->branaEN, misto->EN);
	}

}



/* zobrazi cislo 0 az 9
*  10 jako F a 11 jako G
*  12 jako t a 13 jako C
*  14 jako prazdny znak
*  15 jako Error
*/

#define ERROR_NO (15)
unsigned char cisla[16] = {0x7E,	0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B, 0x47, 0x5E, 0x0F, 0x4E, 0x00, 0x4F};

/*zapise znaky z pole
* postupne na kazde misto displaye
* 
*/
void zapisZnaky(unsigned char *pole){
	
	short i=0;
	MISTA *misto;
	
	misto = mista;

    for (; misto; misto = misto->next)		/* projed cely spojovy seznam */
    {
        
		zapisByte(cisla[pole[i]],misto);
		i++;
	}

}

/*zapis byte
* a zobraz
*
*/
void zapisByte(unsigned char data,MISTA *misto){
	  char i;

	  

	/*nastav CS line na log0 */
	setVybranyPinyLow(misto->brana, misto->CS);


	   for(i=8;i>0;i--){

		/* na vystup prived osmy bit */
		/* BRR (reset) zapne segment*/
	  	if((data & 0x80)){
		   setVybranyPinyLow(misto->brana, misto->DATA);
		}
		else{
		  setVybranyPinyHigh(misto->brana, misto->DATA);

		}

		/*hodinama do log1 se bit posune do registru */
		setVybranyPinyHigh(misto->brana, misto->CLK);

	   /* a hodiny zpet do log0*/
		setVybranyPinyLow(misto->brana, misto->CLK);

		/*posunout o bit doleva */
		data <<= 1;
	  }

	  /*nacti obsah registru na vystup */
	  setVybranyPinyHigh(misto->brana, misto->CS);
}

pin.c


/*writing 1 to PINx register toggles only the bits set as 1*/
void setVybranyPinyHigh(volatile unsigned char *port, unsigned char pin){

	 unsigned char stav = *port;

	 /*nastav jen ty vystupy ktery nejsou v 1*/
	 pin = stav|pin; //v pinu jsou 1 vsude kde je jedna na pin i stav
	 pin = stav^pin; //zustanou 1 jen tam kde jsou navic oproti stavu

 	*port = pin;
}

void setVybranyPinyLow(volatile unsigned char *port, unsigned char pin){

	unsigned char stav = *port;

	//ted chci na pinu 1 jen tam kde je na pinu 1 a na stav 1

 	*port = stav&pin; //by mohlo byt ono


}

pokusny program main()


#include <avr/io.h> // zde je definovan napr. PORTB
#include <avr/iom88.h> // konstanty pro konkretni typ mikrokontroleru
#include <util/delay.h> // toto potrebuji pro pouziti funkce _delay_ms()

#include "display.h"

int main (void){ // hlavni funkce programu
  /*posloupnost pouziti displaye:
*
* nejdrive nastavit vsechny segmenty displaye pomoci pridejMisto()
*
* pak zapnout vystup pomoci aktivujDisp() to zapne enable piny
* 
* pak pomoci vratPocet() je mozne ziskat pocet vytvorenych mist
*
* pomoci funkce vratPole() se ziska ukazatel na pole unsigned char[] do ktereho se do kazde pozice 
* zapise pozadovana hodnota, kterou ma zobrazit kazde dane misto displaye
*
* toto pole se zobrazi pomoci fce zapisZnaky(pole); 
*
*pridejMisto(brana, branaEnablePin, enablePin, csPin, dataPin, clkPin);
*/

pridejMisto(PINB, PINC, 1<<5, 1<<3, 1<<4, 1<<5);
pridejMisto(PINB, PINC, 1<<4, 1<<1, 1<<2, 1<<3);



aktivujDisp();

short pocet = vratPocet();

unsigned char *znaky = vratPole();

unsigned char j=0;
short i;


while(1){

	for(i=pocet;i>0;i--){
			

	znaky[i]=j+i;
	

	}
	zapisZnaky(znaky);
	j++;
}

} // konec main
 
Osobní nástroje