@Harry (X1CR),
hier der Code, war aber für nen' Tiny26 statt dem angegebenen Tiny2313
Ist eine kleine Tastatur von Pollin dran, und läuft mit internem Oszi 4Mhz.
Zwischen PB3 und PB1 hängen 2 IR-Dioden in Reihe (mehr Licht) mit einem Widerstand, das ist alles.
Mit einer Taste kann das Ding abgeschaltet werden, eine andere Taste macht nen Reset und startet die Fernsteuerung wieder. So läufts auch mit 4 Batterien recht lang.
Prg. ist nicht elegant, aber mußte auch auf die schnelle gemacht werden,
da die alte Steuerung kaputt war und Sohnemann nicht mit Geduld gesegnet ist.
Könnte man natürlich eleganter und effizienter machen, aber..[-(
Code:
/* Title: RC5-Sender
Hardware: ATtiny26
*******************************************************************************************************
* Ein- Ausgänge
* PA0 (20) - ADC0 Fahrlicht S1 PB0 ( 1) - MOSI/OC1A (6,16) - GND
* PA1 (19) - ADC1 Blinker li S2 PB1 ( 2) - MISO LED (5,15) - VCC,AVCC
* PA2 (18) - ADC2 Blinker re S3 PB2 ( 3) - SCK
* PA3 (17) - AREF Arbeitslicht1 S4 PB3 ( 4) - OCB1
* PA4 (14) - ADC3 Blitzlicht PB4 ( 7) - XTAL1 Oszi
* PA5 (13) - ADC4 Rundum PB5 ( 8) - XTAL2 LED
* PA6 (12) - AIN0 Sel_1 PB6 ( 9) - INT0 Einschalter
* PA7 (11) - AIN1 Sel_2 PB7 (10) - RESET
*
*******************************************************************************************************
* RC5-Code
* 1 Takt ca. 889µs, "1" -> Low/High, "0" -> High/Low -> 1 Bit = 2x889µs = 1,778ms
* Zustand "1" "0"
* __ __
* __| | | |__
* Takt: 0 1 0 1
*
* Kompletes Telegramm beinhaltet 14 Bit = 24,889ms
* 1.Startbit immer "1"
* 2.Startbit immer "1", bei extd. kann dies "0" sein
* Toggel normal "0", bei Tastenrepeat "1"
* 5 Bit Adresse
* 6 Bit Kommando
* Bei Tastenwiederholung wird neues Telegramm nach 113,78ms (64Bitzeiten) gesendet.
*******************************************************************************************************
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
volatile unsigned char ms, buf_ptr, ms1; // ms Zeitgeber volatile damit auch in IRQ bearbeitet wird.
unsigned char txbuffer[28]; // Sendbuffer halbnibbles
#define tcnt_val 200 // 889µs @ Teiler 64 @ 4MHz
//#define INTERNAL_TESTS 1
#define SET_BIT(PORT, BITNUM) ((PORT) |= (1<<(BITNUM)))
#define CLEAR_BIT(PORT, BITNUM) ((PORT) &= ~(1<<(BITNUM)))
#define TOGGLE_BIT(PORT, BITNUM) ((PORT) ^= (1<<(BITNUM)))
/**************************************************************
Init
Description: Initalisieren des µC
In :
Out: ms
************************************************************/
void init()
{
cli(); // Disable IRQ's
// Port konfigurieren
PORTA = 0x0F; // Pullup aktiv
PORTB = 0x0;
// PORTx Outputs
DDRA = 0b11000000; // PA6+7 Output
DDRB = 0b00001010; // PB1+3 Output, PB3 Led ON/OFF RC5; PB1 LED ON/OFF Trägerfreq.
TCNT0 = 0; // reset TCNT0
TCCR0 = 3; // count with cpu clock/8
TIMSK = 1<<TOIE0; // enable TCNT0 overflow AND Timer1 CompA match
TCCR1A = 1<<COM1A0; // Toggel at match
TCCR1B = 1<<CS10 | 1<<CTC1; // Timer1 count with cpu clock
OCR1C = 55; // Reloadwert = 72kHz
GIMSK = 0; // INT0 IRQ sperren
}
/**************************************************************
ISR (TIMER0_OVF_vect)
Description: Timer 0 Overflow IRQ
In :
Out: alle ,5 ms
************************************************************/
ISR (TIMER0_OVF0_vect)
{
unsigned char sreg;
sreg = SREG;
TCNT0 = TCNT0 + tcnt_val; // Zähler neusetzen
if ( ms==200 ){ // Startkennung ?
if (txbuffer[buf_ptr]) SET_BIT(PORTB,3);
else CLEAR_BIT(PORTB,3);
buf_ptr++;
if (buf_ptr == 28) // Ende erreicht
ms = 168; // Wartezeit starten ca. 155ms
}
else if (ms > 0){
ms--;} // counter --
if (ms1 > 0) ms1--; // counter --
SREG=sreg;
}
/**************************************************************
************************************************************/
int main( void )
{
unsigned char i, j, newstatus, oldstatus, command;
init(); // Initialisierung
sei(); // IRQ freigeben
oldstatus = 0;
ms = 0;
for (i=0;i<4;i++) txbuffer[i] = i & 1; // Startbits setzen
for (i=5;i<29;i++) txbuffer[i-1] = i & 1; // Rest des Telegramm mit "0" beschreiben
/*
txbuffer[ 0] = 0; // Startbit = "1"
txbuffer[ 1] = 1;
txbuffer[ 2] = 0; // Startbit = "1"
txbuffer[ 3] = 1;
txbuffer[ 4] = 1; // Toggle
txbuffer[ 5] = 0;
txbuffer[ 6] = 0; // Adr 4
txbuffer[ 7] = 0;
txbuffer[ 8] = 0; // Adr 3
txbuffer[ 9] = 0;
txbuffer[10] = 0; // Adr 2
txbuffer[11] = 0;
txbuffer[12] = 0; // Adr 1
txbuffer[13] = 0;
txbuffer[14] = 0; // Adr 0
txbuffer[15] = 0;
txbuffer[16] = 0; // Command 5
txbuffer[17] = 0;
txbuffer[18] = 0; // Command 4
txbuffer[19] = 0;
txbuffer[20] = 0; // Command 3
txbuffer[21] = 0;
txbuffer[22] = 0; // Command 2
txbuffer[23] = 0;
txbuffer[24] = 0; // Command 1
txbuffer[25] = 0;
txbuffer[26] = 0; // Command 0
txbuffer[27] = 0;
*/
CLEAR_BIT(PORTA,PA6); // Select 1 schalten
for (;;)
{
if (ms == 0){
// Aktuellen Status holen
SET_BIT(PORTA,PA6); // Select 1 ausschalten
CLEAR_BIT(PORTA,PA7); // Select 2 schalten
ms1=10; // Wartezeit vor Auswertung
while (ms1!=0);
newstatus = ~PINA & 0x0F; // Eingänge holen
SET_BIT(PORTA,PA7); // Select 2 schalten
CLEAR_BIT(PORTA,PA6); // Select 1 schalten
ms=10; // Wartezeit vor Auswertung
while (ms1!=0);
newstatus |= (~PINA & 0x0F) << 4; // Eingänge holen
// Eingänge checken
i = 0;
j = 1;
command = 255;
while ((i < 8) && (command == 255)){ // Alle Bits durchlaufen
// Abfrage auf wiederholte Tasten
if (((newstatus & j) == j) && ((oldstatus & j) == j)){
txbuffer[ 4] = 0; // Togglebit = "1"
txbuffer[ 5] = 1;
command = i; // Ein des Ausgangs
}
// Abfrage auf geänderte Tasten
if (((newstatus & j) == j) && ((oldstatus & j) != j)){
txbuffer[ 4] = 1; // Togglebit = "0"
txbuffer[ 5] = 0;
command = i; // Ein des Ausgangs
}
j = j << 1;
i++;
}
// Commando-Auswertung derzeit bis 7
if (command != 0xff){
for (i=22;i<28;i++) txbuffer[i] = 0; // alle Commands löschen
if(command == 0){
txbuffer[22] = 1;
txbuffer[24] = 1;
txbuffer[26] = 1;
}
if(command == 1){
txbuffer[23] = 1;
txbuffer[24] = 1;
txbuffer[26] = 1;
}
if(command == 2){
txbuffer[22] = 1;
txbuffer[25] = 1;
txbuffer[26] = 1;
}
if(command == 3){
txbuffer[23] = 1;
txbuffer[25] = 1;
txbuffer[26] = 1;
}
if(command == 4){
txbuffer[22] = 1;
txbuffer[24] = 1;
txbuffer[27] = 1;
}
if(command == 5){
txbuffer[23] = 1;
txbuffer[24] = 1;
txbuffer[27] = 1;
}
if(command == 6){
txbuffer[22] = 1;
txbuffer[25] = 1;
txbuffer[27] = 1;
}
if(command == 7){
txbuffer[23] = 1;
txbuffer[25] = 1;
txbuffer[27] = 1;
}
buf_ptr = 0; // Pointer an Anfang setzen
ms = 200; // Start senden
}
oldstatus = newstatus; // aktueller Status merken
if((PINB & 1<<PB6) == 0){ // Ausschalter betätigt
loop_until_bit_is_set(PINB, 6); // Warte bis Ausschalter losgelassen wurde
ms1=255;
while (ms1!=0);
ms1=255;
while (ms1!=0);
ms1=255;
while (ms1!=0);
ms1=255;
while (ms1!=0);
TCCR0 = 0; // Stop counter 0
TCCR1B = 0; // Stop Counter 1
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set Sleep enable
sleep_mode();
}
}
}
}
Grüße
Hans-Josef
Lesezeichen