|
|
  |
Вопрос по WinAVR, как разбить int на два char |
|
|
|
Feb 3 2008, 16:11
|
дятел
    
Группа: Свой
Сообщений: 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, исчите...
|
|
|
|
|
Feb 3 2008, 16:25
|

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

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

Группа: Участник
Сообщений: 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.
|
|
|
|
|
Mar 2 2008, 09:32
|

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

|
Цитата(prottoss @ Mar 2 2008, 12:21)  Тем не менее все это работает на компиляторе от IAR и от INTEL Иногда работает  . Пробуем: #define HIBYTE(word) ((UINT8)((UINT16)word >> 8)) c = HIBYTE( a + b ); Можете перебирать компиляторы. Работать, естественно, не будет ни на одном.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 2 2008, 10:24
|

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

|
Цитата(zltigo @ Mar 2 2008, 16:32)  Иногда работает  . Пробуем: #define HIBYTE(word) ((UINT8)((UINT16)word >> 8)) c = HIBYTE( a + b ); Можете перебирать компиляторы. Работать, естественно, не будет ни на одном. Хмм...Перебрал несколько вариантов на трех компиляторах  Работает и в 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 ); Арифметические операции выше по приоритету, чем логические (побитовые в том числе), Так что я не вижу криминала.
--------------------
|
|
|
|
|
Mar 2 2008, 10:57
|

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

|
Цитата(prottoss @ Mar 2 2008, 13:24)  Арифметические операции выше по приоритету, чем логические (побитовые в том числе), Так что я не вижу криминала. Вы на верном пути  просто я совершенно неподумав  "+" в примере поствил, но сути это не меняет - смотрим другие, которые ниже по приоритету, чем ">>": с = HIBYTE( a | b ); Как эффект?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 2 2008, 15:28
|

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

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

Просто 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) Все-таки не до конца  Здесь Вы скобки почему-то снова опустили. Вот пример  : Код UINT16 var = 0x55AA;
UINT8 test(void) { return LOBYTE(var >> 4); }
|
|
|
|
|
Mar 3 2008, 08:04
|

Местный
  
Группа: Свой
Сообщений: 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];
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|