У меня почти НЕТ опыта кодирования, так что извините за грубый стиль и многословные комментарии. Я пытаюсь сделать выборку с 4 датчиков (1 каждые 15 минут). Я думал, что было бы более эффективно использовать функции delay
и data_write
как отдельные функции для вызова, но это не очень хорошо работает. Я постоянно получаю следующую ошибку:
Ошибка [1302] объявления функций в старом стиле не поддерживаются
в конце data_write
функции независимо от того, где и как я ставлю фигурные скобки (вложенные, та же строка, исключение и т. д.), delay
функция не дает ошибки, будь то до или после функции data_write
.
Пожалуйста, не стесняйтесь рекомендовать лучший макет для меня. Кроме того, я действительно ничего не понимаю в памяти данных, поэтому эта процедура, вероятно, дерьмо, я знаю. Как ни странно, это не дает мне никаких ошибок, поэтому я пока не буду смотреть этому даренному коню в зубы.
======================================
#include <stdio.h>
#include <stdlib.h>
#include <p18f452.h>
#include <delays.h>
#include <adc.h>
int result; // used in ADC result handling
int i; // used in delay loop/function
int data_adr=0x64; // used in data_write function. initial=d100
// assuming 4MHz oscillator => 8fosc. Tinst= (4)*Tosc = (4)*(250ns) = 1us
// all 4 sensors should read every minute so each will begin sequentially,
// after 15sec delay from previous ADC conversion completes.
void delay (void); // delay function prototype declaration
void data_write (int, int); // data-write function prototype declaration
main()
{
// I think I need a while (1) loop here to repeat the loop forever???
// sensor 1 configured to port AN0
OpenADC(ADC_FOSC_8 & ADC_RIGHT_JUST & ADC_5ANA_0REF, ADC_CH0 & ADC_INT_OFF);
//configures ADC for port AN0 = sensor 1 input
delay(); // call the delay function
ConvertADC(); // initiate conversion of sensor1 @ AN0
while(BusyADC()); // waiting to complete conversion
result=ReadADC(); // read the result of sensor1 @ AN0
data_write(); // call data_write function
CloseADC();
// sensor 2 configured to port AN1
OpenADC(ADC_FOSC_8 & ADC_RIGHT_JUST & ADC_5ANA_0REF, ADC_CH1 & ADC_INT_OFF);
//configures ADC for port AN1 = sensor 2 input
delay();
ConvertADC();
while(BusyADC());
result=ReadADC();
data_write ();
CloseADC();
// sensor 3 configured to port AN2
OpenADC(ADC_FOSC_8 & ADC_RIGHT_JUST & ADC_5ANA_0REF, ADC_CH2 & ADC_INT_OFF);
//configures ADC for port AN2 = sensor 3 input
delay();
ConvertADC();
while(BusyADC());
result=ReadADC();
data_write ();
CloseADC();
// sensor 4 configured to port AN3
OpenADC(ADC_FOSC_8 & ADC_RIGHT_JUST & ADC_5ANA_0REF, ADC_CH3 & ADC_INT_OFF);
//configures ADC for port AN3 = sensor 4 input
delay();
ConvertADC();
while(BusyADC());
result=ReadADC();
data_write ();
CloseADC();
return (result);
}
// Delay function sequence
void delay (void)
{ // 15second delay routine
// 15sec/Tinst= 15sec/1us
// = 15*10^6 Tinst = 10K * 1500
// Delay10KTCYx(1)= 0.01sec
// = (10K)*(250)*(6)
i=6;
while(i>0) {
Delay10KTCYx(250); // 2.5sec delay
i=i--; // run 6 times for total 15sec delay loop
}
return;
}
// data write sequence
void data_write (data_adr, result) {
_asm
movlw data_adr // starting data memory address = data_adr
movwf EEADR,A
movlw result // gets data stored in "result" variable
movwf EEDATA,A // places data into data memory holder
bcf EECON1,EEPGD,A // points to data memory
bcf EECON1,CFGS,A // access data eeprom
bsf EECON1,WREN,A // enable write to data EEPROM
bcf INTCON,IE,A // disable interrupt
movlw 0x55 // start flash erase sequence
movwf EECON2,A
movlw 0xAA
movwf EECON2,A // end flash erase sequence
bsf EECONN1,WR,A // enable bit to start the write operation
bsf INTCON,GIE,A // re-enable interrupt
bcf EECON1,WREN // restores the write command to =disabled
_endasm
data_adr = data_adr+2;
if (data_adr >= 0xC6) // if address >= d'198
data_adr = 0x64; // resets starting point to d'100
return; }
Все остальные ответы имеют хорошие стороны и указывают на другие проблемы, но конкретная причина, по которой вы получаете сообщение об ошибке, old style function declarations not supported
заключается в том, что в объявлении вашей data_write
функции отсутствуют типы. Его нужно изменить с
void data_write (data_adr, result)
к
void data_write (int data_adr, int result)
Во-первых, избавьтесь от возврата в основной функции. Куда вы собираетесь возвращать данные? Там нет операционной системы, и возврат бессмысленен, поэтому это может быть источником некоторых проблем.
Как именно вы собираетесь выводить данные? Похоже, вы пытаетесь записать данные в память, но что вы собираетесь делать после этого, вынимать чип и физически читать EEPROM с помощью программатора?
Далее, да, вам нужно while (1), чтобы правильно зацикливаться вокруг функции. Вы можете получить какой-то цикл даже без while. Если я правильно помню, флэш-память PIC18 по умолчанию заполнена NOP. Он будет продолжать выполнять инструкции до тех пор, пока не будет достигнут конец адресного пространства, после чего он должен (опять же, если я правильно помню) выполнить цикл и вернуться к первой инструкции. Вы не должны полагаться на эту функцию и вместо этого должны обернуть содержимое main с помощью while (1) или эквивалентного.
Далее сами ошибки: Ну, в руководстве по компилятору написано, что это вообще не связано с фигурными скобками. Это связано со стилем объявления функции. На самом деле вам нужно написать тип переменной и имя при объявлении функции. Вы создали переменные с тем же именем, что и глобальные переменные. Когда ваш код работает, он не будет использовать глобальные переменные. Вместо этого он будет использовать локальные переменные с таким именем, которое будет маскировать глобальные переменные.
Также вы плохо вызываете функции. Вы должны фактически перечислить аргументы, когда вы вызываете функции!
Далее, в C18 прототип для main должен быть void main (недействительным), что хорошо сочетается с правилом возврата, о котором я упоминал ранее.
Вы также, кажется, неправильно называете регистрационные имена. Попробуйте прочитать в руководстве пользователя, как C18 вызывает каждый регистр в PIC и как обращаться к каждому отдельному биту регистра. Например, вы должны использовать INTCON1bits.GIE
для доступа к общему биту разрешения прерывания в регистре управления прерыванием один.
Еще я заметил, что вы используете int для счетчика циклов. Не делайте этого, если можете этого избежать. Старайтесь использовать символы как можно чаще, так как они являются родным типом данных MCU. Целые числа будут обрабатываться дольше, что приведет к более медленным, чем ожидалось, циклам.
Также вы упомянули функции и эффективность. Имейте в виду, что C18 не может встраивать функции, поэтому, если вам когда-либо понадобится эффективно вызывать функцию, вам придется заменить ее макросом.
Как указывает Андрея, вы неправильно используете оператор return.
Кроме того, теперь фактическое сообщение об ошибке было отредактировано, из него становится ясно, что ошибка, связанная с вашим, data_write
связана с тем, что вы не объявляете типы аргументов, как утверждает Джим в своем ответе. Вы можете увидеть примеры того, как они должны быть объявлены в коде ниже.
Оператор return
используется для передачи вызывающей стороне результата определенного типа, продиктованного определением функции.
Например, эта функция возвращает целое число:
int add(int a, int b)
{
int c;
c = a + b;
return c;
}
Чтобы использовать вышеизложенное, вы делаете что-то вроде:
int result;
result = add(5, 6); // result = 11
Но эта функция не принимает никаких аргументов и ничего не возвращает (обратите внимание на void
тип возврата/аргумента):
void do_something(void)
{
// do something here...
//
}
Существует множество применений функции без возврата/аргументов — например, настройка периферийного устройства, инициализация памяти и т. д.
Другой способ получить информацию из функции — использовать указатель, переданный в качестве аргумента:
void add(int a, int b, int* p_result)
{
int temp;
temp = a + b;
*p_result = temp;
}
Чтобы использовать вышеизложенное, мы передаем адрес переменной результата в качестве третьего аргумента (оператора &
):
int result = 0;
int a = 6;
int b = 5;
add(a, b, &result); // result will equal 11 on function return
Итак, надеюсь, вы видите, что нет смысла иметь return
оператор для функции, объявленной как void
, (если вы не хотите вернуться раньше как часть некоторой логики принятия решения - аналогично операторам continue
и break
, которых у вас нет в ваших функциях выше) Если вы хотите что-то вернуть, объявите тип в начале определения функции. Как предлагает Андрея, я бы немного почитал об основных функциях и указателях C.
Отметка