December 22, 2012
by keith712
|
i searched the forums but so far i haven't found anything about my latest problem
here's my makefile:
GCCFLAGS=-g -Os -Wall -mmcu=atmega168
LINKFLAGS=-Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt -lm
AVRDUDEFLAGS=-c avr109 -p m168 -b 115200 -P /dev/cu.usbserial
LINKOBJECTS=../libnerdkits/delay.o ../libnerdkits/lcd.o ../libnerdkits/uart.o
all:rtACSxLCD-upload
rtACSxLCD.hex:rtACSxLCD.c
make -C ../libnerdkits
avr-gcc ${GCCFLAGS} ${LINKFLAGS} -o rtACSxLCD.o rtACSxLCD.c ${LINKOBJECTS}
avr-objcopy -O ihex rtACSxLCD.hex
rtACSxLCD.ass:rtACSxLCD.hex
avr-objdump -S -d rtACSxLCD.o > rtACSxLCD.ass
rtACSxLCD-upload: rtACSxLCD.hex
avrdude ${AVRDUDEFLAGS} -e
sleep 1.0
avrdude ${AVRDUDEFLAGS} -D -U flash:w:rtACSxLCD.hex:a
here's my source:
//
//
// repeated transorbital Alernating Current Stimulation (rtAc)
// square wave pulse with both + and - polarity and duty cycle generator
// November2012
// keithmac@maui.net
//
// modified December2012 to use LCD to communicate with user
//
// ACS output signal needs to be run through a 100Kohm potentiomenter
// to reduce voltage to treatment levels (threshold voltage)
//
// ACS will need to be split into separate leads for each eye
//
// ACS polarity inversion accomplished by having two output channels wired opposite
// of each other and using 2N7000 (npn) transistors to switch ground and signal leads
//
// hardware:
// ATmega168 at 14.7456MHz, +5V
// LCD uses HD44780 protocol
//
// ATmega168 pins:
// PC0 unused
// PC1 "
// PC2 "
// PC3 "
// PC4 (pin 27) signal output pin
// PC5 (pin 28) signal output pin
// PC6 RESET
//
// PD2-5 (pins 4,5,6,11) = LCD DB4-7 (pins 11,12,13,14) lcd data input
// PD6 (pin 12) = LCD E (pin 6) low nibble or high nibble data switch
// PD7 (pin 13) = LCD RS (pin 4) command or data switch
//
//
// delay.h needs to know clock frequency
//
#define F_CPU 14745600UL // 14.7456MHz
//
// std c library
//
#include <stdlib.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
//#include <util/delay.h>
#include <inttypes.h>
//
// nerdkits c library
//
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
//
// notes to myself:
// use these values to calculate tCnt and time of treatment
// 0.5281s/1cycle/1pulse 1cycle=(5.7,8.0,11.3,16.0,22.6,32.0)
// 1min rest between blocks of cycles
//
//
// functions to be called by main():
// lcd_clear_all()
// pulse()
//
void lcd_clear_all() {
//
// 20 columns x 4 lines
//
lcd_goto_position(0,0);
lcd_write_string(PSTR(" "));
lcd_goto_position(1,0);
lcd_write_string(PSTR(" "));
lcd_goto_position(2,0);
lcd_write_string(PSTR(" "));
lcd_goto_position(3,0);
lcd_write_string(PSTR(" "));
lcd_goto_position(0,0);
}
//
void pulse(uint8_t cMx) {
//
// loop counter
//
uint8_t c;
//
// signal output pins
//
DDRC |= (1<<PC4);
DDRC |= (1<<PC5);
//
// pulse loops
//
c=cMx;
while(c > 0) {
PORTC |= (1<<PC4);
delay_us(44194);
delay_us(44194);
PORTC &= ~(1<<PC4);
PORTC |= (1<<PC5);
delay_us(44194);
delay_us(44194);
PORTC &= ~(1<<PC5);
c--;
}
c=cMx;
while(c>0) {
PORTC |= (1<<PC4);
delay_us(62500);
PORTC &= ~(1<<PC4);
PORTC |= (1<<PC5);
delay_us(62500);
PORTC &= ~(1<<PC5);
c--;
}
c=cMx;
while(c>0) {
PORTC |= (1<<PC4);
delay_us(44194);
PORTC &= ~(1<<PC4);
PORTC |= (1<<PC5);
delay_us(44194);
PORTC &= ~(1<<PC5);
c--;
}
c=cMx;
while(c>0) {
PORTC |= (1<<PC4);
delay_us(31250);
PORTC &= ~(1<<PC4);
PORTC |= (1<<PC5);
delay_us(31250);
PORTC &= ~(1<<PC5);
c--;
}
c=cMx;
while(c>0) {
PORTC |= (1<<PC4);
delay_us(22097);
PORTC &= ~(1<<PC4);
PORTC |= (1<<PC5);
delay_us(22097);
PORTC &= ~(1<<PC5);
c--;
}
c=cMx;
while(c>0) {
PORTC |= (1<<PC4);
delay_us(15625);
PORTC &= ~(1<<PC4);
PORTC |= (1<<PC5);
delay_us(15625);
PORTC &= ~(1<<PC5);
c--;
}
}
int main() {
//
// internal RC oscillator calibration for 8MHz
// the RC oscillator is the clock for read/write to flash memory
// 8.8MHz is maximum rate; read/writes may fail at higher clock rates
// ATmega168 data sheet p38 and table 28-1 on p308 have data on internal RC clock
// 176 = 10110000 = 8MHz (this value comes from musicbox.c)
// 160 = 10100000
// 144 = 10010000
// 128 = 10000000 = lowest value in upper range
// (which is less than the highest value in the lower range = 00001111)
//
OSCCAL = 176;
//
// initialize lcd
//
lcd_init();
//
// display duration -- edit for each change in treatment protocol
//
lcd_write_string(PSTR("treatment will take"));
lcd_goto_position(1,0);
lcd_write_string(PSTR("about 16 minutes")); // edit this time depending on pulse number
delay_ms(8000);
//
//
//
lcd_clear_all();
lcd_goto_position(0,0);
lcd_write_string(PSTR("adj thrshld volts"));
lcd_goto_position(1,0);
lcd_write_string(PSTR("start 10sec of"));
lcd_goto_position(2,0);
lcd_write_string(PSTR("pulses at 6Hz"));
delay_ms(5000);
//
// signal output pins
//
DDRC |= (1<<PC4);
DDRC |= (1<<PC5);
//
// pulses for threshold voltage adjust
//
uint8_t c=64;;
while(c > 0) {
PORTC |= (1<<PC4);
delay_us(44194);
delay_us(44194);
PORTC &= ~(1<<PC4);
PORTC |= (1<<PC5);
delay_us(44194);
delay_us(44194);
PORTC &= ~(1<<PC5);
c--;
}
//
// end voltage adjust
//
lcd_clear_all();
lcd_goto_position(0,0);
lcd_write_string(PSTR("end thrshld adj"));
lcd_goto_position(1,0);
lcd_write_string(PSTR("16min treatment")); // edit time depending on pulse number
lcd_goto_position(2,0);
lcd_write_string(PSTR("starts in 10sec"));
lcd_goto_position(3,0);
lcd_write_string(PSTR(""));
delay_ms(10000);
//
// initialize loop counters
//
int16_t sCnt=256;
int16_t tCnt=948; //edit depending on pulse count
//
// start treatment loop
//
while (sCnt>0) {
//
// display time left
//
lcd_clear_all();
lcd_goto_position(1,1);
lcd_write_string(PSTR("about "));
lcd_write_int16(tCnt/60);
lcd_write_string(PSTR(" min left"));
//
// left & right eye pulsed at the same time
//
pulse(2);
//
// one second rest between sets
//
delay_ms(1000);
//
// decrement loop counter
//
sCnt--;
//
//
// one minute rest between blocks of sets
//
if(sCnt%32==0 && sCnt>0) {
tCnt-=126;
lcd_goto_position(2,2);
lcd_write_string(PSTR("1 minute rest"));
delay_ms(60000);
}
}
//
// end treatment loop
//
lcd_clear_all();
lcd_goto_position(3,1);
lcd_write_string(PSTR("treatment complete"));
return 0;
}
and here's the error message i get when i compile:
k712:rtACS k712$ make
make -C ../libnerdkits
make[1]: Nothing to be done for `all'.
avr-gcc -g -Os -Wall -mmcu=atmega168 -Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt -lm -o rtACSxLCD.o rtACSxLCD.c ../libnerdkits/delay.o ../libnerdkits/lcd.o ../libnerdkits/uart.o
avr-objcopy -O ihex rtACSxLCD.hex
avr-objcopy: 'rtACSxLCD.hex': No such file
make: *** [rtACSxLCD.hex] Error 1
i can't see why the hex file is not being made or saved... pls help me again!!!
k |
December 23, 2012
by keith712
|
thanks... i put '-j .text' back in and the code compiled... YAY
but now my LCD display is back to the crazy stuff described in support>>atmega168 and atmega328p projects... BOO
i originally removed the '-j .text' on a suggestion given to me by Rick_S to look at a thread called Ubuntu LCD problems...
anyway i've been experimenting with various combinations of -Os and -O0 in the first line of the makefile and adding or deleting -j .text in the avr-objcopy line and i finally got a compiled version that displays as expected on the LCD by using -O0 on line one and deleting -j .text from the avr-objcopy line... the .hex file not found error 1 message has mysteriously disappeared!!!
of course, now i'm worried about the difference -Os and -O0 make in the hex code and what's happening to the code if i don't include the -j .text in avr-objcopy...
i haven't done too much digging around for references on makefiles because i'm still busy learning c, studying the datasheet and wiring up projects...
thanks again for all your help... it's much much much appreciated... Merry Christmas... k |