Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Кто подскажет - это глюк Keil ?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > MCS51
IF_P
Перешел на Keil-51. В Proview32 работало нормально а в Keil глючит. Это глюк или так должно быть?
При суммировании 99+99+99+99+99+99+99+99 получем ==03 (видимо старший байт результата - 0x0318)

PS: глобальные переменные
xdata unsigned int W_max, W_mid;
rezident
Либо я не понял сути проблемы, либо вы не понимаете сути типизации и арифметических действий в Си. laughing.gif
Каждое из значений (число 99) слагаемых конечной суммы в вашем выражении можно представить типом char, но сумму из восьми чисел (99*8=792=0x318) уже нельзя представить типом char, т.к. оно превышает разрядность этого типа (0<=unsigned char<=255=0xFF) и происходит переполнение переменной. По этой причине сумма усекается до числа представимого с помощью типа char (0x18=24). Ну а деление полученного (усеченного) числа на 8 и дает искомое число 3 (24/8=3).
В общем рекомендую внимательнее изучить стандарт Си.
IF_P
Цитата(rezident @ Dec 22 2008, 23:34) *
Либо я не понял сути проблемы, либо вы не понимаете сути типизации и арифметических действий в Си. laughing.gif
Каждое из значений (число 99) слагаемых конечной суммы в вашем выражении можно представить типом char, но сумму из восьми чисел (99*8=792=0x318) уже нельзя представить типом char, т.к. оно превышает разрядность этого типа (0<=unsigned char<=255=0xFF) и происходит переполнение переменной. По этой причине сумма усекается до числа представимого с помощью типа char (0x18=24). Ну а деление полученного (усеченного) числа на 8 и дает искомое число 3 (24/8=3).
В общем рекомендую внимательнее изучить стандарт Си.


Я понимаю, что такое тип переменной и как он представляется в Си. Видимо я не совсем понятно объяснил суть проблемы. Суммируются 8 чисел, каждое меньше 100. Результат объявлен как unsigned int. Следовательно, результат помещается в переменной.
Keil суммирует числа так как они написаны в программе: к а прибавляется b (но в формате char). Потом к результату прибавляется c и т.д. Но все в формате char. Получается переполнение.
В отличие от этого Franklin все делает правильно. Он суммирует числа через промежуточные р-ры (R6,R7) с учетом переноса.
Я для сравнения привел ассемблерную мнемонику обеих компиляторов, где и можно все это увидеть.

Что касаетсят программирования на Си, то эта программа нормально работает более двух лет, а вышеуказанная проблема возникла при переходе на Keil.

Я в комментарии указал каким образом Keil работает нормально (все переменные описаны как unsigned int), Но при этом увеличивается память. А ведь Franklin прекрасно все понимает с переменными char. Хотелось бы знать как поступать в будущем.
rezident
Цитата(IF_P @ Dec 23 2008, 03:30) *
Хотелось бы знать как поступать в будущем.
Поступать нужно так, как предписывает стандарт языка Си. Все более современные компиляторы стараются следовать этому стандарту как можно точнее. Причем вам совсем не обязательно все переменные передавать в функцию как unsigned int. Можно всего лишь одну из переменных типа unsigned char в конечном выражении явно привести к типу unsigned int. И тогда все остальные переменные при вычислении суммы будут автоматически приведены к более старшему типу в соответствии со стандартом Си.

Код
W_mid=((unisgned int)a+b+c+d+e+f+g+h)/n_W;
Сергей Борщ
Цитата(rezident @ Dec 23 2008, 00:41) *
И тогда все остальные переменные при вычислении суммы будут автоматически приведены к более старшему типу в соответствии со стандартом Си.
В соответствии со стандартом они и так должны быть приведены к int неявно (integer promotion rules). Микрочиповский MPLAB-C30 по умолчанию не делает этого (описано в документации), но имеет ключик "делать как положено по стандарту". Возможно и Кейл поступает также? Во всяком случае поискать в документации слово "promotion" и внимательно просмотреть описание ключей компилятора не помешает.
rezident
Цитата(Сергей Борщ @ Dec 23 2008, 03:53) *
Возможно и Кейл поступает также? Во всяком случае поискать в документации слово "promotion" и внимательно просмотреть описание ключей компилятора не помешает.
Действительно в Keil есть такая опция!
http://www.keil.com/support/docs/1494.htm
http://www.keil.com/support/man/docs/c51/c51_intpromote.htm
IF_P
Цитата(rezident @ Dec 23 2008, 01:00) *

В документации указано, что по умолчанию INTPROMOTE. Попробовал объявить явно:

#pragma intpromote
или
#pragma nointpromote

Ничего не изменилось. Но это описано касательно условных операторов. Возможно, где-то еще есть "ключик". Может кто знает? У меня мVision2V2.36, C51-V7.04.

А вот что касается рекомендации rezident по приведения типов, то это работает.

W_mid=((unisgned int)a+b+c+d+e+f+g+h)/n_W;
Палыч
Цитата(IF_P @ Dec 23 2008, 16:51) *
В документации указано, что по умолчанию INTPROMOTE. Попробовал объявить явно:
#pragma intpromote
или
#pragma nointpromote
Ничего не изменилось.
А, может - проще: галочку поставить?
Menu -> Project -> Options for Target -> C51 -> Enable ANSI integer promotion rules
IF_P
Цитата(Палыч @ Dec 23 2008, 15:59) *
А, может - проще: галочку поставить?
Menu -> Project -> Options for Target -> C51 -> Enable ANSI integer promotion rules

Галочка стоит (настройка по умолчанию)
Палыч
Цитата(IF_P @ Dec 23 2008, 19:23) *
Галочка стоит (настройка по умолчанию)
Тогда - все char должны приводиться к int в соответствии со стандартом! Может быть, Вы нечаяно убрали эту галку именно для конкретного файла? Посмотрите - нет ли трёх жирных точек у значка файла в окне Project Workspace? Если - есть, то для этого файла также поставьте галочку.
IF_P
Цитата(Палыч @ Dec 23 2008, 19:13) *
Тогда - все char должны приводиться к int в соответствии со стандартом! Может быть, Вы нечаяно убрали эту галку именно для конкретного файла? Посмотрите - нет ли трёх жирных точек у значка файла в окне Project Workspace? Если - есть, то для этого файла также поставьте галочку.

И три точки есть и галочка есть.
rezident
IF_P, в Windows есть растровый графический редактор Paint. Из него можно сохранять изображения в форматах JPG и GIF. Пользуйтесь, пожалуйста им для сохранения скриншотов, а не вставкой картинки в Word. Во-первых, неудобно: картинка в текстовом документа, да еще и зархивированная 07.gif , во-вторых, весьма мелкое изображение получается. Создание изображение в Paint точно такое же как и в Word. PrintScreen или CTRL+PrintScreen для снятия скриншота, а потом в Paint CTRL+V и CTRL+S для сохранения.
IF_P
Цитата(rezident @ Dec 23 2008, 20:29) *
IF_P, в Windows есть растровый графический редактор Paint. Из него можно сохранять изображения в форматах JPG и GIF. Пользуйтесь, пожалуйста им для сохранения скриншотов, а не вставкой картинки в Word. Во-первых, неудобно: картинка в текстовом документа, да еще и зархивированная 07.gif , во-вторых, весьма мелкое изображение получается. Создание изображение в Paint точно такое же как и в Word. PrintScreen или CTRL+PrintScreen для снятия скриншота, а потом в Paint CTRL+V и CTRL+S для сохранения.

Спасибо за замечание. Учту
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.