abebok75
06.06.2020, 20:02
Ich will Roboter per Fernbedienung steuern.
Ich hab 2 Platinen:
1. für Fernbedienung mit Attiny13A
2. für steuerung von Motoren, LEDs, Sensoren, Mp3 Player usw. mit Atmega 328p
Pin PB4 von Attiny13A ist verbunden mit Pin PC1 von Atmega328p.
Wenn ich jetzt auf Fernbedienung die Taste 2 drücke soll auf der Atmega328p platine die blaue LED leuchten.
Statddesen leuchtet grünne LED, wenn ich nochmal 2 drücke leuchtet blaue LED.
Wenn ich jetzt Taste 4 drücke soll auf der Atmega328p gelbe LED leuchten, statddessen leuchtet rote also alles durcheinnader.
Hier ist das Program für Fernbedienung (Attiny13A):
#define F_CPU 9600000UL// Must stay at this speed
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#define IR_Input_Pin PORTB1
#define LED1_PIN PORTB0
#define Output PORTB4
bool IR_Code(uint32_t data); // Check the IR Code
void IR_Scan(); // Scan IR data
void IR_Setup(); // Setup mode
uint32_t IR_data_out = 0; // IR data store
int main(void) {
IR_Setup();
DDRB |= 1 << LED1_PIN;
DDRB |= 1 << Output;
DDRB &= ~(1 << IR_Input_Pin);
DDRB &= ~(1 << PORTB2);
DDRB &= ~(1 << PORTB3);
DDRB &= ~(1 << PORTB5);
PORTB = 0b101110;
while (1) {
if (IR_Code(0xFF18E7)) { // Taster 2 - geradeaus fahren
PORTB ^= (1<<LED1_PIN); // LED toggeln
PORTB ^= (1<<Output); //toggle Output 1x
}
if (IR_Code(0xFF10EF)) { // Taster 4 -links fahren
PORTB ^= (1<<LED1_PIN); // LED toggeln
PORTB ^= (1<<Output); //toggle Output 2x
PORTB ^= (1<<Output);
}
if (IR_Code(0xFF5AA5)) { // Taster 6 - rechts fahren
PORTB ^= (1<<LED1_PIN); // LED toggeln
PORTB ^= (1<<Output); //toggle Output 3x
PORTB ^= (1<<Output);
PORTB ^= (1<<Output);
}
if (IR_Code(0xFF38C7)) { // Taster 5 - STOP
PORTB ^= (1<<LED1_PIN); // LED toggeln
PORTB ^= (1<<Output); //toggle Output 4x
PORTB ^= (1<<Output);
PORTB ^= (1<<Output);
PORTB ^= (1<<Output);
}
if (IR_Code(0xFF4AB5)) { // Taster 8 - rückwärts fahren
PORTB ^= (1<<LED1_PIN); // LED toggeln
PORTB ^= (1<<Output); //toggle Output 5x
PORTB ^= (1<<Output);
PORTB ^= (1<<Output);
PORTB ^= (1<<Output);
PORTB ^= (1<<Output);
}
}
}
void IR_Setup() {
GIMSK |= (1 << INT0); // Enable the interrupt pin ( at PB1)
MCUCR = (1 << ISC00); // Set interrupt configuration in PB1 (see page 46 for any change mode)
sei();
TCCR0B |= ((1 << CS00) | (1 << CS02)); //set timer 0 with max scaler (F_CPU/1024)
}
bool IR_Code(uint32_t data) {
// Prettified IR data output code
uint8_t IR_data_byte[4];
IR_data_byte[0] = (IR_data_out >> 24);
IR_data_byte[1] = (IR_data_out >> 16);
IR_data_byte[2] = (IR_data_out >> 8);
IR_data_byte[3] = (IR_data_out);
// Prettified IR data input code
uint8_t data_byte[4];
data_byte[0] = (data >> 24);
data_byte[1] = (data >> 16);
data_byte[2] = (data >> 8);
data_byte[3] = (data);
if (IR_data_byte[0] == data_byte[0] || IR_data_byte[1] == data_byte[1]) { // If address data is =
if (IR_data_byte[2] == data_byte[2] || IR_data_byte[3] == data_byte[3]) { // If command data is =
IR_data_out = 0; // Clear IR data Output
return true;
}
}
return false;
}
ISR(INT0_vect) {
IR_Scan();
}
uint8_t time_high = 0;
uint8_t time_low = 0;
bool interrupter1 = false;
bool interrupter2 = false;
bool one_time = false;
int conter = -1;
uint8_t TCNT0_buffer = 0;
uint8_t time_span = 0;
void IR_Scan() {
// Timer unit = 106.666 µs
if (TCNT0 >= TCNT0_buffer) // If timer doesn't overflow
time_span = TCNT0 - TCNT0_buffer; // Get span time
else //if timer overflow
time_span = (256 - TCNT0_buffer) + TCNT0; // Get span time
if ((PINB & (1 << IR_Input_Pin)) == 0)
time_high = time_span; // Get the time low
else
time_low = time_span; // Get the time high
if ((time_low >= 78) && (time_low <= 91)) // Low for 9ms
interrupter1 = true; // Enable the first interrupter
if ((time_high >= 36 && time_high <= 49) && (interrupter1 == true)) { // High time 4.5ms
IR_data_out = 0; // Clear data
conter = -1; // Restart counter variable
interrupter2 = true; // Enable the second interrupter (start condition is true)
}
if (conter == 32) { // Check if data send is over
interrupter1 = interrupter2 = false; // Restart interrupters
conter = -1; // Restart conter variable
}
if (interrupter2 == true) { // See if start condition is true
if (one_time == true) { // Enter one time in two loops
if (conter != -1) { // Over enter in the first time
if (time_high > time_low * 2) // Means we read logic 1
IR_data_out |= 0x80000000 >> conter; // Put the logic 1 in high significant bit and shift it to the right every loop
}
// else
// IR_data_out=0; // Clear data
conter++; // Up counter
}
one_time = !one_time; // Reverse state
}
TCNT0_buffer = TCNT0; // Scan timer
}
und hier für Atmega328p:
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define Input_Pin PORTC1
volatile uint8_t i=0;
volatile uint8_t l=0;
// Interrupt Service Routine fuer Timer0
ISR(TIMER0_OVF_vect) {
TCNT0 = 0x00; //Zaehlregister mit Vorladewert vorladen / Berechnung: siehe unten
i++;
if(i==60) //16000000/1024/256 - 1 sek
{
i=0;
switch(l){
case 1:
PORTD ^= (1<<PD1); //LED Blau toggeln - Taster 2
l=0;
break;
case 2:
PORTD ^= (1<<PD2); //LED Gelb toggeln - Taster 4
l=0;
break;
case 3:
PORTD ^= (1<<PD3); //LED Grunn toggeln - Taster 6
l=0;
break;
case 4:
PORTC ^= (1<<PC3); //LED Rot toggeln - Taster 5
l=0;
break;
case 5:
PORTC ^= (1<<PC0); //LED Weiss toggeln - Taster 8
l=0;
break;
default:
l=0;
break;
}
}
}
ISR(PCINT1_vect) //Fernbedienung
{
l++ ;
}
int
main(void)
{
cli();
DDRB = 0b000000; //PB0-PB5 Ausgang
PORTB = 0b111111; // Pullup 1
DDRC = 0b00001001; // PC0,PC3 LED, PC1 eingang Fernbedienung
DDRC &= ~(1 << Input_Pin);
PORTC = 0b11110110;
DDRD = 0b00001110; //PD0 Eingang, PD1-PD3 Ausgang LED
PORTD = 0b11110001;
PCICR |= (1<<PCIE1); //Pin Change Interrupt Enable 1
PCMSK1 |= (1<<PCINT9); //Pin Change Mask Register 1
TCCR0B|= ((1<<CS02)|(1<<CS00)); // Start Timer 0 with prescaler 1024
TIMSK0|= (1<<TOIE0); // Enable Timer 0 overflow interrupt
TCNT0 = 0xFF; //Zaehlregister vorladen mit FF zum Sofortstart
sei(); // Set the I-bit in SREG
/* --- loop --- */
while (1) {
}
return 0;
}
Kann mir bitte jemand helfen ?
Ich hab 2 Platinen:
1. für Fernbedienung mit Attiny13A
2. für steuerung von Motoren, LEDs, Sensoren, Mp3 Player usw. mit Atmega 328p
Pin PB4 von Attiny13A ist verbunden mit Pin PC1 von Atmega328p.
Wenn ich jetzt auf Fernbedienung die Taste 2 drücke soll auf der Atmega328p platine die blaue LED leuchten.
Statddesen leuchtet grünne LED, wenn ich nochmal 2 drücke leuchtet blaue LED.
Wenn ich jetzt Taste 4 drücke soll auf der Atmega328p gelbe LED leuchten, statddessen leuchtet rote also alles durcheinnader.
Hier ist das Program für Fernbedienung (Attiny13A):
#define F_CPU 9600000UL// Must stay at this speed
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#define IR_Input_Pin PORTB1
#define LED1_PIN PORTB0
#define Output PORTB4
bool IR_Code(uint32_t data); // Check the IR Code
void IR_Scan(); // Scan IR data
void IR_Setup(); // Setup mode
uint32_t IR_data_out = 0; // IR data store
int main(void) {
IR_Setup();
DDRB |= 1 << LED1_PIN;
DDRB |= 1 << Output;
DDRB &= ~(1 << IR_Input_Pin);
DDRB &= ~(1 << PORTB2);
DDRB &= ~(1 << PORTB3);
DDRB &= ~(1 << PORTB5);
PORTB = 0b101110;
while (1) {
if (IR_Code(0xFF18E7)) { // Taster 2 - geradeaus fahren
PORTB ^= (1<<LED1_PIN); // LED toggeln
PORTB ^= (1<<Output); //toggle Output 1x
}
if (IR_Code(0xFF10EF)) { // Taster 4 -links fahren
PORTB ^= (1<<LED1_PIN); // LED toggeln
PORTB ^= (1<<Output); //toggle Output 2x
PORTB ^= (1<<Output);
}
if (IR_Code(0xFF5AA5)) { // Taster 6 - rechts fahren
PORTB ^= (1<<LED1_PIN); // LED toggeln
PORTB ^= (1<<Output); //toggle Output 3x
PORTB ^= (1<<Output);
PORTB ^= (1<<Output);
}
if (IR_Code(0xFF38C7)) { // Taster 5 - STOP
PORTB ^= (1<<LED1_PIN); // LED toggeln
PORTB ^= (1<<Output); //toggle Output 4x
PORTB ^= (1<<Output);
PORTB ^= (1<<Output);
PORTB ^= (1<<Output);
}
if (IR_Code(0xFF4AB5)) { // Taster 8 - rückwärts fahren
PORTB ^= (1<<LED1_PIN); // LED toggeln
PORTB ^= (1<<Output); //toggle Output 5x
PORTB ^= (1<<Output);
PORTB ^= (1<<Output);
PORTB ^= (1<<Output);
PORTB ^= (1<<Output);
}
}
}
void IR_Setup() {
GIMSK |= (1 << INT0); // Enable the interrupt pin ( at PB1)
MCUCR = (1 << ISC00); // Set interrupt configuration in PB1 (see page 46 for any change mode)
sei();
TCCR0B |= ((1 << CS00) | (1 << CS02)); //set timer 0 with max scaler (F_CPU/1024)
}
bool IR_Code(uint32_t data) {
// Prettified IR data output code
uint8_t IR_data_byte[4];
IR_data_byte[0] = (IR_data_out >> 24);
IR_data_byte[1] = (IR_data_out >> 16);
IR_data_byte[2] = (IR_data_out >> 8);
IR_data_byte[3] = (IR_data_out);
// Prettified IR data input code
uint8_t data_byte[4];
data_byte[0] = (data >> 24);
data_byte[1] = (data >> 16);
data_byte[2] = (data >> 8);
data_byte[3] = (data);
if (IR_data_byte[0] == data_byte[0] || IR_data_byte[1] == data_byte[1]) { // If address data is =
if (IR_data_byte[2] == data_byte[2] || IR_data_byte[3] == data_byte[3]) { // If command data is =
IR_data_out = 0; // Clear IR data Output
return true;
}
}
return false;
}
ISR(INT0_vect) {
IR_Scan();
}
uint8_t time_high = 0;
uint8_t time_low = 0;
bool interrupter1 = false;
bool interrupter2 = false;
bool one_time = false;
int conter = -1;
uint8_t TCNT0_buffer = 0;
uint8_t time_span = 0;
void IR_Scan() {
// Timer unit = 106.666 µs
if (TCNT0 >= TCNT0_buffer) // If timer doesn't overflow
time_span = TCNT0 - TCNT0_buffer; // Get span time
else //if timer overflow
time_span = (256 - TCNT0_buffer) + TCNT0; // Get span time
if ((PINB & (1 << IR_Input_Pin)) == 0)
time_high = time_span; // Get the time low
else
time_low = time_span; // Get the time high
if ((time_low >= 78) && (time_low <= 91)) // Low for 9ms
interrupter1 = true; // Enable the first interrupter
if ((time_high >= 36 && time_high <= 49) && (interrupter1 == true)) { // High time 4.5ms
IR_data_out = 0; // Clear data
conter = -1; // Restart counter variable
interrupter2 = true; // Enable the second interrupter (start condition is true)
}
if (conter == 32) { // Check if data send is over
interrupter1 = interrupter2 = false; // Restart interrupters
conter = -1; // Restart conter variable
}
if (interrupter2 == true) { // See if start condition is true
if (one_time == true) { // Enter one time in two loops
if (conter != -1) { // Over enter in the first time
if (time_high > time_low * 2) // Means we read logic 1
IR_data_out |= 0x80000000 >> conter; // Put the logic 1 in high significant bit and shift it to the right every loop
}
// else
// IR_data_out=0; // Clear data
conter++; // Up counter
}
one_time = !one_time; // Reverse state
}
TCNT0_buffer = TCNT0; // Scan timer
}
und hier für Atmega328p:
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define Input_Pin PORTC1
volatile uint8_t i=0;
volatile uint8_t l=0;
// Interrupt Service Routine fuer Timer0
ISR(TIMER0_OVF_vect) {
TCNT0 = 0x00; //Zaehlregister mit Vorladewert vorladen / Berechnung: siehe unten
i++;
if(i==60) //16000000/1024/256 - 1 sek
{
i=0;
switch(l){
case 1:
PORTD ^= (1<<PD1); //LED Blau toggeln - Taster 2
l=0;
break;
case 2:
PORTD ^= (1<<PD2); //LED Gelb toggeln - Taster 4
l=0;
break;
case 3:
PORTD ^= (1<<PD3); //LED Grunn toggeln - Taster 6
l=0;
break;
case 4:
PORTC ^= (1<<PC3); //LED Rot toggeln - Taster 5
l=0;
break;
case 5:
PORTC ^= (1<<PC0); //LED Weiss toggeln - Taster 8
l=0;
break;
default:
l=0;
break;
}
}
}
ISR(PCINT1_vect) //Fernbedienung
{
l++ ;
}
int
main(void)
{
cli();
DDRB = 0b000000; //PB0-PB5 Ausgang
PORTB = 0b111111; // Pullup 1
DDRC = 0b00001001; // PC0,PC3 LED, PC1 eingang Fernbedienung
DDRC &= ~(1 << Input_Pin);
PORTC = 0b11110110;
DDRD = 0b00001110; //PD0 Eingang, PD1-PD3 Ausgang LED
PORTD = 0b11110001;
PCICR |= (1<<PCIE1); //Pin Change Interrupt Enable 1
PCMSK1 |= (1<<PCINT9); //Pin Change Mask Register 1
TCCR0B|= ((1<<CS02)|(1<<CS00)); // Start Timer 0 with prescaler 1024
TIMSK0|= (1<<TOIE0); // Enable Timer 0 overflow interrupt
TCNT0 = 0xFF; //Zaehlregister vorladen mit FF zum Sofortstart
sei(); // Set the I-bit in SREG
/* --- loop --- */
while (1) {
}
return 0;
}
Kann mir bitte jemand helfen ?