AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
07.01.2024, 21:11
|
#1
|
Временная регистрация
Регистрация: 07.03.2019
Сообщений: 87
Сказал спасибо: 11
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Запись переменной в массив и дальнейшая работа с содержимым
Снова здравствуйте!
В общем вопрос такой
Допустим есть переменная read например это показатель температуры. Требуется записывать значения данной переменной в массив например 40 раз. Что бы можно было потом в этом массиве например найти максимальное, минимальное, среднее показания. Камень атмега 128, язык Cи
Но так как я мал и глуп, то не смог дочитаться и додуматься до верных действий
Вот что я попробовал делать:
Нажмите, чтобы открыть спойлер
PHP код:
|
int mas [40]={};// создаю пустой массив для накопления данных int c=0, i=0, m=0,read=10,z; // переменные дл
void displey_start(void) // Активирую Порт B на выход, для того что бы активировать дисплей
int main(void) { displey_start();
while (1) { if(i‹=40) {
mas[i++]=read; } _delay_ms(100); int t=mas[4]; // Пробую на дисплей выводить
|
Или так?:
Нажмите, чтобы открыть спойлер
PHP код:
|
int temp = 0; for(i=0;i‹=40;i++) {
mas[i++]=read; temp+=read; }
|
Но явно, это не правильно. Прошу подскажите как правильно начать записывать значения переменной в массив .
Последний раз редактировалось Devil Byte; 08.01.2024 в 06:39.
|
|
|
|
08.01.2024, 08:18
|
#2
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: Запись переменной в массив и дальнейшая работа с содержимым
В цикле for(i = 0; i ‹ 40; i ++) уже выполняется постинкремент переменной i, поэтому в индексе массива array[i ++] её НЕ нужно инкрементировать снова.
Книга автора языка Ритчи "Язык программирования Си" - фпомощь!
Код:
|
#define SIZE 40 // размер массива
int array[SIZE]; // массив значений
/* Цикл заполнения */
for(int i = 0; i ‹ SIZE; i++)
{
array[i] = ReadTemperature(); // чтение температуры и занесение её в массив
} |
|
|
|
|
08.01.2024, 08:48
|
#3
|
Временная регистрация
Регистрация: 07.03.2019
Сообщений: 87
Сказал спасибо: 11
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Запись переменной в массив и дальнейшая работа с содержимым
Сообщение от NewWriter
|
НЕ нужно инкрементировать снова.
|
Да с этим вчера уже разобрался.
Создал функцию, но не понимаю, в каком месте правильно создать массив для накопления. В цикле фор? если да, то как потом возвращать сразу три значения мин,макс и ср?Использовать для возврата массив?типа return [min, max, average] или нужно создавать отдельные функции?
Нажмите, чтобы открыть спойлер
PHP код:
|
int readAdc(uint8_t channel) { //int LowBitValue; ADMUX&=0xF0;// очистить биты MUX ADMUX|=channel; _delay_us(200); int temp=0; unsigned int full; int array[52]; for (int z=0;z‹52;z++) // цикл для устреднения { ADCSRA |= (1‹‹ADSC); // Запуск преобразования while((ADCSRA &(1‹‹ADSC))); // Ожидание заврешения преобразования //while((ADCSRA &(1‹‹ADIF))==0); //ADCSRA |= (1‹‹ADIF); //LowBitValue = ADCL; //return((ADCH‹‹8) | LowBitValue); // Возрат прочитанных значений со старшего и младшего бита temp +=ADC; array[z]=ADC; if (z‹52) { full+=array[z]; } } return full/52; }
|
Последний раз редактировалось Devil Byte; 08.01.2024 в 09:06.
|
|
|
|
08.01.2024, 12:10
|
#4
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: Запись переменной в массив и дальнейшая работа с содержимым
Вообще наоборот:
Код:
|
/**
* Функция, запускающая ADC. Когда результат
* измерения АЦП готов, читается из регистра измеренное
* значение и возвращается return value;
* @return Результат измерения
*/
int ReadTemperature(void)
{
int read;
// запуск ADC, ожидание готовности результата,
// чтение его из регистра АЦП
... read = ...
return read; // это значение возвращается функцией
}
int main(void)
{
#define SIZE 40 // размер массива
int array[SIZE]; // массив значений
/* Цикл заполнения массива результатами измерений */
for(int i = 0; i ‹ SIZE; i++)
{
array[i] = ReadTemperature(); // чтение температуры и занесение её в массив
}
/* Проход по сформированному массиву и поиск минимального
* и максимального значений, а так же вычисление среднего значения */
int min = 0xFFFF; // для минимального значения, изначально оно равно максимально возможному числу
int max = 0; // для максимального значения, изначально оно = 0
int average = 0; // среднее
for(int i = 0; i ‹ SIZE; i++)
{
/* если число больше max, то max = это число */
if(array[i] › max)
max = array[i];
/* если число меньше min, то min = это число */
if(array[i] ‹ min)
min = array[i];
/* Накопление суммы для вычисления среднего */
average += array[i];
}
average /= SIZE; // получение среднего (сумма / число элементов) |
А если хотите это оформить в виде отдельной функции и возвращать все три числа, то придется изучить понятие структуры, либо понятие указателей. Потому как возвращаемое функцией значение может быть только одно. Но его можно представить в виде структуры. Либо входные параметры функции должны быть указателями на переменные. Но это - отдельная и обширная тема, которую невозможно постичь, если нет желания и усидчивости в прочтении книжки.
Код:
|
/**
* Просмотр массива и получение мин, макс и среднего значений.
* @param array[in] - входной массив данных
* @param size - размер массива
* @param min[out] - выход минимального значения
* @param max[out] - выход максимального значения
* @param average[out] - выход среднего значения
*/
void Processing(int *array, int size, int *min, int *max, int *average)
{
int _min = 0xFFFF;
int _max = 0;
int _average = 0;
int _size = size;
while(_size--)
{
if(*array ‹ _min)
_min = *array;
if(*array › _max)
_max = *array;
_average += *array;
array++;
}
*min = _min;
*max = _max;
*average = _average / size;
}
int main(void)
{
#define SIZE 40 // размер массива
int array[SIZE]; // массив значений
/* Цикл заполнения массива результатами измерений */
for(int i = 0; i ‹ SIZE; i++)
{
array[i] = ReadTemperature(); // чтение температуры и занесение её в массив
}
/* Вычисление мин, макс и среднего значений в массиве */
int min, max, average;
Processing(array, SIZE, &min, &max, &average); |
|
|
|
|
08.01.2024, 13:11
|
#5
|
Временная регистрация
Регистрация: 07.03.2019
Сообщений: 87
Сказал спасибо: 11
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Запись переменной в массив и дальнейшая работа с содержимым
Сообщение от NewWriter
|
Вообще наоборот:
|
Про указатели понял, до этого мне пока далеко
я сделал так, что бы можно было вывести на экран показания со всех 7 каналов. По этому мукс принимает в себя значение chanel
Нажмите, чтобы открыть спойлер
PHP код:
|
int readAdc(uint8_t channel)
{
ADMUX&=0xF0;// очистить биты MUX
ADMUX|=channel;
_delay_us(200);
ADCSRA |= (1‹‹ADSC); // Запуск преобразования
while((ADCSRA &(1‹‹ADSC))); // Ожидание заврешения преобразования
//while((ADCSRA &(1‹‹ADIF))==0);
return ADC;
}
|
А если я сделаю как вы порекомендовали, то теряю доступ к возможности переключения каналов(
|
|
|
|
08.01.2024, 13:45
|
#6
|
Гуру портала
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 19,121
Сказал спасибо: 2,569
Сказали Спасибо 11,944 раз(а) в 5,991 сообщении(ях)
|
Re: Запись переменной в массив и дальнейшая работа с содержимым
Сообщение от Devil Byte
|
Создал функцию, но не понимаю, в каком месте правильно создать массив для накопления.
|
Удобнее, массив создавать за пределами функции ("глобальней" относительно неё, если что, тема "области видимости"). Массив передавать функции указателем (указатель на массив - его имя, тема "массивы"). Для универсальности можно передавать функции количество каналов и номер первого канала, можно передать указатель на массив со списком каналов, там можно определить очередность опросов. Функция результат помещает в массив (имя массива с индексом элемента) и в конце работы возвращает признак успешности выполнения (или ничего - по желанию и фантазии).
Можно использовать структуру, но это не так удобно.
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.
|
|
|
|
08.01.2024, 13:48
|
#7
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: Запись переменной в массив и дальнейшая работа с содержимым
Сообщение от Devil Byte
|
что бы можно было вывести на экран показания со всех 7 каналов.
(
|
Со всех семи каналов? У вас дисплей лопнет от обилия цифр
В таком случае, можно создать вне этой функции семь разных массивов для каждого канала и заполнять массив, соотвествующий номеру канала.
Нет, тут без более глубокого изучения языка Си не обойтись, поскольку полюбому нужны некоторые продвинутые инструменты.
И если уж не указатели, то хотябы вот так:
Код:
|
#define SIZE 10
int adc0[SIZE];
int adc1[SIZE];
int adc2[SIZE];
int adc3[SIZE];
int adc4[SIZE];
int adc5[SIZE];
int adc6[SIZE];
void ReadADC(int channel)
{
int read;
// Установить номер канала в мультиплексоре
for(int i = 0; i ‹ SIZE; i++)
{
// Запустить преобразование
// Дождаться готовности результа
read = .... прочитать регистр ADC
/* Выбор массива назначения в зависимости от номера канала */
switch(channel) {
case 0:
adc0[i] = read;
break;
case 1:
adc0[i] = read;
break;
case 2:
adc0[i] = read;
break;
case 3:
adc0[i] = read;
break;
case 4:
adc0[i] = read;
break;
case 5:
adc0[i] = read;
break;
case 6:
adc0[i] = read;
break;
case 7:
adc0[i] = read;
break;
}
}
} |
Или же вот так, используя массив массивов - двумерный массив, в котором первый индекс - номер канала, второй индекс - номер измерения
Код:
|
#define SIZE 10 // размер массивов
#define N 7 // число каналов АЦП
int adc[N][SIZE]; // двухмерный массив, где первый индекс - номер канала, второй - номер измерения
void ReadADC(int channel)
{
int read;
// Установить номер канала в мультиплексоре
for(int i = 0; i ‹ SIZE; i++)
{
// Запустить преобразование
// Дождаться готовности результа
read = .... прочитать регистр ADC
adc[channel][i] = read;
}
} |
Поскольку массивы объявлены глобально, то доступ к ним возможен из любого места этого файла.
|
|
|
|
08.01.2024, 14:45
|
#8
|
Гуру портала
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 19,121
Сказал спасибо: 2,569
Сказали Спасибо 11,944 раз(а) в 5,991 сообщении(ях)
|
Re: Запись переменной в массив и дальнейшая работа с содержимым
Сообщение от NewWriter
|
Нет, тут без более глубокого изучения языка Си не обойтись, поскольку полюбому нужны некоторые продвинутые инструменты.
|
Ну, зря Вы так говорите. Есть минимально необходимый перечень того, что нужно знать,чтобы просто работать с языком, совсем они не крутые, просто - необходимые. И массивы с их "мерностями" входят в число минимальных необходимостей. А "мерность" - да хоть десятая, какая разница? У каждой свой индекс. Вот если захочется через union получить хитровыдуманный доступ - тут уже надо поглубже копнуть, да и то ничего сложного.
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.
|
|
|
|
08.01.2024, 15:03
|
#9
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: Запись переменной в массив и дальнейшая работа с содержимым
union здесь не нужен, да и вообще, он намного реже нужен (чуть больше, чем почти никогда), нежели чем структура struct и тем более, указатель * и ссылка (адрес) &.
Без указателей вообще невозможно хоть сколько-нибудь эффективно писать код. Из-за того, что функция не может возвращать более одного значения, указатель (и структура тоже, но в меньшей степени) является единственным способом вернуть несколько результатов через входные параметры. Так же, по указателю передаются и массивы в функцию. Хотя, можно параметр объявить и как массив, но это архаизм.
Вообще, язык Си достаточно компактен, и изучить его целиком не составляет большого труда. И чтобы эффективно его применять, нужно изучить весь инструментарий, благо, он небольшой.
|
|
|
Сказали "Спасибо" NewWriter
|
|
|
08.01.2024, 15:14
|
#10
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,446
Сказал спасибо: 99
Сказали Спасибо 317 раз(а) в 233 сообщении(ях)
|
Re: Запись переменной в массив и дальнейшая работа с содержимым
Сообщение от Devil Byte
|
По этому мукс принимает в себя значение chanel
|
Я же вам совсем не так говорил. Куча лишних действий и к тому же неверные.
|
|
|
Сказали "Спасибо" Godzilla82
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 15:37.
|
|