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

 
 
> Keil не видит extern SFR bit
IF_P
сообщение Jan 2 2009, 14:40
Сообщение #1


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

Группа: Участник
Сообщений: 136
Регистрация: 2-01-06
Пользователь №: 12 772



51-й проц. Keil 2 V2.36. Когда программа была в одном файле, все работало. Разнес программу в отдельные файлы и поставил описания extern. Со всеми переменными и битами разобрался, а вот одного п/п не видит. Может потому, что SFR бит? Помогите разобраться.
Прикрепленные файлы
Прикрепленный файл  Ttt.rar ( 16.35 килобайт ) Кол-во скачиваний: 30
 
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 11)
тау
сообщение Jan 2 2009, 17:10
Сообщение #2


.
******

Группа: Участник
Сообщений: 2 424
Регистрация: 25-12-08
Пользователь №: 42 757



Цитата(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.
Go to the top of the page
 
+Quote Post
IF_P
сообщение Jan 2 2009, 20:31
Сообщение #3


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

Группа: Участник
Сообщений: 136
Регистрация: 2-01-06
Пользователь №: 12 772



Цитата(тау @ 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"

Сообщение отредактировал IF_P - Jan 2 2009, 20:36
Go to the top of the page
 
+Quote Post
тау
сообщение Jan 2 2009, 22:31
Сообщение #4


.
******

Группа: Участник
Сообщений: 2 424
Регистрация: 25-12-08
Пользователь №: 42 757



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

Так штаа..... Если хочется в одном месте объявить такую переменную то делайте строку sbit ENABLE1 = 0x90; в файл .H
и вставляйте #include там где будете использовать переменную ENABLE1
Go to the top of the page
 
+Quote Post
IF_P
сообщение Jan 3 2009, 14:22
Сообщение #5


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

Группа: Участник
Сообщений: 136
Регистрация: 2-01-06
Пользователь №: 12 772



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

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

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

PS:
Попробовал подключить компъютер - тоже не работает.Получается, что проблема в описаниях "extern". Просмотрел все описания. Вроде все корректно.

Сообщение отредактировал IF_P - Jan 3 2009, 14:37
Go to the top of the page
 
+Quote Post
Nemo2000
сообщение Jan 3 2009, 16:43
Сообщение #6


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

Группа: Свой
Сообщений: 79
Регистрация: 8-04-05
Из: Санк-Петербург
Пользователь №: 3 972



Цитата(тау @ Jan 3 2009, 01:31) *
А вот
char bdata хххххх=adr; полностью и без варнингов игнорируется все начиная с "="


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

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


Так вроде или работает? smile.gif Сам бит-то в дебагере меняется? адрес правильный используется?
Вообще говоря делал так же, как и было посоветовано, только что определение бита делал не в отдельном хедере а прямо в том, где все SFR определены и подключал его там, где требуется. Все нормально работало.
Go to the top of the page
 
+Quote Post
тау
сообщение Jan 3 2009, 18:01
Сообщение #7


.
******

Группа: Участник
Сообщений: 2 424
Регистрация: 25-12-08
Пользователь №: 42 757



Цитата(Nemo2000 @ Jan 3 2009, 19:43) *
не игнорируется. Данная запись означает лишь то, что переменную хххххх проинициализировать значением adr.

Игнорируется в кейле uVision2 2.04 . Проверял!!!
В более новом (3) проверить не могу - нету дома.
Go to the top of the page
 
+Quote Post
IF_P
сообщение Jan 3 2009, 22:59
Сообщение #8


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

Группа: Участник
Сообщений: 136
Регистрация: 2-01-06
Пользователь №: 12 772



Цитата(тау @ 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 3 2009, 23:01
Go to the top of the page
 
+Quote Post
тау
сообщение Jan 3 2009, 23:37
Сообщение #9


.
******

Группа: Участник
Сообщений: 2 424
Регистрация: 25-12-08
Пользователь №: 42 757



http://www.keil.com/support/docs/1175.htm
http://www.keil.com/support/man/docs/c51/c...roublebdata.htm

они сами не знают.
Go to the top of the page
 
+Quote Post
IF_P
сообщение Jan 4 2009, 19:05
Сообщение #10


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

Группа: Участник
Сообщений: 136
Регистрация: 2-01-06
Пользователь №: 12 772



Цитата(тау @ 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

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

Но это ведь описано в разделе технической поддержки, а не в документации.!

Сообщение отредактировал IF_P - Jan 4 2009, 19:08
Go to the top of the page
 
+Quote Post
тау
сообщение Jan 4 2009, 19:07
Сообщение #11


.
******

Группа: Участник
Сообщений: 2 424
Регистрация: 25-12-08
Пользователь №: 42 757



'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 (вторая строка листинка)
Но лень :о)

Сообщение отредактировал тау - Jan 4 2009, 19:14
Go to the top of the page
 
+Quote Post
IF_P
сообщение Jan 4 2009, 20:00
Сообщение #12


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

Группа: Участник
Сообщений: 136
Регистрация: 2-01-06
Пользователь №: 12 772



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

И я о том же. Лень им, видимо, поправить нормально свой софт. biggrin.gif Да и документацию тоже поправить надо бы.

Сообщение отредактировал IF_P - Jan 4 2009, 20:02
Go to the top of the page
 
+Quote Post

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

 


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


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