Hab den Code noch gefunden.
[code:1:b3daeccd1f]
/*
Title: AVR-GCC "SSDC"
Author: Zoltan
Date: 2003,01.05
Purpose: Submarine Stabilizer and Depth Control
Software: AVR-GCC to compile
Hardware: AT90S4433
Note: 8Mhz
v0.9
http://ngrad.bei.t-online.de/microkontroller.htm
*/
#include <compat>
#include <io>
#include <sig>
#include <interrupt>
#include <inttypes>
#include <progmem>
void send_puls (uint16_t x); // Prototypes
void calculate (uint16_t x);
void uart_send(uint8_t x);
uint16_t u16from2u08(uint8_t a,uint8_t b);
int16_t PD(int16_t x);
uint16_t sample_ADC_Inclinometer(void);
uint16_t sample_ADC_Pressure(void);
uint16_t sample_ADC_Temperature(void);
struct // Variables stored in 1Byte
{//
uint8_tb_transmit_on:1;// b_transmit_on needs 1 bit
uint8_tb_i:4;//
}x;// accessing values with x.b_i=...
uint8_t U, R, S, Korr_pressure=0;//Variables
uint16_t Puls_l, Wert1=1536, Puls_l_old, inclinometer_old; //Puls_l: lenght of incoming puls
uint16_t P=1,D=1,O=127, b=0;
int16_t pd_sum, pd;
uint8_t Uart_Recieved[16];
uint16_t damping_inclinometer[128];//0..64
uint16_t damping_pressure[16];//0..16
uint16_t damping_temperature[16];//0..16
int8_t __attribute__ ((progmem)) temp_correcture_values[1024]={0,0,0,0}; //1024 values for temperatur compensating
uint32_t inclinometer_alt;
int main(void)
{cli();
DDRB=0xFF; // use PortB for output (to servo)
DDRD=0x00; // use PortD PIN2 for input (signal)
PORTD=0x07; // pull up PIN 0,1,2
DDRC=0x30; // use PortC for output
GIMSK= (1<<INT0); // enable external int0 (PD2)
MCUCR=(0<<ISC01)|(1<<ISC00);
// any logical change creates interrupt0
ADCSR=(1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS0);
//UCSRB=(1<<UCSZ2);// setup USART for 9.Bit T/R
//UCSRC=(1<<UCSZ1)|(1<<UCSZ0>2000 cycles
}// 1ms-->1000 cycles
// 1,5ms-->1500 cycles...
}
//////////////////////////////////////////////////////////////////////////////////////////
// recieve from USART stopps the program untill all values arrived-> opens UART recieve //
// 9bit for USART transmit synchronisation//
//////////////////////////////////////////////////////////////////////////////////////////
SIGNAL(SIG_UART_RECV)
{
outp((1>>INT0), GIMSK); // disable external int0
x.b_transmit_on=1;// termnal programm->set next signal for first(uart_send)
cli();
do
{
while(bit_is_clear(UCSRA, RXC)){}// Wait for data to be received
Uart_Recieved[x.b_i] = inp(UDR); // get the character
x.b_i++;
//if ( UCSRA & (1<<FE)|(1<<DOR)|(1<<PE) )//check for errors
//return -1; // if error, return -1
}
while(x.b_i<4> P
//D=Uart_Recieved[1];// second signal --> D ....
//Wert1=u16from2u08(Uart_Recieved[2],Uart_Recieved[3]);
O=Uart_Recieved[3];
/*O=Uart_Recieved[4];
O=Uart_Recieved[5];
O=Uart_Recieved[6];
O=Uart_Recieved[7];
O=Uart_Recieved[8];
O=Uart_Recieved[9];
O=Uart_Recieved[10];
O=Uart_Recieved[11];
O=Uart_Recieved[12];
O=Uart_Recieved[13];
O=Uart_Recieved[14];
O=Uart_Recieved[15];*/
x.b_i=0;
cbi(UCSRB, RXEN);// UART recieve off
outp((1<<INT0), GIMSK);// enable external int0
}
//////////////////////////////////////////////////////////////////////////////////////////
// generates 16 bit value out of two 8 bit //
//////////////////////////////////////////////////////////////////////////////////////////
uint16_t u16from2u08(uint8_t a,uint8_t b)// a=LowBit, b=HigBit
{
uint16_t tmp;
tmp=b;// 2x 8bit in ...a=LowBit
tmp<<8>(1/8000000)*32*13*32-->3,33ms
{ // 1/fCK* DivFactor* ConvCykl* j
uint16_t adc_conv=0, ADC=0;
uint8_t adc_l=0, adc_h=0, j=0 ;
outp((1<<ADEN)|(0<<ADSC)|(0<<ADFR)|(1<<ADPS2)|(1<<ADPS0),ADCSR);//enable ADC single conversion
ADMUX = 0; // select channel (PC0)
sbi(PORTB,0);// for oszilloscope
sbi(SFIOR,ADHSM);//ADC High Speed Mode ON
for(j=0;j<40>(1/8000000)*32*13*32-->3,33ms
{ // 1/fCK* DivFactor* ConvCykl* j
uint16_t adc_conv=0, ADC=0;
uint8_t adc_l=0, adc_h=0, j=0 ;
outp((1<<ADEN)|(0<<ADSC)|(0<<ADFR)|(1<<ADPS2)|(1<<ADPS0),ADCSR);//enable ADC single conversion
ADMUX = 1; // select channel (PC1)
sbi(PORTB,0);// for oszilloscope
sbi(SFIOR,ADHSM);//ADC High Speed Mode ON
for(j=0;j<20>(1/8000000)*32*13*32-->3,33ms
{ // 1/fCK* DivFactor* ConvCykl* j
uint16_t adc_conv=0, ADC=0;
uint8_t adc_l=0, adc_h=0, j=0 ;
outp((1<<ADEN)|(0<<ADSC)|(0<<ADFR)|(1<<ADPS2)|(1<<ADPS0),ADCSR);//enable ADC single conversion
ADMUX = 2; // select channel (PC2)
sbi(PORTB,0);// for oszilloscope
sbi(SFIOR,ADHSM);//ADC High Speed Mode ON
for(j=0;j<64>>=8;
H=tmp;
uart_send(L);//Wert1 ->PC_1
uart_send(H);//Wert1 ->PC_2
summe=0;
for(dea=(127);dea>0;dea--)//shiften um 1 nach links
{
damping_inclinometer[dea]=damping_inclinometer[(dea-1)];
}
damping_inclinometer[0]=(uint16_t)inclinometer; //an die "0-te" stelle schreiben
for(dea=0;dea<128>0;dea--)//shiften um 1 nach links
{
damping_pressure[dea]=damping_pressure[(dea-1)];
}
damping_pressure[0]=(uint16_t)pressure; //an die "0-te" stelle schreiben
for(dea=0;dea<16>0;dea--)//shiften um 1 nach links
{
damping_temperature[dea]=damping_temperature[(dea-1)];
}
damping_temperature[0]=(uint16_t)temperature; //an die "0-te" stelle schreiben
for(dea=0;dea<16>>=8;
H=tmp;
uart_send(L);//Wert1 ->PC_3
uart_send(H);//Wert1 ->PC_4
inclinometer += PRG_RDB(&temp_correcture_values[temperature]);
// use in flash stored values to compensate temperatur drift on sensor
// to gather values make temperature callibration run-> 0..40°C = 0..1024
tmp=(uint16_t)inclinometer;
L=tmp;// 16bit into 2x 8bit
tmp>>=8;
H=tmp;
uart_send(L);//Wert1 ->PC_5
uart_send(H);//Wert1 ->PC_6
tmp=(uint16_t)pressure;
L=tmp;// 16bit into 2x 8bit
tmp>>=8;
H=tmp;
uart_send(L);//Wert1 ->PC_7
uart_send(H);//Wert1 ->PC_8
tmp=(uint16_t)temperature;
L=tmp;// 16bit into 2x 8bit
tmp>>=8;
H=tmp;
uart_send(L);//Wert1 ->PC_9
uart_send(H);//Wert1 ->PC_10
inclinometer=PD(inclinometer);
pressure-=Korr_pressure; // 1 = 3mm--> zB. 250mm= +84
//if(pressure <0>>=8;
H=Wert1Temp;
send_puls(Puls_l);// jump to: void output (...)
}
//////////////////////////////////////////////////////////////////////////////////////////
// Proportional differential algorithm for inclinometer//
//////////////////////////////////////////////////////////////////////////////////////////
int16_t PD(int16_t incl)
{
int16_t temp;
static int16_t incl_alt;
int16_t pp;
uint16_t tmp;
uint8_t H,L;
incl-=650;
/*
if(S==O)
{
pd=(pd_sum*D);
pd_sum=0;
S=0;
}
else
{
pd_sum += (incl - incl_alt) ;//pd: -1000..+1000
if((pd_sum>-2) && (pd_sum<2>>=8;
H=tmp;
uart_send(0);//Wert1 ->PC_11
uart_send(0);//Wert1 ->PC_12
tmp=(uint16_t)pd;
L=tmp;// 16bit into 2x 8bit
tmp>>=8;
H=tmp;
uart_send(L);//Wert1 ->PC_13
uart_send(H);//Wert1 ->PC_14
temp=pp+pd;
return temp;
}
//////////////////////////////////////////////////////////////////////////////////////////
// UART sent (9bit)//
//////////////////////////////////////////////////////////////////////////////////////////
void uart_send(uint8_t BYTE)
{
x.b_transmit_on=1;//nur fürs testen
if(x.b_transmit_on)
{
sbi(UCSRB,TXEN); // TX aktivieren
while (bit_is_clear(UCSRA,UDRE));// Warten, bis UDRE eins ist-->UDR ist leer
outp(BYTE,UDR); // BYTE in das UDR Register schreiben
cbi(UCSRB,TXEN);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
// send_puls signal generation PortB0 //
//////////////////////////////////////////////////////////////////////////////////////////
void send_puls (uint16_t Puls_l_out) // Use Puls_l to create puls for Servo
{
cli();
uint16_t k;
if((Puls_l_out>(Puls_l_old-3)) && (Puls_l_out<Puls_l_old>3280)
{
Puls_l_out=3280;
}
if(Puls_l_out<1050)
{
Puls_l_out=1050;
}
sbi(PORTB,0);// START to sent the signal to the servo
for(k=0;k<Puls_l_out>>=8;
H=Puls_l_out;
uart_send(L);//Wert1 ->PC_15
uart_send(H);//Wert1 ->PC_16
outp(0x00,TCNT1H);// Reset timer1
outp(0x00,TCNT1L);
sbi(UCSRB, RXEN);// UART recieve on
sei();
}
[/code:1:b3daeccd1f]
Grüße Horti