From 56d9bdd39ed36c36e9a61411b86c76d5228b2133 Mon Sep 17 00:00:00 2001 From: sicarius Date: Sun, 11 Feb 2007 18:32:03 +0000 Subject: Added lot's of code-files used during work --- source/ct-Bot/mcu/display.c | 272 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 source/ct-Bot/mcu/display.c (limited to 'source/ct-Bot/mcu/display.c') diff --git a/source/ct-Bot/mcu/display.c b/source/ct-Bot/mcu/display.c new file mode 100644 index 0000000..f94ce16 --- /dev/null +++ b/source/ct-Bot/mcu/display.c @@ -0,0 +1,272 @@ +/* + * c't-Bot + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your + * option) any later version. + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307, USA. + * + */ + +/*! @file display.c + * @brief Routinen zur Displaysteuerung + * @author Benjamin Benz (bbe@heise.de) + * @date 20.12.05 +*/ +#include "global.h" +#include "ct-Bot.h" + +#ifdef MCU +#ifdef DISPLAY_AVAILABLE + +#include +#ifdef NEW_AVR_LIB + #include +#else + #include +#endif +#include +#include +#include "command.h" + +#include "display.h" +#include "led.h" +#include "delay.h" +#include "shift.h" +#include "display.h" + +/*! Puffergroesse fuer eine Zeile in bytes */ +#define DISPLAY_BUFFER_SIZE (DISPLAY_LENGTH + 1) + +uint8 display_update=0; /*!< Muss das Display aktualisiert werden? */ +#ifdef DISPLAY_SCREENS_AVAILABLE + #ifdef LOG_DISPLAY_AVAILABLE + uint8 display_screen=4; /*!< Muss das Display aktualisiert werden? */ + #else + uint8 display_screen=0; /*!< Muss das Display aktualisiert werden? */ + #endif +#endif +static char display_buf[DISPLAY_BUFFER_SIZE]; /*!< Pufferstring fuer Displayausgaben */ + +#define DISPLAY_CLEAR 0x01 /*!< Kommando zum Löschen */ +#define DISPLAY_CURSORHOME 0x02 /*!< Kommando für den Cursor */ + +#define DISPLAY_OUT 0x07 /*!< Output-Pins Display */ +#define DISPLAY_IN (1<<5) /*!< Input-Pins Display */ + +#define DISPLAY_PORT PORTC /*!< Port an dem das Display hängt */ +#define DISPLAY_DDR DDRC /*!< Port an dem das Display hängt */ +#define DPC (DISPLAY_PORT & ~DISPLAY_OUT) /*!< Port des Displays */ +//#define DRC (DDRC & ~DISPLAY_PINS) + +//#define DISPLAY_READY_PINR PINC /*!< Port an dem das Ready-Flag des Display hängt */ +#define DISPLAY_READY_DDR DDRC /*!< Port an dem das Ready-Flag des Display hängt */ +#define DISPLAY_READY_PIN (1<<5) /*!< Pin an dem das Ready-Flag des Display hängt */ + +/*! RS-Leitung + * legt fest, ob die Daten an das Display in den Textpuffer (RS=1) kommen + * oder als Steuercode interpretiert werden (RS=0) + */ +#define DISPLAY_RS (1<<0) /*!< Pin an dem die RS-Leitung des Displays hängt */ + +/*! RW-Leitung + * legt fest, ob zum Display geschrieben wird (RW=0) + * oder davon gelesen wird (RW=1) + */ +#define DISPLAY_RW (1<<1) /*!< Pin an dem die RW-Leitung des Displays hängt */ + +/*! Enable Leitung + * schaltet das Interface ein (E=1). + * Nur wenn Enable auf High-Pegel liegt, läßt sich das Display ansprechen + */ +#define DISPLAY_EN (1<<2) /*!< Pin an dem die EN-Leitung des Displays hängt */ + +/* + * Im Moment der Low-High-Flanke von ENABLE liest das Dislplay + * die Werte von RS und R/W ein. Ist zu diesem Zeitpunkt R/W=0, + * dann liest das Display mit der folgenden High-Low-Flanke von ENABLE + * den Datenbus ein (Schreibzyklus). + * War aber R/W=1, dann legt das Display ein Datenword auf den + * Datenbus (Lese-Zyklus), solange bis die High-Low-Flanke von ENABLE + * das Interface wieder deaktiviert. + */ + +/*! + * Übertrage Kommando an das Display + * @param cmd Kommando + */ +void display_cmd(uint8 cmd){ //ein Kommando cmd an das Display senden + uint8 i; + shift_data_out(cmd,SHIFT_LATCH,SHIFT_REGISTER_DISPLAY); + // Enable muss für mind. 450 ns High bleiben, bevor es fallen darf! + // ==> Also mind. 8 Zyklen warten + for (i=0; i<150; i++){ + asm volatile("nop"); + } + DISPLAY_PORT=DPC; // Alles zurück setzen ==> Fallende Flanke von Enable +} + + +/*! + * Ein Zeichen auf das Display schreiben + * @param data Das Zeichen + */ +void display_data(char data){ //ein Zeichen aus data in den Displayspeicher schreiben + uint8 i; + shift_data_out(data,SHIFT_LATCH,SHIFT_REGISTER_DISPLAY|DISPLAY_RS); + + // Enable muss für mind. 450 ns High bleiben, bevor es fallen darf! + // ==> Also mind. 8 Zyklen warten + for (i=0; i<150; i++){ + asm volatile("nop"); + } + DISPLAY_PORT=DPC; // Alles zurück setzen ==> Fallende Flanke von Enable +} + +/*! + * Löscht das ganze Display + */ +void display_clear(void){ + display_cmd(DISPLAY_CLEAR); // Display loeschen, Cursor Home + #ifdef DISPLAY_REMOTE_AVAILABLE + command_write(CMD_AKT_LCD, SUB_LCD_CLEAR, NULL, NULL,0); + #endif +} + +/*! + * Positioniert den Cursor + * @param row Zeile + * @param column Spalte + */ +void display_cursor (uint8 row, uint8 column) { + switch (row) { + case 1: + display_cmd (0x80 + column - 1); + break; + case 2: + display_cmd (0xc0 + column - 1); + break; + case 3: + display_cmd (0x94 + column - 1); + break; + case 4: + display_cmd (0xd4 + column - 1); + break; + default: break; + } + + #ifdef DISPLAY_REMOTE_AVAILABLE + int16 r=row-1; + int16 c=column-1; + command_write(CMD_AKT_LCD, SUB_LCD_CURSOR, &c,&r,0); + #endif + +} + +/*! + * Init Display + */ +void display_init(void){ + shift_init(); + + DISPLAY_DDR |= DISPLAY_OUT; // Ausgänge + DISPLAY_DDR &= ~DISPLAY_IN; // Eingänge + + delay(12); // Display steht erst 10ms nach dem Booten bereit + + // Register in 8-Bit-Modus 3x Übertragen, dazwischen warten + shift_data_out(0x38,SHIFT_LATCH,SHIFT_REGISTER_DISPLAY); + DISPLAY_PORT= DPC; + delay(5); + shift_data_out(0x38,SHIFT_LATCH,SHIFT_REGISTER_DISPLAY); + DISPLAY_PORT= DPC; + delay(5); + shift_data_out(0x38,SHIFT_LATCH,SHIFT_REGISTER_DISPLAY); + DISPLAY_PORT= DPC; + delay(5); + + display_cmd(0x0f); //Display On, Cursor On, Cursor Blink + + display_cmd(DISPLAY_CLEAR); // Display loeschen, Cursor Home + + display_data('i'); +} + +/*! + * Zeigt einen String an + * @return -1 falls string zuende 0 falls Zeile (20 zeichen) zuende + */ +/*int display_string(char data[20]){ + int i=0; + + while ((i<20) && (data[i] != 0x00)){ // Abbruch, sobald ein Nullstring erreicht wird + // oder 20 Zeichen gesendet sind + display_data(data[i++]); // einzelnes Zeichen schicken + } + + // return -1 falls string zuende, 0 falls zeile (20 zeichen) zuende + if (data[i]==0x00) return -1; else return 0; +} +*/ + +/*! + * Schreibt einen String auf das Display. + * @param format Format, wie beim printf + * @param ... Variable Argumentenliste, wie beim printf + */ +void display_printf(char *format, ...) { + + unsigned int run = 0; + va_list args; + + /* Sicher gehen, das der zur Verfuegung stehende Puffer nicht + * ueberschrieben wird. + */ + va_start(args, format); + vsnprintf(display_buf, DISPLAY_BUFFER_SIZE, format, args); + va_end(args); + + /* Ausgeben bis Puffer leer ist */ + while(display_buf[run] != '\0') { + display_data(display_buf[run]); + run++; + } + + #ifdef DISPLAY_REMOTE_AVAILABLE + command_write_data(CMD_AKT_LCD, SUB_LCD_DATA, NULL, NULL, display_buf); + #endif + + return; +} + +/* +void display_test(){ + shift_init(); + +// shift_data_out(0xAA,SHIFT_LATCH,SHIFT_REGISTER_DISPLAY); + + display_cmd(0x38); //Display auf 8 Bit Betrieb + for(;;){} + display_cmd(0x0f); //Display On, Cursor On, Cursor Blink + + display_cmd(DISPLAY_CLEAR); // Display l�schen, Cursor Home + display_cursor(2,2); + + display_string("Hallo"); + for(;;){ + } +} +*/ + +#endif + +#endif -- cgit v1.2.3