PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Atmega168p: PD0/PD1 (RXD/TXD) als normalen Ausgang/Eingang verwenden



schorsch_76
14.11.2012, 07:51
Hallo zusammen,
ich hab eine kleine Schaltung welche die PD1(txd pin) als normalen Ausgang verwenden will und PD0(rxd pin) als normalen Eingang. Aber das folgende Programm "stoppt den irq1" wenn ich set_txd_on()/set_txd_off() im ISR(INT1_vect) umschalte. Ich sehe das, daß die LEDs nicht mehr umschalten.



/*
Hardware:
---------

MCU: Atmega 168
Clock: 16 MHz
Prescale: 8

Timer 1 can measure times up up 1/(16000000/8) * 65535 = 0,0327675 s

*/

#define PRESCALE 8

#include <stdlib.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

#include "rc5.h"

// -----------------------------------------------------
// defines for better readability
// -----------------------------------------------------

// inputs
#define is_ir_high() (PIND & (1 << PIND3))
#define is_rts_high() (PIND & (1 << PIND4))
#define is_pwren_high() (PIND & (1 << PIND5))
#define is_prg_btn_high() (PINC & (1 << PINC0))
#define is_rxd_high() (PIND & (1 << PIND0))

// outputs
#define set_cts_on() (PORTD |= (1 << PD2))
#define set_cts_off() (PORTD &= ~(1 << PD2))
#define set_ri_on() (PORTD |= (1 << PD6))
#define set_ri_off() (PORTD &= ~(1 << PD6))
#define set_txd_on() (PORTD |= (1 << PD1))
#define set_txd_off() (PORTD &= ~(1 << PD1))

// leds are low active
#define set_led_error_on() (PORTB &= ~(1 << PB0))
#define set_led_error_off() (PORTB |= (1 << PB0))
#define set_led_rxd_on() (PORTB &= ~(1 << PB1))
#define set_led_rxd_off() (PORTB |= (1 << PB1))
#define set_led_txd_on() (PORTB &= ~(1 << PB2))
#define set_led_txd_off() (PORTB |= (1 << PB2))

// -----------------------------------------------------
// global variables
// - communication of IRQ routines with main loop
// -----------------------------------------------------
RC5 g_decoder;

// -----------------------------------------------------
// io handling
// -----------------------------------------------------
void init_io()
{
// DDRX: Bit 1 = output / 0 = input
// if input : PORTX = 1 : Pullup active
// if output : PORTX = state of the output

// Port B, Pullups for input pins
// LEDS as output (Bit 0,1,2)
DDRB = 0b00000111;
PORTB = 0b11111111;

// Port C
// All input, enable pull ups
DDRC = 0b00000000;
PORTC = 0b11111111;

// Port D
// Inputs
// rxd (pd0)
// ir (pd3)
// rts (pd4)
// pwren (pd5)
// Output txd (pd1)
// cts (pd2)
// ri (pd6)
// unused (as input + pullup)
// (pd7)
DDRD = 0b01000110;
PORTD = 0b10111001;
}

// -----------------------------------------------------
// Timer handling
// -----------------------------------------------------
void init_timer(void)
{
// ----------------------------
// Timer 1, Normal mode, runs up to 0xffff and then OVF ISR
// ----------------------------
TCCR1A = 0;
TCCR1B = (1 << CS11); // prescale factor 8
TIMSK1 |= (1 << TOIE1);
}

// Timer ISR Overflow
ISR(TIMER1_OVF_vect)
{
// g_decoder.time_overrun();
}


// -----------------------------------------------------
// INT1
// -----------------------------------------------------
void init_interrupts()
{
// enable Timer1 overflow
// TIMSK1 |= (1<<TOIE1);

// enable int1 irq. Both Edges
EICRA |= (1 << ISC10);
EICRA &= ~(1 << ISC11);

EIMSK |= (1 << INT1);
}

ISR(INT1_vect)
{
// read timer, set it to 0 and convert to us (mikro seconds)
int us = TCNT1;
TCNT1 = 0;
us /= (F_CPU / PRESCALE / 1000);

// check 0->1 or 1->0
if (is_ir_high())
{
// 0->1
//g_decoder.low_to_high(us);

// show the user, we are alive
set_led_rxd_on();
set_led_txd_on();

// bit-bang the status to the FTDI
set_txd_on(); // <<--- Hier
}
else
{
// 1->0
// g_decoder.high_to_low(us);

// show the user, we are alive
set_led_rxd_off();
set_led_txd_off();

// bit-bang the status to the FTDI
set_txd_off(); // <<--- Hier
}
}

// -----------------------------------------------------
// main loop
// -----------------------------------------------------
int main(void)
{
// io port directions
init_io();

// init timer at 1ms rate
// init_timer();

// init pin change interrupts
init_interrupts();

// allow all interrupts
sei();

// endless loop
while(1)
{
// live signal
_delay_ms(500);
set_led_error_on();
_delay_ms(500);
set_led_error_off();
}
}




Die Zeilen "<<--- Hier", sind die markanten Stellen. Wenn ich die set_txt_on()/off() auskommentiere toggeln die anderen LEDs. Die Error LED blinkt weiter, also ist der AVR nicht "abgesoffen".

Was kann das sein?

Gruß
Georg

markusj
14.11.2012, 08:45
Ich finde nichts auffälliges, vermute aber, dass die Ursache außerhalb des AVRs liegt. Evtl. verursacht das Umschalten des Pins irgendwelche Seiteneffekte bei der restlichen Schaltung?

mfG
Markus

schorsch_76
14.11.2012, 12:23
Danke fürs ansehen. Dann werd ich mal nochmal das Oszi zücken und kucken ob ich da noch was finde...
Gruß
Georg