Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: передача последовательных данных с двух и более выводов порта поочередно. (C51)
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
dobrik
упрощенный пример:

sbit B=P2^0;

void serial (void)
{
B=0;
B=1;
}

В этом случае все работает.

Задача состоит в том, что нужно поочередно применить эту функцию к разным выводам (P2.0, P2.1, P2.2)
пробовал передать вывод в качестве параметра функции - не работает.
... пытался использовать указатели - на работает .
как это можно решить?
demiurg_spb
Вот процедура, которая переворачивает любой бит в любом порту:
Код
inline void toggle_bit(volatile unsigned char* port, unsigned char bit)
{
     *port ^= (unsigned char)(1<<bit);
}

или так, что может оказаться оптимальнее
Код
inline void toggle_bit2(volatile unsigned char* port, unsigned char bit_mask)
{
     *port ^= bit_mask;
}

Использовать так:
Код
toggle_bit(&P2, 3);
toggle_bit2(&P2, 1<<3);

ПС:
A ^= B означает A = A^B или A = A XOR B
dobrik
прошу прощения - я непонятно объяснил задачу, уточняю:

имеются несколько устройств которые по очереди передают контроллеру данные , причем каждое устройство соединено с отдельной ножкой контроллера. Обмен напоминает 1 Ware. Обработка производится одной функцией. Задача состоит в том как применить эту функцию с разными ножками.
demiurg_spb
Я Вам уже ответил на вопрос. Передаёте в функцию адрес порта и номер ножки (см. мой пример). Функция будет всего одна - ваша задача сократилась лишь до написания тела этой функции. Можно описать структуру с адресом порта, номером ножки и прочей необходимой Вам информацией и передавать указатель на эти структуры в одну единственную функцию - так будет даже красивее.
Код
typedef struct
{
     volatile unsigned char* port;
     unsigned char bit_mask;
     unsigned char data;
     unsigned char bit_cnt;
} serial_t;
void read_bit_serial(serial_t* s)
{
     s->data =  (s->data<<1) + ((*s->port & s->bit_mask) != 0);
     s->bit_cnt = (s->bit_cnt+1)&7;                    // 0-7 counter  if 0 data is ready
}
dobrik
спасибо за информацию, попробую разобраться со структурами - раньше обходился без них, но видимо пришло время. На первый вариант с указанием адреса порта компилятор ругается ( "&" on bit/sfr illegal).
demiurg_spb
Цитата(dobrik @ Feb 21 2009, 18:51) *
На первый вариант с указанием адреса порта компилятор ругается ( "&" on bit/sfr illegal).
Тут нужна подсказка от практикующих с x51. Я уже лет 7 для них ничего не писал. Выкладывайте Ваш код - посмотрим. Почитайте datasheet на контроллер в разделе косвенная адресация регистр DPTR или @R0... (стерлось из памяти за давностью лет) и глянте какую область памяти он может адресовать и как в памяти расположены регистры специальных функций (SFR) и порты ввода-вывода. Не должно быть проблем на мой взгляд.
DpInRock
Обычно прямая адресация указывает на SFR, а косвенная по тому же адресу - просто память.
Проще не применять функция много раз к разным ногам, а применить один раз ко всем ногам сразу. Будет круто.
dobrik
спасибо за идею о применении функции сразу ко всем выводам, в коде добавляется всего две строки условного выбора!!! Еще раз СПАСИБО за идею.

P.S. все гениальное просто.
demiurg_spb
Ещё можно по таймеру копировать состояния портов ввода-вывода в ОЗУ, а потом вызывать процедуру, которая адресует ячейки ОЗУ, а не SFR..
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.