Commit cf2bf208 authored by Diedrich Wolter's avatar Diedrich Wolter
Browse files

irq ausgeschaltet

parent cabbedf7
......@@ -7,6 +7,41 @@
* PC7 : IR-LED TXD1
* PC6 : IR-Empfänger (invertiert), RXD1
* PD1 : Motor-Transistor OC0B
*
* Funktionsweise:
* ===============
*
* IR-Empfänger:
* -------------
* Mit dem IR-Empfänger wird der Empfang von Fernbedienungen im RC5-Format realisiert.
* Hinweis: Der Empfänger-Pin lässt sich als RxD1 der UART konfigurieren, um ein einfaches
* IR-Modem zu realisieren.
* Das Nutzsignal besteht aus 14 Bits, die seriell in Manchesterkodierung übertragen
* werden (Pegelwechsel in der Mitte eines Bits, 0->1 für 1-Bit, 1->0 für 0-Bit). Zur
* Bestimmung des Nutzsignals wird ein (einmaliger) Interrupt beim Taktwechsel ausgelöst,
* die ISR (PORTC_INT0_vect) stellt diese IRQ-Quelle ab und initialisiert einen Timer-IRQ,
* der in der "zweiten Bithälfte" auslöst. In der Timer-ISR (TCC0_OVF_vect) wird ein
* Bit eingelesen und nach Ende der Übertragung wird der Timer-IRQ aus- und der Flanken-IRQ
* wieder eingeschaltet. Um dem IR-Empfängerbaustein Zeit zur Rückkehr zum Ruhepegel zu
* geben, wird ein 15. Bit eingelesen und wieder verworfen.
* wichtige Variablen:
* gRC5Ready = 1
*
* IR-Sender:
* ----------
* Ein IR-Signal von 37khz kann per Software durch PORTC, Bit 7 eingeschaltet werden.
* Hinweis: Pin 7 kann als Ausgang TxD1 der Uart 1 von Port C konfiguriert werden,
* um ein einfaches IR-Modem zu realisieren.
* Das 37kHz-Signal wird durch Timer/Counter D1 erzeugt und liegt ständig an Port C,
* Pin 0 an. Pin 0 ist mit Pin 7 leitend verbunden und die Pins sind als "wired and"
* konfiguriert, so daß der Pegel an Pin 7 das Taktsignal ein- bzw. ausschaltet.
* Eine IR-UART ist derzeit nicht realisiert.
*
* Motorsteuerung:
* ---------------
* Der Motor wird über einen einfachen Darlington-NPN (TIP 110) ein- bzw. ausgeschaltet.
* Der Anshluss erfolgt über den Pin PD1, der als Ausgang von PWM-Kanal B von Timer/Counter 0
* von Port D konfiguriert ist.
*/
#include "system.h"
......@@ -15,15 +50,16 @@
#define PWMMAX 8191
uint8_t gRC5SampleCount, gRC5Ready;
unsigned int gRCC5Data;
int __attribute__((OS_main)) main( void )
{
unsigned int speed = 0;
/* Clock auf 32Mhz einstellen damit die I2C schnell genug bedient werden kann */
OSC.PLLCTRL = OSC_PLLSRC_RC2M_gc | 16;
OSC.CTRL |= OSC_PLLEN_bm | OSC_RC2MEN_bm | OSC_RC32KEN_bm;;
while (!(OSC.STATUS & OSC_PLLRDY_bm));
OSC.CTRL |= OSC_PLLEN_bm | OSC_RC2MEN_bm;
while (!(OSC.STATUS & OSC_PLLRDY_bm)) {};
DFLLRC2M.CTRL = DFLL_ENABLE_bm ;
CCP = CCP_IOREG_gc;
CLK.CTRL = CLK_SCLKSEL_PLL_gc;
......@@ -44,17 +80,23 @@ int __attribute__((OS_main)) main( void )
TCD0.PER = PWMMAX; // bei DIV4 macht das 125Hz
TCD0.CCB = speed; // Dutycycle A
TCD0.CTRLA = TC_CLKSEL_DIV4_gc;
TCD0.CTRLB = 0x23; // PWM single slope (x3) auf Kanal A (2x)
TCD0.CTRLB = 0x23; // PWM single slope (0x03) auf Kanal A (0x20)
/* IR-Sender 37 kHz */
TCD1.CTRLA = TC_CLKSEL_DIV1_gc;
TCD1.PER = 865;
TCD1.INTCTRLA = 1;
/* IR-Empfänger als Eingang schalten */
PORTC.DIRCLR = 64;
/* IR-Empfänger als Eingang schalten; IRQ 0 */
PORTC.DIRCLR = 64;
PORTC.PIN6CTRL = PORT_OPC_PULLUP_gc;
PORTC.INT0MASK = 64;
PORTC.PIN0CTRL = PORT_ISC_RISING_gc; // TSOP-Empfänger wird bei Pegelwandlung invertiert, Ruhepegel deshalb low
PORTC.INTCTRL |= PORT_INT0LVL_LO_gc;
if (PORTC.IN & 64) {
usart_puts_P(&USART_data, "Fehler: IR-Eingang auf High-Pegel!\n");
}
gRC5Ready = 0;
/* LEDs als Statusinfo */
LEDPORT.OUT = 0xff; // alle LEDs aus
......@@ -70,8 +112,13 @@ int __attribute__((OS_main)) main( void )
unsigned int speeds[] = {0, 3000, 6000, 8191};
while (1) {
LEDPORT.OUT = (PORTC.IN & 64) ? 0 : 0xff;
// LEDPORT.OUT = (PORTC.IN & 64) ? 0 : 0xff;
if (gRC5Ready) {
gRC5Ready = 0;
usart_putDec(&USART_data, gRCC5Data);
usart_putc(&USART_data, ' ');
}
if (USART_RXBufferData_Available(&USART_data)) {
char c = usart_getc(&USART_data);
switch (c) {
......@@ -107,11 +154,7 @@ int __attribute__((OS_main)) main( void )
}
*/
} else {
if (PORTC.IN & 64) {
spdCnt = (spdCnt + 1) & 3;
TCD0.CCB = speeds[spdCnt];
delay_ms(500);
}
}
}
}
......@@ -119,3 +162,38 @@ int __attribute__((OS_main)) main( void )
ISR(TCD1_OVF_vect) {
PORTC.OUTTGL = 1;
}
/*
* Port C IRQ 0 wird beim Start einer IR-Übertragung ausgelöst
*/
ISR(PORTC_INT0_vect){
PORTC.INT0MASK = 0; // folgende IRQs unterdrücken
LEDPORT.OUTTGL = 0xff; // DEBUG
gRC5SampleCount = 14+1; // 14 Bit + 1 Bit "Müll", damit IR-Empfänger auf Ruhepegel zurückkehrt
gRCC5Data = 0;
/* Timer/Count C0 auf Überlauf alle 1778µs einstellen (= 56896 Taktzyklen @ 32Mhz) */
TCC0.CTRLA = TC_CLKSEL_DIV4_gc;
TCC0.CTRLB = 0x00; // normaler Zählmodus
TCC0.PER = 14224 + 3556; // Zähler Top-Wert in Zyklen @ 32Mhz = 1788µs + 1/4 Zyklus
TCC0.CNT = 0x00; // Zähler zurücksetzen
TCC0.INTCTRLA = 0b00000011; // Interrupt mit hoher Priorität
}
/*
* Port C Timer/Counter 0 tastet die IR-Übertragung ab
*/
ISR(TCC0_OVF_vect)
{
TCC0.PER = 14224; // ab nun: Zähler Top-Wert 3556 Zyklen = 1788µs
gRCC5Data <<= 1; // nächstes Bit reinschieben
if (PORTC.IN & 64) gRCC5Data |= 1;
gRC5SampleCount--;
if (!gRC5SampleCount) { // alle Bits gesampelt?
TCC0.INTCTRLA = 0b00000000; // Timer-Interrupt ausschalten
gRCC5Data >>= 1; // "Müll"-Bit entfernen
gRC5Ready = 1;
LEDPORT.OUTTGL = 0xff; // DEBUG
PORTC.INT0MASK = 64; // neue IR-Übertragungen zulassen
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment