/***********************************************************************/ /* */ /* FILE :BikeTemp_v6_abgespeckt.c */ /* DATE :Sat, Mar 03, 2011 */ /* DESCRIPTION :Main Program */ /* CPU GROUP :Other */ /* */ /* This file is generated by Renesas Project Generator (Ver.4.17). */ /* Temp.Messung mit MAX6675 */ /* */ /***********************************************************************/ #include "sfr_r813.h" // SpecialFunctionRegister des R8C/13 #pragma interrupt Timer_C_int; // Timer C Interrupt enabled #define uint unsigned int // Abkürzungen #define uchar unsigned char /* SI von LCD auf P1.1 (R8C13 Pin 14) */ /* CLK von LCD auf P1.2 (R8C13 Pin 13) */ /* RS von LCD auf P1.3 (R8C13 Pin 12) */ /* SO von MAX6675 auf P3.0 (R8C13 Pin 22) */ /* SCK von MAX6675 auf P3.1 (R8C13 Pin 20) */ /* CS von MAX6675 auf P3.2 (R8C13 Pin 18) */ /* SO von MAX6675 auf P3.0 (R8C13 Pin 22) */ /* SCK von MAX6675 auf P3.1 (R8C13 Pin 20) */ /* CS von MAX6675 auf P3.3 (R8C13 Pin 17) */ // Aliase für Port-Bits definieren für bessere Lesbarkeit #define SI p1_addr.bit.b1 // Ausgangsport für die Datenleitung zum LCD ist Bit 1 von Port 1 #define CLK p1_addr.bit.b2 // Ausgangsport für die Taktleitung zum LCD ist Bit 2 von Port 1 #define RS p1_addr.bit.b3 // Ausgangsport für die Statusleitung zum LCD ist Bit 3 von Port 1 // globale Variable unsigned int TempP32; // Zwischenspeicher für Overtemp. Alarm P3.2 unsigned int TempP33; // Zwischenspeicher für Overtemp. Alarm P3.3 unsigned int zaehler1 = 5; long AlarmLedBlinkfrequenz = 0; // Zähler für Blinkfrequenz long LcdAnzeigeDelay = 0; // Zähler für Anzeigeverzögerung gegen LCD flimmern long z; // Wert für Waitschleifen µs und ms // Deklaration Funktionen void send_byte_to_lcd(char byte); // ein Byte zum LCD senden void int_lcd162(void); // LCD initialisieren void display_chars_on_lcd(char* characters, int size); // Mit 'size' anzugebende Anzahl alphanumerischer Zeichen auf LCD ausgeben void display_digits_on_lcd(char digit); // einstellige Ganzzahl ausgeben void display_2digits_on_lcd(char digit); // zweistellige Ganzzahl ausgeben void set_lcd_cursor_pos(char column, char row); // Cursorpsotion auf LCD setzen void display_time_and_date_on_lcd(void); // Zeit und Datum auf LCD ausgeben void lcd_integer (uint data); // Ausgabe von Integerwerten 0 ... 9999 an LCD void lcd_MAX6675 (uint t); // Messwertausgabe vom MAX6675 auf LCD void lcd_MAX6675_full (uint data); // Messwertausgabe vom MAX6675 auf LCD mit voller Auflösung void MAX6675_P32_on_LCD (uint t); // erster MAX6675 void MAX6675_P33_on_LCD (uint t); // zweiter MAX6675 unsigned int read_MAX6675_P32 (void); // erster MAX6675 mit CS an P3.2 unsigned int read_MAX6675_P33 (void); // zweiter MAX6675 mit CS an P3.3 void Alarm_LED (void); // Alarm LED blinkt bei Overtemp. void LCD_Delay (void); // LCD Anzeigeverzögerung gegen flimmern // void MAX6675_P32_on_LCD (uint t1, uint t2); // Prototypen // Funktionen für Zeit void delayus (uint micros); // warte Microsekunden void wait_us(long y); // warte Microsekunden void wait_ms(long y); // warte Millisekunden void OSC_Ext_20Mhz(void); // externer Oszillator mit 20 MHz void Init_Timer_C(void); // Initialisierung von Timer C // Funktionen für LCD void lcd_data(uchar data); // Daten an LCD void lcd_ctrl(uchar data); // Control an LCD void lcd_init(void); // Initialisiert LCD void lcd_pos(uint Zeile, uint Spalte); // positioniert Zeile 1...2 und Spalte 1...20 auf LCD void lcd_integer (uint data); // Ausgabe von Integer 0000 ... 9999 auf LCD void lcd_text (char text[20]); // Ausgabe von Text auf LCD void lcd_print(char *s); // Ausgabe von Text auf LCD // Funktionen für COM void com1_init(void); // initialisiert UART0 = COM mit 9600 Baud 8N1 void com1_txd(uchar data); // sendet an Txd0 UART0 = COM ein Byte void com1_print(char *daten); // sendet string an COM void com1_integer (uint data); // Ausgabe von Integer 0 ... 9999 an COM void com1_integer2 (long data); // Ausgabe von Integer 0 ... 999999 an COM uchar com0_rxd(void); // empfaengt von Rxd0 ein Byte // Werte umrechnen in String buff int ltoa_format(char *erg, long zahl, uint vk, uint nk, char vorz ); // Long in Zeichenkette umwandeln //************************************* Funktionen für Zeit ************************* //************************************* Wartezeit in Microsekunden void delayus (uint micros) { unsigned int i; for (i = 0; i < micros; i++) { asm("nop"); } } //************************************* Wartezeit in Microsekunden void wait_us(long y) // warte micro-sec { y = y * 2; for( z=0; z Register freigeben cm13 = 1; // Xin Xout pin -> Port auf Quarz umschalten cm15 = 1; // XCIN-XCOUT drive capacity select HIGH -> Hohe Treiberleistung cm05 = 0; // Main Clock (Xin-Xout) stop bit ON -> Externen Takt einschalten cm16 = 0; // Main clock = No division mode -> Maximaler Quarztakt, also 20MHz cm17 = 0; // cm16+17 CPU clock division cm06 = 0; // CM16 and CM17 enable -> Vorteiler einschalten asm("nop"); // Waiting for stable of oscillation -> Wartezeit bis Takt stabil asm("nop"); asm("nop"); asm("nop"); ocd2 = 0; // Select main clock -> Systemclock auswaehlen prc0 = 0; // Protect on -> Register schuetzen } // Und jetzt laeuft alles mit 20MHz //****** Initialisierung von Timer C ****** \\ void Init_Timer_C(void) { //prcr = 0x01; // cm0, cm1, ocd write enable //cm0 = 0x08; // initialize //cm1 = 0x78; // initialize //ocd = 0x00; // initialize //prcr = 0x00; // cm0, cm1, ocd write disable tcc0 = 0x04; // count stop, source f32, Rising edge, INT3 tcc1 = 0x00; // 0x00, no filter, TC register reset, output compare mode: comp0=High, comp1=Low tcout = 0x00; // alle CMPs abgeschalten tcic = 0x05; // Interrupt Priorität 5 //tcc00 = 1; // Bit0 = 1, Counter Start } //************************************* Funktionen für COM ************************* //************************************* initialisiert UART1 = COM mit 9600 Baud 8N1 void com1_init(void) { u1brg = 130-1; // 9600 UART1 auf 9600 Baud bei 20MHz u1mr = 0x05; // 0000.0101 UART1: 8bit; int. CLK; 1 Stop Bit; No parity; No Sleep // || | |^^^ 8 Bit // || | ^ Interne Clock // || ^ 1 Stop Bit // |^ Parität ausgeschaltet // ^ Sleep Mode deaktiviert u1c0 = 0x00; // 0000.0000 UART1: f1 as CLK; CTS, RTS disabled // |||| ^^ f1 is selected as clock // ^ write 0 u1c1 = 0x05; // 0000.0101 UART1: Rx, TX enabled, 00000101 // | ^ Tx enabled // ^ Rx enabled txd1sel=1; ucon = 0x20; // P00=RXD11, 00100100, 00100000 } //************************************* sendet an Txd1 UART1 = COM ein Byte void com1_txd(uchar data) { while (ti_u1c1 == 0); // Wait for transmission buffer emty u1tb = data; // Set transmission data te_u1c1 = 1; // Transmission enabled } //************************************* sendet string an COM void com1_print(char *daten) { while( *daten) { com1_txd(*daten++); } } // ----------------------------------------------------------------------------------------------------- // Der MAX6675 wird ausgelesen und der 12-Bit-Wert zurückgegeben ******** // P3 = x x x x x CS SCK SO // max_reg=0 b11 b10 b9 b8 b7 b6 b5 / b4 b3 b2 b1 b0 tco 0 0 unsigned int read_MAX6675_P32 (void) { int i; unsigned int data; data=0; p3_2=0; // CS=Low Port 3.2 for(i=0;i<16;i++) { wait_us(100); // warte 100us p3_1=1; // SCK=High wait_us(100); // warte 100us data=((data<<1)|p3_0); // schiebe nach links und lies SO p3_1=0; // SCK=Low } wait_us(100); p3_2=1; // CS=High wait_us(100); // warte 100us return (data>>3); // gib 12-Bit Wert zurück } // ----------------------------------------------------------------------------------------------------- // Der MAX6675 wird ausgelesen und der 12-Bit-Wert zurückgegeben ******** // P3 = x x x x x CS SCK SO // max_reg=0 b11 b10 b9 b8 b7 b6 b5 / b4 b3 b2 b1 b0 tco 0 0 unsigned int read_MAX6675_P33 (void) { int i; unsigned int data; data=0; p3_3=0; // CS=Low Port 3.3 for(i=0;i<16;i++) { wait_us(100); // warte 100us p3_1=1; // SCK=High wait_us(100); // warte 100us data=((data<<1)|p3_0); // schiebe nach links und lies SO p3_1=0; // SCK=Low } wait_us(100); p3_3=1; // CS=High wait_us(100); // warte 100us return (data>>3); // gib 12-Bit Wert zurück } // ********************************* Ausgabe an LCD ****************************** \\ void lcd_MAX6675 (uint data) { uchar byt; uint wert; wert = data; // Variablensicherung für Nullstellenunterdrückung if ( data >= 10000 ) {data = 9999; } byt = data / 1000; data = data - byt * 1000; if(wert<1000) // wenn Tausenderstelle = 0 display_chars_on_lcd(" ", 1); // dann wird ein Leerzeichen ausgegeben else display_digits_on_lcd(byt + 48); // Tausender Stelle byt = data / 100; data = data - byt * 100; if(wert<100) // wenn Hunderter = 0 display_chars_on_lcd(" ", 1); // dann wird ein Leerzeichen ausgegeben else display_digits_on_lcd(byt + 48); // Hunderter Stelle byt = data / 10; data = data - byt * 10; if(wert<10) // wenn Zehnerstelle = 0 display_chars_on_lcd(" ", 1); // dann wird ein Leerzeichen ausgegeben else display_digits_on_lcd(byt + 48); // Zehner Stelle display_digits_on_lcd(data + 48); // Einer Stelle send_byte_to_lcd(0xDF); // Zeichen ° an LCD display_chars_on_lcd("C", 1); // Zeichen C an LCD } //******************************* Ausgabe von Integer 0000 ... 9999 an LCD void lcd_integer (uint data) { uchar byt; uint wert; wert = data; // Variablensicherung für Nullstellenunterdrückung if ( data >= 10000 ) {data = 9999; } byt = data / 1000; data = data - byt * 1000; if(wert<1000) // wenn Tausender = 0 display_chars_on_lcd(" ", 1); // dann wird ein Leerzeichen ausgegeben else display_digits_on_lcd(byt + 48); // Tausender Stelle byt = data / 100; data = data - byt * 100; if(wert<100) // wenn Hunderter = 0 display_chars_on_lcd(" ", 1); // dann wird ein Leerzeichen ausgegeben else display_digits_on_lcd(byt + 48); // Hunderter Stelle byt = data / 10; data = data - byt * 10; if(wert<10) // wenn Zehner = 0 display_chars_on_lcd(" ", 1); // dann wird ein Leerzeichen ausgegeben else display_digits_on_lcd(byt + 48); // Zehner Stelle display_digits_on_lcd(data + 48); // Einer Stelle } //******************************* Ausgabe von Integer 0000 ... 9999 an COM void com1_integer (uint data) { uchar byt; if ( data >= 10000 ) {data = 9999; } byt = data / 1000; data = data - byt * 1000; com1_txd(byt + 48); byt = data / 100; data = data - byt * 100; com1_txd(byt + 48); byt = data / 10; data = data - byt * 10; com1_txd(byt + 48); com1_txd(data + 48); // com1_txd(0x0d); // "CR" Zeilemumbruch } //************************************* Ausgabe von Delayzeitergebnis an COM void com1_integer2 (long data) { long byt; if ( data >= 1000000 ) {data = 999999; } byt = data / 100000; data = data - byt * 100000; com1_txd(byt + 48); byt = data / 10000; data = data - byt * 10000; com1_txd(byt + 48); byt = data / 1000; data = data - byt * 1000; com1_txd(byt + 48); byt = data / 100; data = data - byt * 100; com1_txd(byt + 48); byt = data / 10; data = data - byt * 10; com1_txd(byt + 48); com1_txd(data + 48); } // ********** Temperaturalarm mit LED Anzeige **************************** \\ void Alarm_LED (void) { AlarmLedBlinkfrequenz++; if (AlarmLedBlinkfrequenz > 1) // 50.000 ca. 3,8Hz bei alleiniger Funktion { p1_0 ^= 1; // XOR, Port 1.0 schaltet immer um AlarmLedBlinkfrequenz = 0; } } //---------------------------------------------------------------------------------------------------------------------- // 8 Bits eines Bytes hintereinander an das LCD senden (SPI) void send_byte_to_lcd(char byte) { int i; for (i = 0; i < 8; i++) // Schleife für alle 8 Bits des übergebenen Bytes { CLK = 0; // Taktleitung auf LOW setzen SI = ((byte&128) != 0); // most significant bit (also das 8. Bit = 0b10000000 = 128) gesetzt? Wenn ja SI = 1, sonst SI = 0 byte <<= 1; // Alle 8 Bits des Bytes um eine Stelle nach links schieben. Most significant bit ist jetzt also das vormals 7. Bit CLK = 1; // Taktleitung auf HIGH setzen: Damit wird das gesendete Bit gültig wait_us(30); }; }; //---------------------------------------------------------------------------------------------------------------------- // LCD "EA DOGM162" nach Vorgaben im Datenblatt initialisieren void int_lcd162(void) { wait_ms(500); RS = 0; // RS = LOW: Es folgen Kommandos // siehe Datenblatt EA DOGM 162-A send_byte_to_lcd(0x39); // Function Set, 0 0 1 1 1 0 0 1 send_byte_to_lcd(0x1C); // Bias Set, 0 0 0 1 1 1 0 0 send_byte_to_lcd(0x52); // Power Control, 0 1 0 1 0 0 1 0 send_byte_to_lcd(0x69); // Follower Control, 0 1 1 0 1 0 0 1 send_byte_to_lcd(0x74); // Contrast Set, 0 1 1 1 0 1 0 0 send_byte_to_lcd(0x38); // zurück Instruction Table 0 send_byte_to_lcd(0x0C); // Display ein, Cursor aus, ohne Cursor blinken //send_byte_to_lcd(0x0F); // Display ein, Cursor ein, Cursor blinken send_byte_to_lcd(0x01); // Clear Display wait_ms(1); send_byte_to_lcd(0x06); // Cursor Auto Increment }; //---------------------------------------------------------------------------------------------------------------------- // Alphanumerische Zeichen auf LCD ausgeben, Anzahl der Zeichen = 'size' // char* ist ein Zeiger auf das erste Element des Buchstaben-Feldes 'characters' // Der integrierte LCD-Kontroller ST7036 rückt den Cursor automatisch nach Empfang eines Bytes um eine Stelle weiter void display_chars_on_lcd(char* characters, int size) { int i; RS = 1; // RS = HIGH: Es folgen Daten for (i = 0; i < size;i++) // Alle Buchstaben 0 bis size-1 des Feldes an LCD senden send_byte_to_lcd(characters[i]); }; //---------------------------------------------------------------------------------------------------------------------- // Einstellige Ganzzahl auf LCD ausgeben // Zahlen 0 - 9 sind in Zeichensatztabelle ab Stelle 48, deswegen wird 48 addiert void display_digits_on_lcd(char digit) { RS = 1; // RS = HIGH: Es folgen Daten send_byte_to_lcd(digit); }; //---------------------------------------------------------------------------------------------------------------------- // Zweistellige Ganzzahlen auf LCD ausgeben >>> für DCF77 UHR // Zahlen 0 - 9 sind in Zeichensatztabelle ab Stelle 48, deswegen wird 48 addiert void display_2digits_on_lcd(char digit) { RS = 1; // RS = HIGH: Es folgen Daten send_byte_to_lcd(digit / 10 + 48); // Zehnerstelle = Division durch 10 send_byte_to_lcd(digit % 10 + 48); // Einerstelle ('%' = Modulo, Rest einer Divsion durch 10) }; //---------------------------------------------------------------------------------------------------------------------- // Cursor auf bestimmte Spalte (0...15) und Reihe (0 oder 1) setzen // Der eingebaute LCD-Kontroller würde sonst erst beim Erreichen der 40. Spalte automatisch in die 2. Zeile springen void set_lcd_cursor_pos(char column, char row) { char addr; wait_ms(5); RS = 0; // RS = HIGH: Es folgen Kommandos addr = column + (row * 0x40); send_byte_to_lcd(addr | 0x80); wait_ms(5); }; // ----------------------------------------------------------------------------------------------------- // MAX6675 >>> vordere Bremsentemperatur, CS Signal an Port 3.2 void MAX6675_P32_on_LCD (uint t) { set_lcd_cursor_pos(1, 0); display_chars_on_lcd("P3.2", 4); set_lcd_cursor_pos(6, 0); lcd_MAX6675(t); //com1_print("P3.2 "); com1_integer(t); //com1_txd(0x20); // Leerzeichen } // ----------------------------------------------------------------------------------------------------- // MAX6675 >>> hintere Bremsentemperatur, CS Signal an Port 3.3 void MAX6675_P33_on_LCD (uint t) { set_lcd_cursor_pos(1, 1); display_chars_on_lcd("P3.3", 4); set_lcd_cursor_pos(6, 1); lcd_MAX6675(t); //com1_print("P3.3 "); com1_integer(t); //com1_txd(0x0d); // "CR" Zeilemumbruch } /* *** Timer C interrupt routine *** */ void Timer_C_int(void) { zaehler1++; } // ----------------------------------------------------------------------------------------------------- // *********************************************************************************** // *********************************************************************************** // ************************************ Hauptprogramm **************************** void main(void) { asm("FCLR I"); // Interrupt verhindern OSC_Ext_20Mhz(); // ext. Oszillator mit 20 MHz Init_Timer_C(); // Initialisierung von Timer C prc1 = 0; // Protection Port 1 ausschalten p0 = 0xfd; // Port 0 setzen prc2 = 1; // Protect 2 aus pd0 = 0b11110001; // P0.0 und P0.4 bis P0.7 Ausgang, // AN4 bis AN6 (P0.1 bis P0.3 AD / Kanal 4 bis 6 sind Eingänge // Protect 2 geht von selbst wieder an pd3 = 0b00001110; // Port 3, Bit 3, 2, 1 sind Ausgänge, Bit 0 ist Eingang p3 = 0b00001100; // P3.1 SCK=Low, P3.2 + P3.3 CS=High pd1 = 0b11001111; // Port Direction 1.0 bis 1.3 und 1.6 und 1.7 auf Ausgang setzen, LCD + Alarm LED p1 = 0x00; // Port 1 alles ausschalten p1 = 0x01; // Port 1.0, LED einschalten wait_ms(100); p1 = 0x00; // Port 1 alles ausschalten // pur1=2; // Pullup on 4.5 com1_init(); // COM 1 mit 9600 baud 8N1 initialisieren (Pin 10/11 bzw. P1.4/P1.5)) int_lcd162(); // EA DOGM162 LCD initialsieren asm("FSET I"); // Interrupt erlauben tcc00 = 1; // Bit0 = 1, Timer C Start while (1) // Loop \\ { TempP32 = (read_MAX6675_P32()+2)/4; // Temperaturwert vom ersten MAX6675 einlesen TempP33 = (read_MAX6675_P33()+2)/4; // Temperaturwert vom zweiten MAX6675 einlesen wait_ms(60); // nach auslesen vom MAX6675 mindestens 50ms warten if ((TempP32 > 30 || TempP33 > 30)) Alarm_LED(); else p1_0 = 0; // wenn P3.2 ODER P3.3 Overtemp Alarm, sonst LED aus if (zaehler1 >= 5) // LCD Anzeigen Refresh aller 524ms (5 * 104,86ms) { p1_6 = 1; p1_7 = 1; MAX6675_P32_on_LCD (TempP32); // MAX6675 mit CS auf Port 3.2 an LCD MAX6675_P33_on_LCD (TempP33); // MAX6675 mit CS auf Port 3.3 an LCD zaehler1 = 0; p1_6 = 0; p1_7 = 0; } com1_integer2(zaehler1); com1_txd(0x20); com1_integer2(tc); com1_txd(0x20); com1_integer2(TempP32); com1_txd(0x20); com1_integer2(TempP33); com1_txd(0x20); com1_txd(0x0d); } // while } // main