- Вложения
-
- ADC.png
- (153.36 КБ) 435 скачиваний
Передача int побайтно по UART
- Сообщения: 147
- Зарегистрирован: Вс мар 09, 2014 09:13:00
Идея свести расчет среднеквадратичного значения 10ти разрядного АЦП к результату, хранящемуся в переменной типа int, затем ее побайтно отправить через UART. Для этого пытался взять адрес на нужный мне байт через указатель. Получается передавать только значения нижнего регистра ADCL. Значения верхнего регистра принимают нулевые значения. Приложил исходник и картину в протеусе, по идеи должен выводить 03ff (1023), так как ползунок вверху. Вообще при перемещении ползунка значения нижнего регистра принимают верные значения. Подскажите, как наиболее правильно реализовывать такую задачу? Или выгоднее поступить кардинально иначе?
- Реклама
У Вас ukazatel - указатель на int, а значит "ukazatel + 1" - это адрес, равный ukazatel + sizeof(int).
Если Вы вытаскиваете байты из памяти, то и указатель должен быть на байтовый тип.
Добавлено after 3 minutes 27 seconds:
Чтобы не путаться, лучше сделайте всё через union.
Если Вы вытаскиваете байты из памяти, то и указатель должен быть на байтовый тип.
Добавлено after 3 minutes 27 seconds:
Чтобы не путаться, лучше сделайте всё через union.
имея l_adc и h_adc, которые можно напрямую выдать в UART, к чему плодить лишние сущности типа указателя?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Оптимизатор с ними справится, я думаю. А вот использование ADCH и ADCL реально увеличивает код. Лучше сразу 16битную переменную ADC использовать, не нужны избыточные преобразования 8 битных переменных в 16 битную.
Добавлено after 4 minutes 27 seconds:
Судя по закоментаренному коду, предполагается передавать среднеквадратичное значения, расчет которого и передача, скорее всего, не стоит делать в прерывании. Но это наверное наброски кода.
Добавлено after 4 minutes 27 seconds:
Судя по закоментаренному коду, предполагается передавать среднеквадратичное значения, расчет которого и передача, скорее всего, не стоит делать в прерывании. Но это наверное наброски кода.
- Сообщения: 147
- Зарегистрирован: Вс мар 09, 2014 09:13:00
[uquote="ARV",url="/forum/viewtopic.php?p=3277094#p3277094"]имея l_adc и h_adc, которые можно напрямую выдать в UART, к чему плодить лишние сущности типа указателя?[/uquote]
Нужно по UART передать среднеквадратичное значение АЦП как корень квадратный из суммы квадратов измерений, отнесенной к количеству измерений s=sqr((x1^2+x2^2+...xn^2)/n), так вот чтобы найти сумму квадратов - планирую использовать переменную типа long int, количество измерений думаю взять 20ть, а следовательно чтобы уместить значение под корнем, а это по максимуму 1023^1023*20=1046529=0хFF801, т.е. 3и байта. Затем извлекаем корень и делим на 20ть(кол-во измерений). А уже отсюда посылать побайтно разбитую переменную по UART
Нужно по UART передать среднеквадратичное значение АЦП как корень квадратный из суммы квадратов измерений, отнесенной к количеству измерений s=sqr((x1^2+x2^2+...xn^2)/n), так вот чтобы найти сумму квадратов - планирую использовать переменную типа long int, количество измерений думаю взять 20ть, а следовательно чтобы уместить значение под корнем, а это по максимуму 1023^1023*20=1046529=0хFF801, т.е. 3и байта. Затем извлекаем корень и делим на 20ть(кол-во измерений). А уже отсюда посылать побайтно разбитую переменную по UART
- Реклама
ну и указатель нафига?DenChik87 писал(а):А уже отсюда посылать побайтно разбитую переменную по UART
Код: Выделить всё
void send_int(int d){
transmit(d >> 8);
transmit(d);
}если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 147
- Зарегистрирован: Вс мар 09, 2014 09:13:00
ну и указатель нафига?
Сделал как вы написали, нижний байт передается правильно, а в верхнем при перемещении потонцеометра от земли выше 13% возникакт ошибка, вместо положенного в нем нуля появляется значение FF., далее эта ошибка повторяется пока ползунок резистора не дайдет до 25% от земли, после значения и верхнего и нижнего регистра вновь принимают верные значения 
Код: Выделить всё
void send_int(int d){
transmit(d >> 8);
transmit(d);
}- Вложения
-
- adc3.png
- (92.34 КБ) 356 скачиваний
Во-первых, чтобы не было ЛИШНИХ проблем, используйте ADC вместо пары ADCL и ADCH - для вас же сделали ОДНУ переменную...DenChik87 писал(а):нижний байт передается правильно, а в верхнем при перемещении потонцеометра от земли выше 13% возникакт ошибка
во-вторых, просто не представляю, как мой код из двух абсолютно прозрачных строк может работать не правильно... разбирайтесь, что у вас ЕЩЕ не так...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
[uquote="DenChik87",url="/forum/viewtopic.php?p=3277825#p3277825"]выше 13% возникакт ошибка, вместо положенного в нем нуля появляется значение FF., далее эта ошибка повторяется пока ползунок резистора не дайдет до 25% от земли, после значения и верхнего и нижнего регистра вновь принимают верные значения
[/uquote]
Похоже на переполнение при вычислениях. Следите за размерностью промежуточных результатов.
Похоже на переполнение при вычислениях. Следите за размерностью промежуточных результатов.
Нужно посмотреть как АЦП инициализировано. Кроме того, DenChik87, ну кто же Вам мешает, зачем то введенным переменным l_adc и h_adc, присвоить проблемные значения и посмотреть как передаются данные, сразу станет понятно в какой половине кода копать. Аналогичным образом затем поступите с другими участками исходного кода и постепенно локализуется проблема да больного(ых) места (мест).
Добавлено after 5 minutes 22 seconds:
Добавлено after 5 minutes 22 seconds:
Наверное это просто опечатка, но операция извлекания корня должна делаться последней.DenChik87 писал(а):Затем извлекаем корень и делим на 20ть(кол-во измерений).
- Сообщения: 289
- Зарегистрирован: Чт ноя 06, 2014 13:09:06
[uquote="DenChik87",url="/forum/viewtopic.php?p=3277825#p3277825"]Сделал как вы написали, нижний байт передается правильно, а в верхнем ...[/uquote]
unsigned char h_adc, l_adc;
а вообще h_adc, l_adc - лишние, уже же имеются ADCH и ADCL или как подсказывают 16-ти битнное ADC - чем не устраивают?
unsigned char h_adc, l_adc;
а вообще h_adc, l_adc - лишние, уже же имеются ADCH и ADCL или как подсказывают 16-ти битнное ADC - чем не устраивают?
- Сообщения: 147
- Зарегистрирован: Вс мар 09, 2014 09:13:00
Болшое спасибо всем кто отвечал
отдельное огромное спсибо viiv.
[uquote="viiv",url="/forum/viewtopic.php?p=3277825#p3277825"]...или как подсказывают 16-ти битнное ADC - чем не устраивают?[/uquote]
Я не знал, что регистровю пару можно назвать ADC и работать с ней как с двухбайтной. Если использовать ADC, то с ней все работает. Когда в первый раз подсказал ARV я не сообразил что он имел в виду, видимо со второго раза лучше доходит
[uquote="viiv",url="/forum/viewtopic.php?p=3277825#p3277825"]а вообще h_adc, l_adc - лишние, уже же имеются ADCH и ADCL...[/uquote]
Да получается l_adc и h_adc лишние. Но так как я не знал, что можно все так ловко с ADC сделать, делал, через как не надо. А когда не выгружал в l_adc и h_adc, а вместо них писал ADCH и ADCL, то тогда значения в терминал выводятся правильно, но только один раз, будто следующее прерывание не выполнялось, или не обновлялись регистры ADCH/ADCL
И как писал viiv - в варианте с l_adc и h_adc нужно указать тип unsigned и все заработало верно. Был бы счастлив если еще проясните, почему нужно задать unsigned, ведь по умолчанию char и так должен быть беззнаковй?
[uquote="viiv",url="/forum/viewtopic.php?p=3277825#p3277825"]...или как подсказывают 16-ти битнное ADC - чем не устраивают?[/uquote]
Я не знал, что регистровю пару можно назвать ADC и работать с ней как с двухбайтной. Если использовать ADC, то с ней все работает. Когда в первый раз подсказал ARV я не сообразил что он имел в виду, видимо со второго раза лучше доходит
[uquote="viiv",url="/forum/viewtopic.php?p=3277825#p3277825"]а вообще h_adc, l_adc - лишние, уже же имеются ADCH и ADCL...[/uquote]
Да получается 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 раза.
http://radiokot.ru/forum/viewtopic.php? ... 6#p3277106 Вообще через раз читаете.DenChik87 писал(а):Когда в первый раз подсказал ARV я не сообразил что он имел в виду,
Просто еще какую-то ошибку придумали.DenChik87 писал(а):а вместо них писал ADCH и ADCL, то тогда значения в терминал выводятся правильно, но только один раз, будто следующее прерывание не выполнялось, или не обновлялись регистры ADCH/ADCL
Знаковый или беззнаковый будет на совести того или иного компилятора (это только для char), но скорее всего будет знаковый.DenChik87 писал(а): Был бы счастлив если еще проясните, почему нужно задать unsigned, ведь по умолчанию char и так должен быть беззнаковй?
- Сообщения: 147
- Зарегистрирован: Вс мар 09, 2014 09:13:00
Z_h_e писал(а):Вообще через раз читаете.,
Да и впраду плохо читаю, или поимаю, или и то и то
- Сообщения: 289
- Зарегистрирован: Чт ноя 06, 2014 13:09:06
[uquote="DenChik87",url="/forum/viewtopic.php?p=3278690#p3278690"]почему нужно задать unsigned, ведь по умолчанию char и так должен быть беззнаковй?[/uquote]
В общем случае, это неверно. например, в gcc при взмахе волшебной палочки указании соответствующей опции компилятору - char может быть как знаковым, так и беззнаковым (-funsigned-char)
В общем случае, это неверно. например, в gcc при взмахе волшебной палочки указании соответствующей опции компилятору - char может быть как знаковым, так и беззнаковым (-funsigned-char)



