Hallo
Sorry dass ich so still war.
Die Rahmenbedingungen hab ich festgelegt. Also wie groß die einzelnen Frameinhalte sind. Ich denke das bekomm ich jetzt auch hin. Hab im Moment noch ein anderes "komisches" Problem.
Und zwar möchte ich zwei Ports mit
Code:
sbit fuse = P1^6
sbit relais_on = P1^7
ansteuern. Das funktioniert auch. Ich kann die Ports EIN und AUS schalten. Wenn ich dann aber den Zustand eines Ports als Bedingung in einer if Schleife verwenden will, dann funktioniert es mit fuse nicht und mit relais_on funktioniert es. Also ich schalte beide Ports auf 1 und dann frage ich ab:
Code:
if(relais_on==1)
{
.
.
.
}
Hier springt der Controller in die if Schleife
Code:
if(fuse==1)
{
.
.
.
}
Hier springt der Controller nicht in die Schleife. Und ich hab keine wirkliche Ahnung warum. Ich vermute dass es daher kommt dass hinter sbit fuse ja eigentlich eine Adresse steht aber kein Zustand.
Hier mal noch der komplette Code. Ist für meine Verhältnisse schon ganz schön angewachsen....
Code:
// FID: 33X000032
// Target: ToolStick C8051F330
// Tool chain: Keil C51 7.50 / Keil EVAL C51
// Command Line: None
//
//
// Release 1.0
// -Initial Revision (PD/GV/GP)
// -06 AUG 2006
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <C8051F330.h> // SFR declarations
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F33x
//-----------------------------------------------------------------------------
sfr16 TMR2RL = 0xca; // Timer2 reload value
sfr16 TMR2 = 0xcc; // Timer2 counter
sfr16 ADC0 = 0xbd; // ADC Data Word Register
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK 24500000 // SYSCLK frequency in Hz
#define BAUDRATE 115200 // Baud rate of UART in bps
#define TIMER2_RATE 1000 // Timer 2 overflow rate in Hz
#define RX_length 25 //Länge des UART empfangsarrays definieren
//#define adress 10 //Adresse der Sicherung (benötigt für Buskommunikation)
sbit fuse = P1^6; //fuse wird mit fuse=1 eingeschaltet
sbit relais_on = P1^7; //relais wird mit relais_on = 1 eingeschaltet
#define TRUE 1
#define FALSE 0
//-----------------------------------------------------------------------------
// current Sensor Calibration Parameters
//-----------------------------------------------------------------------------
#define CURRENT_SENSOR_GAIN 185000 //Current Sensor Gain in (uV / A). Value obtained from datasheet
#define VREF 3370 //ADC Voltage Reference (mV)
#define FUSE_VALUE 100 //Nennstrom der Sicherung
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
int ADC_offset;
bit RX_ready; //True = string empfangen
volatile char RX_buf[RX_length]; //Array als Eingangsbuffer anlegen
volatile unsigned char the_char; //zwischenspeicher
//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void);
void ADC0_Init (void);
void UART0_Init (void);
void PORT_Init (void);
void TIMER2_Init (int);
char UART_ISR (void);
void Print_String (char pstring[]);
int Get_Current (void);
unsigned int Measure_current (void);
void Wait_One_Second (void);
void Print_current (unsigned int);
#define BIT0 1<<0
#define BIT1 1<<1
#define BIT2 1<<2
#define BIT3 1<<3
#define BIT4 1<<4
#define BIT5 1<<5
#define BIT6 1<<6
#define BIT7 1<<7
#define P1_6 P1&BIT6
#define P1_7 P1&BIT7
//-----------------------------------------------------------------------------
// main Routine
//-----------------------------------------------------------------------------
void main (void)
{
unsigned int current; // Stores last measurement
int messung=0;
//Adresse = 11;
// Disable Watchdog timer
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
// enable)
PORT_Init(); // Initialize Port I/O
OSCILLATOR_Init (); // Initialize Oscillator
TIMER2_Init (SYSCLK/TIMER2_RATE); // Init Timer 2
UART0_Init ();
AD0EN = 1; // Enable ADC
fuse = 0; //Sicherung ausschalten
Wait_One_Second();
ADC0_Init (); // Init ADC0
EA = 1; //Interrupts global freigeben
ES0 = 1; //UART interrupt freigeben
RI0 = 0;
relais_on = 0;
while (1)
{
if(fuse==1)
{
printf("Gebe Strommessung aus:\t");
current = Get_Current ();
Print_current(current);
}
else{
printf("P1_6 = 0x%x \t",P1_6);
printf("P1_7 = 0x%x\t", P1_7);
if(P1_6 == P1_7){
printf("P1_6 == P1_7 (%x)\t", P1_6 & P1_7);
}
printf("\r");
}
if(current > FUSE_VALUE)
{
fuse = 0;
Print_String ("Warning: overload\n");
Wait_One_Second();
messung = 0;
}
if (RX_ready != 0)
{
char *pch;
pch = strtok (RX_buf," ");
while (pch != NULL)
{
if(strcmp(pch, "g")==0)
{
Print_String("getmethode");
}
else if (strcmp(pch, "s")==0)
{
Print_String("setmethode");
}
else if(strcmp(pch, "temp")==0)
{
Print_String("temperaturausgeben");
}
else if(strcmp(pch, "on")==0)
{
relais_on = 1; //relais einschalten
fuse = 1; //Sicherung einschalten
Wait_One_Second();
}
else if(strcmp(pch, "off")==0)
{
fuse = 0;
relais_on = 0;
Wait_One_Second();
}
else
{
Print_String("keine bekannte Methode");
}
printf("%s\n",pch);
pch = strtok (NULL, " ");
}
RX_ready = 0;
}
}
}
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// P0.4 digital push-pull UART TX
// P0.5 digital open-drain UART RX
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
P0SKIP |= 0x01; // Skip P0.0 for external VREF
P1MDIN |= 0xEF; // Configure P1.4 as analog input.
P0MDOUT |= 0x10; // enable UTX as push-pull output
XBR0 = 0x01; // Enable UART on P0.4(TX) and P0.5(RX)
XBR1 = 0x40; // Enable crossbar and weak pull-ups
P0MDIN = 0xFE;
P1MDIN = 0xEF;
P0SKIP = 0x4D;
XBR0 = 0x07;
XBR1 = 0x40;
}
//-----------------------------------------------------------------------------
// OSCILLATOR_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine initializes the system clock to use the internal 24.5MHz
// oscillator as its clock source. Also enables missing clock detector reset.
//
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
OSCICN |= 0x03; // Configure internal oscillator for
// its maximum frequency
RSTSRC = 0x04; // Enable missing clock detector
}
//-----------------------------------------------------------------------------
// ADC0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure ADC0 to use ADBUSY as conversion source, and to sense the output
// of the temp sensor. Disables ADC end of conversion interrupt. Leaves ADC
// disabled.
//
//-----------------------------------------------------------------------------
void ADC0_Init (void)
{
ADC0CN = 0x40; // ADC0 disabled; LP tracking
// mode; ADC0 conversions are initiated
// on a write to ADBusy
AMX0P = 0x0C; // P1.4 selected at + input
AMX0N = 0x11; // Single-ended mode
ADC0CF = (SYSCLK/3000000) << 3; // ADC conversion clock <= 3MHz
ADC0CF &= ~0x04; // Make ADC0 right-justified
REF0CN = 0x0e; // enable temp sensor, VREF = VDD, bias
// generator is on.
AD0EN = 1; // Enable ADC0
ADC_offset = 0;
ADC_offset = Measure_current(); // Nullpunkt Offset messen
EIE1 &= ~0x08; // Disable ADC0 EOC interrupt
}
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
//
//-----------------------------------------------------------------------------
void UART0_Init (void)
{
SCON0 = 0x10; // SCON0: 8-bit variable bit rate
// level of STOP bit is ignored
// RX enabled
// ninth bits are zeros
// clear RI0 and TI0 bits
if (SYSCLK/BAUDRATE/2/256 < 1) {
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON &= ~0x0B; // T1M = 1; SCA1:0 = xx
CKCON |= 0x08;
} else if (SYSCLK/BAUDRATE/2/256 < 4) {
TH1 = -(SYSCLK/BAUDRATE/2/4);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01
CKCON |= 0x09;
} else if (SYSCLK/BAUDRATE/2/256 < 12) {
TH1 = -(SYSCLK/BAUDRATE/2/12);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
} else {
TH1 = -(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
CKCON |= 0x02;
}
TL1 = TH1; // Init Timer1
TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreload
TMOD |= 0x20;
TR1 = 1; // START Timer1
TI0 = 1; // Indicate TX0 ready
}
//-----------------------------------------------------------------------------
// TIMER2_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters :
// 1) int counts - number of milliseconds of delay
// range is postive range of integer: 0 to 32767
//
// Configure Timer2 to auto-reload at interval specified by <counts> (no
// interrupt generated) using SYSCLK as its time base.
//
//-----------------------------------------------------------------------------
void TIMER2_Init (int counts)
{
TMR2CN = 0x00; // STOP Timer2; Clear TF2H and TF2L;
// disable low-byte interrupt; disable
// split mode; select internal timebase
CKCON |= 0x10; // Timer2 uses SYSCLK as its timebase
TMR2RL = -counts; // Init reload values
TMR2 = TMR2RL; // Init Timer2 with reload value
ET2 = 0; // Disable Timer2 interrupts
TR2 = 1; // Start Timer2
}
//-----------------------------------------------------------------------------
// Measure_current
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
//-----------------------------------------------------------------------------
unsigned int Measure_current (void)
{
unsigned i; // Sample counter
unsigned long accumulator = 0L; // Where the ADC samples are integrated
unsigned int currval;
AD0INT = 0; // Clear end-of-conversion indicator
AD0BUSY = 1; // Initiate conversion
// read the ADC value and add to running total
i = 0;
do
{
while (!AD0INT); // Wait for conversion to complete
AD0INT = 0; // Clear end-of-conversion indicator
currval = ADC0; // Store latest ADC conversion
AD0BUSY = 1; // Initiate conversion
accumulator += (currval); // Accumulate
i++; // Update counter
} while (i != 20);
return (unsigned int) (accumulator);
}
//-----------------------------------------------------------------------------
// Get_Current
//-----------------------------------------------------------------------------
//
// Return Value : int - returns the current in hundredths of degrees
// Parameters : None
//
//-----------------------------------------------------------------------------
int Get_Current (void)
{
long result;
result = Measure_current ();
result = result - ADC_offset;
result = result / 20;
result = result * 7580;
result = result / 1024;
return (int) result;
}
//-----------------------------------------------------------------------------
// Support Functions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Print_String
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters :
// 1) char pstring[] - null terminated character string
//
// Prints the strings stored in pstring to the UART.
// This function is used instead of printf() because printf() consumes
// a considerable amount of code space.
//
//-----------------------------------------------------------------------------
void Print_String (char pstring[])
{
unsigned char i = 0;
while (pstring[i])
{
putchar(pstring[i++]);
}
}
//-----------------------------------------------------------------------------
// Wait_One_Second
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine uses Timer2 to insert a delay of approximately one second.
// Timer 2 overflows <TIMER2_RATE> times per second.
//
//-----------------------------------------------------------------------------
void Wait_One_Second (void)
{
unsigned int count;
TF2H = 0; // Clear Timer2 overflow flag
TR2 = 1; // Start Timer2
for (count = TIMER2_RATE; count != 0; count--)
{
while (!TF2H); // Wait for overflow
TF2H = 0; // Clear overflow indicator
}
TR2 = 0; // Stop Timer2
}
void Print_current (unsigned int current)
{
Print_String ("Current = ");
// This method of printing the current is an alternative to using
// printf() and its capabilities
EA = 0;
putchar ((current / 1000) + 0x30); // Tens digit
putchar (((current / 100) % 10) + 0x30); // Ones digit
putchar ('.');
putchar (((current / 10) % 10) + 0x30); // Tenths digit
putchar ((current % 10) + 0x30); // Hundredths digit
EA = 1;
Print_String (" A\n");
}
//-----------------------------------------------------------------------------
// Interrupt service routines
//-----------------------------------------------------------------------------
void UART0_ISR (void) interrupt 4 using 3
{
static unsigned char RX_index; //zwischenspeicher
if(RI0 == 1)
{
if(RX_ready != 1)
{
the_char = SBUF0;
if(the_char != '\r')
{
RX_buf[RX_index] = the_char;
RX_index++;
RI0 = 0;
RX_buf[RX_index] = '\0';
}
else
{
RX_buf[RX_index] = '\0';
RX_index = 0;
RX_ready = 1;
RI0 = 0;
}
}
}
}
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
Lesezeichen