2013-02-26 3 views
1

У меня есть код, который я не уверен, очень оценил бы безуспешность его работы.Тип литья и указатели

Первый бит касается типа литья. Может кто-нибудь сказать мне, если я правильно читал следующий код:

#define A_TIME   0xC0500000 
#define B_TIME   *(UINT_8 *)(A_TIME + 0x00002909) 

ли выход из этого, что B_TIME является указателем на целое число без знака 8 бит = 0x09? Я не уверен, как работает литье типа? Назначает ли он 8 LSB B_TIME? Кроме того, я смущен * (UINT_8 *)? Что именно это означает/сказать? Это указатель на целое число без знака 8 бит?

Вторая часть, вероятно, будет ясно для меня, когда я знаю, что и выше, но я отправлю его в любом случае:

UINT_8 Timer = 0; 
Input_Time (&Timer); 



#define C_TIME     *(UINT_16 *)0xC0C0B000 
#define MASK      0x003F 

void Input_Time (UINT_8 *Time) 
{ 
    *Time = 0xC0; 
    *Time |= (UINT_8)((C_TIME >> 4) & MASK); 

    return; 
} 

Что такое значение * Время следующие функции Input_Time? Может кто-то пройти через код и объяснить каждый шаг для меня?

Извините за новизну (это слово ?!) вопроса.

Большое значение. Джеймс

EDIT:

ОК, я доволен выше. Благодарю. Я сейчас озадачен к следующему, которое происходит в коде, после Input_Time() был вызван:

#define OUT_TIME *(UINT_8 *)0xC0411297 
OUT_TIME = Timer; 

Как это возможно? Не OUT_TIME 8-битное значение в адресе 0XC0411297? Как это работает?

ответ

2

Код, который вы смотрите, выглядит так: memory mapped registers.

  1. B_TIME будет получить доступ к 8-битовый регистр, расположенный по адресу A_TIME плюс заданное смещение - в этом случае, это означает, что 0xC0502909. То, что на самом деле читается, зависит от используемого вами оборудования. Давайте сломаем то, что происходит на куски.B_TIME везде, где он используется, заменяется текстом:

    *(UINT_8 *)(A_TIME + 0x00002909) 
    

    И в свою очередь, A_TIME заменяется 0xC0500000, уступая:

    *(UINT_8 *)(0xC0500000 + 0x00002909) 
    

    Немного разработка арифметики дает:

    *(UINT_8 *)(0xC0502909) 
    

    Это означает «обработать 0xC0502909 как указатель на 8-битное значение, а затем разыменовать его».

  2. Ваш второй вопрос следует тому же поведению. Существует регистр, отображаемый на 0xC0C0B000, который считывается при вызове Input_Time(). 16-битное значение считывается с этого адреса, сдвигается вниз на 4, а затем замаскировано. Предполагая, что этот пример 16-битное значение, используя буквы, чтобы однозначно представляют собой биты:

    abcdefghijklmnop 
    

    понижающую передачу на 4:

    0000abcdefghijkl 
    

    И тогда маска (3f гекс 00111111 двоичный) применяется:

    0000000000ghijkl 
    

    Тогда этот результат имеет ORed с 0xc0 (11000000 двоичный), дающий:

    0000000011ghijkl 
    

    Это значение сохраняется обратно в 8-бит передается в байт, возвращая:

    11ghijkl 
    

    вызывающему абоненту.

  3. Ваш новый пример:

    #define OUT_TIME *(UINT_8 *)0xC0411297 
    OUT_TIME = Timer; 
    

    ли написание значение по этому адресу памяти.

+0

Большое спасибо, теперь это имеет гораздо больше смысла! 1. Таким образом, значение B_TIME равно любому 8-битовому значению (в ОЗУ) по адресу 0xC0502909. 2. После того как вы поняли мое понимание 1. часть 2. была прямолинейной, чтобы понять. Я должен поблагодарить вас за то, что вы нашли время, чтобы объяснить это, особенно учитывая, что он был только на такое короткое время. – James

+0

@James, это может быть не ОЗУ, но да. –

+0

@James - обновляется с ответом на ваш новый вопрос. –

0

Значение B_TIME является величиной типа UINT8.

#define B_TIME *(UINT_8 *)(A_TIME + 0x00002909) 

Оператор * разыменовывает указатель на UINT8 в следующем выражении:

(UINT_8 *)(A_TIME + 0x00002909)

В приведенном выше выражении константа целое A_TIME + 0x00002909 преобразуется в указатель на UINT8 от среднего значения литье (UINT8 *).

Смежные вопросы