; ; mic thru to speaker on audiomega ; ;.include "t44def.inc" .device ATtiny44 ; ; definitions ; .equ tx = PA1 ; transmit pin .equ tx_pin = PINA .equ tx_port = PORTA .equ tx_ddr = DDRA .equ nloop = 200 ; number of samples between framing ; ; registers ; .def bit_count = R16; bit counter .def temp = R17; temporary storage .def temp1 = R18; temporary storage .def txbyte = R19; data byte .def loop_count = R20 ; loop counter .def sample = R21 ; mic sample ; ; code segment ; .cseg .org 0 rjmp reset ; ; bit delay ; serial bit delay ; ;.equ b = 13 ; 9600 baud (clock /8) ;.equ b = 130 ; 9600 baud (clock /1) .equ b = 8 ; 115200 baud (clock /1) bit_delay: ldi temp, b bitloop: dec temp brne bitloop ret ; ; putchar ; assumes no line driver (doesn't invert bits) ; .equ sb = 1; number of stop bits putchar: ldi bit_count, 9+sb; 1+8+sb com txbyte; invert everything sec; set start bit putchar0: brcc putchar1; if carry set sbi tx_port, tx; send a '0' rjmp putchar2; else putchar1: cbi tx_port, tx ; send a '1' nop ; even out timing putchar2: rcall bit_delay; one bit delay rcall bit_delay lsr txbyte; get next bit dec bit_count; if not all bits sent brne putchar0; send next bit ret; ; ; char_delay ; delay between characters ; char_delay: ldi temp, 255 char_delay_loop: ldi temp1, 10 char_delay_loop1: dec temp1 brne char_delay_loop1 dec temp brne char_delay_loop ret ; ; main program ; reset: ; ; set clock divider to /1 ; ldi temp, (1 << CLKPCE) ldi temp1, (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0) out CLKPR, temp out CLKPR, temp1 ; ; set stack pointer to top of RAM ; ldi temp, high(RAMEND) out SPH, temp ldi temp, low(RAMEND) out SPL, temp ; ; set up A/D ; sbi ADMUX, REFS1 ; use internal 1.1V reference cbi ADMUX, REFS0 ; sbi ADMUX, ADLAR ; left-adjust result sbi ADMUX, MUX5 ; Differential, 20x gain on pos: ADC7, neg: ADC3 (111001) sbi ADMUX, MUX4 ; sbi ADMUX, MUX3 ; cbi ADMUX, MUX2 ; cbi ADMUX, MUX1 ; sbi ADMUX, MUX0 ; cbi DDRA, PA7 ; input on PA7 (vpos) cbi DDRA, PA3 ; input on PA3 (vneg) sbi ADCSRA, ADEN ; enable A/D cbi ADCSRA, ADATE ; disable auto-trigger cbi ADCSRA, ADIE ; disable interrupts sbi ADCSRA, ADPS2 ; set prescaler for /16 cbi ADCSRA, ADPS1 ; " cbi ADCSRA, ADPS0 ; " ; ; set up PWM ; sbi DDRB, PB2 ; enable OC0B output pin cbi PORTB, PB2 ldi temp, ((1 << COM0B0) | (1 << COM0B1) | (1 << WGM01) | (1 << WGM00)) out TCCR0A, temp ; set OC0B on compare match and fast PWM mode, 0xFF bottom ldi temp, ((0 << WGM02) | (0 << CS02) | (0 << CS01) | (1 << CS00)) out TCCR0B, temp ; set timer 0 prescalar to 1 ; ; init comm pin for output ; sbi tx_port, tx sbi tx_ddr, tx ; ; main loop ; main_loop: ; ; send framing ; ldi txbyte, 1 rcall putchar rcall char_delay ldi txbyte, 2 rcall putchar rcall char_delay ldi txbyte, 3 rcall putchar rcall char_delay ldi txbyte, 4 rcall putchar rcall char_delay ; ; sample loop ; ldi loop_count, nloop sample_loop: ; ; read A/D ; sbi ADCSRA, ADSC adloopup: sbic ADCSRA, ADSC ; loop until complete rjmp adloopup ; ; send conversion ; lds sample, ADCH ; hi byte - left adjusted. satisfied with 8 bit. mov txbyte, sample rcall putchar ldi txbyte, 0 rcall putchar out OCR0B, sample ; ; loop ; dec loop_count brne sample_loop rjmp main_loop