Below is the code for the 90S2313 micro. I compiled it in Codevision and had no errors. There are two warnings that will come up "unreferenced variable count_h" and "unreferenced variable T0_count". You will also have to increase the Data Stack size.
The included files near the start are part of Codevision. If you use another compiler you will have to use the corresponding files for that compiler.
Have fun and I hope you get something working from it.
Rick
This program was produced by the
CodeWizardAVR V1.24.3b Evaluation
Automatic Program Generator
© Copyright 1998-2004 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
e-mail:office@hpinfotech.com
Project :
Version :
Date : 8/15/2004
Author : Freeware, for evaluation and non-commercial use only
Company :
Comments:
Chip type : AT90S2313
Clock frequency : 10.000000 MHz
Memory model : Tiny
External SRAM size : 0
Data Stack size : 32
************************************************** ***/
#include <90s2313.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x18
#endasm
// included files are all in Codevision
#include <lcd.h>
#include <90s2313.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <delay.h>
//
#define enable_i #asm("sei") // global enable interrupts
#define disable_i #asm("cli") // global disable interrupts
//
// now a bunch of port definitions
//
#define relay_ON PORTD.2 = 1
#define relay_OFF PORTD.2 = 0
#define polarize_ON PORTD.3 = 1
#define polarize_OFF PORTD.3 = 0
#define squelch_ON PORTD.6 = 1
#define squelch_OFF PORTD.6 = 0
//
// Declare your global variables here
//
flash float alpha = 2.4051189e11; // value for 1024 proton cylces and
a 10 MHz clock
long value;
flash char SignOnLogo[]="RICK'S MAG";
#pragma regalloc-
//
unsigned char counth, error, T0_count;
//
// the following global variables are used in the UART receive
interrupt routine
//
//
// prototype declarations
//
void polarize(void);
void WriteResult(void);
void measure(void);
void report(void);
//
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In
Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T
State0=T
PORTB=0x00;
DDRB=0x00;
// Port D initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=DDRD|00x4c;
// Timer/Counter 0 initialization
// Clock source: T0 pin Falling Edge
TCCR0=0x06;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 10000.000 kHz
// Mode: Normal top=FFFFh
// OC1 output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x01;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1H=0x00;
OCR1L=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
GIMSK=0x00;
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x82;
// UART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// UART Receiver: On
// UART Transmitter: On
// UART Baud rate: 9600
UCR=0x18;
UBRR=0x40;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
// LCD module initialization
lcd_init(16);
// Global enable interrupts
#asm("sei")
//
lcd_init(16);
lcd_gotoxy(0,0);
lcd_putsf(SignOnLogo);
//
polarize();
//
measure();
//
report();
//
WriteResult();
//
}
//
void polarize(void)
{
//
// the routine which turns the HEXFET's and relay on and off
//
squelch_ON;
delay_ms(3); // wait three mS
relay_ON;
delay_ms(20); // wait 20 mS
polarize_ON;
delay_ms(5000); //polarization time
polarize_OFF;
delay_ms(10);
relay_OFF;
delay_ms(70);
squelch_OFF;
delay_ms(15);
}
void measure(void){
/*
This is all done in assembler. Basically, the program looks at
the T0 input
and waits for a trailing edge. Just to be on the safe side, it first
looks for a trailing edge,
then a leading edge and finally, another trailing edge. The T0 timer
is set up to read this
signal as an input and to toggle on a trailing edge.The T0 interrupt
routine is set to be activated on
T0 overflow. It is zeroed to start with and the number of overflows is
counted with T0_COUNT.
After 1024 cycles of the signal (four T0 overflows) T1 is turned off in
this routine.
While this is happening,the T1 timer is running at the clock
rate of 10.0 MHz. On each overflow of T1, it's interrupt routine
increments the variable,
COUNTH. When T0 overflows, the T1 timer is stopped. At this time, the
total number
of clock cycles will be a three byte number with COUNTH as the most
significant byte
with T1H, the next most and T1L the least significant byte.
*/
#asm
.equ pd = 0x10 ; PIND
.equ t0 = 0x32 ; TCNT0
.equ t1h = 0x2d ; TCNT1H
.equ t1l = 0x2c ; TCNT1L
.equ t0cntl = 0x33 ; TCCR0
.equ t1cntl = 0x2e ; TCCR1B
.equ tmsk = 0x39 ; TIMSK
push r31
cli ; disable interrupts
clt ; clear T flag
ldi r31,0
out t0cntl,r31 ; stop T0 tcnto
out t1cntl,r31 ; stop T1 tccr1b
out t0,r31 ; reset counter 0 to 0 tcnto
out t1h,r31 ; reset counter 1 HIGH to 0 tcnt1h
out t1l,r31 ; reset counter 1 LOW to 0 tcnt1l
sts _counth,r31 ; set COUNTH to 0
sts _error,r31 ; set ERROR to 0
sts _T0_count,r31 ; set T0_count to 0 also
ldi r31,0x82
out tmsk,r31 ; enable T0 and T1 overflow interrupts
loop1:
sbic pd,4 ; skip if input is low
rjmp loop1 ; otherwise, go back
;
; it only gets here if the input is low
;
loop2:
sbis pd,4 ; skip if the input is high
rjmp loop2
;
; it only gets here if the input is high
;
loop3:
sbic pd,4 ; skip if the input is low
rjmp loop3
; finally, the input has just gone low when it gets here
; and we''re ready to count trailing edges
;
ldi r31,0x06 ; set T0 to count on external input,
trailing edge
out t0cntl,r31
ldi r31,1 ; set T1 to count at the clock rate
out t1cntl,r31
sei ; and ENABLE interrupts to let ''er
rip!
;
; when it is done, the T0_COUNT will be 4
;
waitloop:
lds r31,_T0_count
cpi r31,4 ; is it four overflows?
breq is_done
lds r31, _counth
subi r31,90 ; subtract 90 from counth
brpl is_error ; if result is negative, it is OK
rjmp waitloop ; otherwise, it is an error
is_error:
ldi r31,1
sts _error,r31
is_done:
ldi r31,0
out t1cntl,r31 ; stop T1
out t0cntl,r31 ; and T0
pop r31
#endasm
}
//
void report(void){
//
#asm
push r23
ldi r23,0
sts _value+3,r23
lds r23,_counth
sts _value+2,r23
in r23,0x2c ; TCNT1L
sts _value,r23
in r23,0x2d ; TCNT1H
sts _value+1,r23
pop r23
#endasm
value = (long) (alpha / value);
if (error) value = 999999L; //returns 99999 on lcd
}
void WriteResult(void)
{
//
char str[16];
lcd_gotoxy(0,1);
ltoa(value,str);
lcd_puts(str);
}
//Below are the timer interrupt routines.
#pragma savereg-
interrupt [TIM1_OVF] void timer1_overflow(void) {
#asm
push r30
in r30,SREG
push r30
lds r30,_counth
inc r30
sts _counth,r30
pop r30
out SREG,r30
pop r30
#endasm
}
interrupt [TIM0_OVF] void timer0_overflow(void)
{
// TCCR1B = 0; // stop T1
// #asm("set") // set T flag
#asm
push r30
in r30,SREG
push r30
lds r30, _T0_count
inc r30
sts _T0_count,r30
cpi r30,4
brne isnt_finished
;
; if here, it is finished counting so I should clear TCCR1B
;
clr r30 ; set TCCR1B to 0
out 0x2e,r30
isnt_finished:
pop r30
out SREG,r30
pop r30
#endasm
}
#pragma savereg+
The included files near the start are part of Codevision. If you use another compiler you will have to use the corresponding files for that compiler.
Have fun and I hope you get something working from it.
Rick
This program was produced by the
CodeWizardAVR V1.24.3b Evaluation
Automatic Program Generator
© Copyright 1998-2004 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
e-mail:office@hpinfotech.com
Project :
Version :
Date : 8/15/2004
Author : Freeware, for evaluation and non-commercial use only
Company :
Comments:
Chip type : AT90S2313
Clock frequency : 10.000000 MHz
Memory model : Tiny
External SRAM size : 0
Data Stack size : 32
************************************************** ***/
#include <90s2313.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x18
#endasm
// included files are all in Codevision
#include <lcd.h>
#include <90s2313.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <delay.h>
//
#define enable_i #asm("sei") // global enable interrupts
#define disable_i #asm("cli") // global disable interrupts
//
// now a bunch of port definitions
//
#define relay_ON PORTD.2 = 1
#define relay_OFF PORTD.2 = 0
#define polarize_ON PORTD.3 = 1
#define polarize_OFF PORTD.3 = 0
#define squelch_ON PORTD.6 = 1
#define squelch_OFF PORTD.6 = 0
//
// Declare your global variables here
//
flash float alpha = 2.4051189e11; // value for 1024 proton cylces and
a 10 MHz clock
long value;
flash char SignOnLogo[]="RICK'S MAG";
#pragma regalloc-
//
unsigned char counth, error, T0_count;
//
// the following global variables are used in the UART receive
interrupt routine
//
//
// prototype declarations
//
void polarize(void);
void WriteResult(void);
void measure(void);
void report(void);
//
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In
Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T
State0=T
PORTB=0x00;
DDRB=0x00;
// Port D initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=DDRD|00x4c;
// Timer/Counter 0 initialization
// Clock source: T0 pin Falling Edge
TCCR0=0x06;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 10000.000 kHz
// Mode: Normal top=FFFFh
// OC1 output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x01;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1H=0x00;
OCR1L=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
GIMSK=0x00;
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x82;
// UART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// UART Receiver: On
// UART Transmitter: On
// UART Baud rate: 9600
UCR=0x18;
UBRR=0x40;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
// LCD module initialization
lcd_init(16);
// Global enable interrupts
#asm("sei")
//
lcd_init(16);
lcd_gotoxy(0,0);
lcd_putsf(SignOnLogo);
//
polarize();
//
measure();
//
report();
//
WriteResult();
//
}
//
void polarize(void)
{
//
// the routine which turns the HEXFET's and relay on and off
//
squelch_ON;
delay_ms(3); // wait three mS
relay_ON;
delay_ms(20); // wait 20 mS
polarize_ON;
delay_ms(5000); //polarization time
polarize_OFF;
delay_ms(10);
relay_OFF;
delay_ms(70);
squelch_OFF;
delay_ms(15);
}
void measure(void){
/*
This is all done in assembler. Basically, the program looks at
the T0 input
and waits for a trailing edge. Just to be on the safe side, it first
looks for a trailing edge,
then a leading edge and finally, another trailing edge. The T0 timer
is set up to read this
signal as an input and to toggle on a trailing edge.The T0 interrupt
routine is set to be activated on
T0 overflow. It is zeroed to start with and the number of overflows is
counted with T0_COUNT.
After 1024 cycles of the signal (four T0 overflows) T1 is turned off in
this routine.
While this is happening,the T1 timer is running at the clock
rate of 10.0 MHz. On each overflow of T1, it's interrupt routine
increments the variable,
COUNTH. When T0 overflows, the T1 timer is stopped. At this time, the
total number
of clock cycles will be a three byte number with COUNTH as the most
significant byte
with T1H, the next most and T1L the least significant byte.
*/
#asm
.equ pd = 0x10 ; PIND
.equ t0 = 0x32 ; TCNT0
.equ t1h = 0x2d ; TCNT1H
.equ t1l = 0x2c ; TCNT1L
.equ t0cntl = 0x33 ; TCCR0
.equ t1cntl = 0x2e ; TCCR1B
.equ tmsk = 0x39 ; TIMSK
push r31
cli ; disable interrupts
clt ; clear T flag
ldi r31,0
out t0cntl,r31 ; stop T0 tcnto
out t1cntl,r31 ; stop T1 tccr1b
out t0,r31 ; reset counter 0 to 0 tcnto
out t1h,r31 ; reset counter 1 HIGH to 0 tcnt1h
out t1l,r31 ; reset counter 1 LOW to 0 tcnt1l
sts _counth,r31 ; set COUNTH to 0
sts _error,r31 ; set ERROR to 0
sts _T0_count,r31 ; set T0_count to 0 also
ldi r31,0x82
out tmsk,r31 ; enable T0 and T1 overflow interrupts
loop1:
sbic pd,4 ; skip if input is low
rjmp loop1 ; otherwise, go back
;
; it only gets here if the input is low
;
loop2:
sbis pd,4 ; skip if the input is high
rjmp loop2
;
; it only gets here if the input is high
;
loop3:
sbic pd,4 ; skip if the input is low
rjmp loop3
; finally, the input has just gone low when it gets here
; and we''re ready to count trailing edges
;
ldi r31,0x06 ; set T0 to count on external input,
trailing edge
out t0cntl,r31
ldi r31,1 ; set T1 to count at the clock rate
out t1cntl,r31
sei ; and ENABLE interrupts to let ''er
rip!
;
; when it is done, the T0_COUNT will be 4
;
waitloop:
lds r31,_T0_count
cpi r31,4 ; is it four overflows?
breq is_done
lds r31, _counth
subi r31,90 ; subtract 90 from counth
brpl is_error ; if result is negative, it is OK
rjmp waitloop ; otherwise, it is an error
is_error:
ldi r31,1
sts _error,r31
is_done:
ldi r31,0
out t1cntl,r31 ; stop T1
out t0cntl,r31 ; and T0
pop r31
#endasm
}
//
void report(void){
//
#asm
push r23
ldi r23,0
sts _value+3,r23
lds r23,_counth
sts _value+2,r23
in r23,0x2c ; TCNT1L
sts _value,r23
in r23,0x2d ; TCNT1H
sts _value+1,r23
pop r23
#endasm
value = (long) (alpha / value);
if (error) value = 999999L; //returns 99999 on lcd
}
void WriteResult(void)
{
//
char str[16];
lcd_gotoxy(0,1);
ltoa(value,str);
lcd_puts(str);
}
//Below are the timer interrupt routines.
#pragma savereg-
interrupt [TIM1_OVF] void timer1_overflow(void) {
#asm
push r30
in r30,SREG
push r30
lds r30,_counth
inc r30
sts _counth,r30
pop r30
out SREG,r30
pop r30
#endasm
}
interrupt [TIM0_OVF] void timer0_overflow(void)
{
// TCCR1B = 0; // stop T1
// #asm("set") // set T flag
#asm
push r30
in r30,SREG
push r30
lds r30, _T0_count
inc r30
sts _T0_count,r30
cpi r30,4
brne isnt_finished
;
; if here, it is finished counting so I should clear TCCR1B
;
clr r30 ; set TCCR1B to 0
out 0x2e,r30
isnt_finished:
pop r30
out SREG,r30
pop r30
#endasm
}
#pragma savereg+
Comment