UKHAS Wiki

UK High Altitude Society

User Tools

Site Tools


communication:avr

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
communication:avr [2007/12/24 12:12] – Hardware update laurencebcommunication:avr [2007/12/24 23:29] (current) – removed laurenceb
Line 1: Line 1:
-====== AVR radio project (by Laurenceb) ====== 
  
- This is designed for data downlink in flight, and based on rocketboys pulse shaping technique. The plan is to use the pwm output of an avr to modulate a[[http://www.radiometrix.co.uk/products/ntx2nrx2.htm|radiometrix ntx2 module]]. This technique has previously been demonstrated to have a range [[communication:basics|in excess of 200Km]] using a pulse shaping modulation technique.  
- 
-===== Hardware design ===== 
- 
-The nxt2 module has an enable pin, that can be used by the avr to save power whilst not transmitting 
- 
-{{communication:ntx2_pinout.gif|}} 
- 
-  
-This apparently takes 3v logic levels, but there is nothing said about a TTL or 5v enable input, only that the voltage on any pin must not exceed vcc, so, for good measure theres a resistor between the avr and the EN pin. One nice feature of the nxt2 is the fact that there appears to be no schmitt trigger on the data input, allowing it to be driven with analogue signal levels. However, the behaviour when subjected to high frequency pwm input has not been examined, so filtering on the pwm will be needed, using an LCR or RC filter. At 300 baud downlink, the frequency of our desired modulation will be in the 150Hz or less range, whereas at 16Mhz clock, the pwm fundamental frequency is 62Khz, so filtering is a fairly easy job.  
- 
- T1 and T2 are 20K and 40K trimpots respectively, C2 and C5 and 100nF, and R2 R5 are 1K. C4 and C5 should be 20pF other values are not critical 
- 
- 
-{{communication:radioschem4.png?700|}} 
- 
-===== AVR code ===== 
- 
- The code has not been tested with anything other than an led as yet, the next aim is to try with a voltage controlled oscillator, and truetty. It will run on a mega48 at 16 or 20Mhz. The RBAUD, CBAUD and F_CPU constants, along with the target uc and all important settings are located at the top of the makefile. The lookup table is then generated by tabletool and stored in program space. You will need the procyon avrlib code timerx8.c, uart.c, and buffer.c to get this to work, but remember to edit the uart code correctly first - [[http://www.mil.ufl.edu/~chrisarnold/components/microcontrollerBoard/AVR/avrlib/|see here for more information on procyon]] 
- 
-==== Main sourcecode====  
-Note that this includes printf debug statements and has inverted enable pin output when debug is defined, to allow an led to go between B.1 and B.2  
- 
-<code c> 
-#include "Radiopulseshaper.h" 
- 
-//#define RBAUD x - use the makefile for these 
-//#define CBAUD x 
-//#define pulse_res (F_CPU/256/RBAUD) //<--  RBAUD with clkdiv=1 
- 
- 
-#ifdef debug 
-int get_char0(FILE* stream) 
-{ 
- int c=-1; 
- while(c==-1) 
- {c=uartGetByte();} //getchar gets the stream, loop until we get something 
- return (u08) c; 
-} 
-  
- 
-int put_char0(char c, FILE *stream) 
-{ 
-   if(uartReadyTx || !uartBufferedTx ) //if buffer is empty or we arent buffered 
-   {uartSendByte(c);                  //sends directly to uart 
- return 0; 
-   } 
-   else 
-   { 
-    //while(!bufferAddToEnd(Txbuff0,c));    //send the character to buffer 
-    if(uartAddToTxBuffer(c)) 
-    {return 0;} 
-    else 
-    {return -1;} 
-   } 
-} 
-#endif 
- 
- 
-void overflow() 
-{ 
-static u08 bufone; 
-timer1PWMASet(bufone); 
-timer1overflows++; 
-if(radioout) 
- { 
-  if(position<pulse_res_minus2) 
-  {position++;} 
- } 
-else 
- { 
-  if(position) 
-  {position--;} 
- } 
-bufone=pgm_read_byte(&sin_l[position]); 
-} 
- 
-void send(unsigned char c) 
-{ 
- u08 n; 
- radioout=0;                              //start bit 
- timer1overflows=0; 
- while(timer1overflows<pulse_res); 
-#ifdef debug 
- printf("send\r\n"); 
-#endif 
- for(n=0;n<=7;n++)                        //byte 
- { 
-  radioout=c&(1<<n); 
-  timer1overflows=0; 
-  while(timer1overflows<pulse_res){}; 
-#ifdef debug 
-  printf("n= %d p= %d\r\n", (int) n, (int) position ); 
-#endif 
- } 
- radioout=1;                              //stop bit 
- timer1overflows=0; 
- while(timer1overflows<pulse_res); 
-#ifdef debug 
- printf("exit\r\n"); 
-#endif 
-} 
- 
-void tuneup() 
-{ 
- radioout=0; 
- timer1overflows=0; 
- while(timer1overflows<(unsigned int)(pulse_res)); 
-#ifdef debug 
- cbi(PORTB,2);                                                    // allow output to stabilise before turn on 
-#else  
- sbi(PORTB,2); 
-#endif 
- while(timer1overflows<(unsigned int)(2*RBAUD*pulse_res));          // 2 second normally 
- radioout=1; 
- timer1overflows=0; 
- while(timer1overflows<(unsigned int)(2*RBAUD*pulse_res));          //2 seconds with altered definition at top 
-} 
- 
-int main() 
-{ 
-int c; 
-u08 radio=1,lenght=0,nodata=0; 
-DDRB=0b00000110; 
-cbi(PORTB,2);                                  //note inverted enable pin 
-uartInit();  
-uartSetBaudRate(CBAUD); 
-#ifdef debug 
-FILE mystdio0 = FDEV_SETUP_STREAM(put_char0, get_char0, _FDEV_SETUP_RW);  //so we can printf to the radio 
-stdout = &mystdio0; //set our stdio out function 
-stdin = &mystdio0; // set our stdio in funciton  
-#endif 
-sei(); 
-timerInit(); 
-timer1SetPrescaler(TIMER_CLK_DIV1); 
-timer1PWMInitICR(255); 
-timer1PWMAOn(); 
-timerAttach(1,overflow); 
-tuneup(); 
-#ifdef debug 
-printf("setup ok\r\n"); 
-#endif 
-while(1) 
-{ 
- c=uartGetByte(); 
- if(c!=-1)                   //there was something in the buffer 
- { 
-#ifdef debug   
-  printf("Got %c\r\n",(char) c); 
-#endif 
-  if(lenght>120 || !radio) 
-  { 
-   radio=1; 
-   //cbi(PORTB,2); 
-   tuneup(); 
-   lenght=0; 
-  } 
-#ifdef debug 
-  printf("sending now, lenght= %d\r\n",(int) lenght); 
-#endif 
-  send((unsigned char) c); 
-  lenght++; 
-  nodata=0; 
- } 
- else 
- { 
-  radio=0; 
-#ifdef debug 
-  sbi(PORTB,2); 
-  printf("waiting...%d\r\n",(int) nodata); 
-#else 
-  cbi(PORTB,2); 
-#endif 
-  for(c=0;c<100;c++) 
-  {_delay_ms(5);} 
-  nodata++; 
-  if(nodata>20) 
-  { 
-   radio=1; 
-   //cbi(PORTB,2); 
-   tuneup(); 
-   radio=0; 
-#ifdef debug 
-   sbi(PORTB,2); 
-#else 
-   cbi(PORTB,2); 
-#endif 
-   nodata=0; 
-  } 
- } 
-} 
-return 0; 
-} 
- 
-</code> 
- 
-==== Header file ==== 
- 
- 
-<code c> 
-#include <avr/interrupt.h> 
-#include <stdio.h> 
-#include <avr/io.h> 
-#include <stdlib.h> 
-#include <util/delay.h> 
-#include <avr/pgmspace.h> 
- 
- 
-#include "global.h" 
-#include "uart.h" 
-#include "buffer.h" 
-#include "avrlibtypes.h" 
-#include "avrlibdefs.h" 
-#include "timerx8.h" 
-#include "default\table.h" 
- 
-#define pulse_res_minus2 pulse_res-2  
-//#define debug                          //uncomment for debugging 
- 
- 
-void overflow(void); 
-void tuneup(void); 
-#ifdef debug 
-int put_char0(char c, FILE *stream); 
-int get_char0(FILE *stream);  
-FILE mystdio0; 
-#endif 
-volatile unsigned int timer1overflows; 
-u08 radioout=1; 
-volatile int position; 
- 
-</code> 
- 
-==== Changes to uart.h ==== 
- 
-<code c> 
-#ifndef UART_TX_BUFFER_SIZE 
-//! Number of bytes for uart transmit buffer. 
-/// Do not change this value in uart.h, but rather override 
-/// it with the desired value defined in your project's global.h 
- #ifdef debug 
-  #define UART_TX_BUFFER_SIZE 0x00FF 
- #else     
-  #define UART_TX_BUFFER_SIZE 0x0000 
- #endif 
-#endif 
-</code> 
- 
-==== Change to uart.c ==== 
- 
- 
-comment out line 244 as so 
- 
-<code c> 
- //uartBufferedTx = FALSE; 
-</code> 
- 
-===== Compile time code ===== 
- 
-==== Tabletool source ==== 
- 
-<code c> 
-#include <stdio.h> 
-#include <stdlib.h> 
-#include <math.h> 
-#include <string.h> 
- 
-int main(int argc, char *argv[]) 
-{ 
-  long F_CPU=(long) atoi(argv[argc-3]); 
-  int RBAUD=(int) atoi(argv[argc-2]); 
-  int CBAUD=(int) atoi(argv[argc-1]);    
-  int pulse_res=(F_CPU/256/RBAUD);  
-  float c; 
-  FILE *fone; 
-  printf("Tabletool by Laurenceb\n configuring radio to use:\n //F_CPU=%d\n //RBAUD=%d\n //CBAUD=%d\n //pulse_res=%d\n",F_CPU,RBAUD,CBAUD,pulse_res); 
-  fone = fopen("table.h","w+"); 
-  fprintf(fone,"//Lookup table \n// F_CPU=%d\n// RBAUD=%d\n// pulse_res=%d\n",F_CPU,RBAUD,pulse_res); 
-  fprintf(fone,"#define pulse_res %d\n",pulse_res); 
-  fprintf(fone,"const uint8_t sin_l[%d] PROGMEM={",pulse_res); 
-  for(c=0;c<pulse_res;c++) 
-  { 
-   fprintf(fone,"%.0f,", 255.0*(1.0-cos(M_PI*c/pulse_res))/2.0); 
-  } 
-  fprintf(fone,"};\n"); 
-  fclose(fone); 
-  //system("PAUSE");  
-  return 0; 
-} 
- 
-</code> 
- 
-==== Makefile ==== 
- 
-<code> 
-############################################################################### 
-# Makefile for the project Radiopulseshaper 
-############################################################################### 
- 
-## General Flags - change F_CPU and RBAUD to suit your project 
-## Begin user editable section 
-PROJECT = Radiopulseshaper 
-MCU = atmega168 
-TARGET = Radiopulseshaper.elf 
-CC = avr-gcc.exe 
-F_CPU=16000000UL 
-RBAUD=300 
-CBAUD=4800 
-## programmer configuration 
-programmer=avrdude  
-programmerinstallation=$(path) 
-programmerarguments=-p m168 -b 19200 -c avr911 -e -P com7 -U flash:w:./Radiopulseshaper.hex:i -v 
-## For other programmers change the -c flag and the -P flag 
-## End user editable section 
- 
-## Options common to compile, link and assembly rules 
-COMMON = -mmcu=$(MCU) 
- 
-## Compile options common for all C compilation units. 
-CFLAGS = $(COMMON) 
-CFLAGS += -Wall -gdwarf-2               -DF_CPU=${F_CPU} -DRBAUD=${RBAUD} -DCBAUD=${CBAUD} -Os -funsigned-char -funsigned-bitfields 
-CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d  
- 
-## Assembly specific flags 
-ASMFLAGS = $(COMMON) 
-ASMFLAGS += $(CFLAGS) 
-ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 
- 
-## Linker flags 
-LDFLAGS = $(COMMON) 
-LDFLAGS +=  -Wl,-Map=radio.map 
- 
- 
-## Intel Hex file production flags 
-HEX_FLASH_FLAGS = -R .eeprom 
- 
-HEX_EEPROM_FLAGS = -j .eeprom 
-HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" 
-HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings 
- 
- 
-## Libraries 
-LIBS = -lc -lm -lprintf_flt -lprintf_min -lscanf_flt -lscanf_min  
- 
-## Objects that must be built in order to link 
-OBJECTS = Radiopulseshaper.o buffer.o timerx8.o uart.o  
- 
-## Objects explicitly added by the user 
-LINKONLYOBJECTS =  
- 
-## Build 
-all: $(TARGET) Radiopulseshaper.hex Radiopulseshaper.eep Radiopulseshaper.lss size 
- ${programmerinstallation}${programmer}${programmerarguments} 
-      
- 
-## Header production code 
-table.h: 
- tabletool ${F_CPU} ${RBAUD} ${CBAUD} 
- 
- 
-## Compile 
-Radiopulseshaper.o: ../Radiopulseshaper.c table.h 
- $(CC) $(INCLUDES) $(CFLAGS) -c  $< 
- 
-buffer.o: ../buffer.c 
- $(CC) $(INCLUDES) $(CFLAGS) -c  $< 
- 
-timerx8.o: ../timerx8.c 
- $(CC) $(INCLUDES) $(CFLAGS) -c  $< 
- 
-uart.o: ../uart.c 
- $(CC) $(INCLUDES) $(CFLAGS) -c  $< 
- 
-##Link 
-$(TARGET): $(OBJECTS) 
- $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET) 
- 
-%.hex: $(TARGET) 
- avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@ 
- 
-%.eep: $(TARGET) 
- -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 
- 
-%.lss: $(TARGET) 
- avr-objdump -h -S $< > $@ 
- 
-size: ${TARGET} 
- @echo 
- @avr-size -C --mcu=${MCU} ${TARGET} 
- 
-## Clean target 
-.PHONY: clean 
-clean: 
- -rm -rf $(OBJECTS) Radiopulseshaper.elf dep/* Radiopulseshaper.hex Radiopulseshaper.eep Radiopulseshaper.lss Radiopulseshaper.map table.h 
- 
- 
-## Other dependencies 
--include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) 
-</code> 
communication/avr.1198498343.txt.gz · Last modified: 2008/07/19 23:30 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki