Перейти к содержанию
    

Пару вопросов по Си для MCS51

Доброе время суток. Начал тут изучать C для 51-х и возникли глупые вопросы:

1) Как Вы отсчитываете (формируете) боле-мене точные временные интервалы? Допустим надо сформировать задержку в 1 секунду, стандартной функции у Keil'a нет, надо писать самим. Есть ли стандартные приемы? Или надо написать какую-нить простенькую конструкцию аля for (i=40;i>0;i--), посмотреть какой ассемблеровский код ей соответствует после компиляции и затем прикинуть? Или в программном симуляторе засечь? Но это же так тоскливо... Можно ли решить задачу не методом такого подбора?

2) Как массив помещается в память програм? Keil пихает в драгоценное ОЗУ даже при объявлении со спецификатором const.

Буду благодарен за ответы)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Доброе время суток. Начал тут изучать C для 51-х и возникли глупые вопросы:

1) Как Вы отсчитываете (формируете) боле-мене точные временные интервалы? Допустим надо сформировать задержку в 1 секунду, стандартной функции у Keil'a нет, надо писать самим. Есть ли стандартные приемы? Или надо написать какую-нить простенькую конструкцию аля for (i=40;i>0;i--), посмотреть какой ассемблеровский код ей соответствует после компиляции и затем прикинуть? Или в программном симуляторе засечь? Но это же так тоскливо... Можно ли решить задачу не методом такого подбора?

2) Как массив помещается в память програм? Keil пихает в драгоценное ОЗУ даже при объявлении со спецификатором const.

Буду благодарен за ответы)

 

const и не должен помещать в ОЗУ. Вам нужен code. Пример:

unsigned char code password[] = "65535";

Изменено пользователем alcosar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Доброе время суток. Начал тут изучать C для 51-х и возникли глупые вопросы:

1) Как Вы отсчитываете (формируете) боле-мене точные временные интервалы?

Временные интервалы лучше формировать встроенными в МК51 таймерами...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

const и не должен помещать в ОЗУ. Вам нужен code. Пример:

unsigned char code password[] = "65535";

Спасибо, именно то, что надо.

Временные интервалы лучше формировать встроенными в МК51 таймерами...

Это-то понятно, но есть вагон и маленькая тележка ситуаций, когда таймер занят, например опрос АЦП каждую секунду, а при этом I2C формируется программно и нужны боле-мене точные задержки...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это-то понятно, но есть вагон и маленькая тележка ситуаций, когда таймер занят, например опрос АЦП каждую секунду, а при этом I2C формируется программно и нужны боле-мене точные задержки...

Ваяете в перывании одного таймера ядро с циклом, к примеру 1мС и в этом ппрерывании лепите таймеры, от которых тактируете запуск АЦП и меряете секундные интервалы. Точность - 0.1%. Обычно достаточно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ваяете в перывании одного таймера ядро с циклом, к примеру 1мС и в этом ппрерывании лепите таймеры, от которых тактируете запуск АЦП и меряете секундные интервалы. Точность - 0.1%. Обычно достаточно.

Спасибо за идею, стоит попробывать.

 

Еще возник вопрос (навеное от нежелания вчитываться в несамую лучшую документацию) - KEIL побитово к порту не позволяет обращаться? Например ругается на конструкцию "P1.1=1"...

Изменено пользователем Lotor

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще возник вопрос (навеное от нежелания вчитываться в несамую лучшую документацию) - KEIL побитово к порту не позволяет обращаться? Например ругается на конструкцию "P1.1=1"...

 

удобно это делать вот так:

 

объявить

sbit SCL = P3^4;

sbit SDA = P3^5;

 

и потом их использовать:

SDA = 1;

SCL = 1;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

удобно это делать вот так:

 

объявить

sbit SCL = P3^4;

sbit SDA = P3^5;

 

и потом их использовать:

SDA = 1;

SCL = 1;

Мне привычнее через #define, главное синтаксис P3^4 - спасибо, не знал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это-то понятно, но есть вагон и маленькая тележка ситуаций, когда таймер занят, например опрос АЦП каждую секунду, а при этом I2C формируется программно и нужны боле-мене точные задержки...

 

По простому:

пишем asm файл с кодом (нужно знать частоту ядра и время исполнения инструкций):

см. delay.a51

 

В файле заголовка:

см. delay.h

 

Использование:

SDA = 1;
Delay_Nop_us(20);
SDA = 0;

delay.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

пишем...

Потрудитесь оформить свои чрезмено обширные вcтавки предыдущего поста в виде приложения.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

alcosar: const и не должен помещать в ОЗУ. Вам нужен code. Пример:

unsigned char code password[] = "65535";

в иар для авр, использовал flash unsigned char Rn[] = { 0x30,0x31,0x32,0x33,0x34} ;

 

off: такая тема очень актуально для тех кто начинает, её бы прикрепить, а еще лучще оформить как faq.

alcosar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это-то понятно, но есть вагон и маленькая тележка ситуаций, когда таймер занят, например опрос АЦП каждую секунду, а при этом I2C формируется программно и нужны боле-мене точные задержки...

 

ну в общем то правильные идеи уже прозвучали. Вы успешно подберете контроллер с количеством таймеров равным количеству необходимых задач (по одной на каждый таймер), если таких задач одна-две. Хорошим тоном в программе средней сложности является организация "службы времени" которая в большинстве случаев базируется на одном из таймеров прерыванию на переполнение. В обработке прерывания анализируется количество переполнений (необходимые Вам периоды времени). В зависимости от свободных ресурсов либо расставляются "флажки" действий, которые можно обработать в основном цикле Main, либо эти действия отрабатываются прямо в прерывании.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

..Хорошим тоном в программе средней сложности является организация "службы времени" которая в большинстве случаев базируется на одном...

 

+1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насчет побитового обращения к портам. Я пытаюсь работать с cy7c68013A и там можно к порту обращаться побитово. Реализуется это так. Есть отдельный файл с описанием всех регистров и вот как там например порт А описывается:

sfr IOA = 0x80;

/* IOA */

sbit PA0 = 0x80 + 0;

sbit PA1 = 0x80 + 1;

sbit PA2 = 0x80 + 2;

sbit PA3 = 0x80 + 3;

 

sbit PA4 = 0x80 + 4;

sbit PA5 = 0x80 + 5;

sbit PA6 = 0x80 + 6;

sbit PA7 = 0x80 + 7;

 

Далее в тексте программы рпосто обращаешься к битам порта:

OEA=0xff;

PA1=0x00;

PA1=0x01;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день.

 

Не стал создавать новую тему.

 

Вопрос в следующем. Вернее проблемма.

Дано:

компилятор Keil

C Compiler C51.exe v8.06

Assembler A51.exe v8.00c

Linker/Locator BL51.exe v6.05

Librarian LIB51.exe v4.24

Hex Converter OH51.exe v2.6

 

Суть проблеммы

В рабочем режиме иногда прошивка виснет. Выяснил, что зависает (зацикливается) она по причине того что локальные переменные процедуры кто-то запорол.

Нашел в карте памяти что данные ячейки относятся еще к двум процедурам (причем там эти переменные тоже локальные). Одна из которых вызывается в прерывании.

Как мне теперь заставить Keil убрать из перекрестных ссылок эти переменные (чтобы они лежали в разных адресах DATA)?

Делать их глобальными внутри одного файла желания нет.

 

Пока я проверил только локальные переменные в области DATA, быть может такая петрушка есть еще с переменными в области XDATA. Почему Keil их так расположил? Ведь при компиляции он знает какие процедуры попадают в прерывание и по идее должен этим процедурам для локальных переменных выдилять свои адреса. Может нужно что-то указать??

 

Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...