/* No responsibility whatsoever. Free to copy. MSP430 (good for any). Simple serial data exchange with 74hc273 through P1.4(data)& P1.5(clock). Made quickly, just for screen testing. See skootsone.yolasite.com/msp430-7segment for schematic diagramm. */ #include volatile unsigned int position_on_led_screen [8] = {0x7F,0xbf,0xdf,0xef,0xf7,0xFB,0xFD,0xFE}; //Last byte-position ('0'-position'ON'), 7Fh=01111111b,BFh=10111111,DFh=11011111b, etc volatile unsigned int digit_to_led [10] = {0xC000,0xF900,0xA400,0xB000,0x9900,0x9200,0x8200,0xF800,0x8000,0x9000}; //Hi byte respond to segment ('0'-segment'ON'). Format - dot,g,f,e,d,c,b,a volatile unsigned int string_of_leds [8] = {0x7f00,0x3f00,0x1f00,0x0f00,0x0700,0x0300,0x0100,0}; //Hi byte respond to LED ('0'-LED'ON'). Format - 1,2,3,4,5,6,7,8. 00111111b light 2 first LEDs volatile unsigned int buffer_line_to_leds [6] = {0xc07f,0x40bf,0xf9df,0x99ef,0x8bf7,0xe0FB}; //String on the screen. Firsf byte - image, second - position int i,j,k,l,m,n,temp_l,temp_h; //tonn of variables, half not used int counter_int, counter_part_sec, counter_sec, counter_min; //vars for counter of seconds or so void count_the_time (); //function, collect the time ticks, part of seconds, seconds & minutes void time_to_symbols(); //function, convert dec. digit to image on the screen int main(void) { DCOCTL = 0; BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; //Setup CPU frequency to 16MHz WDTCTL = WDT_MDLY_8; //Run WDT as 8msec/16(MHz)=0.5msec interrupt source (2000 times per sec.) IE1 |= WDTIE; //Enable WDT interrupt P1DIR |= 0x30; //Set P1.0 to output direction j=0; //Counter to drain serial data to the 74hc273 __bis_SR_register(LPM0_bits + GIE); //Sleep, w/int., only CPU=OFF, MCLK=SMCLK(for WDT) } //If 8 usec. have elapsed, an interrupt is generated and this part is started #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void) { k=buffer_line_to_leds [j]; //digit & position, in 16bit variable copyed to 'k' for (i=0;i<16;i++) //from here, var 'k', puhed to output P1.4, bit by bit, 16 times { //Next 2 lines must be inverted if you power LEDs from 'clock' & 'data' lines P1OUT &= ~0x10; //Reset P1.4 (data) if(k & 0x01) P1OUT |= 0x10; //Set P1.4 (data) if current bit is Hi P1OUT |= 0x20; //Set P1.5 (clock) that would snap (data) in 74hc273 k=k>>1; //Shift 16bit right & buy some time for clock signal P1OUT &= ~0x20; //Reset P1.5 (clock line) } //at this moment var 'k' (16bit) copyed to 74hc273 j++; //Prep. counter for next interrupt if(j==6)j=0; //Reset position counter to 0, if all 6 position, on the screen, are already shown count_the_time (); //Call to function, to convert ticks to real time time_to_symbols(); //Call to function, to convert time's vars and fill the dim. (buffer_line_to_leds []) with digits (frst.byte) & relevant position (sec.byte) } void count_the_time () //Stupid solution to show how it works { counter_int++; if (counter_int == 19){ //Must be 20, but in real - 19 is ticks per 1/100 sec. Ajust it if you want counter_int=0; counter_part_sec++;} if (counter_part_sec == 100){ //Increase seconds counter. 100msec == 1 sec. counter_part_sec=0; counter_sec++;} if (counter_sec == 60){ //Increase minutes counter, each 60 seconnds counter_sec=0; counter_min++;} } void time_to_symbols() //Even more stupid solution, but it works { temp_l = counter_min % 10; buffer_line_to_leds [0] = digit_to_led [temp_l] + position_on_led_screen [0] ; temp_l = counter_sec % 10; temp_h = (counter_sec / 10) % 10; buffer_line_to_leds [1] = digit_to_led [temp_h] + position_on_led_screen [1] ; buffer_line_to_leds [2] = digit_to_led [temp_l] + position_on_led_screen [2] ; temp_l = counter_part_sec % 10; temp_h = (counter_part_sec / 10) % 10; buffer_line_to_leds [3] = digit_to_led [temp_h] + position_on_led_screen [3] ; buffer_line_to_leds [4] = digit_to_led [temp_l] + position_on_led_screen [4] ; }