Launcpad + hcf4094be +7 segment näyttö

Elikkäs ostin tuollaisia hcf4094be bitti rekisrereitä. Nyt tarvitsiain apua, kum en löytänyt yhtään ohjetta kuinka käyttäää niitä laumchpadin kanssa?

Sitten olisi tarkoitus käyttää niitä kingbright sa52-11hwa 7 segment displayn kanssa. Mutta ostin vahingossa mallin jossa ei ole common ground vaan toisin päin.
Eli yhteen pinniin kiinnitetään virta ja sitten yhdistämällä maa johonkin muista pinneistä ohjataan tuota näyttöä.

Eli kuinka voin operoida tuolla rekisterillä maata? transistoreilla tietääkseni onnistuisi muttei oikein viitsisi sille tielle lähteä, onnistuuko ilman lisä komponentteja?

eiköhän se toimi kun kytket sen näytön yhteisen natsan käyttöjännitteeseen ja ajat rekisteriin bitit käänteisenä, toisin sanoen 0 sytyttää (maattaa)segmentin ja 1 sammuttaa.
laita myös sopivat etuvastukset rekisterin pinnien ja näytön väliin jottei tule toimintasavut ulos

Ok. Kiitos! Nyt pitäis sitten selvittää kuinka ajaa tuota rekisteriä launcpadilla…?

se tieto miten sitä ohjataan löytyy piirin datalehdestä, jotenka se tekstiosuus kannattaa lukea ajatuksella parikertaa läpi ja tutustua truth tableen.

Käytännössä sivistynyt tapa lienee silmukka jossa nitkutelleen tarvittava määrä ykköstä tai nollaa ulos kellon saattelemana, bitinsiirtoa ja maskaustakin voi samalla harjoitella ja lopuksi OE pinnillä tms. data ulos rekisteristä

Toimiikos se tällä ohjeella? processors.wiki.ti.com/index.php … t_Register

Voisikos tuollaista näyttöä ajaa suoraan launchpadilla? Kuinka siis saan launchpadin pinneistä maata? :slight_smile:

Eikö ne tuolla ole noita kelloja tehny, joissa ajetaan kaikkia nastoja tuolla prossalla. Eli multipleksataan 4 7seg näyttöä.

Edit:
Tossa justiin ite kirjoittelemassa tollaista 4 multipleksausta jännitteen näyttämiseksi.
Pitäs vielä toi timeri konffata.

Edit2:
Lukasin noita hcf4094be datalehtiä, niin vaikuttaa ettei virta piisaa ajamaan lediä.

Varmaan onnistus suoraan tolla prossalla ajaa paremmin.
msp430g2553 IO kohtianen max virta +/-6 mA ja 48mA yht.

tässä on aika hyvä projekti jossa ajetaan G2231:sellä neljää näyttöä. koodi mahtuu just ja just kontrolleriin :smiley:
simpleavr.com/msp430-projects/3p4w-clock

tarpeeks nopeasti kun ajaa niin saa kaikki neljä käyttöön. tähän tyyliin:
näytöt pois;
näyttö1 päälle;
numero;
näyttö yksi pois;
näyttö kaksi päälle;
numero;
näyttö kaksi pois;
jne…

ite nyt 2 näyttöä onnistunu ajamaan. Ihan alottelija olen joten koodi on aika “huonoa”
Seuraavaks pitäs tehä countteri joka laskee 0-99 :smiley:

Tässä myös koodi joka laskee 0-9sec. Saa muokattua yhteiselle anodille toimivaks kääntämällä vaan |= x --> &= ~ x ja toiste päin.
processors.wiki.ti.com/index.php … lay_Driver

tossa on hahmotelmaa omsasta kirjastosta.

[code]/*

  • disp_7seg.c
  • Created on: 19.4.2012
  •  Author: Limba
    

*/

#include <msp430.h>
#include <stdbool.h>

// Pin Configuration

#define Disp_P1_seg_a 0x01
#define Disp_P1_seg_b 0x02
#define Disp_P1_seg_c 0x04
#define Disp_P1_seg_d 0x08
#define Disp_P1_seg_e 0x10
#define Disp_P1_seg_f 0x00
#define Disp_P1_seg_g 0x00
#define Disp_P1_seg_dp 0x00

#define Disp_P2_seg_a 0x00
#define Disp_P2_seg_b 0x00
#define Disp_P2_seg_c 0x00
#define Disp_P2_seg_d 0x00
#define Disp_P2_seg_e 0x01
#define Disp_P2_seg_f 0x02
#define Disp_P2_seg_g 0x00
#define Disp_P2_seg_dp 0x00

#define Disp_P1_Act_1 0x20
#define Disp_P1_Act_2 0x40
#define Disp_P1_Act_3 0x00
#define Disp_P1_Act_4 0x00

#define Disp_P2_Act_1 0x00
#define Disp_P2_Act_2 0x00
#define Disp_P2_Act_3 0x04
#define Disp_P2_Act_4 0x08

// a
// f b
// g
// e c
// d
char disp_7seg_char_P1[10] = {
Disp_P1_seg_a | Disp_P1_seg_b | Disp_P1_seg_c | Disp_P1_seg_d | Disp_P1_seg_e | Disp_P1_seg_f, // 0
Disp_P1_seg_b | Disp_P1_seg_c, // 1
Disp_P1_seg_a | Disp_P1_seg_c | Disp_P1_seg_d | Disp_P1_seg_f | Disp_P1_seg_g, // 2
Disp_P1_seg_a | Disp_P1_seg_b | Disp_P1_seg_c | Disp_P1_seg_d | Disp_P1_seg_g, // 3
Disp_P1_seg_b | Disp_P1_seg_c | Disp_P1_seg_e | Disp_P1_seg_f, // 4
Disp_P1_seg_a | Disp_P1_seg_b | Disp_P1_seg_d | Disp_P1_seg_e | Disp_P1_seg_g, // 5
Disp_P1_seg_a | Disp_P1_seg_c | Disp_P1_seg_d | Disp_P1_seg_e | Disp_P1_seg_f | Disp_P1_seg_g, // 6
Disp_P1_seg_a | Disp_P1_seg_b | Disp_P1_seg_c, // 7
Disp_P1_seg_a | Disp_P1_seg_b | Disp_P1_seg_c | Disp_P1_seg_d | Disp_P1_seg_e | Disp_P1_seg_f | Disp_P1_seg_g, // 8
Disp_P1_seg_a | Disp_P1_seg_b | Disp_P1_seg_c | Disp_P1_seg_d | Disp_P1_seg_f | Disp_P1_seg_g}; // 9

char disp_7seg_char_P2[10] = {
Disp_P2_seg_a | Disp_P2_seg_b | Disp_P2_seg_c | Disp_P2_seg_d | Disp_P2_seg_e | Disp_P2_seg_f, // 0
Disp_P2_seg_b | Disp_P2_seg_c, // 1
Disp_P2_seg_a | Disp_P2_seg_c | Disp_P2_seg_d | Disp_P2_seg_f | Disp_P2_seg_g, // 2
Disp_P2_seg_a | Disp_P2_seg_b | Disp_P2_seg_c | Disp_P2_seg_d | Disp_P2_seg_g, // 3
Disp_P2_seg_b | Disp_P2_seg_c | Disp_P2_seg_e | Disp_P2_seg_f, // 4
Disp_P2_seg_a | Disp_P2_seg_b | Disp_P2_seg_d | Disp_P2_seg_e | Disp_P2_seg_g, // 5
Disp_P2_seg_a | Disp_P2_seg_c | Disp_P2_seg_d | Disp_P2_seg_e | Disp_P2_seg_f | Disp_P2_seg_g, // 6
Disp_P2_seg_a | Disp_P2_seg_b | Disp_P2_seg_c, // 7
Disp_P2_seg_a | Disp_P2_seg_b | Disp_P2_seg_c | Disp_P2_seg_d | Disp_P2_seg_e | Disp_P2_seg_f | Disp_P2_seg_g, // 8
Disp_P2_seg_a | Disp_P2_seg_b | Disp_P2_seg_c | Disp_P2_seg_d | Disp_P2_seg_f | Disp_P2_seg_g}; // 9

int disp_curr_disp;

// Clear Display a…g + en1…4
char disp_DisableDisplay[2] = {
Disp_P1_seg_a | Disp_P1_seg_b | Disp_P1_seg_c | Disp_P1_seg_d | Disp_P1_seg_e | Disp_P1_seg_f | Disp_P1_seg_g | Disp_P1_seg_dp,
Disp_P2_seg_a | Disp_P2_seg_b | Disp_P2_seg_c | Disp_P2_seg_d | Disp_P2_seg_e | Disp_P2_seg_f | Disp_P2_seg_g | Disp_P2_seg_dp};

// En1…4
char disp_ActiveDisplay_P1[4] = {Disp_P1_Act_1, Disp_P1_Act_2, Disp_P1_Act_3, Disp_P1_Act_4};
char disp_ActiveDisplay_P2[4] = {Disp_P2_Act_1, Disp_P2_Act_2, Disp_P2_Act_3, Disp_P2_Act_4};

// Displaydata char 1…4 (9999)
char disp_Data[4] = {0,0,0,0};

// Init
int disp_7seg_init()
{
disp_curr_disp = 0;
return 0;
}

// Print Integer
void disp_7seg_disp_int(int val)
{

int new_value;
int a;

for(a = 0; a<4; a++)
{
	disp_Data[3-a] = new_value % 10;
	new_value /= 10;
}

}

// Print Integer
void disp_7seg_disp_hex(int val)
{

int new_value;
int a;

for(a = 0; a<4; a++)
{
	disp_Data[3-a] = new_value % 16;
	new_value /= 16;
}

}

// Timer interrupt for multiplexing
void disp_int_atim()
{
// print curr disp

int value;

P1OUT &= ~disp_DisableDisplay[0];
P2OUT &= ~disp_DisableDisplay[1];

value = disp_Data[disp_curr_disp];
P1OUT |= disp_7seg_char_P1[value];
P2OUT |= disp_7seg_char_P2[value];

P1OUT |= disp_ActiveDisplay_P1[disp_curr_disp];
P2OUT |= disp_ActiveDisplay_P2[disp_curr_disp];

disp_curr_disp++;
if(disp_curr_disp >= 4)
{
	disp_curr_disp = 0;
}

}
[/code]

Joo… Tuota mutta siis… Kun eihän nuo pinnit riitä kuin yhdelle näytölle…?

Ei kai niitä pinnejä tarvitse olla yhtä monta, kuin segmenttejä on. Vilkkuminen ei kuitenkaan näy ihmissilmälle, kun se on tarpeeksi nopeata. Tarvitaan siis 7-8 pinniä + 1 per näyttö. Ne 7 (tai 8 jos piste lasketaan) tarvitaan jokaiselle segmentille esimerkiksi maadottamaan ne ja ne siis kytketään kaikkiin näyttöihin. Sitten se yksittäinen laitetaan joko suoraan antamaan virta näytölle tai sitten vaikka jonkinlaisen transistorin kautta (näytön virrantarve voi olla muuten liian suuri). Sitten valitaan näyttö sillä näytön omalla pinnillä ja merkki niillä 7 jaetulla. Sitä kun vilkutetaan tarpeaksi nopeasti, niin näyttää että kaikki palavat yhtä aikaa. Luulisin että näin, en ole vielä koskaan toteuttanut.

Tjuu nonhan se menee. Kiitos. Mutta ei taida suoraan launchpadilla onnistua, Ainakaan noilla mukana tulevilla kontollereilla. Kun niissä on se 7 jota voi ohjailla. Sitten jos on kaksi näyttöä, tarvitaan ohjaamaan niitä vielä 2 pinniä (tai jos kikkailee transistoreilla niin vain yksi).

Noissa vakioissa on tuo P1.0-P.7 eli 8 IO:ta.

Ite hommasin MSP430G2553, jossa on P1.0-P1.7 + P2.0-P2.5 eli 14 IO:ta.

Edit:
noille pikkupiireille suosittelisin 74HC595. Tuo pystyy antaan max 25 mA per IO ja rajoittavaksi tekijäksi jää tuo 70 mA käyttis/maa rajoitus. 6 mA pysytään vielä tilojen jännitespekseissä.
digikey.fi/product-detail/en … -ND/763088

Miksei onnistuisi? Tuossa linkissäni ylempänä launchpadilla ohjataan neljää näyttöä.
Suosittelen kummiskin tuota G2553. Enemmän io pinnejä ja tilaa koodille

No selitähän kädeatä pitäen kuinka tuo ohjaus menee? Jos jokaiseta näytöstä menee sama segmentti yhteen pinniin launcpadilla, menee jo 7 pinniä, jolloin on jäljellä 1 vapaa pinni joka valitsee mikä näyttö käytössä?

Vai kuinka?

EDIT: Joo tuossa linkissäsi on noita ledejä ohjattu muillakin pinneillä kuin näillä 8 io pinnillä. Kuinka noita muita ohjaillaan? :0

Ainakin piirin sivuilla on GPIO määräksi merkattu 10 eli varmaan P2 ylimmät 2 bittiä myös käytössä (P2.6 - P2.7 nastat 13 ja 12).

Päivittelempä miten menee. Nyt olen siis siinä vaiheessa että olen tunnit näyttävän 1-7segmenttinäytön saanut tehtyä. numerot 10-11-12 ei onnistu Yhdellä näytöllä, tietenkään. Uusia rekistereitä odotellessa.
Parannus ehdotuksia Koodiini?:

[code]#include <msp430g2231.h> //kiitokset koodinpohjastsa hutasu.net
unsigned int sekunnit=0; // luodaan globaali muuttuja joka pitää sekunnit tallessa
unsigned int minuutit=0; // luodaan minuuteille oma globaali muuttuja
unsigned int tunnit=0; //tunneille myös

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // watchdog pysäytys
P1DIR |= 0x01 + BIT1 +BIT2 + BIT3 + BIT4 + BIT5 +BIT6 +BIT7; // t P1.0 ulostulo
P1OUT |= 0x01 + BIT1 +BIT2 + BIT3 + BIT4 + BIT5 +BIT6 +BIT7;
P1DIR &= ~BIT3; // S2 (P1.3) kytkin tuloksi

      BCSCTL3 = XCAP_3;   // asetetaan 12,5 pF:n sisäiset kondensaattorit aktiiviseksi
      CCTL0 = CCIE;   // sallitaan vertailijan keskeytys
      TACTL |= ID_0 + TASSEL_1;   // asetetaan jakaja 0, laskentamoodi vertaileva ja ACLK-kello.
      CCR0 = 32767;    // ladataan vertailurekisterin arvo 1 sekunnin keskeytystä varten
       __enable_interrupt();   // sallitaan globaalit keskeytykset
      TACTL |= MC_1;      // käynnistetään laskuri

      while(1)
      {
    	  volatile unsigned int i;
    	     // luetaan P1IN rekisteri muuttujaan talteen
    	                 if( ! (BIT3 & P1IN) ) // vertaillaan onko juuri BIT3 nollassa vai ei
    	                 {
    	                	 tunnit++;
    	                	 do i--;
    	                	 	while (i != 0);
    	                	 	P1OUT ^= BIT3  +BIT5 + BIT4 + BIT0 +BIT2;
    	                	 	i = 100000;                          // viivettä vähän ettei ota liikaa painalluksia kerralla
    	                 }
      if(sekunnit == 60)
              {

                   minuutit++; // lisätään minuutit muuttujaa yhdellä kun 60 s on mennyt
                      sekunnit = 0;  // nollataan sekuntilaskuri jotta vertailu onnistuu joka kierroksella
              }
              if (minuutit == 60) // jos minuutteja mennyt 60
              {
                	   tunnit++; //lisätään tunteja yhdellä
                	   minuutit = 0;  //nollataan minuutit
              }
                	   if (tunnit == 12) {
                		   tunnit = 0;
                	   }
                		   if (tunnit == 1) {
                			   P1OUT ^= BIT7 + BIT6;// laitetaan 2 segmenttiä päälle
                			   P1OUT |= BIT1 + BIT0 +BIT2 +BIT4 +BIT5; // ja muut pois
                		   }

                		   if (tunnit == 2) {
                			   P1OUT ^= BIT7  +BIT5 + BIT4 + BIT0 +BIT2; //sama jatkuu tästä eteenpäin
                			   P1OUT |= BIT1 + BIT6;
                	   }

                		 if (tunnit == 3) {
                			 P1OUT ^= BIT7  +BIT5 + BIT6 + BIT0 +BIT2;
                			 P1OUT |= BIT1 + BIT4;
                		 }
                		 if (tunnit == 4) {
                			 P1OUT ^= BIT7  +BIT0 + BIT6  +BIT1;
                			 P1OUT |= BIT2 + BIT4 +BIT5;
                		                    		 }
                		 if (tunnit == 5) {
                			 P1OUT ^= BIT2  +BIT0 + BIT6  +BIT1 +BIT5;
                		                    			 P1OUT |= BIT7 + BIT4;
                		                    		                    		 }
                		 if (tunnit == 6) {
                			 P1OUT ^= BIT4  +BIT0 + BIT6  +BIT1 +BIT5 +BIT2;
                		                     		                    			 P1OUT |= BIT7;
                		                     		                    		                    		 }
                		 if (tunnit == 7) {
                		                     			 P1OUT ^= BIT6 +BIT7 +BIT2;
                		                     		                     		         P1OUT |= BIT0 +BIT1 +BIT4 +BIT5;
                		                     		                     		                    		                    		 }
                		 if (tunnit == 8) {
                		                    		                     			 P1OUT ^= 0x01 + BIT1 +BIT2 + BIT7 + BIT4 + BIT5 +BIT6 +BIT7;

                		                    		                     		                     		                    		                    		 }

                		 if (tunnit == 9) {
                		                    		                    		                     			 P1OUT ^= 0x01 + BIT1 +BIT2 + BIT7 +BIT6;
                		                    		                    		                     			 P1OUT |= BIT4 +BIT5;
                		                    		                    		                     		                     		                    		                    		 }

                		 if (tunnit == 10) {
                			 P1OUT ^= BIT7 + BIT6;
                			                    			   P1OUT |= BIT1 + BIT0 +BIT2 +BIT4 +BIT5;               		                                 		                    		 }
                		 if (tunnit == 11) {
                		                    			 P1OUT ^= BIT6 + BIT4;
                		                    			                    			   P1OUT |= BIT1 + BIT7 +BIT0 +BIT2 +BIT5;               		                                 		                    		 }



              }
      }

#pragma vector = TIMERA0_VECTOR // huomaa että tässä tapauksessa keskeytysvektori on TIMERA0
__interrupt void TimerA0(void)
{

  sekunnit++;

}
[/code]
Kuinka olisi mahdollista tehdä vain yhtä näyttöä käyttävä kello joka toimisi näin:

näytetään kymmenet tunnit
“lyhyttauko”
näytetään 1 tunnnit
“lyhyttauko”
näytetään 10 minuutit
“pitkätauko”
näytetään 1 minuutit
“pitkätauko”
Palataan alkuun.

Ongelmahan on se että, ensinnäkin jos jatkan tuota if lauseiden tekoa menee ikuisiuus jokaiselle minuutille ja jokaiselle tunnille eli 12 *60 if lausetta. Ei kiitos! Kuinka teen tämän järkevästi?
Lisäksi kun kokeilin laittaa tuotta viivettä niinkuin äsken esittelin, niin sekosi koko koodi.

Helpoimmalla varmaan pääsee kun luo taulukon, johon tallennetaan lukujen 0-9 esittämiseen tarvittavat bittikombinaatiot esim. seuraavasti

unsigned char taulu[]={luvun 0 bittikombinaatio, luvun 1 bittikombinaatio, jne };

Tätä taulukkoa käyttämällä voidaan helposti tulostaa luvut 0-9. Esimerkiksi jos muuttujassa tunnit on luku 5, löytyy muuttujaa vastaava numero taulukosta seuraavasti

taulu[tunnit]

Tällöin ei tarvitse jokaiselle tunnille ja minuutille tehdä omaa if-lausetta.

Kiitos!
Taulukon käyttöhän tässä onnistuu. :slight_smile:
Mutta nyt on ongelmaa, että kun käynnistän ykkösen segmentit, ja sitten seuraavana kakkosen segmentit. Jäävät myös ykkösen päällesammumatta. Tajuatteko?

Se olikin helppo homma. Koodini. Kiitos! :=)

[code]#include <msp430g2231.h>
unsigned int sekunnit=0; // luodaan globaali muuttuja joka pitää sekunnit tallessa
unsigned int minuutit=0; // luodaan minuuteille oma globaali muuttuja
unsigned int tunnit=0; //tunneille myös
unsigned int nappi =0;
unsigned char taulu[]={ BIT7 + BIT6, BIT7 +BIT5 + BIT4 + BIT0 +BIT2,BIT7 +BIT5 + BIT6 + BIT0 +BIT2,BIT7 +BIT0 + BIT6 +BIT1, BIT2 +BIT0 + BIT6 +BIT1 +BIT5,BIT4 +BIT0 + BIT6 +BIT1 +BIT5 +BIT2, BIT6 +BIT7 +BIT2, BIT0 + BIT1 +BIT2 + BIT4 + BIT5 +BIT6 +BIT7,0x01 + BIT1 +BIT2 + BIT7 +BIT6,BIT7 + BIT6,BIT6 + BIT4 };

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // watchdog pysäytys
P1DIR |= 0x01 + BIT1 +BIT2 + BIT3 + BIT4 + BIT5 +BIT6 +BIT7; // Set P1.0 to output direction
P1OUT |= 0x01 + BIT1 +BIT2 + BIT3 + BIT4 + BIT5 +BIT6 +BIT7;
P1DIR &= ~BIT3; // S2 (P1.3) kytkin tuloksi

      BCSCTL3 = XCAP_3;   // asetetaan 12,5 pF:n sisäiset kondensaattorit aktiiviseksi
      CCTL0 = CCIE;   // sallitaan vertailijan keskeytys
      TACTL |= ID_0 + TASSEL_1;   // asetetaan jakaja 0, laskentamoodi vertaileva ja ACLK-kello.
      CCR0 = 32767;    // ladataan vertailurekisterin arvo 1 sekunnin keskeytystä varten
       __enable_interrupt();   // sallitaan globaalit keskeytykset
      TACTL |= MC_1;      // käynnistetään laskuri

      while(1)
      {
    	  P1OUT |= 0x01 + BIT1 +BIT2 + BIT3 + BIT4 + BIT5 +BIT6 +BIT7;
    	  P1OUT ^= taulu[tunnit];
    	  volatile unsigned int i;
    	     // luetaan P1IN rekisteri muuttujaan talteen
    	                 if( ! (BIT3 & P1IN) ) // vertaillaan onko juuri BIT3 nollassa vai ei
    	                 {

    	                	 tunnit++;
    	                	 do i--;
    	                	 	while (i != 0);
    	                	 	P1OUT ^= BIT3  +BIT5 + BIT4 + BIT0 +BIT2;
    	                	 	i = 100000;                          // SW Delay
    	                 }
      if(sekunnit == 60)
              {

                   minuutit++; // lisätään minuutit muuttujaa yhdellä kun 60 s on mennyt
                      sekunnit = 0;  // nollataan sekuntilaskuri jotta vertailu onnistuu joka kierroksella
              }
              if (minuutit == 60) // jos minuutteja mennyt 60
              {

                	   tunnit++; //lisätään tunteja yhdellä
                	   minuutit = 0;  //nollataan minuutit
              }
                	   if (tunnit == 12) {
                		   tunnit = 0;
                	   }


              }
      }

#pragma vector = TIMERA0_VECTOR // huomaa että tässä tapauksessa keskeytysvektori on TIMERA0
__interrupt void TimerA0(void)
{

  sekunnit++;

}[/code]