Подскажите пожалуйста

Учебный лабораторный комплекс SDK-1.1 на базе микроконтроллера ADuC812 с ядром MCS51 # RS-232C, I2C

Подскажите пожалуйста

Сообщение nekto » 16 фев 2011, 22:07

Здравствуйте. Учусь работать со стендом sdk-1.1 . Запустила все примеры, которые были на этом сайте, все работает. Дальше, когда пытаюсь сама написать программу, возникла такая проблема:

float a;
a=2.1;

после такой записи выдается ошибка. Если же написать

char a;
a=2;

все в порядке.. Почему не хочет компилироваться программа, в которой используются числа с плавающей точкой?

Да, еще я для написания программы на языке си и создания 16-тиричного файла использую не те утилиты, которые здесь рекомендуют, а Keil uversion 2, а для того чтобы передать программу в стенд использую программу T2
nekto
 
Сообщения: 10
Зарегистрирован: 16 фев 2011, 21:59

Re: Подскажите пожалуйста

Сообщение h0rr0rr_drag0n » 16 фев 2011, 22:40

В архитектуре MCS-51 не предусмотрен сопроцессор для работы с числами с плавающей точкой. Поэтому float a выдает ошибку.
Университет развивает все способности, в том числе — глупость.
-- Антон Павлович Чехов
Аватара пользователя
h0rr0rr_drag0n
 
Сообщения: 99
Зарегистрирован: 18 мар 2009, 22:27
Откуда: СПб

Re: Подскажите пожалуйста

Сообщение DinKa » 17 фев 2011, 02:24

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

float a;
a=2.1;

после такой записи выдается ошибка.

Приведите, пожалуйста, исходный код программы целиком (надеюсь, он не очень большой) и напишите, какую именно ошибку выдает компилятор.
DinKa
 
Сообщения: 247
Зарегистрирован: 23 апр 2008, 18:01

Re: Подскажите пожалуйста

Сообщение DinKa » 17 фев 2011, 02:29

h0rr0rr_drag0n писал(а):В архитектуре MCS-51 не предусмотрен сопроцессор для работы с числами с плавающей точкой. Поэтому float a выдает ошибку.

Видимо, программная реализация операций с плавающей точкой невозможна :cry:
DinKa
 
Сообщения: 247
Зарегистрирован: 23 апр 2008, 18:01

Re: Подскажите пожалуйста

Сообщение h0rr0rr_drag0n » 17 фев 2011, 09:03

DinKa писал(а):Видимо, программная реализация операций с плавающей точкой невозможна :cry:


Упс, я ошибся. :sorry: Действительно, возможна еще и программная реализация.
Университет развивает все способности, в том числе — глупость.
-- Антон Павлович Чехов
Аватара пользователя
h0rr0rr_drag0n
 
Сообщения: 99
Зарегистрирован: 18 мар 2009, 22:27
Откуда: СПб

Re: Подскажите пожалуйста

Сообщение nekto » 18 фев 2011, 10:33

А подскажите, как можно программно реализовать работу с числами с плавающей точкой?

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

#include <aduc812.h>
#include <sio.h>
#include <dac.h>
#include <adc.h>
#include <stdio.h>

static float v[ 2 ] = { 0.0, 0.0 };


void putchar( char c ) { wsio( c ); }
char getchar( void ) { return rsio(); }

void inc_voltage( unsigned char n_dac )
{
if( n_dac > 1 ) return;

if( v[ n_dac ] < 4.95 )
v[ n_dac ] += 0.1;

set_voltage( v[ n_dac ], n_dac );

printf_fast_f( "Set DAC%d, U = %.1fV \r\n", n_dac, v[ n_dac ] );
}


void dec_voltage( unsigned char n_dac )
{
if( n_dac > 1 ) return;

if( v[ n_dac ] >= 0.1 )
v[ n_dac ] -= 0.1;

set_voltage( v[ n_dac ], n_dac );

printf_fast_f( "Set DAC%d, U = %.1fV \r\n", n_dac, v[ n_dac ] );
}

void print_voltage( void )
{
float v0, v1;

v0 = get_voltage( 0 );
v1 = get_voltage( 1 );

printf_fast_f( "U0 = %.3fV, U1 = %.3fV \n", v0, v1 );
}

void main( void )
{
unsigned char c;

init_sio( S9600 );
init_dac( _8BIT );
init_adc();


switch_dac( DAC0, ON );
switch_dac( DAC1, ON );


printf_fast_f( "Test DAC & ADC\r\n" );


type("1 - +voltage, DAC0\r\n");
type("2 - -voltage, DAC0\r\n");
type("3 - +voltage, DAC1\r\n");
type("4 - -voltage, DAC1\r\n");

type("r - get voltage, ADC1 & ADC2 \r\n");


while( 1 )
{
if( rsiostat() )
{
c = rsio();

switch( c )
{
case '1': inc_voltage( DAC0 ); break;
case '2': dec_voltage( DAC0 ); break;
case '3': inc_voltage( DAC1 ); break;
case '4': dec_voltage( DAC1 ); break;

case 'r': print_voltage(); break;

default: type("\r\n"); break;
}
}
}
}



Если в этом примере заменить тип массива v с float на char или short, и заменить тип аргумента, пересылаемого в set_voltage с float тоже на
char, все работает. Но хотелось бы работать с дробными числами.
Заранее спасибо:)
nekto
 
Сообщения: 10
Зарегистрирован: 16 фев 2011, 21:59

Re: Подскажите пожалуйста

Сообщение nekto » 18 фев 2011, 10:44

ошибка Fatal Error L210: I/O Error on Input file
Exception 0021H: Path or file not found
File:C:/Keil/C51/LIB/C51FPS.LIB
nekto
 
Сообщения: 10
Зарегистрирован: 16 фев 2011, 21:59

Re: Подскажите пожалуйста

Сообщение OYTIS » 18 фев 2011, 15:56

Captain Obvious to the rescue!
Проверьте, лежит ли библиотека C51FPS.LIB в указанной директории. Возможно, у вас неправильно прописаны пути. Возможно, в вашей версии Keil вовсе нет библиотеки работы с плавающей точкой.
OYTIS
 
Сообщения: 76
Зарегистрирован: 22 апр 2008, 12:11

Re: Подскажите пожалуйста

Сообщение nekto » 18 фев 2011, 16:43

Спасибо большое) правда нет библиотеки))))

ps но вопросов наверное еще будет море, поскольку пишу диплом, в котором использую ацп и цап из sdk
nekto
 
Сообщения: 10
Зарегистрирован: 16 фев 2011, 21:59

Re: Подскажите пожалуйста

Сообщение nekto » 22 фев 2011, 11:49

а еще подскажите пожалуйста- что за метод
printf_fast_f( "Test DAC & ADC\r\n" );


ни в одном из объявленных в программе заголовочных файлов я его не вижу: aduc812.h,sio.h,dac.h,adc.h,stdio.h

ps извините за глупые вопросы :oops:
nekto
 
Сообщения: 10
Зарегистрирован: 16 фев 2011, 21:59

Re: Подскажите пожалуйста

Сообщение DinKa » 22 фев 2011, 14:27

Исследуемый Вами пример программы написан под компилятор SDCC. Функция printf_fast_f(__code char *fmt, ...) реализована в библиотеке этого компилятора (соответствующий прототип функции есть в stdio.h) для форматного вывода float. Кроме того, чтобы этот вывод выполнялся в последовательный канал, дописана функция putchar().
Таким образом, Вы можете найти аналогичную функцию для форматного вывода данных типа float (если он Вам нужен) в библиотеке компилятора C51 Keil. Кроме того, обратите внимание, что для организации вывода в последовательный канал Вам будет необходимо дописать функцию putchar(), например, таким образом:
Код: Выделить всё
void putchar (char c)
{
     while (!TI); // UART должен быть инициализирован!
     TI = 0;
     SBUF = c;
}
DinKa
 
Сообщения: 247
Зарегистрирован: 23 апр 2008, 18:01

Re: Подскажите пожалуйста

Сообщение nekto » 27 апр 2011, 16:09

Здравствуйте. Снова нужна ваша помощь, спасибо за предыдущие ответы.

Такой вопрос: мне нужно сделать программную задержку на заданное количество микросекунд. Я подумала сделать это с помощью таймера. В приведенных здесь материалах нашла такой код:

void T0_ISR(void) interrupt 1 // Обработчик прерывания от таймера 0
{
// Действия, выполняемые обработчиком
}
void SetVector(unsigned char xdata * Address, void * Vector) // Функция, устанавливающая вектор прерывания Vector по адресу Address
{
unsigned short xdata * TmpVector; // Временная переменная
*Address = 0x02; // Первым байтом по указанному адресу записывается код команды
// передачи управления ljmp, равный 02h
TmpVector = (unsigned short xdata *) (Address+1);
*TmpVector = (unsigned short) Vector;
// Далее записывается адрес перехода Vector //
Таким образом, по адресу Address теперь располагается инструкция ljmp Vector
}
void main(void) {
/*…*/
SetVector(0x200B, (void *) T0_ISR); // Установка вектора в пользовательской таблице ET0=1; EA=1;
// Разрешение прерываний от таймера 0 /*…*/
}


в этом коде я так понимаю, написанно как обработать прерывание по переполнению таймера Т0. Но вот как задать количество секунд, по которым будет переполнение?

Если я не права и надо пользоваться другим таймером(вроде часы реального времени тоже могут работать как таймер), подскажите пожалуйста выход и поправьте меня. Заранее спасибо
nekto
 
Сообщения: 10
Зарегистрирован: 16 фев 2011, 21:59

Re: Подскажите пожалуйста

Сообщение DinKa » 27 апр 2011, 21:38

nekto писал(а):Такой вопрос: мне нужно сделать программную задержку на заданное количество микросекунд. Я подумала сделать это с помощью таймера.

Программируемые таймеры микроконтроллера ADuC812 можно использовать для измерения единиц милисекунд, в случае организации работы по прерыванию, и сотен микросекунд - без прерываний (по опросу). Для измерения интервалов времени с точностью до 1-10 мкс производительности данного МК не хватает, так как частота его работы 11,0592 МГц, а частота машинных циклов еще в 12 раз ниже :arrow: время выполнения 1 ассемблерной команды приблизительно 1-4 мкс. Что уж в таком случае говорить о микросекундных замерах времени при программировании на Си...
nekto писал(а):Но вот как задать количество секунд, по которым будет переполнение?

Для этого нужно правильно настроить/инициализировать таймер. Исходными данными для этого являются уже названная частота машинных циклов МК, разрядность программируемого таймера, выбранный режим работы и желаемая частота прерываний от таймера. Более подробно можете посмотреть здесь (с. 82, с. 251).
Часы реального времени для микросекундных замеров точно не подходят.
DinKa
 
Сообщения: 247
Зарегистрирован: 23 апр 2008, 18:01

Re: Подскажите пожалуйста

Сообщение nekto » 29 апр 2011, 13:39

Спасибо за помощь.
А поскажите- что за метод __interrupt() приведен в коде на странице 251 пособия, на которое вы дали ссылку?
в коде метод используется, но не описан. И ранее в пособии про него ничего не сказанно. Из какой он библиотеки?
nekto
 
Сообщения: 10
Зарегистрирован: 16 фев 2011, 21:59

Re: Подскажите пожалуйста

Сообщение DinKa » 29 апр 2011, 14:21

nekto писал(а):Спасибо за помощь.
А поскажите- что за метод __interrupt() приведен в коде на странице 251 пособия, на которое вы дали ссылку?
в коде метод используется, но не описан. И ранее в пособии про него ничего не сказанно. Из какой он библиотеки?

Так функция-обработчик прерывания описывается для компилятора sdcc. У Вас выше описан аналогичный обработчик прерывания от таймера T0_ISR только для Keil C51.
DinKa
 
Сообщения: 247
Зарегистрирован: 23 апр 2008, 18:01

Re: Подскажите пожалуйста

Сообщение nekto » 29 апр 2011, 14:28

ПАСИБО!

вы меня прямо спасаете с этим стендом)

программа работает теперь)
nekto
 
Сообщения: 10
Зарегистрирован: 16 фев 2011, 21:59

Re: Подскажите пожалуйста

Сообщение nekto » 21 май 2011, 08:10

здравствуйте.

Подскажите пожалуйста еще, запускаю демонстрационную программу работы с периферийными устройствами



#include "ADuC812.h"
#include "sio.h"
#include "max.h"
#include "lcd.h"
#include "eeprom.h"
#include "rtc.h"
#include "parallel.h"
#include "buzz.h"
#include "kb.h"

unsigned char xdata buffer[50];

TIME xdata time = {0, 1, 2, 1};



void main(void)
{
unsigned short i, p;
unsigned char ch, leds;


InitLCD();
InitSIO(S9600, 0);
Type("Hello!\r\n");


Buzz();



for(i = 0; i < 50; i++)
buffer[i] = (unsigned char)(~i);//EEPROM

LCD_Clear();
LCD_Type(" EEPROM ");
LCD_GotoXY(0,1);

if( WriteBlockEEPROM(0, buffer, 29) )
LCD_Type("Write error!");
else
LCD_Type("Write OK");

for(i = 0; i < 65000; i++);


LCD_GotoXY(0,1);
if( ReadBlockEEPROM(0, buffer, 29) )
LCD_Type("Read error!");
else
{
for(i = 0; i < 29; i++)
if( buffer[i] != (unsigned char)(~i) )
{
LCD_Type("Check error!");
break;
}

if(i == 29) LCD_Type("Check OK");
}

for(i = 0; i < 60000; i++)
if(RSioStat())
{
RSio(); break;
}



if(SetTime(&time))
Type("Clock setting failed!\r\n");

LCD_Clear();
LCD_Type(" Clock ");

while(1)
{
if(RSioStat())
{
RSio(); break;
}

Type("Current time: ");
LCD_GotoXY(0,1);

if( GetTime(&time) )
{
LCD_Type("Error!");
Type("failed to retrieve!\r\n");
break;
}
else
{
i = 0;
//Hours
buffer[i++] = (time.hour / 10) + '0';
buffer[i++] = (time.hour % 10) + '0';
buffer[i++] = ':';

//Minutes
buffer[i++] = (time.min / 10) + '0';
buffer[i++] = (time.min % 10) + '0';
buffer[i++] = ':';

//Seconds
buffer[i++] = (time.sec / 10) + '0';
buffer[i++] = (time.sec % 10) + '0';

buffer[i] = '\0';

Type(buffer); WSio(13);
LCD_Type(buffer);
}
}


Type("\r\nReading keyboard\r\n");
LCD_Clear();
leds = 0;
while(1)
{
WriteMax(LEDLINE, leds);

leds <<= 1;
if( !(leds & 0x80) )
leds |= 1;

if( ScanKBOnce(&ch) )
{
WSio(ch);
LCD_Putch(ch);
}
else
for(i = 0; i < 2000; i++);

}


}



все работает, но пьезоизлучатель никаких сигналов не подает. Драйвер работы с ним взяла тоже из примера- buzz.c
Подскажите , в чем может быть проблема?


#include "max.h"


void Buzz(void)
{
unsigned char i;//
unsigned short dur;

for(dur = 0; dur < 500; dur++)
{
WriteMax(ENA,0x24);
for(i=0; i < 2; i++)continue;
WriteMax(ENA,0x20);
for(i=0; i < 2; i++)continue;
}

}
nekto
 
Сообщения: 10
Зарегистрирован: 16 фев 2011, 21:59

Re: Подскажите пожалуйста

Сообщение nekto » 22 май 2011, 14:40

Вопрос снят. Все работает

теперь другой вопрос.....


А можно ли как-то сохранять программы не в ОЗУ, а в ПЗУ? И если можно ее сохранить там, то как сделать так, чтобы при запуске стенда запускалась именно эта программа? Такое возможно?


Буду благодарна за ответы
nekto
 
Сообщения: 10
Зарегистрирован: 16 фев 2011, 21:59

Re: Подскажите пожалуйста

Сообщение DinKa » 22 май 2011, 23:32

nekto писал(а):А можно ли как-то сохранять программы не в ОЗУ, а в ПЗУ? И если можно ее сохранить там, то как сделать так, чтобы при запуске стенда запускалась именно эта программа? Такое возможно?

Возможно. Для этого Вам нужно заменить резидентный загрузчик (HEX-202 или UL3), находящийся во Flash-памяти МК ADuC812 и исполняющийся при запуске стенда, на свою программу. Чтобы создать свою программу с такими характеристиками, необходимо изменить ключи компиляции, работать с "родной" таблицей прерываний (т.е. есть только системная таблица во Flash-памяти, а пользовательской в SRAM нет :arrow: никаких SetVector). Для этого посмотрите исходники UL3 (текущая версия резидентного загрузчика, HEX-202 - предыдущая). Кроме того, необходимо знать, что в Вашем распоряжении для кода программы всего 8 Кб и те с ограниченным числом перезаписи (10000-50000 циклов, нужно уточнить по спецификации на ADuC812), для загрузки программы во Flash-память использовать не t167b/t2/m3p, а dl.exe.
DinKa
 
Сообщения: 247
Зарегистрирован: 23 апр 2008, 18:01


Вернуться в SDK 1.1

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

cron