Обсуждаем контроллеры компании Atmel.
Ответить

Передача int побайтно по UART

Вс янв 07, 2018 09:56:05

Идея свести расчет среднеквадратичного значения 10ти разрядного АЦП к результату, хранящемуся в переменной типа int, затем ее побайтно отправить через UART. Для этого пытался взять адрес на нужный мне байт через указатель. Получается передавать только значения нижнего регистра ADCL. Значения верхнего регистра принимают нулевые значения. Приложил исходник и картину в протеусе, по идеи должен выводить 03ff (1023), так как ползунок вверху. Вообще при перемещении ползунка значения нижнего регистра принимают верные значения. Подскажите, как наиболее правильно реализовывать такую задачу? Или выгоднее поступить кардинально иначе?
Вложения
ADC.png
(153.36 KiB) Скачиваний: 408

Re: Передача int побайтно по UART

Вс янв 07, 2018 10:18:04

У Вас ukazatel - указатель на int, а значит "ukazatel + 1" - это адрес, равный ukazatel + sizeof(int).
Если Вы вытаскиваете байты из памяти, то и указатель должен быть на байтовый тип.

Добавлено after 3 minutes 27 seconds:
Чтобы не путаться, лучше сделайте всё через union.

Re: Передача int побайтно по UART

Вс янв 07, 2018 15:36:34

имея l_adc и h_adc, которые можно напрямую выдать в UART, к чему плодить лишние сущности типа указателя?

Re: Передача int побайтно по UART

Вс янв 07, 2018 15:52:17

Оптимизатор с ними справится, я думаю. А вот использование ADCH и ADCL реально увеличивает код. Лучше сразу 16битную переменную ADC использовать, не нужны избыточные преобразования 8 битных переменных в 16 битную.

Добавлено after 4 minutes 27 seconds:
Судя по закоментаренному коду, предполагается передавать среднеквадратичное значения, расчет которого и передача, скорее всего, не стоит делать в прерывании. Но это наверное наброски кода.

Re: Передача int побайтно по UART

Вс янв 07, 2018 17:03:09

имея l_adc и h_adc, которые можно напрямую выдать в UART, к чему плодить лишние сущности типа указателя?

Нужно по UART передать среднеквадратичное значение АЦП как корень квадратный из суммы квадратов измерений, отнесенной к количеству измерений s=sqr((x1^2+x2^2+...xn^2)/n), так вот чтобы найти сумму квадратов - планирую использовать переменную типа long int, количество измерений думаю взять 20ть, а следовательно чтобы уместить значение под корнем, а это по максимуму 1023^1023*20=1046529=0хFF801, т.е. 3и байта. Затем извлекаем корень и делим на 20ть(кол-во измерений). А уже отсюда посылать побайтно разбитую переменную по UART

Re: Передача int побайтно по UART

Вс янв 07, 2018 17:54:34

DenChik87 писал(а):А уже отсюда посылать побайтно разбитую переменную по UART
ну и указатель нафига?
Код:
void send_int(int d){
   transmit(d >> 8);
   transmit(d);
}

Re: Передача int побайтно по UART

Пн янв 08, 2018 15:02:10

ну и указатель нафига?
Код:
void send_int(int d){
   transmit(d >> 8);
   transmit(d);
}

Сделал как вы написали, нижний байт передается правильно, а в верхнем при перемещении потонцеометра от земли выше 13% возникакт ошибка, вместо положенного в нем нуля появляется значение FF., далее эта ошибка повторяется пока ползунок резистора не дайдет до 25% от земли, после значения и верхнего и нижнего регистра вновь принимают верные значения :?
Вложения
adc3.png
(92.34 KiB) Скачиваний: 338

Re: Передача int побайтно по UART

Пн янв 08, 2018 15:11:19

DenChik87 писал(а):нижний байт передается правильно, а в верхнем при перемещении потонцеометра от земли выше 13% возникакт ошибка
Во-первых, чтобы не было ЛИШНИХ проблем, используйте ADC вместо пары ADCL и ADCH - для вас же сделали ОДНУ переменную...
во-вторых, просто не представляю, как мой код из двух абсолютно прозрачных строк может работать не правильно... разбирайтесь, что у вас ЕЩЕ не так...

Re: Передача int побайтно по UART

Пн янв 08, 2018 15:32:50

выше 13% возникакт ошибка, вместо положенного в нем нуля появляется значение FF., далее эта ошибка повторяется пока ползунок резистора не дайдет до 25% от земли, после значения и верхнего и нижнего регистра вновь принимают верные значения :?

Похоже на переполнение при вычислениях. Следите за размерностью промежуточных результатов.

Re: Передача int побайтно по UART

Пн янв 08, 2018 16:40:19

Нужно посмотреть как АЦП инициализировано. Кроме того, DenChik87, ну кто же Вам мешает, зачем то введенным переменным l_adc и h_adc, присвоить проблемные значения и посмотреть как передаются данные, сразу станет понятно в какой половине кода копать. Аналогичным образом затем поступите с другими участками исходного кода и постепенно локализуется проблема да больного(ых) места (мест).

Добавлено after 5 minutes 22 seconds:
DenChik87 писал(а):Затем извлекаем корень и делим на 20ть(кол-во измерений).
Наверное это просто опечатка, но операция извлекания корня должна делаться последней.

Re: Передача int побайтно по UART

Пн янв 08, 2018 22:11:54

Сделал как вы написали, нижний байт передается правильно, а в верхнем ...

unsigned char h_adc, l_adc;

а вообще h_adc, l_adc - лишние, уже же имеются ADCH и ADCL или как подсказывают 16-ти битнное ADC - чем не устраивают?

Re: Передача int побайтно по UART

Вт янв 09, 2018 18:47:44

Болшое спасибо всем кто отвечал :)) отдельное огромное спсибо viiv.
...или как подсказывают 16-ти битнное ADC - чем не устраивают?

Я не знал, что регистровю пару можно назвать ADC и работать с ней как с двухбайтной. Если использовать ADC, то с ней все работает. Когда в первый раз подсказал ARV я не сообразил что он имел в виду, видимо со второго раза лучше доходит :music:
а вообще h_adc, l_adc - лишние, уже же имеются ADCH и ADCL...

Да получается l_adc и h_adc лишние. Но так как я не знал, что можно все так ловко с ADC сделать, делал, через как не надо. А когда не выгружал в l_adc и h_adc, а вместо них писал ADCH и ADCL, то тогда значения в терминал выводятся правильно, но только один раз, будто следующее прерывание не выполнялось, или не обновлялись регистры ADCH/ADCL

И как писал viiv - в варианте с l_adc и h_adc нужно указать тип unsigned и все заработало верно. Был бы счастлив если еще проясните, почему нужно задать unsigned, ведь по умолчанию char и так должен быть беззнаковй?
Последний раз редактировалось DenChik87 Вт янв 09, 2018 19:01:46, всего редактировалось 2 раз(а).

Re: Передача int побайтно по UART

Вт янв 09, 2018 18:56:50

DenChik87 писал(а):Когда в первый раз подсказал ARV я не сообразил что он имел в виду,
viewtopic.php?p=3277106#p3277106 Вообще через раз читаете.
DenChik87 писал(а):а вместо них писал ADCH и ADCL, то тогда значения в терминал выводятся правильно, но только один раз, будто следующее прерывание не выполнялось, или не обновлялись регистры ADCH/ADCL
Просто еще какую-то ошибку придумали.
DenChik87 писал(а): Был бы счастлив если еще проясните, почему нужно задать unsigned, ведь по умолчанию char и так должен быть беззнаковй?
Знаковый или беззнаковый будет на совести того или иного компилятора (это только для char), но скорее всего будет знаковый.

Re: Передача int побайтно по UART

Вт янв 09, 2018 19:17:14

Z_h_e писал(а):Вообще через раз читаете.,

Да и впраду плохо читаю, или поимаю, или и то и то :oops:спсибо за исчерпывающий ответ Z_h_e :beer:

Re: Передача int побайтно по UART

Вт янв 09, 2018 22:43:41

почему нужно задать unsigned, ведь по умолчанию char и так должен быть беззнаковй?

В общем случае, это неверно. например, в gcc при взмахе волшебной палочки указании соответствующей опции компилятору - char может быть как знаковым, так и беззнаковым (-funsigned-char)
Ответить