/********************************************* Laser Communication System Transmitter File Authors: Keith Carter, Michael Muccio Cornell University, Electrical and Computer Engineering ECE 476, Spring 2003 This program is used to program a Mega32 MCU to be the transmitter for a serial voice data laser communication system. It utilizes a timer and ADC interrupt to ensure 3kHz voice sampling. Chip type : ATmega32 Program type : Application Clock frequency : 16.000000 MHz Memory model : Small Internal SRAM size : 2048 External SRAM size : 0 Data Stack size : 512 *********************************************/ #include #include #include #include #include //set baud for 27.7 kbps #define baudnum 36 #define halfbaudnum 18 //set ADC reference to AREF #define ADC_VREF_TYPE 0x20 //timeout value for task1 voice sampler //a value of 1 ensures the task executes at //every overflow #define t1 1 //global variables char bitcnt; // bit counter char Txbyte; // data to be transmitted char sb; // number of stop bits (1, 2, ...) char carry; // carry bit unsigned char reload; // timer 0 reload int time1; // timeout counter unsigned char temp; // temporary data holder //the task subroutine void task1(void); //the data transmit subroutine void put(void); //********************************************************** //timer 0 overflow ISR interrupt [TIM0_OVF] void timer0_overflow(void) { //reload to force overflow period TCNT0=reload; //decrement the time if not zero if (time1>0) --time1; } // ADC interrupt service routine interrupt [ADC_INT] void adc_isr(void) { // Read the 8 most significant bits // of the AD conversion result and // transfer to the transmit byte Txbyte=ADCH; temp=Txbyte; put(); } //********************************************************** //Task 1 void task1(void) { time1=t1; //reset the task timer ADCSR.6=1; //initiate ADC conversion PORTB=temp; //send result to PORTB for debugging } //Transmit Byte void put(void) { bitcnt=9+sb; //initiate bit counter Txbyte=~Txbyte; //invert byte for easier handling carry=1; //set carry to 1 for start bit //while loop transmits the data bits using delay while(bitcnt>0) { //transmit opposite of what is in carry if (carry) { PORTD.1=0; } else { PORTD.1=1; #asm("nop") } delay_us(baudnum); //1 bit delay carry=(Txbyte&0b00000001); //move LSB to carry1 Txbyte=Txbyte>>1; //shift transmit byte right bitcnt--; //decrement bitcnt, 1 bit sent } } void main(void) { //set up timer 0 reload=256-21; //value for about 1/3 Msec at 16 MHz TCNT0=reload; //initial reload TIMSK=1; //turn on timer 0 overflow ISR TCCR0=4; //prescalar to 256 //init the task timers time1=t1; DDRB=0xff; //direction for debugging port DDRD=0b00000010; //direction for UART pins sb=1; // set to 1 stop bit // ADC initialization // ADC Clock frequency: 125.000 kHz // ADC Voltage Reference: AREF pin // Only the 8 most significant bits of // the AD conversion result are used ADMUX=ADC_VREF_TYPE; ADCSR=0x8F; // Global enable interrupts #asm("sei") //infinite loop ensures task1 executes at evey overflow //ISRs do the rest of the work while (1) { //execute task1 when time1 is 0 if (time1==0) task1(); } }