Bei McDoof gibt es derzeit eine Art Reaktvilicht bzw. -sound.
Beim Happymeal für Kinder gibt es einen Bewegungsmelder. Dieser reagiert auf Lichtänderungen. Aus den Kinderzimmern piepst es seit heute Mittag permanent
;
; Reaktive light with Atmel AT Tiny 13
; Inspired by Windi
;
.nolist
.include "tn13def.inc"
.list
.def mp = R16
.def ldr_l = R17
.def ldr_h = R18
.def old_ldr_l = R19
.def old_ldr_h = R20
.def daycount = R21
.def dayblink = R22
.def param = R23
.def temp_l = R24
.def temp_h = R25
.equ THRESHOLD = 50
.equ DAYTIME_THRESHOLD = 800
.equ DAYTIME_CHECKS = 200
.equ DAYBLINK_PAUSES = 8
.equ LED_OUT = PORTB3
.equ LDR_IN = PORTB4
.equ DELAY_16ms = 0
.equ DELAY_32ms = 1
.equ DELAY_64ms = 2
.equ DELAY_125ms = 3
.equ DELAY_250ms = 4
.equ DELAY_500ms = 5
.equ DELAY_1s = 6
.equ DELAY_2s = 7
.equ DELAY_4s = 32
.equ DELAY_8s = 33
;
; Interrupt vectors
;
.cseg
rjmp main ; Reset handler
.org WDTaddr
reti ; Watchdog handler
.org ADCCaddr
reti ; ADC handler
;
; Main program
;
main:
;
; Setup stack pointer
;
ldi mp, low(RAMEND)
out SPL, mp
;
; Set clock prescaler to /16
;
ldi mp, 0b10000000
out CLKPR, mp
ldi mp, 0b00000100
out CLKPR, mp
;
; Disable Analog Comparator and reference voltage
;
sbi ACSR, ACD
cbi ACSR, AINBG
;
; Setup sleep mode to power-down mode
;
ldi mp, (1<<SE) | (1<<SM1) | (0<<SM0) | (0<<PUD)
out MCUCR, mp
;
; Set LED as output, all other pins to input
;
ldi mp, (1<<LED_OUT)
out DDRB, mp
out PORTB, mp
;
; Configure ADC
;
ldi mp, (0<<REFS0) | (1<<MUX1) | (0<<MUX0) | (0<<ADLAR)
out ADMUX, mp
ldi mp, (1<<ADTS2)
out ADCSRB, mp
ldi mp, (1<<ADC2D)
out DIDR0, mp
; Initalize daytime and old LDR values
ldi dayblink, DAYBLINK_PAUSES
ldi daycount, DAYTIME_CHECKS
ldi old_ldr_l, low(1023)
ldi old_ldr_h, high(1023)
;
; Main loop
;
main_loop:
; Short delay between measurements (disable for long distance?)
ldi param, DELAY_125ms
rcall delay
; Read LDR value
rcall read_ldr
; Check if difference to old LDR value is above threshold
mov temp_l, ldr_l
mov temp_h, ldr_h
sub temp_l, old_ldr_l
sbc temp_h, old_ldr_h
mov old_ldr_l, ldr_l
mov old_ldr_h, ldr_h
cpi temp_l, low(THRESHOLD)
ldi mp, high(THRESHOLD)
cpc temp_h, mp
brlt no_blink
; Above threshold, let LED blink ten times and reset old LDR value
ldi param, 10
rcall blink_led
ldi old_ldr_l, low(1023)
ldi old_ldr_h, high(1023)
; Check if LDR value is above daytime threshold
no_blink:
cpi ldr_l, low(DAYTIME_THRESHOLD)
ldi mp, high(DAYTIME_THRESHOLD)
cpc ldr_h, mp
brlt nighttime
; Above daytime threshold, decrease daycount if it isn't already zero
tst daycount
breq daytime_check
dec daycount
rjmp daytime_check
nighttime:
ldi daycount, DAYTIME_CHECKS
daytime_check:
; If LD has been over daytime threshold for along time,
; pause a bit and blink once in a while
tst daycount
brne main_loop
ldi param, DELAY_8s
rcall delay
dec dayblink
brne main_loop
ldi param, 1
rcall blink_led
ldi dayblink, DAYBLINK_PAUSES
rjmp main_loop
;
; Read LDR value via ADC
;
read_ldr:
push mp
ldi mp, (1<<ADEN) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
out ADCSRA, mp
ldi mp, (1<<SE) | (0<<SM1) | (1<<SM0) | (0<<PUD)
out MCUCR, mp
sleep
cli
in ldr_l, ADCL
in ldr_h, ADCH
ldi mp, (0<<ADEN)
out ADCSRA, mp
ldi mp, (1<<SE) | (1<<SM1) | (0<<SM0) | (0<<PUD)
out MCUCR, mp
sei
pop mp
ret
;
; Let LED blink "blinks" times
;
blink_led:
push mp
push param
mov mp, param
blink_loop:
cbi PORTB, LED_OUT
ldi param, DELAY_32ms
rcall delay
sbi PORTB, LED_OUT
ldi param, DELAY_125ms
rcall delay
dec mp
brne blink_loop
pop param
pop mp
ret
;
; Delay subroutine
;
delay:
push mp
; Setup watchdog timer
cli
wdr
ldi mp, (1<<WDCE) | (1<<WDE)
out WDTCR, mp
mov mp, param
ori mp, (0<<WDCE) | (0<<WDE) | (1<<WDTIE)
out WDTCR, mp
sei
; Delay
sleep
; Stop watchdog timer
cli
wdr
ldi mp, (1<<WDCE) | (1<<WDE)
out WDTCR, mp
ldi mp, (0<<WDE)
out WDTCR, mp
sei
pop mp
ret
avrdude -p attiny13 -c ponyser -P com1 -U flash:w:rl_4.2.hex:i
//rl_4.2.c
//Reaktives Licht mit ATTiny13
//Modifiziertes Grundprogramm aus Kapitel 4.2 des Kochbuchs http://reaktivlicht.de/kochbuch.pdf vom 16.12.2006
//Änderungen gegebüber Grundprogramm:
//-Taktfrequenz 128kHz
//- Entladezeit als Konstante (ansonsten werden Floating Point Libraries mitgeladen und der Code passt nicht mehr in den ATTiny13)
//- Entladezeit verkürzt auf 1000µs ( angepasst an Pollin LED's Best. Nr, 120437), ggf. noch weitere Anpassungen nötig
// - Nur noch lokale Variablen: Geringere Codegröße, da diese Variablen in den Registern gehalten werden statt im RAM
#include <avr/io.h>
//#define F_CPU 128000 //Taktfrequenz ist bereits im makefile definiert
#include <util/delay.h> //maximale delays bei 128 kHz: _delay_us(6000), _delay_ms(2047)
unsigned char led_abfrage(void)
{
unsigned char led_status;
PORTB &= ~(1<<PB3); // Portb.3 auf Masse schalten
PORTB |= (1<<PB4); // Portb.4 auf +Ub schalten, um die LED zu 'laden'
_delay_us(1); // Ladezeit 1 µs, kann ggf. noch verkleinert werden
DDRB &= ~(1<<PB4); // Portb.4 nun zwecks Abfrage der LED-Ladung auf 'Eingang' schalten
PORTB &= ~(1<<PB4); // Pullup abschalten, sonst geht's nicht!
_delay_us(1000); // Entladezeit zeit_ms (1500 µs) - je kleiner, je unempfindlicher
led_status = (PINB & (1<<PINB4)); // Ladezustand einlesen
DDRB |= (1<<PB4); // Portb.4 wieder auf Ausgang schalten
PORTB &= ~(1<<PB4); // Portb.4 auf Masse schalten
return led_status;
}
int main(void)
{
unsigned char i;
DDRB = 0b00011000; // Pinb.3 und .4 auf 'Ausgang', Rest auf 'Eingang' schalten
PORTB = 0b11100111; // Pullups zuschalten, außer für Pinb.3 und .4
ADCSRA &= ~(1<<ADEN); // A/D-Wandler abschalten, eigentlich unnötig da Voreinstellung
ACSR |= (1<<ACD); // AnalogKomparator abschalten
while (1) {
if ( led_abfrage() == 0)
{ // LED durch Licht entladen?
for (i = 0; i < 10 ; i++)
{ // 10x blinken
PORTB |= (1<<PB3); // PB3 auf Vcc schalten
_delay_ms(50); // 50 ms Blitz
PORTB &= ~(1<<PB3); // PB3 auf GND schalten
_delay_ms(500); // ca. 500ms Pause
}
}
}
return 0;
}
#Minimal Makefile für ein einfaches avr-gcc Projekt
#Getestet mit der WinAVR (http://winavr.sourceforge.net/) Distribution vom 22.01.07
#Die folgenden 3 Make Targets sind definiert
# - make all: compiliert den Sourcecode, erzeugt das .hex file
# - make clean: löscht alle Files, die beim compilieren generiert wurden
# - make program: überträgt das generierte .hex file in den Mircocontroller über den einfachen seriellen Programmieradapter
#Achtung: Eigene Anpassungen sollten normalerweise nur in 1.) und 2.) nötig sein
# 1.) Microcontrollerspezifisches
MCU = attiny13
F_CPU = 128000
# 2.) Target und Source Files
TARGET = rl_4.2
SRC = $(TARGET).c
# 3.) Compilerflags
# implizite Regel: n.o is made automatically from n.c with a command of the form '$(CC) -c $(CPPFLAGS) $(CFLAGS)'.
OPT = -Os
CDEFS = -DF_CPU=$(F_CPU)UL
CFLAGS = -Wall $(OPT) -mmcu=$(MCU) $(CDEFS)
# 4.) Linkerflags
LDFLAGS = -Wl,-Map,$(TARGET).map
LIBS =
# 5.) Define programs and commands.
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
# 6.) Regeln
OBJ = $(SRC:%.c=%.o)
%.elf: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
%.lss: %.elf
$(OBJDUMP) -h -S $< > $@
%.hex: %.elf
$(OBJCOPY) -j .text -j .data -O ihex $< $@
# 7.) Make Targets
.PHONY : all clean program
all: $(TARGET).elf $(TARGET).lss $(TARGET).hex
clean:
rm -rf *.o *.elf *.hex *.map *.lss *.lst
program: $(TARGET).hex
avrdude -q -q -p $(MCU) -c ponyser -P com1 -U flash:w:$(TARGET).hex:i
chrisi01 schrieb:alle Einstellungen sind so wie sie am Anfang waren 1 uC hab ich schon geschrottet hab nur den takt mal geändert (auf bild 1 zu sehen) und schon kam ich nicht mehr auf den uC
Das Problem habe ich bei mir nur wenn ich auf 128kHz und Teilung durch 8 einstelle.eigengott schrieb:Kannst du die Datenrate des Programmers ändern? Wenn man den internen Oszillator weit genug 'runterdreht - so wie bei dir - klappt die serielle Kommunikation nur noch mit entsprechend geringer Datenrate. Ich stelle in solchen Fällen bei meinem Programmer die niedrigste Datenrate ein um die Lock-Bits neu zu setzen (höherer Takt, keine Teilung). Danach lässt sich der Chip wieder normal ansprechen.
Das könnte auch ein Softwareproblem sein.chrisi01 schrieb:aber wie setzt ich den nun die Fusebits richtig damit er auch funkt? hab ihn programmiert und in die Schaltung eingebaut (es ist nur eine LED an Port B0 die ich anschalte per programm) und die leuchtet leider net wenn ich den uC in die Schaltung steck.
#define F_CPU 128000
#include <avr\io.h>
#include <util\delay.h> //ok die bräuchte ichjetzt nicht aba egal ne pause soll später eh mal rein
void initPorts(void)
{
DDRB=0x01;
}
main (void)
{
{
PORTB = 1;
}
while (true);
}
Es hätte wohl auch in der initPorts()-Funktion funktioniert, wenn du die nur mal irgendwo aufgerufen hättestchrisi01 schrieb:habs hinbekommen hab das konfigurieren aus der funktion rausgenommen und ins hauptprogramm gepackt![]()
Aus einem älteren Katalog eines Batterieherstellers aus .de:chrisi01 schrieb:nur noch eine frage hab hier 2 Monozellen genommen (glaub ich sind die ganz großen batterien) steht aber nix drauf wieviel mah die normalerweise haben weiss das wer was da in etwa normal ist?
wollt jetzt ne _delay_ms(500); verwenden da wird die hex file aber gleich ganze 9kbyte groß Shocked Shocked das bringt der ja logischerweise nie ind en 1kb speicher des uCs wo isn etz der tricky dabei?
Das interessiert mich jetzt. Welcher Compiler, welche Compilerversionen vorher/nachher?hab jetzt nen anderen kompiler genommen und das blinklicht blinkt grad so schön vor sich hin Smile vielen dank für die hilfe Smile klappt nun alles Smile