реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> 2 байта в AVR, как сранить и обработать 16 разрядов в ATmega?
slanted
сообщение Jan 3 2008, 16:36
Сообщение #16


Частый гость
**

Группа: Участник
Сообщений: 140
Регистрация: 2-01-08
Пользователь №: 33 768



Цитата(pimen @ Jan 3 2008, 18:57) *
а как это реализуется/используется на С в AVRstudio?

Теоретически, оно должно само уметь обсчитывать стандартные сишные типы с помощью этих инструкций. WinAVR, к примеру, точно умеет. А вопрос-то был про восьмибитки вообще, я на него и ответил.

ps. Собственно, подобные инструкции есть везде, в x86 тоже.
Go to the top of the page
 
+Quote Post
pimen
сообщение Jan 6 2008, 01:02
Сообщение #17


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 30-11-07
Пользователь №: 32 846



ЛЮДИ!!!!
Объясните!
есть программа:

#include <avr/io.h>

int T=0x0;

main ()
{
T=(0b10001100<<8)>>3;
}

это нечто выдает значение Т=0b1111000110000000, хотя должен 0b0001111000110000.
если заменить сдвиг право на 3 на деление на 0b1000, то результат все равно 0b1111000110000000.
деление и сдвиг просто числа 0b1000110000000000 дает правильные результаты.
что я не учел??????????
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 6 2008, 01:47
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(pimen @ Jan 6 2008, 03:02) *
это нечто...

Главная ошибка - Вы начали использовать "нечто" пытающееся эмулировать дебильную бинарную запись при наличии в языках много более удобных средств, например, возможности поименовать биты. Разбираться (только зачем - правильнее не пользоваться) можете начинать с реализации этой самой 0b....
Потенциальная ошибка - препроцессор особым умом обычно особо не отличается, посему не не искушайте его и пользуйтесь не менее выразительным " <<( 8-3 )" а не "(<<8)>>3"
Примечание - разрядность констант не резиновая и по умолчанию чаще всего 16bit, посему нежели в будующем потребуется большая, то не забудте указать сие явно через 'L'.

C некоторой долей вероятности основываясь на типичных ошибках в реализации макросов на основе которых построено "нечто" можете попробовать:
T=(0b10001100) << (8-3);


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jan 6 2008, 05:41
Сообщение #19


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата
T=(0b10001100<<8)>>3;
...
выдает значение Т=0b1111000110000000, хотя должен 0b0001111000110000.


И что тут не правильного? Было 2 нуля справа, стало 7. Как раз сдвиг влево на 5.

А с единичками в старших разрядах что-то напутано:-)


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
slanted
сообщение Jan 6 2008, 12:12
Сообщение #20


Частый гость
**

Группа: Участник
Сообщений: 140
Регистрация: 2-01-08
Пользователь №: 33 768



Цитата(zltigo @ Jan 6 2008, 05:47) *
Главная ошибка - Вы начали использовать "нечто" пытающееся эмулировать дебильную бинарную запись при наличии в языках много более удобных средств, например, возможности поименовать биты. Разбираться (только зачем - правильнее не пользоваться) можете начинать с реализации этой самой 0b....
Потенциальная ошибка - препроцессор особым умом обычно особо не отличается, посему не не искушайте его и пользуйтесь не менее выразительным " <<( 8-3 )" а не "(<<8)>>3"
Примечание - разрядность констант не резиновая и по умолчанию чаще всего 16bit, посему нежели в будующем потребуется большая, то не забудте указать сие явно через 'L'.

C некоторой долей вероятности основываясь на типичных ошибках в реализации макросов на основе которых построено "нечто" можете попробовать:
T=(0b10001100) << (8-3);

И где тут хоть один макрос?
Кстати, >>(8-3) сработает, но по совсем другой причине.

Цитата(pimen @ Jan 6 2008, 05:02) *
int T=0x0;

main ()
{
T=(0b10001100<<8)>>3;
}

это нечто выдает значение Т=0b1111000110000000, хотя должен 0b0001111000110000.
если заменить сдвиг право на 3 на деление на 0b1000, то результат все равно 0b1111000110000000.
деление и сдвиг просто числа 0b1000110000000000 дает правильные результаты.
что я не учел??????????


Проблема в том, что: а) стандарт Си не специфицирует, будет ли ">>" арифметическим сдвигом, или логическим; б) не специфицируется размер int'а, который в данном случае составляет 16 бит. В результате сдвига на 8 влево, 0b10001100 превращается в 0x8C00, которое содержит единицу в знаковом бите (типа это отрицательное число). Сдвиг вправо, который как оказалось, в данном случае арифметический, размазывает эту единицу по старшим битам числа чтобы сохранить отрицательность. В результате имеем то, что имеем.

При сдвиге "просто числа" 0b1000110000000000 такого не происходит, потому что данная реализация компилятора считает константы данного вида unsigned, и генерирует для них логический сдвиг.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 6 2008, 12:16
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(slanted @ Jan 6 2008, 14:03) *
И где тут хоть один макрос?

Прибамбасы (0b.... ) штатными средствами компиляторов не поддерживаются и в этом случае реализуются твердыми последователями ассемблеров не имеющих поддержки макросов на на макросах smile.gif - вот такой парадокс.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
pimen
сообщение Jan 10 2008, 20:22
Сообщение #22


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 30-11-07
Пользователь №: 32 846



Еще вопрос по С:
использовал оператор goto. Сам оператор находится в подпрограмме, метка находится в main(). Компилятор пишет ошибку.
Если переношу оператор goto в main(), то все нормально.
что за ерунда?
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Jan 10 2008, 20:48
Сообщение #23


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Цитата(pimen @ Jan 10 2008, 23:22) *
Еще вопрос по С:
использовал оператор goto. Сам оператор находится в подпрограмме, метка находится в main(). Компилятор пишет ошибку.
Если переношу оператор goto в main(), то все нормально.
что за ерунда?

Прочитать книгу по языку С и понять назначение оператора goto в языке. В ассемблере переход не запрещен из функции, программирование на С структурное и выход из функции должен быть корректно оформлен (очистка стека и другое).


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
slanted
сообщение Jan 10 2008, 22:28
Сообщение #24


Частый гость
**

Группа: Участник
Сообщений: 140
Регистрация: 2-01-08
Пользователь №: 33 768



Цитата(pimen @ Jan 11 2008, 00:22) *
Еще вопрос по С:
использовал оператор goto. Сам оператор находится в подпрограмме, метка находится в main(). Компилятор пишет ошибку.
Если переношу оператор goto в main(), то все нормально.
что за ерунда?

Так задумано. Если хотите прострелить себе ногу -- прочитайте про setjmp/longjmp, которым такое поведение эмулируется.
Go to the top of the page
 
+Quote Post
alexander55
сообщение Jan 11 2008, 08:34
Сообщение #25


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(pimen @ Jan 10 2008, 23:22) *
Еще вопрос по С:
использовал оператор goto. Сам оператор находится в подпрограмме, метка находится в main().

Это что за издевательство ?
Подумайте, что будет со стеком ?
PS. Мой Вам совет - забудьте про goto и никогда не вспоминайте .
Go to the top of the page
 
+Quote Post
pimen
сообщение Jan 11 2008, 09:35
Сообщение #26


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 30-11-07
Пользователь №: 32 846



по поводу оператора goto, пользуясь вашими советами, забуду.
Подскажите, как корректно переместиться из подпрограммы в main()
структура программы приведена ниже:

void hot(void)
{
//отсюда надо попасть в main()
}

void compare(void)
if (....)
{
hot()
}

SIGNAL(SIG_OVERFLOW1)
{
...
compare()
...
}

main()
{
// сюда надо перескочить из hot()
}
Go to the top of the page
 
+Quote Post
alexander55
сообщение Jan 11 2008, 10:34
Сообщение #27


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(pimen @ Jan 11 2008, 12:35) *
по поводу оператора goto, пользуясь вашими советами, забуду.
Подскажите, как корректно переместиться из подпрограммы в main()
структура программы приведена ниже:

void hot(void)
{
//отсюда надо попасть в main()
}

void compare(void)
if (....)
{
hot()
}

SIGNAL(SIG_OVERFLOW1)
{
...
compare()
...
}

main()
{
// сюда надо перескочить из hot()
}

Давайте уточним задачу.
По некоторому прерыванию SIGNAL(SIG_OVERFLOW1)
при выполнении каких-то условий (скажем аварийных), Вы быстро должны произвести какие-то действия в hot() и завершить выполнение прерывания.
Так или что-то еще осталось за кадром ?
PS. Вспомнил про обсуждения на эту тему
http://electronix.ru/forum/index.php?showt...&hl=*goto*#
Go to the top of the page
 
+Quote Post
pimen
сообщение Jan 11 2008, 11:42
Сообщение #28


Участник
*

Группа: Участник
Сообщений: 67
Регистрация: 30-11-07
Пользователь №: 32 846



Цитата(alexander55 @ Jan 11 2008, 13:34) *
Давайте уточним задачу.
По некоторому прерыванию SIGNAL(SIG_OVERFLOW1)
при выполнении каких-то условий (скажем аварийных), Вы быстро должны произвести какие-то действия в hot() и завершить выполнение прерывания.
Так или что-то еще осталось за кадром ?
PS. Вспомнил про обсуждения на эту тему
http://electronix.ru/forum/index.php?showt...&hl=*goto*#


Вы совершенно правильно поняли
в hot() происходит выключение источников, потом в main(), пока есть авария (в данном случае перегрев), ждем устранение аварийного фактора, и поехали дальше

спасибо за ссылку
Go to the top of the page
 
+Quote Post
alexander55
сообщение Jan 11 2008, 12:12
Сообщение #29


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(pimen @ Jan 11 2008, 14:42) *
Вы совершенно правильно поняли
в hot() происходит выключение источников, потом в main(), пока есть авария (в данном случае перегрев), ждем устранение аварийного фактора, и поехали дальше


В main Вы попадете по окончании прерывания без всяких фокусов (причем с корректным стеком).
Если Вам надо заблокировать какие-то действия в прерывании, установите флаг аварии при выходе за допустимые пределы и анализируя этот флаг не выполняйте, что не требуется.
После устранения аварии этот флаг сбросьте (подозреваю, что он уже существует).
Вот и все.
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 08:14
Рейтинг@Mail.ru


Страница сгенерированна за 0.01469 секунд с 7
ELECTRONIX ©2004-2016