MSP430 Numitron Clock, Teil 2: Die Ansteuerung

numitron_tubes_iv16In diesem Teil geht es um die Ansteuerung der Röhren. Ich habe lange überlegt wie ich die Ansteuerung von 6 Segmentanzeigen (also insgesamt 6*7=42 Segemente) realisiere. Da die MSP430 G-Serie nur maximal 2 Ports (also 2*8 I/O’s) haben, wobei schonmal zwei Eingänge (XIN/XOUT) für den Uhrenquarz reserviert sind, 4 Ausgänge für das LCD und 3 weitere Eingänge für die Taster, musste die Ansteuerung seriell geschehen. Weiterhin sollte der Code für die Ansteuerung auch sehr simpel gestaltet werden. Also wurden dazu 3 8bit-Schieberegister benutzt. Um die Daten an die Schieberegister zu senden werden insgesamt 3 Ausgänge benötitgt. Jedes Schieberegister ist mit zwei 7-Seg-Decoder verbunden, die als Input einen BCD-Code erwarten und den nötigen Strom für die Segmente liefern. Somit werden insgesamt 9 IC’s benötigt (kann man natürlich mit Mulitplexer & Co reduzieren).

Ein weiteres Problem war die Gestaltung der Lochrasterplatine. Die Platine sollte kompakt sein (wenn man bei Lochraster überhaupt von “kompakt” reden kann) und die Verbindungswege zwischen den IC’s und Segmenten sollten soweit wie möglich kurz bleiben. Das fertige Layout der Platine:

numitron_platine

Daten:

  • 3x 74HC4094
  • 6x MOS4511
  • 9x 100nF Keramikkondensatoren
  • 9x IC-Sockel
  • Stiftleiste + Präzisionsbuchsenleiste
  • 60x Metallschichtwiderstände
  • ziemlich viele Litzen

Schaltplan:

numitron_clock_platine

Die Schieberegister bekommen immer ein Byte in der Form von zwei BCD-Codes zugeschickt. Eine Zahl besteht aus zwei Ziffern, z.B.: 12 -> 1=0001 und 2=0010. Das Byte was an die Schieberegister gesendet wird, sieht dann folgendermaßen aus: 00010010. Die erste Ziffer wird also 4 mal nach links geschoben (siehe Schaltplan oder Testprogramm).

Die fertige Platine:

IMAG0348IMAG0352

Und einmal voll bestückt (die RGB-LEDs fehlen hier noch) für einen Test:

IMAG0364

Video:

In dem Video läuft ein einfaches Testprogramm, die erste Zahl (2 Ziffern) wird immer an die beiden restlichen Stellen geschoben, also: 01, 00, 00 – 02, 01, 00 – 03, 02, 01 usw.

Testprogramm:

  1. /*************************************************
  2.  *     ___       _             _    
  3.  *    |   |_ _ _| |___ ___   _| |___
  4.  *    | | |_'_| . | -_|  _|_| . | -_|
  5.  *    |___|_,_|___|___|___|_|___|___|
  6.  *
  7.  * FILE:     main.c
  8.  * Author:   declis (xdec.de)
  9.  ************************************************/
  10.  
  11. #include <msp430g2452.h>
  12.  
  13. void main(void)
  14. {
  15.     volatile unsigned char s1=0,s2=0,zaehler=0,byte=0,bit_num=0;
  16.     volatile unsigned int m_sec=400;
  17.  
  18.     WDTCTL=WDTPW+WDTHOLD;
  19.     BCSCTL1=CALBC1_1MHZ;
  20.     DCOCTL=CALDCO_1MHZ;
  21.  
  22.     P1DIR|=(BIT0+BIT1+BIT2);        //P1.0 Strobe, P1.1 Data, P1.2 CLK
  23.     P1OUT&=~(BIT0+BIT1+BIT2);
  24.  
  25.     while(1)
  26.     {
  27.         byte=0;
  28.         s2=zaehler%10;              //split number in two digits (12 -> 1,2)
  29.         s1=zaehler/10;
  30.         s1<<=4;                     //left-shift 1st digit 4 times (bit 7-4)
  31.         byte|=s2+s1;                //prepare new byte (two BCD codes)
  32.                                     //1st digit: bit 7-4, 2nd digit: bit 3-0
  33.         zaehler++;                  //"zaehler" is real number (0-59)
  34.         if(zaehler>59) zaehler=0;
  35.  
  36.         while(bit_num!=8)           //start transmission
  37.         {
  38.             if(byte&(0x01<<bit_num))//LSB to MSB
  39.                 P1OUT|=BIT1;        //if bit is "1" -> data-port "high"
  40.             else
  41.                 P1OUT&=~BIT1;       //if bit is "0" -> data-port "low"
  42.  
  43.             P1OUT|=BIT2;            //clock pulse
  44.             P1OUT&=~BIT2;
  45.             bit_num++;
  46.             P1OUT&=~BIT1;
  47.         }
  48.         P1OUT|=BIT0;                //transmission done, strobe pulse
  49.         P1OUT&=~BIT0;
  50.         bit_num=0;
  51.  
  52.         while(m_sec--)
  53.             __delay_cycles(1000);
  54.  
  55.         m_sec=400;
  56.     }
  57. }
/*************************************************
 *     ___       _             _     
 *    |   |_ _ _| |___ ___   _| |___
 *    | | |_'_| . | -_|  _|_| . | -_|
 *    |___|_,_|___|___|___|_|___|___|
 *
 * FILE:     main.c
 * Author:   declis (xdec.de)
 ************************************************/

#include <msp430g2452.h>

void main(void)
{
	volatile unsigned char s1=0,s2=0,zaehler=0,byte=0,bit_num=0;
	volatile unsigned int m_sec=400;

	WDTCTL=WDTPW+WDTHOLD;
	BCSCTL1=CALBC1_1MHZ;
  	DCOCTL=CALDCO_1MHZ;

  	P1DIR|=(BIT0+BIT1+BIT2);		//P1.0 Strobe, P1.1 Data, P1.2 CLK
  	P1OUT&=~(BIT0+BIT1+BIT2);

  	while(1)
  	{
		byte=0;
		s2=zaehler%10;				//split number in two digits (12 -> 1,2)
		s1=zaehler/10;
		s1<<=4;						//left-shift 1st digit 4 times (bit 7-4)
		byte|=s2+s1;				//prepare new byte (two BCD codes)
									//1st digit: bit 7-4, 2nd digit: bit 3-0
		zaehler++;					//"zaehler" is real number (0-59)
		if(zaehler>59) zaehler=0;

		while(bit_num!=8)			//start transmission
		{
			if(byte&(0x01<<bit_num))//LSB to MSB
				P1OUT|=BIT1;		//if bit is "1" -> data-port "high"
			else
				P1OUT&=~BIT1;		//if bit is "0" -> data-port "low"

			P1OUT|=BIT2;			//clock pulse
			P1OUT&=~BIT2;
			bit_num++;
			P1OUT&=~BIT1;
		}
		P1OUT|=BIT0;				//transmission done, strobe pulse
		P1OUT&=~BIT0;
		bit_num=0;

		while(m_sec--)
			__delay_cycles(1000);

		m_sec=400;
  	}
}

weitere Bilder:










Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.