Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вставка в СИ кода на ассемблере
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Яrik
Тут (www.atmel.ru/Articles/Atmel13.htm) нашел программу на ассемблере,наз. bcdfp, преобразующая двоичные числа с плавающей точкой, в последовательность (строку) из 8 ASCII-символов, которая включает в себя ASCII-символ знака, шесть ASCII-символов значащих десятичных цифр и ASCII-символ точки. Но у меня его неполучается использоватьэтот код в CodeVisionAVR.
Выдает какието ошибки при компелировании. help.gif

Может, ктото растолкует, что и как, буду весьма благодарен.
Ryzhuk
Привет.. У меня таже проблемка....
Может старожилы помогут...
Ryzhuk
Может вместе решим эту проблему.... Стучи в аську 130712520
beer_warrior
Цитата
Выдает какието ошибки при компелировании.

Вообще-то нехило код в студию вместе с ошибками компилятора.
Потому как Нео тут не водятся smile.gif

Во-вторых. Зачем такие половые извращения, когда существует семейство функций *printf() ?
big256
если вы о этом :
http://www.atmel.ru/Articles/Atmel13_app4.htm

то там написано : ;Подпрограмма может вызываться из головной программы, написанной на IAR C для AVR:

а у Иара другой синтаксис , нежели у CodeVision'a
в ЦВ надо использовать #asm, #endasm (если не ошибаюсь smile.gif ) для ассемблерных вставок -посмотрите пример С_asm поставляемый с кодевиженом и попробуйте притулить этот код туда wink.gif
_Bill
Цитата(Яrik @ Jan 8 2007, 21:34) *
Тут (www.atmel.ru/Articles/Atmel13.htm) нашел программу на ассемблере,наз. bcdfp, преобразующая двоичные числа с плавающей точкой, в последовательность (строку) из 8 ASCII-символов, которая включает в себя ASCII-символ знака, шесть ASCII-символов значащих десятичных цифр и ASCII-символ точки. Но у меня его неполучается использоватьэтот код в CodeVisionAVR.
Выдает какието ошибки при компелировании. help.gif

Может, ктото растолкует, что и как, буду весьма благодарен.

Все должно быть в документации. Но лучше вставками вообще не пользоваться, поскольку эффекта от них нет. Лучше сделать отдельный модуль на ассемблере и включить его в проект. Сам я пользуюсь IAR, как это сделать в CV не знаю.
kamedi_clab
в CVAVR по моему вот так вставку АСМ делают:

http://www.rambler.ru/srch?words=%23asm%28...%E0%E9%F2%E8%21
aleksey_g
Сам пользуюсь этой штучкой под ИАР для "Печати" CHAR, INT, FLOAT.
Про КВ не знаю, но проблем не должно быть. Только не пользуйтесь вставками.
Подключайте как отдельный асм-модуль. Посмотрите, только соглашения
про передачу параметров (какими регистрами) в иаре и кв.
Яrik
Цитата
Может вместе решим эту проблему.... Стучи в аську 130712520


Давай попробуем cheers.gif , но я аськой не пользуюсь, пеши на мыло.
Яrik
Цитата
Во-вторых. Зачем такие половые извращения, когда существует семейство функций *printf() ?


Да, printf() мощьная функция, но при выводе чисел с плавающей точкой занимает много памяти МК.
У меня, программа измеряющая напряжение на входе встроеного АЦП (ATmega8L) с выводом на LCD, заняла почти 50% памяти.

Может, у кого небудь есть наработки по выводу чисел с плавающей точкой на дисплей? Поделитесь пожалуйста.
Яrik
Цитата
Все должно быть в документации. Но лучше вставками вообще не пользоваться, поскольку эффекта от них нет. Лучше сделать отдельный модуль на ассемблере и включить его в проект. Сам я пользуюсь IAR, как это сделать в CV не знаю.


Документация это хорошо, но есть проблема, она на английском. А у меня с ним проблемы. smile.gif

Включить в проэкт пробывал, но (насколько я понял) CV добаляет только СИ модули. Исправте если не так.

Цитата
если вы о этом :
http://www.atmel.ru/Articles/Atmel13_app4.htm

то там написано : ;Подпрограмма может вызываться из головной программы, написанной на IAR C для AVR:

а у Иара другой синтаксис , нежели у CodeVision'a
в ЦВ надо использовать #asm, #endasm (если не ошибаюсь ) для ассемблерных вставок -посмотрите пример С_asm поставляемый с кодевиженом и попробуйте притулить этот код туда


C_asm смотрел. Неподскажите, что в нем означает:
...
#pragma warn-
...
#pragma warn+
...
Potter
Собствено в помощь людям которым очень нужно написать асемдлерную функцию в сишном проекте(в IAR-е).

Создаем файл с расширением asm и пристегиваем его к проекту.

В этом файле пишем свою функцию.... К примеру:

//***********************************************
NAME set_int
#include <iom16.h>
PUBLIC set_int
RSEG CODE
EXTERN sinus

set_int:
cpi r16, 0x08
brne opt
clr r16
opt:

inc r16

ret

END set_int
//***********************************************

Теперь как вызвать эту функцию в main.c:

Сначала ее нужно в обьявить в main.c:

//*********************************
extern unsigned char set_int(unsigned char);
//*********************************

А теперь эту функцию "set_int" можно вызывать в любом месте в main.c. К примеру:

//*********************
//Обработчик прерывания по таймер вектору 1.
#pragma vector = TIMER1_OVF_vect
__interrupt void Timer1_interrupt(void){
F1 = set_int(F2);
F2 = F1;
TCNT1 = TIMER1_DELAY; //Перезапуск таймера на новый отчет времени
}
//*********************

Где "F1" и "F2"- глобальные переменныя которые объявленны как unsigned char....
Передоваемое значение функции ("F2") занаосится в r16. Потом с этим значением нужно работать уже в самой асемблерной функции. Передает асемблерная функция то значение которое находится опять же в регистре r16 на момент когда функция закончивает свою работу(т. е. в "F1" сохраняется значение которое на момент окончания функции находилось в регистре r16).

Мне когда-то очень нужно было разобраться как выполнить эту задачу..... Надеюсь что это кому-нибудь поможет. Удачи.
Сергей Борщ
Цитата(Potter @ Jan 9 2007, 23:15) *
Собствено в помощь людям которым очень нужно написать асемдлерную функцию в сишном проекте(в IAR-е).
В ИАРе все подробно расписано в документации. И делается как и положено в "больших" компиляторах с раздельной компиляцией и линковкой. А люди хотят перетащить это в CV, у которого нет понятия модулей, объектных файлов, линковки. Он все файлы склеивает в один с помощью #include, компилирует эту "колбасу", получает один большой ассемблерный файл на весь проект из которого при помощи avrasm (или avrasm32 - не помню, давно смотрел) получает сразу .hex прошивки. При этом в документации создание кусков на асме описано весьма скудно, часть #pragma не описана вообще - о них можно догадаться только просматривая прилагаемые исходники "библиолтек".
В CV асм-вставки делаются так (в свое время полдня убил пока разобрался):
Код
#pragma    asm_function+
void TX_Putchar ( char TX_byte) {
#asm
    LD    R16,Y+    ;// first parameter (TX_byte) passed in [Y]
    RJMP    TX_PUTCHAR
#endasm
}

unsigned int Get_Serial(void) {
#asm     asm_function+

    RCALL    GET_SERIAL
    MOV        R30,R16
    MOV        R31,R17     ;// return unsigned int in R30:R31
    RET
#endasm
}
#pragma    asm_function-
Про то, как передаются параметры и возвращаются значения было описание в документации.
aleksey_g
Цитата(Яrik @ Jan 9 2007, 21:05) *
Может, у кого небудь есть наработки по выводу чисел с плавающей точкой на дисплей? Поделитесь пожалуйста.

Дык выше говорил!
Попробуйте bcdfp
float value
value=12.345
bcdfp(value,str)
в str получите 12.3450
aleksey_g
Цитата(Яrik @ Jan 9 2007, 21:05) *
Может, у кого небудь есть наработки по выводу чисел с плавающей точкой на дисплей? Поделитесь пожалуйста.


Я пользуюсь так:
Сразу предвижу ругательства гуру от С.
Но я более паскалист, чем сионист. Может гуру и подоптимизируют код?
Цитата
// ********************************************************************* //
// *** Display a variable char, int, float *** //
// ********************************************************************* //
void LCD_print(float value)
{
unsigned char i,mt,fl;
bcdfp(value,str);
if (str[0]==' ') mt=1; else mt=0;//печатать ли знак '-'
while (mt<8) {if (str[mt]=='.') break; else {LCD_DisplayCharacter(str[mt]);mt++;}}// пытаемся печатать целую часть
i=mt+1;
fl=0;
while (i<8) {if (str[i]=='0') {i++;} else {fl=1;break;} }// отличная ли от 0 дробная часть?
if (fl==1) { while (mt<8) {LCD_DisplayCharacter(str[mt]);mt++;} } // если да, то продолжаем печать
}
big256
Цитата(Яrik @ Jan 9 2007, 23:17) *
C_asm смотрел. Неподскажите, что в нем означает:
...
#pragma warn-
...
#pragma warn+
...


выключить/включить warnings(предупреждения)
zorromen
А про #pragma asm_function+ Можно подробнее... Что оно делает?
Dog Pawlowa
Цитата(Яrik @ Jan 9 2007, 23:05) *
Цитата
Во-вторых. Зачем такие половые извращения, когда существует семейство функций *printf() ?


Да, printf() мощьная функция, но при выводе чисел с плавающей точкой занимает много памяти МК.
У меня, программа измеряющая напряжение на входе встроеного АЦП (ATmega8L) с выводом на LCD, заняла почти 50% памяти.

А зачем Вам выводить показания АЦП 10-битного разрешения с точностью плавающей точки!?
Захотели красивой и легкой жизни? biggrin.gif
Я лично всегда использую целочисленную арифметику даже для АЦП 16-битной точности.
big256
Цитата(zorromen @ Jan 10 2007, 20:02) *
А про #pragma asm_function+ Можно подробнее... Что оно делает?


В ЦВ который у меня установлен(1.24.6) такой опции прагмы нет (это можно глянуть в разделе хелпа The Preprocessor) . Но судя по названию это наверно разрешение асм вставок/ф-й smile.gif
Яrik
Цитата
А зачем Вам выводить показания АЦП 10-битного разрешения с точностью плавающей точки!? Захотели красивой и легкой жизни?
Я лично всегда использую целочисленную арифметику даже для АЦП 16-битной точности.

Да прсто не где невстричал примера. А у самого опыта маловато.
Значение измеряного напряжения ведь дробное число.
U=adc*2,56/1023 (опорное напряжение 2,56В, adc - результат преобразования).

Помогите новичку, пожалуйста, приведите свой пример (только не на Асме, вобще его незнаю).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.