Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос по WinAVR
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
sergeus
Здравствуйте! Не смог разобраться, как сделать чтобы функция принимаящая int-овое значение записала младший байт в один регист, а старший в другой?

void pwm_out(int level){


OCR1AH = ??
OCR1AL = ??

return 0;
}

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

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

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

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

Так это вопрос не о WinAvr, а в общем по С.
Здесь еще идеологическая ошибка - параметр должен быть unsigned.
Код
    OCR1AH = ((unsigned)level)>>8;    
    OCR1AL =  level;
prottoss
Код
/* 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))))
interrupt
Цитата(sergeus @ Feb 3 2008, 19:04) *
Здравствуйте! Не смог разобраться, как сделать чтобы функция принимаящая int-овое значение записала младший байт в один регист, а старший в другой?

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

return 0;
}

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

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


А я бы сделал через union.
zltigo
Цитата(prottoss @ Feb 3 2008, 20:14) *

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


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

Замучаешься и запутаешся все переменые, которые может потребоваться побайтно запихнуть через union-ы описывать и использовать, или типы преобразовывать.
prottoss
Цитата(zltigo @ Mar 2 2008, 15:15) *
Маски совершенно лишние, зато скобок не хватает sad.gif
Тем не менее все это работает на компиляторе от IAR и от INTEL
zltigo
Цитата(prottoss @ Mar 2 2008, 12:21) *
Тем не менее все это работает на компиляторе от IAR и от INTEL

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

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

Вы на верном пути smile.gif просто я совершенно неподумав sad.gif "+" в примере поствил, но сути это не меняет - смотрим другие, которые ниже по приоритету, чем ">>":
с = HIBYTE( a | b );
Как эффект?
prottoss
Цитата(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)
Baser
Цитата(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);
}
prottoss
Цитата(Baser @ Mar 3 2008, 03:35) *
Все-таки не до конца smile.gif
Да, конечно.
Aesthete Animus
Цитата(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];
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.