/* dcf_transmitter.c A simulation of the bit stream RAM usage: 91 bytes (9 local), 133 bytes free Optimizing - removed 29 instructions (-1 %) File 'prototype_new8.occ' File 'prototype_new8.hex' Total of 1650 code words (80 %) * Estimated CODE SIZE of full optimization: 1372 code words (-16 %) ********************************* TODO> Set fake time Save time in EEPROM INC/DEC Sound ________ ________ | \/ | LCD.D6 <-|RA2 16F628 RA1|-> LCD.D5 LCD.D7 <-|RA3 RA0|-> LCD.D4 Btn SET >-|RA4-od RA7/OSC1|-< Btn INC -|RA5/MCLR RA6/OSC2|-< Btn MODE GND --|Vss Vdd|-- +5V pulse out <-|RB0/INT (RB7)/PGD|-- XTAL 32,768 kHz pulse out <-|RB1/Rx (RB6)/PGC|-- XTAL 32,768 kHz Btn START >-|RB2/Tx RB5|-> LCD.RS LCD.EN <-|RB3/CCP (RB4)/PGM|-- 1k- Gnd |__________________| PROGRAM OVERVIEW Interrupt, 1 Hz ------------------------------------------ | If start_mode = 1 | Update clock (step up one second) | Output pulse-sequence | Update display | Check buttons | If MODE-button | Step up display mode 0->1->2->3->0 | If SET-button | Setting > 0 | Stop interrupt, jump out to setting sequence ---------------------------------------------------------- Main ----------------------------------------------------- | Initialization | Interrupt is active 1 Hz, but the clock is stopped | Loop | Check START-button | If START-button | Toggle start_mode ---------------------------------------------------------- Setting sequence (interrupt is stopped) ----------------- | Step through set sequence, read INC-button | Setting = 0 | Start interrupt ---------------------------------------------------------- */ /* _____________ INCLUDE ______________________________ */ #include "16F628.h" #include "int16CXX.H" /* _____________ CONFIGURATION _________________________ */ #pragma config |= 0x3fb0 // use internal 4MHz oscillator /* _____________ GLOBAL VARIABLES _______________________ */ char bit_value[60]; // The one-minute bit stream to output char tick_pos; // Current position in the bit stream char tick_pos_1; char tick_pos_10; char no_of_ones; // Counter of total no. of ones for parity bit setting int sec_1; // DCF77-simulator clock; second units int sec_10; // DCF77-simulator clock; second tens int min_1; // DCF77-simulator clock; minute units int min_10; // DCF77-simulator clock; minute tens int hr_1; // DCF77-simulator clock; hour units int hr_10; // DCF77-simulator clock; hour tens int day_1; // DCF77-simulator clock; day units int day_10; // DCF77-simulator clock; day tens int month_1; // DCF77-simulator clock; month units int month_10; // DCF77-simulator clock; month tens int year_1; // DCF77-simulator clock; year units (2000 + ...) int year_10; // DCF77-simulator clock; year tens (2000 + ...) char weekday; // DCF77-simulator clock; day of week, starting Sunday ??? char dst; // DCF77-simulator clock; Daylights saving time on/off bit start_mode; // Clock running or not char display_mode; // Display alternatives: 1=clock, 2=bit overview, 3=details char set_mode; // Setting mode; 0=no set, 1=minutes, 2=hours, 3=day, 4=month, 5=year char bit_val; /* _____________ FUNCTIONS _____________ */ void delay( char millisec); void delay10( char n); void get_bitvalue(); // Get the value of the current bit void output_bitvalue(); // Send the bitvalue to LED and output void set_bitvalue (void); // Set bit stream once per minute based on clock void delay10( char n ); void delay( char millisec ); void pixel_def( void ); void lcd_init( void ); // Initalize the LCD display void lcd_putchar( char data ); // Display one character on LCD void lcd_strobe( void ); void lcd_startmsg(void); void lcd_command ( char cmd ); char text1( char ); char text2( char ); char text11( char ); char text12( char ); char text13( char ); char text14( char ); char text15( char ); char text16( char ); char text17( char ); void show_digit(char digit); void minute_bcd(char m_dec); void hour_bcd(char h_dec); void update_clock (void); void update_minutes (void); void set_clock (void); void blink_empty (char digits); void blink_digits (char dig1, char dig2); void check_btn (void); void display_time(void); void display_weekday (void); void display_dst (void); interrupt int_server(void); /* ____ I/O PIN DEFINITIONS ____ */ #pragma bit D4 @ PORTA.0 #pragma bit D5 @ PORTA.1 #pragma bit D6 @ PORTA.2 #pragma bit D7 @ PORTA.3 #pragma bit EN @ PORTB.3 #pragma bit RS @ PORTB.5 #pragma bit START @ PORTB.2 #pragma bit MODE @ PORTA.6 #pragma bit INC @ PORTA.7 #pragma bit SET @ PORTA.4 //#pragma bit start_mode @ 0x20.7 #pragma origin 4 // Special interrupt instruction CC5x #pragma sharedAllocation // Special interrupt instruction CC5x /* ________________________ INTERRUPT FUNCTION ________________________ */ interrupt int_server(void) { int_save_registers // W, STATUS (and PCLATH) char sv_FSR = FSR; if (TMR1IF) // TMR1 overflow interrupt { TMR1IF = 0; // Reset overflow flag TMR1H = 0x80; // Reset counter TMR1L = 0x00; if (start_mode ==1) { tick_pos++; // Step up tick_pos one second (not needed ) sec_1++; // Step up one second update_clock (); // Main clock updated every second if (tick_pos == 60) { tick_pos = 0; } if (tick_pos == 00) { set_bitvalue(); // Set all 60 bits with initial value } output_bitvalue(); // Binary pulse on output } } if (display_mode == 1) { display_time (); } check_btn (); FSR = sv_FSR; int_restore_registers // W, STATUS (and PCLATH) } /* ________________________ MAIN FUNCTION start ________________________ */ void main(void) { //#pragma interruptSaveCheck n // No warning or error CM0=1; CM1=1; CM2=1; // No comparators on PORTA pins TRISA.0 = 0; // LCD D4 TRISA.1 = 0; // LCD D5 TRISA.2 = 0; // LCD D6 TRISA.3 = 0; // LCD D7 TRISB.3 = 0; // LCD EN TRISB.5 = 0; // LCD RS TRISB.0 = 0; // Output pulse TRISB.1 = 0; // Output pulse, inverted TRISB.2 = 1; // Button START TRISA.6 = 1; // Button MODE TRISA.7 = 1; // Button INC TRISA.4 = 1; // Button SET sec_1 = 9; // Sec = 59 sec_10 = 5; // Sec = 59 min_1 = 4; // Minute = 14 min_10 = 1; // Minute = 14 hr_1 = 3; // Hour = 23 hr_10 = 2; // Hour = 23 day_1 = 5; // Day = 30 day_10 = 0; // Day = 30 month_1 = 2; // Month = 01 month_10 = 0; // Month = 01 year_1 = 0; // Year = 10 year_10 = 1; // Year = 10 weekday = 6; // Saturday dst = 0; // Daylights saving time tick_pos = 59; display_mode = 1; // Show clock at start + bitvalue set_mode = 0; lcd_init(); // Initiate the LCD pixel_def(); // Define the special characters char i; RS = 0; // LCD in command-mode lcd_putchar( 0b00000010 ); //Cursor hoME RS = 1; // LCD in character-mode // display the 16 char text1() sentence for(i=0; i<16; i++) lcd_putchar(text1(i)); delay10(90); // reposition to "line 2" (the next 8 chars) RS = 0; // LCD in command-mode lcd_putchar( 0b11000000 ); RS = 1; // LCD in character-mode // display the 16 char text2() sentence for(i=0; i<16; i++) lcd_putchar(text2(i)); delay10(40); /* Definition of interrupt 1 Hz 00.xx.x.x.x.x -- xx.00.x.x.x.x Prescale 1/1 xx.xx.1.x.x.x TMR1-oscillator is on xx.xx.x.0.x.x - (clock input synchronization) xx.xx.x.x.1.x Use external clock 32.768 xx.xx.x.x.x.1 TIMER1 is ON */ T1CON = 0b00.00.1.1.1.1 ; /* CCPR = CLOSC * Timer1Period = 32768*1 = 32768 */ /* CCPR = 32768 = 0x8000 CCPR1H = 0x80, CCPR1L = 0x00 */ TMR1IE = 0; TMR1H = 0x00; //Short time to initial interrupt after Start TMR1L = 0x11; /* Timer1Period is now 1 s */ //********************************************************* RS = 0; // LCD in command-mode lcd_putchar(0b0000.0000); //Clear display RS = 1; display_time (); // Display initial time tick_pos = 59; //next interrupt should start at 00 start_mode = 1; RB1 = 1; TMR1H = 0x01; //Short time to initial interrupt after Start TMR1L = 0x00; TMR1IE = 1; // Enable TMR1 interrupt GIE = 1; // Interrupts allowed PEIE = 1; while (1) // Infinite loop, wait for button press */ { while( START == 0) ; // Button pressed { start_mode = ! start_mode; // Start/stop signal delay10 (1); } while( START == 1 ) ; // Button up { delay10 (1); } } } /* ________________________ TRANSMITTER OUTPUT FUNCTION start ________________________ */ void output_bitvalue(void) { bit_val = bit_value[tick_pos]; tick_pos_1 = tick_pos%10; // Get the single digit for display tick_pos_10 = tick_pos/10; // Get the single digit for display if (display_mode == 1) { lcd_command (0b1100.0000); // reposition to "line 2, position 0 RS = 1; // LCD in character-mode show_digit(tick_pos_10); show_digit(tick_pos_1); } if (bit_val == 0) { if (display_mode == 1) { RS = 0; // LCD in command-mode lcd_putchar( 0b00000010 ); //Cursor hoME RS = 1; // LCD in character-mode lcd_putchar('0'); } RB0 = 1; delay(1); RB1 = 0; delay10(10); RB0 = 0; delay(1); RB1 = 1; } /* RS = 0; // LCD in command-mode lcd_putchar( 0b11000000 ); // reposition to "line 2 RS = 1; // LCD in character-mode lcd_putchar(bit_value[tick_pos]); lcd_putchar(bit_value[tick_pos - 1]); lcd_putchar(bit_value[tick_pos - 2]); lcd_putchar(bit_value[tick_pos - 3]); lcd_putchar(bit_value[tick_pos - 4]); lcd_putchar(bit_value[tick_pos - 5]); lcd_putchar(bit_value[tick_pos - 6]); lcd_putchar(bit_value[tick_pos - 7]); lcd_putchar(bit_value[tick_pos - 8]); lcd_putchar(bit_value[tick_pos - 9]); lcd_putchar(bit_value[tick_pos - 10]); lcd_putchar(bit_value[tick_pos - 11]); lcd_putchar(bit_value[tick_pos - 12]); lcd_putchar(bit_value[tick_pos - 13]); lcd_putchar(bit_value[tick_pos - 14]); lcd_putchar(bit_value[tick_pos - 15]); // reposition to "line 2" (the next 8 chars) //RS = 0; // LCD in command-mode //lcd_putchar( 0b11000000 ); //RS = 1; // LCD in character-mode // display the 16 char text2() sentence //lcd_putchar(' '); // //delay10(10); */ if (bit_val == 1) { if (display_mode == 1) { lcd_command (0b1000.0000); // reposition to "line 1, position 0 RS = 1; // LCD in character-mode lcd_putchar('1'); } RB0 = 1; delay(1); RB1 = 0; delay10(20); RB0 = 0; delay(1); RB1 = 1; } /* RS = 0; // LCD in command-mode lcd_putchar( 0b11000000 ); // reposition to "line 2 RS = 1; // LCD in character-mode lcd_putchar(bit_value[tick_pos]); lcd_putchar(bit_value[tick_pos - 1]); lcd_putchar(bit_value[tick_pos - 2]); lcd_putchar(bit_value[tick_pos - 3]); lcd_putchar(bit_value[tick_pos - 4]); lcd_putchar(bit_value[tick_pos - 5]); lcd_putchar(bit_value[tick_pos - 6]); lcd_putchar(bit_value[tick_pos - 7]); lcd_putchar(bit_value[tick_pos - 8]); lcd_putchar(bit_value[tick_pos - 9]); lcd_putchar(bit_value[tick_pos - 10]); lcd_putchar(bit_value[tick_pos - 11]); lcd_putchar(bit_value[tick_pos - 12]); lcd_putchar(bit_value[tick_pos - 13]); lcd_putchar(bit_value[tick_pos - 14]); lcd_putchar(bit_value[tick_pos - 15]); RS = 0; // LCD in command-mode //lcd_putchar( 0b00011100 ); //Right right RS = 1; // LCD in character-mode // reposition to "line 2" (the next 8 chars) RS = 0; // LCD in command-mode lcd_putchar( 0b11000000 ); RS = 1; // LCD in character-mode lcd_putchar(' '); */ if (bit_val == 9) //last second before new minute, no pulse { if (display_mode == 1) { RS = 0; // LCD in command-mode lcd_putchar( 0b00000010 ); //Cursor hoME RS = 1; // LCD in character-mode lcd_putchar('-'); } RB0 = 0; } /* lcd_putchar( 0b11000000 ); // reposition to "line 2 RS = 1; // LCD in character-mode lcd_putchar(bit_value[tick_pos]); lcd_putchar(bit_value[tick_pos - 1]); lcd_putchar(bit_value[tick_pos - 2]); lcd_putchar(bit_value[tick_pos - 3]); lcd_putchar(bit_value[tick_pos - 4]); lcd_putchar(bit_value[tick_pos - 5]); lcd_putchar(bit_value[tick_pos - 6]); lcd_putchar(bit_value[tick_pos - 7]); lcd_putchar(bit_value[tick_pos - 8]); lcd_putchar(bit_value[tick_pos - 9]); lcd_putchar(bit_value[tick_pos - 10]); lcd_putchar(bit_value[tick_pos - 11]); lcd_putchar(bit_value[tick_pos - 12]); lcd_putchar(bit_value[tick_pos - 13]); lcd_putchar(bit_value[tick_pos - 14]); lcd_putchar(bit_value[tick_pos - 15]); RS = 0; // LCD in command-mode //lcd_putchar( 0b00011100 ); //Right right RS = 1; // LCD in character-mode // reposition to "line 2" (the next 8 chars) RS = 0; // LCD in command-mode lcd_putchar( 0b11000000 ); RS = 1; // LCD in character-mode lcd_putchar(' '); */ } void check_btn (void) { if (MODE == 0) // Button pressed { display_mode = display_mode+1; // Step up display mode if (display_mode==2) { display_mode = 0; lcd_command (0b0000.0000); // Clear LCD RS = 1; } } if (SET == 0) // Button pressed { set_mode = 1; // Step up display mode if (set_mode==1) { set_clock (); } } } /* ________________________ SET CLOCK start ________________________ */ void set_clock (void) // Setting clock sequence { start_mode = 0; TMR1IE = 0; // Disable TMR1 interrupt TMR1IF = 0; GIE = 0; // Interrupts not allowed PEIE = 0; while (set_mode !=2) { lcd_command (0b1000.0000); // reposition to "line 1, position 0 blink_empty (2); lcd_command (0b1000.0000); // reposition to "line 1, position 0 blink_digits (hr_10, hr_1); if (INC ==0) { hr_1++; if(hr_1>9) { hr_1 = 0; hr_10++; } if(hr_10 >2) { hr_10 = 0; } if(hr_10 >=2 && hr_1>3) { hr_1 = 0; hr_10 = 0; } } if (SET == 0) { set_mode = 2; } } while (set_mode !=3) { lcd_command (0b1000.0011); // reposition to "line 1, position 3 blink_empty (2) ; lcd_command (0b1000.0011); // reposition to "line 1, position 3 blink_digits (min_10, min_1); if (INC ==0) { min_1++; if(min_1>9) { min_1 = 0; min_10++; } if(min_10>5) { min_10 = 0; } } if (SET == 0) { set_mode = 3; } } while (set_mode !=4) { lcd_command (0b1000.0110); // reposition to "line 1, position 6 blink_empty (2); lcd_command (0b1000.0110); // reposition to "line 1, position 6 blink_digits (sec_10, sec_1); if (INC ==0) { sec_1++; if(sec_1>9) { sec_1 = 0; sec_10++; } if(sec_10>5) { sec_10=0; } tick_pos = sec_10*10 + sec_1; } if (SET == 0) { set_mode = 4; } } while (set_mode !=5) { lcd_command (0b1000.1111); // reposition to "line 1, position 5 blink_empty (1); lcd_command (0b1000.1111); // reposition to "line 1, position 5 blink_digits (dst, dst); if (INC ==0) { dst++; if(dst>1) { dst = 0; } } if (SET == 0) { set_mode = 5; } } while (set_mode !=6) { lcd_command (0b1100.0010); // reposition to "line 2, position 2 blink_empty (2); lcd_command (0b1100.0010); // reposition to "line 2, position 2 blink_digits (year_10, year_1); if (INC ==0) { year_1++; if(year_1>9) { year_1 = 0; year_10++; } if(year_10>9) { year_10=0; } } if (SET == 0) { set_mode = 6; } } while (set_mode !=7) { lcd_command (0b1100.0101); // reposition to "line 2, position 5 blink_empty (2); lcd_command (0b1100.0101); // reposition to "line 2, position 5 blink_digits (month_10, month_1); if (INC ==0) { month_1++; if(month_1>9) { month_1 = 0; month_10++; } if(month_10==1 && month_1>2) { month_10 = 0; month_1 = 1; } } if (SET == 0) { set_mode = 7; } } while (set_mode !=8) { lcd_command (0b1100.1000); // reposition to "line 2, position 8 blink_empty (2); lcd_command (0b1100.1000); // reposition to "line 2, position 8 blink_digits (day_10, day_1); if (INC ==0) { day_1++; if(day_1>9) { day_1 = 0; day_10++; } if(day_10 >2 && day_1>1) { day_1 = 1; day_10 = 0; } } if (SET == 0) { set_mode = 8; } } while (set_mode !=0) { lcd_command (0b1100.1011); // reposition to "line 2, position 11 blink_empty (3) ; lcd_command (0b1100.1011); // reposition to "line 2, position 11 delay(1); //display_weekday (); delay10(20); //RS = 1; // LCD in character-mode if (INC ==0) { weekday++; if (weekday > 7) { weekday = 1; } } if (SET == 0) { set_mode=0; } //display_time(); } TMR1H = 0x80; // Reset counter TMR1L = 0x00; TMR1IE = 1; // Enable interrupt GIE = 1; // Interrupts llowed PEIE = 1; } void blink_empty (char digits) // Erases a number of LCD characters { //RS = 1; char i; for (i=0; i 9) { sec_1 = 0; sec_10++; } if (sec_10 > 5) { sec_10 = 0; min_1++; } update_minutes (); } void update_minutes (void) // Clock over minute > hour > day > month > year { if(min_1>9) { min_1 = 0; min_10++; } if(min_10>5) { min_10 = 0; hr_1++; } if(hr_1>9){ hr_1 = 0; hr_10++; } if(hr_10 >2){ hr_10 = 0; } if(hr_10 >=2 && hr_1>3){ hr_1 = 0; hr_10 = 0; day_1++; } if(day_1>9){ day_1 = 0; day_10++; } if(day_10 >=2 && day_1>1){ day_1 = 1; day_10 = 0; month_1++; } if(month_1>9) { month_1 = 0; month_10++; } if(month_10 >=1 && month_1>2) { month_1 = 1; month_10 = 0; year_1++; } if(year_1>9) { year_1 = 0; year_10++; } } void display_time ( void ) { RS = 0; lcd_putchar( 0b1000.0000); // reposition to "line 1, position 0 delay(1); RS = 1; // LCD in character-mode lcd_putchar(48+hr_10); // 48 = 0011.0000 delay(1); lcd_putchar(48+hr_1); delay(1); lcd_putchar(':'); delay(1); lcd_putchar(48+min_10); delay(1); lcd_putchar(48+min_1); delay(1); lcd_putchar(':'); delay(1); lcd_putchar(48+sec_10); delay(1); lcd_putchar(48+sec_1); delay(1); lcd_putchar(' '); delay(1); lcd_putchar(' '); delay(1); lcd_putchar(' '); delay(1); lcd_putchar('D'); lcd_putchar('S'); lcd_putchar('T'); lcd_putchar('='); lcd_putchar(48+dst); delay(1); RS = 0; // LCD in command-mode lcd_putchar( 0b11000000 ); // reposition to "line 2, position 0 delay(1); RS = 1; // LCD in character-mode lcd_putchar('2'); delay(1); lcd_putchar('0'); delay(1); lcd_putchar(48+year_10); // 48 = 0011.0000 delay(1); lcd_putchar(48+year_1); delay(1); lcd_putchar('-'); delay(1); lcd_putchar(48+month_10); delay(1); lcd_putchar(48+month_1); delay(1); lcd_putchar('-'); delay(1); lcd_putchar(48+day_10); delay(1); lcd_putchar(48+day_1); delay(1); lcd_putchar(' '); delay(1); display_weekday (); delay(1); } void display_weekday (void) { // ger problem RS = 0; // LCD in command-mode lcd_putchar (0b1100.1011); // reposition to "line 2, position 11 delay(1); RS = 1; // LCD in character-mode if (weekday == 1) { lcd_putchar('M'); lcd_putchar('o'); lcd_putchar('n'); } if (weekday == 2) { lcd_putchar('T'); lcd_putchar('i'); lcd_putchar('s'); } if (weekday == 3) { lcd_putchar('O'); lcd_putchar('n'); lcd_putchar('s'); } if (weekday == 4) { lcd_putchar('T'); lcd_putchar('o'); lcd_putchar('r'); } if (weekday == 5) { lcd_putchar('F'); lcd_putchar('r'); lcd_putchar('e'); } if (weekday == 6) { lcd_putchar('L'); lcd_putchar('o'); lcd_putchar('r'); } if (weekday == 7) { lcd_putchar('S'); lcd_putchar('o'); lcd_putchar('n'); } } /* ________________________ SET TRANSMIT BIT VALUES________________________ */ void set_bitvalue (void) // Set new bitvalues before a new minute { char i; min_1 = min_1 + 1; // Time to transmit = +1 minute update_minutes (); bit_value[0] = 0; bit_value[1] = 0; bit_value[2] = 1; bit_value[3] = 0; bit_value[4] = 0; bit_value[5] = 0; bit_value[6] = 0; bit_value[7] = 0; bit_value[8] = 0; bit_value[9] = 0; bit_value[10] = 0; bit_value[11] = 0; bit_value[12] = 0; bit_value[13] = 0; bit_value[14] = 0; bit_value[15] = 0; // 0 = primary antenna in use bit_value[16] = 0; // 0 = No DST change in the next hour bit_value[17] = dst; // DST on/off bit_value[18] = 1; // Timezone, usually opposite of bit 17 bit_value[19] = 0; // Leap second insertion (not used in simulator) bit_value[20] = 1; // Always 1 bit_value[21] = min_1.0; // Minutes BCD, least significant first bit_value[22] = min_1.1; bit_value[23] = min_1.2; bit_value[24] = min_1.3; bit_value[25] = min_10.0; bit_value[26] = min_10.1; bit_value[27] = min_10.2; no_of_ones = 0; for (i=21; i<28; i++) { no_of_ones = no_of_ones+bit_value[i]; } bit_value[28] = no_of_ones%2; // Even parity bit, minute bits bit_value[29] = hr_1.0; // Hours BCD, least significant first bit_value[30] = hr_1.1; bit_value[31] = hr_1.2; bit_value[32] = hr_1.3; bit_value[33] = hr_10.0; bit_value[34] = hr_10.1; no_of_ones = 0; for (i=29; i<35; i++) // Calculate number of "ones" { no_of_ones = no_of_ones + bit_value[i]; } bit_value[35] = no_of_ones%2; // Even parity bit, hour bits bit_value[36] = day_1.0; // Day of month BCD, least significant first bit_value[37] = day_1.1; bit_value[38] = day_1.2; bit_value[39] = day_1.3; bit_value[40] = day_10.0; bit_value[41] = day_10.1; bit_value[42] = weekday.0; // Day of week BCD, least significant first, Mon=1 bit_value[43] = weekday.1; bit_value[44] = weekday.2; bit_value[45] = month_1.0; // Month BCD, least significant first bit_value[46] = month_1.1; bit_value[47] = month_1.2; bit_value[48] = month_1.3; bit_value[49] = month_10.0; bit_value[50] = year_1.0; // Year BCD, least significant first bit_value[51] = year_1.1; bit_value[52] = year_1.2; bit_value[53] = year_1.3; bit_value[54] = year_10.0; bit_value[55] = year_10.1; bit_value[56] = year_10.2; bit_value[57] = year_10.3; no_of_ones = 0; for (i=36; i<58; i++) // Calculate number of "ones" { no_of_ones = no_of_ones + bit_value[i]; } bit_value[58] = no_of_ones%2; // Even parity bit, all transmitted bits bit_value[59] = 9; // No transmission min_1 = min_1 - 1; // Reset to real time if(min_1<0) { min_1 = 9; min_10--; } if(min_10 < 0) { min_10 = 9; hr_1--; } if(hr_1 < 0 ){ hr_1 = 9; hr_10--; } if(hr_10 <0){ hr_10 = 0; } // MORE FUNCTIONS required } /* ________________________ LCD TEXT STORAGE________________________ */ char text1( char x) // this is the way to store a sentence { skip(x); /* internal function CC5x. */ #pragma return[] = "DCF77 simulator " // 16-teckens rad } char text2( char x) // this is the way to store a sentence { skip(x); /* internal function CC5x. */ #pragma return[] = "Set clock, start" // 8 chars max! } /* ________________________ LCD INITIALIZE________________________ */ void lcd_init( void ) // must be run once before using the display { delay(40); // give LCD time to settle RS = 0; // LCD in command-mode lcd_putchar(0b0011.0011); /* LCD starts in 8 bit mode */ lcd_putchar(0b0011.0010); /* change to 4 bit mode */ lcd_putchar(0b0010.1000); /* two line (8+8 chars in the row) */ lcd_putchar(0b0000.1100); /* display on, cursor off, blink off */ lcd_putchar(0b0000.0001); /* display clear */ lcd_putchar(0b0000.0110); /* increment mode, shift off */ //lcd_putchar(0b0011.0011); /* LCD starts in 8 bit mode */ //lcd_putchar(0b0010.0011); /* change to 4 bit mode */ //lcd_putchar(0b00101100); /* two line (8+8 chars in the row) */ //lcd_putchar(0b00001100); /* display on, cursor off, blink off */ //lcd_putchar(0b00000001); /* display clear */ //lcd_putchar(0b00000110); /* increment mode, shift off */ RS = 1; // LCD in character-mode } /* ________________________ LCD PUT CHARACTER________________________ */ void lcd_putchar( char data ) { // Must set LCD-mode before calling this function // RS = 1 LCD in character-mode // RS = 0 LCD in command-mode D7 = data.7; // upper Nibble D6 = data.6; D5 = data.5; D4 = data.4; EN = 0; nop(); EN = 1; delay(5); D7 = data.3; // lower Nibble D6 = data.2; D5 = data.1; D4 = data.0; EN = 0; nop(); EN = 1; delay(5); } void lcd_command ( char cmd ) // Write command to LCD { RS = 0; lcd_putchar( cmd ); RS = 1; // Back to character mode delay(1); } /* ________________________ SPECIAL CHARACTERS________________________ */ void pixel_def(void) // Definition of special characters { RS = 0; // LCD in command-mode lcd_putchar(0b0100.0000); // Enter DDRAM RS = 1; lcd_putchar(0b000.11100); // Defines a short pulse character on address 0 lcd_putchar(0b000.10100); lcd_putchar(0b000.10100); lcd_putchar(0b000.10100); lcd_putchar(0b000.10100); lcd_putchar(0b000.10100); lcd_putchar(0b000.11111); lcd_putchar(0b000.00000); lcd_putchar(0b000.11110); // Defines a long pulse character on address 1 lcd_putchar(0b000.10010); lcd_putchar(0b000.10010); lcd_putchar(0b000.10010); lcd_putchar(0b000.10010); lcd_putchar(0b000.10010); lcd_putchar(0b000.11111); lcd_putchar(0b000.00000); } void show_digit(char digit) // Behövs denna? { if (digit==1) {lcd_putchar('1');} if (digit==2) {lcd_putchar('2');} if (digit==3) {lcd_putchar('3');} if (digit==4) {lcd_putchar('4');} if (digit==5) {lcd_putchar('5');} if (digit==6) {lcd_putchar('6');} if (digit==7) {lcd_putchar('7');} if (digit==8) {lcd_putchar('8');} if (digit==9) {lcd_putchar('9');} if (digit==0) {lcd_putchar('0');} } /* ____ DELAY CAUSING PROBLEMS SOMETIMES ____ */ void delay ( char millisec) /* Delays a multiple of 1 milliseconds at 4 MHz using the TMR0 timer */ { OPTION = 2; /* prescaler divide by 8 */ do { TMR0 = 0; while ( TMR0 < 125) /* 125 * 8 = 1000 */ ; } while ( -- millisec > 0); } /* void delay ( char millisec) { char k; for (k=0; k<255; k++) { nop(); } } */ void delay10 ( char n) /* Delays a multiple of 10 milliseconds using the TMR0 timer Clock : 4 MHz => period T = 0.25 microseconds 1 IS = 1 Instruction Cycle = 1 microsecond error: 0.16 percent */ { char i; OPTION = 7; do { i = TMR0 + 39; /* 256 microsec * 39 = 10 ms */ while ( i != TMR0) ; } while ( --n > 0); }