Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Keil не видит extern SFR bit
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > MCS51
IF_P
51-й проц. Keil 2 V2.36. Когда программа была в одном файле, все работало. Разнес программу в отдельные файлы и поставил описания extern. Со всеми переменными и битами разобрался, а вот одного п/п не видит. Может потому, что SFR бит? Помогите разобраться.
тау
Цитата(IF_P @ Jan 2 2009, 17:40) *
51-й проц. Keil 2 V2.36. Когда программа была в одном файле, все работало. Разнес программу в отдельные файлы и поставил описания extern. Со всеми переменными и битами разобрался, а вот одного п/п не видит. Может потому, что SFR бит? Помогите разобраться.


попробуйте "bdata". Смысл имхо в том что не все sbit без bdata могут быть extern

Bit-addressable Objects
Bit-addressable objects are objects that can be addressed as words or as bits.
Only data objects that occupy the bit-addressable area of the 8051 internal
memory fall into this category. The Cx51 compiler places variables declared
with the bdata memory type into this bit-addressable area. Furthermore,
variables declared with the bdata memory type must be global. You may declare
these variables as shown below:
Код
int bdata ibase; /* Bit-addressable int */
char bdata bary [4]; /* Bit-addressable array */

The variables ibase and bary are bit-addressable. Therefore, the individual
bits of these variables may be directly accessed and modified. Use the sbit
keyword to declare new variables that access the bits of variables declared using
bdata. For example:
Код
sbit mybit0 = ibase ^ 0; /* bit 0 of ibase */
sbit mybit15 = ibase ^ 15; /* bit 15 of ibase */
sbit Ary07 = bary[0] ^ 7; /* bit 7 of bary[0] */
sbit Ary37 = bary[3] ^ 7; /* bit 7 of bary[3] */

The above example represents declarations, not assignments to the bits of the
ibase and bary variables declared above. The expression following the carat
symbol (‘^’) in the example specifies the position of the bit to access with this
declaration. This expression must be a constant value. The range depends on
the type of the base variable included in the declaration. The range is 0 to 7 for
char and unsigned char, 0 to 15 for int, unsigned int, short, and unsigned
short, and 0 to 31 for long and unsigned long.
You may provide external variable declarations for the sbit type to access these
types in other modules. For example:
Код
extern bit mybit0; /* bit 0 of ibase */
extern bit mybit15; /* bit 15 of ibase */
extern bit Ary07; /* bit 7 of bary[0] */
extern bit Ary37; /* bit 7 of bary[3] */

Declarations involving the sbit type require that the base object be declared with
the memory type bdata.
The only exceptions are the variants for special
function bits.

Special function bits represent an independent declaration class that may not be
interchangeable with other bit declarations or bit fields.
The sbit data type declaration may be used to access individual bits of variables
declared with the bdata memory type specifier.
IF_P
Цитата(тау @ Jan 2 2009, 19:10) *
попробуйте "bdata". Смысл имхо в том что не все sbit без bdata могут быть extern

Bit-addressable Objects

Попробовал поменять:

sbit Enable_Display = 0x90; // CS для дешифратора LCD P1.0

на

char bdata P1=0x90;
sbit Enable_Display = P1^0; // CS для дешифратора LCD P1.0

Откомпилировалось без ошибок, но программа не работает-не выполняется инициализация LCD, где и задействован этот сигнал.

PS.
Посмотрел в DEBUG.

Enable_Display=0; - не сбрасывается в 0, так и стоит "1"
тау
Вопщем только
char bdata хххххх позволяет создать битовую переменную
типа sbit yyyy
которую в другом модуле можно связать через extern
и оно работает , но по тем адресам которые линкер придумывает.
А вот
char bdata хххххх=adr; полностью и без варнингов игнорируется все начиная с "="

Так штаа..... Если хочется в одном месте объявить такую переменную то делайте строку sbit ENABLE1 = 0x90; в файл .H
и вставляйте #include там где будете использовать переменную ENABLE1
IF_P
Цитата(тау @ Jan 3 2009, 00:31) *
Вопщем только
char bdata хххххх позволяет создать битовую переменную
типа sbit yyyy
которую в другом модуле можно связать через extern
и оно работает , но по тем адресам которые линкер придумывает.
А вот
char bdata хххххх=adr; полностью и без варнингов игнорируется все начиная с "="

Так штаа..... Если хочется в одном месте объявить такую переменную то делайте строку sbit ENABLE1 = 0x90; в файл .H
и вставляйте #include там где будете использовать переменную ENABLE1

Сделел так. Инициализация прошла, а вывода в LCD нет. Смотрел в DEBUG-режимы - все вроде работает. Нужные байты выводятся на свои места. А в железе тишина. Где искать?
Программа ведь рабочая и если все файлы не компилировать отдельно, а подключить по "include" - все ОК

PS:
Попробовал подключить компъютер - тоже не работает.Получается, что проблема в описаниях "extern". Просмотрел все описания. Вроде все корректно.
Nemo2000
Цитата(тау @ Jan 3 2009, 01:31) *
А вот
char bdata хххххх=adr; полностью и без варнингов игнорируется все начиная с "="


не игнорируется. Данная запись означает лишь то, что переменную хххххх проинициализировать значением adr.

Цитата(IF_P @ Jan 3 2009, 17:22) *
Сделел так. Инициализация прошла, а вывода в LCD нет. Смотрел в DEBUG-режимы - все вроде работает. Нужные байты выводятся на свои места. А в железе тишина. Где искать?
Программа ведь рабочая и если все файлы не компилировать отдельно, а подключить по "include" - все ОК


Так вроде или работает? smile.gif Сам бит-то в дебагере меняется? адрес правильный используется?
Вообще говоря делал так же, как и было посоветовано, только что определение бита делал не в отдельном хедере а прямо в том, где все SFR определены и подключал его там, где требуется. Все нормально работало.
тау
Цитата(Nemo2000 @ Jan 3 2009, 19:43) *
не игнорируется. Данная запись означает лишь то, что переменную хххххх проинициализировать значением adr.

Игнорируется в кейле uVision2 2.04 . Проверял!!!
В более новом (3) проверить не могу - нету дома.
IF_P
Цитата(тау @ Jan 3 2009, 20:01) *
Игнорируется в кейле uVision2 2.04 . Проверял!!!
В более новом (3) проверить не могу - нету дома.

Игнорируется, если описание extern. Обычное объявление работает:
см. первый пост

char bdata OUT_1 = 0x23;
sbit VENT_1 =OUT_1 ^ 0;
sbit VENT_2 =OUT_1 ^ 1;
sbit VENT_3 =OUT_1 ^ 2;
sbit VENT_4 =OUT_1 ^ 3;
sbit VENT_5 =OUT_1 ^ 4;
sbit VENT_6 =OUT_1 ^ 5;
sbit VENT_7 =OUT_1 ^ 6;

А в extern будет игнорироваться ИМХО из даташита:

-----------------------------------
EXTERN

The extern storage class declares a global variable that is defined in another source module. It is used as follows:

extern data-type name;

Where

data-type is the data type of the variable.
name is the name of the variable.

When you use extern to declare a variable, the variable cannot be initialized (it is already initialized where it is defined).

Проверял и на uVision3 V3.60 тоже.

А что касается моей проблемы - все заработало. Что именно помогло точно не знаю. Начал все с начала. С общего файла выделил один модуль "display.c". Описал все extern, скомпилировал с ошибками: не указаны прототипы четырех ф-ций этого модуля. Но ведь они не были указаны и в варианте с одним общим файлом, а компилировалось без ошибок и в железе работает без проблем.

Указал прототипы - предыдущая ошибка с битами. А заработало, когда два раза объявил биты??? 05.gif

Получилось вот так:

----- MAIN.C -----

sbit Enable_Display = 0x90; // CS для дешифратора LCD P1.0
sbit DISPLAY_E = 0x82; // ENABLE P0.2

main()
{
...
}

----- DISPLAY.C -----

sbit Enable_Display = 0x90; // CS для дешифратора LCD P1.0
sbit DISPLAY_E = 0x82; // ENABLE P0.2

{
...
}

Если ставлю в одном из файлов extern, то получаю:

extern sbit Enable_Display = 0x90;

либо

extern sbit Enable_Display;

error C141: syntax error near 'sbit'

Линкер бы должен выдавать ошибку о повторном объявлении (в случае с обычной переменной). Ат нет, Ошибки не выдает и в железе работает нормально.

Что же все таки с этими SFR-битами?
IF_P
Цитата(тау @ Jan 4 2009, 01:37) *


Да, вроде, знают, но молчат. Вот нашел на их форуме.
http://www.keil.com/support/docs/1317.htm

Получается, то, что я сделал - правильно (угадал !). А почему бы не описать это в документации?

Цитата(тау @ Jan 4 2009, 01:37) *


Да, вот еще нашел - объявление через ассемблер. Может кому-нибудь поможет.

http://www.keil.com/support/docs/168.htm

Попробовал. компилировалось нормально. И в железе все работает. Только-что проверил.

Получил такой вариант:

=======================
extern bit DISPLAY_E; // ENABLE P0.2
extern bit Enable_Display; // CS для дешифратора LCD P1.0

------MAIN.C------
{
...
}

==================

extern bit DISPLAY_E; // ENABLE P0.2
extern bit Enable_Display; // CS для дешифратора LCD P1.0

-----DISPLAY.C------
{
...
}

=============

-------bits.a51-----

PUBLIC DISPLAY_E
PUBLIC Enable_Display

DISPLAY_E BIT 82h ; ENABLE P0.2

Enable_Display BIT 90h ; CS для дешифратора LCD P1.0

END

======================

Но это ведь описано в разделе технической поддержки, а не в документации.!
тау
'sbit' всегда имеют отношение к конкретным адресам. И как правило объявляются в .h файлах. Линкеру нет никакого дела до конкректных аппаратных адресов 'sbit'. Разве что по extern привязать в другом модуле. Но линкер ленивый и отбрыкивается.
Блеск и нищета :
Код
BL51 BANKED LINKER/LOCATER V5.12                                                      01/04/2009  22:01:56  PAGE 2


B:0090H.0       PUBLIC        ENABLE1
  -------         PROC          MAIN
  C:000FH         LINE#         3
  C:000FH         LINE#         4
  C:000FH         LINE#         5
  C:0011H         LINE#         6
  C:0013H         LINE#         7
  C:0015H         LINE#         8
  -------         ENDPROC       MAIN
  -------         ENDMOD        QQQMAIN

  -------         MODULE        QQQRER
  C:0000H         SYMBOL        _ICE_DUMMY_
  C:0016H         PUBLIC        rer
  -------         PROC          RER
  C:0016H         LINE#         2
  C:0016H         LINE#         3
  C:0018H         LINE#         4
  -------         ENDPROC       RER
  -------         ENDMOD        QQQRER

*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
    SYMBOL:  ENABLE1
    MODULE:  qqqrer.obj (QQQRER)

*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
    SYMBOL:  ENABLE1
    MODULE:  qqqrer.obj (QQQRER)
    ADDRESS: 0017H

Program Size: data=9.0 xdata=0 code=25
LINK/LOCATE RUN COMPLETE.  2 WARNING(S),  0 ERROR(S)


Обратите внимание - линкеру известно о существовании ENABLE1 по адресу B:0090H.0 (вторая строка листинка)
Но лень :о)
IF_P
Цитата(тау @ Jan 4 2009, 21:07) *
'sbit' всегда имеют отношение к конкретным адресам. И как правило объявляются в .h файлах. Линкеру нет никакого дела до конкректных аппаратных адресов 'sbit'. Разве что по extern привязать в другом модуле. Но линкер ленивый и отбрыкивается.
Блеск и нищета :
...
Обратите внимание - линкеру известно о существовании ENABLE1 по адресу B:0090H.0 (вторая строка листинка)
Но лень :о)

И я о том же. Лень им, видимо, поправить нормально свой софт. biggrin.gif Да и документацию тоже поправить надо бы.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.