diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..5618215 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,13 @@ +Author: Pascal Gollor +web: http://www.pgollor.de + +Dieses Werk ist unter einer Creative Commons Lizenz vom Typ +Namensnennung - Nicht-kommerziell - Weitergabe unter gleichen Bedingungen 3.0 Deutschland zugänglich. +Um eine Kopie dieser Lizenz einzusehen, konsultieren Sie +http://creativecommons.org/licenses/by-nc-sa/3.0/de/ oder wenden Sie sich +brieflich an Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + + +----- WICHTIG!!! ----- +Ich uebernehme keinerlei Haftung fuer Schaeden die durch die Nutzung dieser Software enstehen. +----- WICHTIG!!! ----- diff --git a/adc.c b/adc.c new file mode 100644 index 0000000..e8b101b --- /dev/null +++ b/adc.c @@ -0,0 +1,78 @@ +/** + * @file adc.c + * + * @date 18.03.2013 + * @author Pascal Gollor + * web http://www.pgollor.de + * + * @copyright Dieses Werk ist unter einer Creative Commons Lizenz vom Typ + * Namensnennung - Nicht-kommerziell - Weitergabe unter gleichen Bedingungen 3.0 Deutschland zugänglich. + * Um eine Kopie dieser Lizenz einzusehen, konsultieren Sie + * http://creativecommons.org/licenses/by-nc-sa/3.0/de/ oder wenden Sie sich + * brieflich an Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + * + * -- englisch version -- + * @n This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Germany License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + * + */ + + +#include "adc.h" + +/** + * @brief ADC initialisieren + * + * Initialisieren fuer 16MHz + * 16MHz / 128 = 125kHz + * Der ADC sollte immer im Bereich von 50 - 200kHz arbeiten. + */ +void adc_init(void) +{ + uint16_t result; + + // Aref als Referenzspannung beim Atmega16/32 + ADMUX &= ~((1< + + +void adc_init(void); +uint16_t adc_read(uint8_t kanal); +uint16_t adc_read_avg(uint8_t kanal, uint8_t messungen); + + +#endif // _ADC_H_ diff --git a/fifo.c b/fifo.c new file mode 100644 index 0000000..f128892 --- /dev/null +++ b/fifo.c @@ -0,0 +1,37 @@ +/* + * fifo.c + * + * Created on: 01.12.2012 + * Author: mikrocontroller.net + * web: http://www.mikrocontroller.net + * sub Author: Pascal Gollor (www.pgollor.de) + */ + + +#include "fifo.h" + +void fifo_init (fifo_t *f, uint8_t *buffer, const uint8_t size) +{ + f->count = 0; + f->pread = f->pwrite = buffer; + f->read2end = f->write2end = f->size = size; +} + +uint8_t fifo_put (fifo_t *f, const uint8_t data) +{ + return _inline_fifo_put (f, data); +} + +uint8_t fifo_get_wait (fifo_t *f) +{ + while (!f->count); + + return _inline_fifo_get (f); +} + +int fifo_get_nowait (fifo_t *f) +{ + if (!f->count) return -1; + + return (int) _inline_fifo_get (f); +} diff --git a/fifo.h b/fifo.h new file mode 100644 index 0000000..11fcb30 --- /dev/null +++ b/fifo.h @@ -0,0 +1,84 @@ +/* + * fifo.h + * + * Created on: 01.12.2012 + * Author: mikrocontroller.net + * web: http://www.mikrocontroller.net + * sub Author: Pascal Gollor (www.pgollor.de) + */ + + +#ifndef FIFO_H +#define FIFO_H + +#include +#include + +typedef struct +{ + uint8_t volatile count; // # Zeichen im Puffer + uint8_t size; // Puffer-Größe + uint8_t *pread; // Lesezeiger + uint8_t *pwrite; // Schreibzeiger + uint8_t read2end, write2end; // # Zeichen bis zum Überlauf Lese-/Schreibzeiger +} fifo_t; + +extern void fifo_init (fifo_t*, uint8_t* buf, const uint8_t size); +extern uint8_t fifo_put (fifo_t*, const uint8_t data); +extern uint8_t fifo_get_wait (fifo_t*); +extern int fifo_get_nowait (fifo_t*); + +static inline uint8_t +_inline_fifo_put (fifo_t *f, const uint8_t data) +{ + if (f->count >= f->size) + return 0; + + uint8_t * pwrite = f->pwrite; + + *(pwrite++) = data; + + uint8_t write2end = f->write2end; + + if (--write2end == 0) + { + write2end = f->size; + pwrite -= write2end; + } + + f->write2end = write2end; + f->pwrite = pwrite; + + uint8_t sreg = SREG; + cli(); + f->count++; + SREG = sreg; + + return 1; +} + +static inline uint8_t +_inline_fifo_get (fifo_t *f) +{ + uint8_t *pread = f->pread; + uint8_t data = *(pread++); + uint8_t read2end = f->read2end; + + if (--read2end == 0) + { + read2end = f->size; + pread -= read2end; + } + + f->pread = pread; + f->read2end = read2end; + + uint8_t sreg = SREG; + cli(); + f->count--; + SREG = sreg; + + return data; +} + +#endif /* FIFO_H */ diff --git a/main.c b/main.c new file mode 100644 index 0000000..630e187 --- /dev/null +++ b/main.c @@ -0,0 +1,46 @@ +/* + * main.c + * + * Created on: 25.01.2013 + * Author: kalle + */ + +#include +#include // sei +#include // delay_ms + +#include "uart.h" // uart (RS232) +#include "adc.h" +#include "matrix.h" + + +#define CR "\r\n" + +#define BAUDRATE 9600 + + +int main() +{ + adc_init(); + + // initialisiere uart + usart_init(BAUDRATE); + sei(); + + _delay_ms(100); + printf("-- start --" CR CR); + _delay_ms(100); + + + + while (1) + { + uint8_t taste = matrix_getKey(); + + // Taste ausgeben + printf("Taste: %c" CR, taste); + uart_flush(); + } + + return 0; +} diff --git a/matrix.c b/matrix.c new file mode 100644 index 0000000..4efa251 --- /dev/null +++ b/matrix.c @@ -0,0 +1,109 @@ +/** + * @file matrix.c + * + * @date 04.03.2013 + * @author Pascal Gollor + * web http://www.pgollor.de + * + * @copyright Dieses Werk ist unter einer Creative Commons Lizenz vom Typ + * Namensnennung - Nicht-kommerziell - Weitergabe unter gleichen Bedingungen 3.0 Deutschland zugänglich. + * Um eine Kopie dieser Lizenz einzusehen, konsultieren Sie + * http://creativecommons.org/licenses/by-nc-sa/3.0/de/ oder wenden Sie sich + * brieflich an Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + * + * -- englisch version -- + * @n This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Germany License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + * + */ + +#include "matrix.h" +#include "adc.h" + +#include // delay_ms + + +/** + * @brief gedrueckte Taste + * @return Taste + * + * ADC 4x4 Matrix + * + * @n Pin: U/mV + * @n 1: 1019 + * @n 2: 509 + * @n 3: 339 + * @n 4: 817 + * @n 5: 453 + * @n 6: 313 + * @n 7: 683 + * @n 8: 408 + * @n 9: 291 + * @n 0: 371 + * @n A: 254 + * @n B: 239 + * @n C: 226 + * @n D: 214 + * @n *: 586 + * @n #: 271 + */ +uint8_t matrix_getKey(void) +{ + uint8_t taste = 'x'; + + uint16_t adc = adc_read_avg(MATRIX_PIN, 3); + if (adc > 200) + { + // Zeit zum Entprellen + _delay_ms(10); + + // Anschliessend Wert zum verwerten einlesen + uint16_t wert = adc_read_avg(MATRIX_PIN, 3); + + // wenn der Wert < 200 ist, dann wurde eine Taste zu kurz gedrueckt + if (wert < 200) + return 'x'; + + // solange warten bis die Taste wieder losgelassen wurde + while (adc != 0) + { + adc = adc_read_avg(MATRIX_PIN, 3); + } + + // Taste auf der 4x4 Matrix + if (wert > 998) + taste = '1'; + else if (wert > 800) + taste = '4'; + else if (wert > 668) + taste = '7'; + else if (wert > 573) + taste = '*'; + else if (wert > 498) + taste = '2'; + else if (wert > 443) + taste = '5'; + else if (wert > 399) + taste = '8'; + else if (wert > 363) + taste = '0'; + else if (wert > 331) + taste = '3'; + else if (wert > 306) + taste = '6'; + else if (wert > 284) + taste = '9'; + else if (wert > 265) + taste = '#'; + else if (wert > 248) + taste = 'A'; + else if (wert > 233) + taste = 'B'; + else if (wert > 220) + taste = 'C'; + else if (wert > 209) + taste = 'D'; + } + + // Taste ausgeben + return taste; +} diff --git a/matrix.h b/matrix.h new file mode 100644 index 0000000..13bb3eb --- /dev/null +++ b/matrix.h @@ -0,0 +1,32 @@ +/** + * @file matrix.h + * + * @date 04.03.2013 + * @author Pascal Gollor + * web http://www.pgollor.de + * + * @copyright Dieses Werk ist unter einer Creative Commons Lizenz vom Typ + * Namensnennung - Nicht-kommerziell - Weitergabe unter gleichen Bedingungen 3.0 Deutschland zugänglich. + * Um eine Kopie dieser Lizenz einzusehen, konsultieren Sie + * http://creativecommons.org/licenses/by-nc-sa/3.0/de/ oder wenden Sie sich + * brieflich an Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + * + * -- englisch version -- + * @n This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Germany License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. + * + */ + +#ifndef MATRIX_H_ +#define MATRIX_H_ + +#include + +/** + * @brief ADC an dem die MAtrix angeschlossen ist (0-7) + */ +#define MATRIX_PIN 0 + +uint8_t matrix_getKey(void); + + +#endif /* MATRIX_H_ */ diff --git a/uart.c b/uart.c new file mode 100644 index 0000000..42f68a2 --- /dev/null +++ b/uart.c @@ -0,0 +1,207 @@ +/* + * uart.c + * + * Created on: 01.12.2012 + * Author: mikrocontroller.net + * web: http://www.mikrocontroller.net + * sub Author: Pascal Gollor (www.pgollor.de) + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include "uart.h" +#include "fifo.h" // erklärt im Artikel "FIFO mit avr-gcc" + + +// FIFO-Objekte und Puffer für die Ein- und Ausgabe + +#define BUFSIZE_IN 0x0F +uint8_t inbuf[BUFSIZE_IN]; +fifo_t infifo; + +#define BUFSIZE_OUT 0xFF +uint8_t outbuf[BUFSIZE_OUT]; +fifo_t outfifo; + + +void uart_init (unsigned long baudrate) +{ + uint8_t sreg = SREG; + uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16UL*baudrate) - 1); + + UBRRH = (uint8_t) (ubrr>>8); + UBRRL = (uint8_t) (ubrr); + + // Interrupts kurz deaktivieren + cli(); + + // UART Receiver und Transmitter anschalten, Receive-Interrupt aktivieren + // Data mode 8N1, asynchron + UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE); + UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0); + + // Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte) + do + { + // UDR auslesen (Wert wird nicht verwendet) + UDR; + } + while (UCSRA & (1 << RXC)); + + // Rücksetzen von Receive und Transmit Complete-Flags + UCSRA = (1 << RXC) | (1 << TXC); + + // Global Interrupt-Flag wieder herstellen + SREG = sreg; + + // FIFOs für Ein- und Ausgabe initialisieren + fifo_init (&infifo, inbuf, BUFSIZE_IN); + fifo_init (&outfifo, outbuf, BUFSIZE_OUT); +} + +// Empfangene Zeichen werden in die Eingangs-FIFO gespeichert und warten dort +ISR (USART_RXC_vect) +{ + _inline_fifo_put (&infifo, UDR); +} + +// Ein Zeichen aus der Ausgabe-FIFO lesen und ausgeben +// Ist das Zeichen fertig ausgegeben, wird ein neuer SIG_UART_DATA-IRQ getriggert +// Ist die FIFO leer, deaktiviert die ISR ihren eigenen IRQ. +ISR (USART_UDRE_vect) +{ + if (outfifo.count > 0) + UDR = _inline_fifo_get (&outfifo); + else + UCSRB &= ~(1 << UDRIE); +} + +int uart_putc (const uint8_t c) +{ + int ret = fifo_put (&outfifo, c); + + UCSRB |= (1 << UDRIE); + + return ret; +} + +void uart_puts (const char *s) +{ + do + { + uart_putc (*s); + } + while (*s++); +} + +int uart_getc_nowait (void) +{ + return fifo_get_nowait (&infifo); +} + +uint8_t uart_getc_wait (void) +{ + return fifo_get_wait (&infifo); +} + + + + +//------------------------------------------------------------------------------ +void usart_write_P (const char *Buffer,...) +{ + va_list ap; + va_start (ap, Buffer); + + int format_flag; + char str_buffer[10]; + char str_null_buffer[10]; + char move = 0; + char Base = 0; + int tmp = 0; + //char by; + uint8_t by; + char *ptr; + + //Ausgabe der Zeichen + for(;;) + { + by = pgm_read_byte(Buffer++); + if(by==0) break; // end of format string + + if (by == '%') + { + by = pgm_read_byte(Buffer++); + if (isdigit(by)>0) + { + str_null_buffer[0] = by; + str_null_buffer[1] = '\0'; + move = atoi(str_null_buffer); + by = pgm_read_byte(Buffer++); + } + + switch (by) + { + case '%': + usart_write_char('%'); + break; + case 's': + ptr = va_arg(ap,char *); + while(*ptr) { usart_write_char(*ptr++); } + break; + case 'b': + Base = 2; + goto ConversionLoop; + case 'c': + //Int to char + format_flag = va_arg(ap,int); + usart_write_char (format_flag++); + break; + case 'i': + Base = 10; + goto ConversionLoop; + case 'o': + Base = 8; + goto ConversionLoop; + case 'x': + Base = 16; + //**************************** + ConversionLoop: + //**************************** + itoa(va_arg(ap,int),str_buffer,Base); + int b=0; + while (str_buffer[b++] != 0){}; + b--; + if (b +#include +#include + +extern void uart_init (unsigned long); +extern int uart_putc (const uint8_t); +void uart_puts (const char *s); +extern uint8_t uart_getc_wait (void); +extern int uart_getc_nowait (void); + +void usart_write_P (const char *Buffer,...); + +#define usart_init(baudrate) uart_init(baudrate); +#define usart_write_char(c) uart_putc(c); +#define usart_write_str(c) uart_puts(c); +#define usart_write(format, args...) usart_write_P(PSTR(format) , ## args); +#define printf(format, args...) usart_write_P(PSTR(format), ## args); + +static inline void uart_flush (void) +{ + while (UCSRB & (1 << UDRIE)); +} + + +#endif /* UART_H_ */