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

 
 
 
Reply to this topicStart new topic
> Вопрос по WinAVR, как разбить int на два char
sergeus
сообщение Feb 3 2008, 16:04
Сообщение #1


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

Группа: Участник
Сообщений: 157
Регистрация: 11-12-07
Из: Москва
Пользователь №: 33 174



Здравствуйте! Не смог разобраться, как сделать чтобы функция принимаящая int-овое значение записала младший байт в один регист, а старший в другой?

void pwm_out(int level){


OCR1AH = ??
OCR1AL = ??

return 0;
}

С уважением, Сергей

P.S. посоветуйте пожалуйста какой-нибудь help по WinAVR
Go to the top of the page
 
+Quote Post
singlskv
сообщение Feb 3 2008, 16:11
Сообщение #2


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(sergeus @ Feb 3 2008, 19:04) *
Здравствуйте! Не смог разобраться, как сделать чтобы функция принимаящая int-овое значение записала младший байт в один регист, а старший в другой?
void pwm_out(int level){
OCR1AH = ??
OCR1AL = ??

return 0;
}
P.S. посоветуйте пожалуйста какой-нибудь help по WinAVR
Попробуйте вот так:
OCR1A=level;

help уже есть в установке WinAVR, исчите...
Go to the top of the page
 
+Quote Post
KRS
сообщение Feb 3 2008, 16:25
Сообщение #3


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(sergeus @ Feb 3 2008, 19:04) *
Здравствуйте! Не смог разобраться, как сделать чтобы функция принимаящая int-овое значение записала младший байт в один регист, а старший в другой?

Так это вопрос не о WinAvr, а в общем по С.
Здесь еще идеологическая ошибка - параметр должен быть unsigned.
Код
    OCR1AH = ((unsigned)level)>>8;    
    OCR1AL =  level;
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 3 2008, 17:14
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Код
/* integer */
typedef int     INT;
typedef signed int   SINT;
typedef unsigned int  UINT;
#define MAXUINT    ((UINT)(-1))

/* byte */
typedef char    CHAR;
typedef signed char   SCHAR;
typedef unsigned char  UCHAR;

typedef CHAR    INT8;
typedef SCHAR    SINT8;
typedef UCHAR    UINT8;
#define MAXUINT8   ((UINT8)(-1))

/* word */
typedef short    INT16;
typedef signed short  SINT16;
typedef unsigned short  UINT16;
#define MAXUINT16   ((UINT16)(-1))

/* double word */
typedef long    INT32;
typedef signed long   SINT32;
typedef unsigned long  UINT32;
#define MAXUINT32   ((UINT32)(-1))

/* quad word */
typedef long long   INT64;
typedef signed long long SINT64;
typedef unsigned long long UINT64;
#define MAXUINT64   ((UINT64)(-1))



/* utils */
#define MAKEUINT16(byte_h, byte_l) ((UINT16)(((UINT16)byte_h << 8)|(UINT16)byte_l))
#define HIBYTE(word)    ((UINT8)((UINT16)word >> 8))
#define LOBYTE(word)    ((UINT8)((UINT16)word & 0xff))

#define MAKEUINT32(word_h, word_l) ((UINT32)(((UINT32)word_h << 16)|(UINT32)word_l))
#define HIWORD(longv)    ((UINT16)((UINT32)longv >> 16))
#define LOWORD(longv)    ((UINT16)((UINT32)longv & 0xffff))

#define SWAP16(n16)     (MAKEUINT16(LOBYTE(n16), HIBYTE(n16)))
#define SWAP32(n32)     (MAKEUINT32(SWAP16(LOWORD(n32)), SWAP16(HIWORD(n32))))


--------------------
Go to the top of the page
 
+Quote Post
interrupt
сообщение Mar 1 2008, 22:08
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 28-02-08
Пользователь №: 35 466



Цитата(sergeus @ Feb 3 2008, 19:04) *
Здравствуйте! Не смог разобраться, как сделать чтобы функция принимаящая int-овое значение записала младший байт в один регист, а старший в другой?

void pwm_out(int level){
OCR1AH = ??
OCR1AL = ??

return 0;
}

С уважением, Сергей

P.S. посоветуйте пожалуйста какой-нибудь help по WinAVR


А я бы сделал через union.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Mar 2 2008, 08:15
Сообщение #6


Гуру
******

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



Цитата(prottoss @ Feb 3 2008, 20:14) *

Маски совершенно лишние, зато скобок не хватает sad.gif


Цитата(interrupt @ Mar 2 2008, 01:08) *
А я бы сделал через union.

Замучаешься и запутаешся все переменые, которые может потребоваться побайтно запихнуть через union-ы описывать и использовать, или типы преобразовывать.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
prottoss
сообщение Mar 2 2008, 09:21
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(zltigo @ Mar 2 2008, 15:15) *
Маски совершенно лишние, зато скобок не хватает sad.gif
Тем не менее все это работает на компиляторе от IAR и от INTEL


--------------------
Go to the top of the page
 
+Quote Post
zltigo
сообщение Mar 2 2008, 09:32
Сообщение #8


Гуру
******

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



Цитата(prottoss @ Mar 2 2008, 12:21) *
Тем не менее все это работает на компиляторе от IAR и от INTEL

Иногда работает sad.gif. Пробуем:
#define HIBYTE(word) ((UINT8)((UINT16)word >> 8))
c = HIBYTE( a + b );
Можете перебирать компиляторы. Работать, естественно, не будет ни на одном.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
prottoss
сообщение Mar 2 2008, 10:24
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(zltigo @ Mar 2 2008, 16:32) *
Иногда работает sad.gif . Пробуем:
#define HIBYTE(word) ((UINT8)((UINT16)word >> 8))
c = HIBYTE( a + b );
Можете перебирать компиляторы. Работать, естественно, не будет ни на одном.
Хмм...Перебрал несколько вариантов на трех компиляторах smile.gif Работает и в IAR и в Intel C++ Compiler и в Borland Builder....

Делал вот такие варианты

Код


UINT8 c;
UINT16 a = 256;
UINT16 b = 512;
c = HIBYTE(a + b);

...

UINT16 c;
UINT16 a = 256;
UINT16 b = 512;
c = HIBYTE(a + b);

....

UINT16 c;
UINT32 a = 256;
UINT32 b = 512;
c = HIBYTE(a + b);

...

UINT32 c;
UINT16 a = 256;
UINT16 b = 512;
c = HIBYTE(a + b);

....

UINT32 c;
UINT32 a = 256;
UINT32 b = 512;
c = HIBYTE(a + b);


Все прекрасно вычисляется. Так где проблема??? Чем отличается

c = HIBYTE( a + b );
от, к примеру,

c = HIBYTE( d );

Арифметические операции выше по приоритету, чем логические (побитовые в том числе), Так что я не вижу криминала.


--------------------
Go to the top of the page
 
+Quote Post
zltigo
сообщение Mar 2 2008, 10:57
Сообщение #10


Гуру
******

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



Цитата(prottoss @ Mar 2 2008, 13:24) *
Арифметические операции выше по приоритету, чем логические (побитовые в том числе), Так что я не вижу криминала.

Вы на верном пути smile.gif просто я совершенно неподумав sad.gif "+" в примере поствил, но сути это не меняет - смотрим другие, которые ниже по приоритету, чем ">>":
с = HIBYTE( a | b );
Как эффект?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
prottoss
сообщение Mar 2 2008, 15:28
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(zltigo @ Mar 2 2008, 17:57) *
Вы на верном пути smile.gif просто я совершенно неподумав sad.gif "+" в примере поствил, но сути это не меняет - смотрим другие, которые ниже по приоритету, чем ">>":
с = HIBYTE( a | b );
Как эффект?
Да, согласен. Хотя я не помню, чтоб пользовался вычислениями в параметре макросов, скобки обязательно нужны. Спасибо smile.gif Одним потенциальным затыком меньше

Думаю, вот так будет правильно, учитывая, что "...Маски совершенно лишние..."

Код


/* Utils */
#define MAKEUINT16(byte_h, byte_l) ((UINT16)(((UINT16)((byte_h) << 8))|(UINT16)(byte_l)))
#define HIBYTE(word)    ((UINT8)((word) >> 8))
#define LOBYTE(word)    ((UINT8)word)

#define MAKEUINT32(word_h, word_l) ((UINT32)(((UINT32)((word_h) << 16))|(UINT32)word_l))
#define HIWORD(dword)    ((UINT16)((dword) >> 16))
#define LOWORD(dword)    ((UINT16)dword)


--------------------
Go to the top of the page
 
+Quote Post
Baser
сообщение Mar 2 2008, 20:35
Сообщение #12


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(prottoss @ Mar 2 2008, 17:28) *
Хотя я не помню, чтоб пользовался вычислениями в параметре макросов, скобки обязательно нужны.

Насколько я помню, при макроподстановке с аргументами наличие скобок обязательно, и на это обращают внимание все авторы. Вот, посмотрел в Кернигана и Ричи:
Цитата
4.11.2 Макроподстановка.
....следует позаботиться о скобках, чтобы обеспечить нужный порядок вычислений. Задумайтесь, что случится, если при определении

#define square(x) x*x /* НЕВЕРНО */

вызвать square (z+1)


Цитата(prottoss @ Mar 2 2008, 17:28) *
Думаю, вот так будет правильно

#define LOBYTE(word) ((UINT8)word)
#define LOWORD(dword) ((UINT16)dword)

Все-таки не до конца smile.gif Здесь Вы скобки почему-то снова опустили. Вот пример smile.gif :
Код
UINT16 var = 0x55AA;

UINT8 test(void) {
  return LOBYTE(var >> 4);
}
Go to the top of the page
 
+Quote Post
prottoss
сообщение Mar 3 2008, 02:30
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Baser @ Mar 3 2008, 03:35) *
Все-таки не до конца smile.gif
Да, конечно.


--------------------
Go to the top of the page
 
+Quote Post
Aesthete Animus
сообщение Mar 3 2008, 08:04
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 222
Регистрация: 9-06-07
Пользователь №: 28 317



Цитата(sergeus @ Feb 3 2008, 19:04) *
Здравствуйте! Не смог разобраться, как сделать чтобы функция принимаящая int-овое значение записала младший байт в один регист, а старший в другой?

Иногда, когда начинаю сильно тупить и грешу на сдвиги, полагая что в них я теряю какой-то байт, то поступаю так:
Код
uint16_t word = 0xABCD;
uint8_t lo, hi;
lo = ((uint8_t*)&word)[0];
hi = ((uint8_t*)&word)[1];
Go to the top of the page
 
+Quote Post

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

 


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


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