реклама на сайте
подробности

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Странное поведение портов!, Мега32 - что может быть???
Laksus
сообщение May 16 2006, 18:06
Сообщение #16


Частый гость
**

Группа: Участник
Сообщений: 146
Регистрация: 16-05-05
Пользователь №: 5 069



Доп. устройство итак подвешено через пулап резисторы в 1 К.
...
___________________
Ну а если проверить нет ли там обрыва где нибудь?

Александр
2006 05 16
Go to the top of the page
 
+Quote Post
WHALE
сообщение May 16 2006, 18:14
Сообщение #17


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



Насколько я помню протокол,последней операцией записи данных LCD по 4-х проводной линии должна
быть установка шины данных в 1.и ваши проблемы не совсем понятны-привели-бы кусок схемы и кода.
З.Ы. а в симуляторе пробовали смотреть?


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
_artem_
сообщение May 16 2006, 18:58
Сообщение #18


учащийся
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249



Я Вас может быть неправильно понял но не могу интерпретировать эти предложения с одним смыслом :

"Нет - я вообще ничего не читаю из LCD!!! Мало того, если я отсоединяю LCD то ничего ровным счетом не меняется! Дело не в дисплее. Я выдаю на мл. линии "0", переключаю порт на прием, выжидаю паузу - и читаю. И читаю те самые нули, которые я же туда и выдал."


и вот это :

"Если отключаем LCD, и код, его обслуживающий, то все работает правильно. Мало того, если прерывание возникает не в период обращения к дисплею, то тоже все нормально. Функция работы с LCD настраивает старшую тетраду на выход, младшая - остается на прием."


--------------------
Зачем лаять на караван , когда на него можно плюнуть?

Go to the top of the page
 
+Quote Post
defunct
сообщение May 16 2006, 20:05
Сообщение #19


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(_artem_ @ May 16 2006, 21:58) *
Я Вас может быть неправильно понял но не могу интерпретировать эти предложения с одним смыслом :

"Нет - я вообще ничего не читаю из LCD!!! Мало того, если я отсоединяю LCD то ничего ровным счетом не меняется! Дело не в дисплее. Я выдаю на мл. линии "0", переключаю порт на прием, выжидаю паузу - и читаю. И читаю те самые нули, которые я же туда и выдал."


и вот это :

"Если отключаем LCD, и код, его обслуживающий, то все работает правильно. Мало того, если прерывание возникает не в период обращения к дисплею, то тоже все нормально. Функция работы с LCD настраивает старшую тетраду на выход, младшая - остается на прием."


Связать можно, в первом случае, я полагаю, код, обслуживающий LCD, не был отключен. А просто был отсоединен экран. Во втором случае код отключен тоже. Проблема помоему очевидна, и скрывается в коде, обслуживающем LCD. Похоже, что операция вывода байта на экран должна быть атомарной операцией (нельзя переключать порт передав только старшую тетраду данных). Как уже писал ранее, один из путей решения проблемы - запрещать прерывания, на время работы с LCD.
Go to the top of the page
 
+Quote Post
_artem_
сообщение May 16 2006, 21:23
Сообщение #20


учащийся
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249



Мне это так не кажется - передача тетрады для порта половина которого работает не передачу а остальная на прием как такового значение не имеет - в любом случае в PORTB регистр записывается байт. Для авр все равно и я честно говоря не видел ограничений на манипуляцию с gpio портами (было маленькое примечание о переходе с приема на передачу и наоборот и то что при чтении порт опаздывает как минимум на один машинный цикл но не 10 микросек при 16 МГц тактовой). Если предположить что нули выдаются дисплеем потому что может затягиватся сигнал Е на входе дисплея и при этом дисплей каким то макаром работает на передачу - не подтверждается так как без физически подключенного дисплея те же самые нули (если я правильно понял написанное).

Без кода и схемы никак .


--------------------
Зачем лаять на караван , когда на него можно плюнуть?

Go to the top of the page
 
+Quote Post
OlegIvanov
сообщение May 16 2006, 23:06
Сообщение #21


Участник
*

Группа: Новичок
Сообщений: 38
Регистрация: 12-09-05
Пользователь №: 8 464



[/quote]
Что касается выдачи данных, то для того, чтобы передать байт в дисплей по четырехпроводному интерфейсу, нужно проделать следующее:

OutPort(data & 0xf0)
OutPort(data << 4)

т.о. младшие биты передаются нулями.
Если я отключаю устройство от порта, то я не могу различить то ли я читаю те нули, что передал сам же, то ли это те нули, которые вызваны отсутствием устройства на шине.
[/quote]

Вообще-то если предвидится прерывание кода изменения состояния порта
иной подпрограммой которая может изменять состояние того же порта
то логично делать примерно так

cbr Data,0b00001111; сброс мл. части команды/данных
cli;
in CopyPort,Port;
cbr CopyPort,0b11110000; сброс ст. части состояния порта
or CopyPort,Data; получили в старшей части то что надо
out Port,CopyPort;
sei; и состояние мл. части порта осталось неизменным
Go to the top of the page
 
+Quote Post
Sergio66
сообщение May 17 2006, 05:54
Сообщение #22


Местный
***

Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526



Цитата(_artem_ @ May 16 2006, 22:58) *
Я Вас может быть неправильно понял но не могу интерпретировать эти предложения с одним смыслом :

"Нет - я вообще ничего не читаю из LCD!!! Мало того, если я отсоединяю LCD то ничего ровным счетом не меняется! Дело не в дисплее. Я выдаю на мл. линии "0", переключаю порт на прием, выжидаю паузу - и читаю. И читаю те самые нули, которые я же туда и выдал."


и вот это :

"Если отключаем LCD, и код, его обслуживающий, то все работает правильно. Мало того, если прерывание возникает не в период обращения к дисплею, то тоже все нормально. Функция работы с LCD настраивает старшую тетраду на выход, младшая - остается на прием."

В первом случае отключался только LCD, во втором - и код, его обслуживающий.
Go to the top of the page
 
+Quote Post
Sergio66
сообщение May 17 2006, 06:40
Сообщение #23


Местный
***

Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526



Цитата(_artem_ @ May 17 2006, 01:23) *
Мне это так не кажется - передача тетрады для порта половина которого работает не передачу а остальная на прием как такового значение не имеет - в любом случае в PORTB регистр записывается байт. Для авр все равно и я честно говоря не видел ограничений на манипуляцию с gpio портами (было маленькое примечание о переходе с приема на передачу и наоборот и то что при чтении порт опаздывает как минимум на один машинный цикл но не 10 микросек при 16 МГц тактовой). Если предположить что нули выдаются дисплеем потому что может затягиватся сигнал Е на входе дисплея и при этом дисплей каким то макаром работает на передачу - не подтверждается так как без физически подключенного дисплея те же самые нули (если я правильно понял написанное).

Без кода и схемы никак .

Это код вывода байта в дисплей

void LCD_Write (unsigned char CMD, char type)
{
char Data;
CONFIG_CONTROL_PINS;

/*#define CONFIG_CONTROL_PINS LCD_E_PORT_DIR |=(1<<LCD_E_PIN); LCD_RS_PORT_DIR |= (1<<LCD_RS_PIN); LCD_RW_PORT_DIR |=(1<<LCD_RW_PIN);*/

SET_DATA_LINES_OUT;

/*#define SET_DATA_LINES_OUT LCD_DATA_PORT_DIR = ((1<<LCD_D4) | (1<<LCD_D5) | (1<<LCD_D6) | (1<<LCD_D7))*/

CLEAR_LCD_E; // Disable LCD

if (type == DATA) SET_LCD_DATA;
else SET_LCD_CMD; // Set LCD to command
OUT_DATA_PORT(CMD & 0xf0); //выдаем в порт старший полубайт

/* #define OUT_DATA_PORT(data) SET_LCD_READ; CLEAR_DATA_PINS; LCD_DATA_PORT |=0;/*data*/ ;SET_LCD_WRITE*/

GENERATE_E_STROB; // Write data to LCD

OUT_DATA_PORT(CMD <<4); //выдаем в порт младший полубайт
GENERATE_E_STROB; // Write data to LCD


Short_Delay(50);
}

А вот так выглядит та часть обработчика прерывания, которая опрашивает доп. устройство:

char PORTB_config = DDRB;

DDRB &= ~((1<<PB0) | (1<<PB1) | (1<<PB3) | (1<<PB4));
__delay_cycles(10); //10 тактов генератора

if ((PINB & 0x1b) )
{

if (PT_status & PT_LINE_ACTIVE) PT_status |= PT_ACTIVE;

else PT_status |=PT_LINE_ACTIVE;
}
else
{
if (PT_status & PT_LINE_ACTIVE)
PT_status &=~PT_LINE_ACTIVE;
else
PT_status &= ~PT_ACTIVE;
}
DDRB = PORTB_config;

Вот, так обстоят дела.
На сегодня доподлинно мне известно, что весь бардак из-за линии РВ5 (общей у LCD и доп. устройства). Всегда читается последний записанный бит (в случае, если прерывание встряло в работу функции обмена с дисплеем), а не фактическое состояние линии доп. устройства.

/* #define OUT_DATA_PORT(data) SET_LCD_READ; CLEAR_DATA_PINS; LCD_DATA_PORT |=0;/*data*/ ;SET_LCD_WRITE*/

Пардон, в этой строчке опечатка - это было сделано в проверочных целях, на самом деле все обстоит так:
/* #define OUT_DATA_PORT(data) SET_LCD_READ; CLEAR_DATA_PINS; LCD_DATA_PORT |=data ;SET_LCD_WRITE*/
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
_artem_
сообщение May 17 2006, 10:06
Сообщение #24


учащийся
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249



Можно отрассировать по выходу из обработчика прерывания содержимое стека, точнее адресс куда программа вернется после инструкции RETI когда проблема произошла? Можно прямо перед выходом из обработчика прерываний в одну переменную сохранить содержимое стека а в другую флаг присутствия проблемы установленный в :
if ((PINB & 0x1b) )
{
.......
}
else
{
flag = 1;
}

потом в конце вывода в дисплей проверить флаг и если он установлен вывести значение стека на дислпеы или уарт и затем сбросить флаг после . И потом конечно листинг ассемблера с С кодом вместе (как минимум куска на кторый указывает стек).

Еше один вопрос - читается ли 0 все время когда вывод на лсд или иногда ?

Можно также на время OUT_DATA_PORT запретить прерывание dlja vyvoda obeix tetrad :

__disable_interrupts();
OUT_DATA_PORT;
__enable_interrupts();

и сообшить результат.


--------------------
Зачем лаять на караван , когда на него можно плюнуть?

Go to the top of the page
 
+Quote Post
Sergio66
сообщение May 17 2006, 10:35
Сообщение #25


Местный
***

Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526



Цитата(_artem_ @ May 17 2006, 14:06) *
Можно отрассировать по выходу из обработчика прерывания содержимое стека, точнее адресс куда программа вернется после инструкции RETI когда проблема произошла? Можно прямо перед выходом из обработчика прерываний в одну переменную сохранить содержимое стека а в другую флаг присутствия проблемы установленный в :
if ((PINB & 0x1b) )
{
.......
}
else
{
flag = 1;
}

потом в конце вывода в дисплей проверить флаг и если он установлен вывести значение стека на дислпеы или уарт и затем сбросить флаг после . И потом конечно листинг ассемблера с С кодом вместе (как минимум куска на кторый указывает стек).

Еше один вопрос - читается ли 0 все время когда вывод на лсд или иногда ?

Можно также на время OUT_DATA_PORT запретить прерывание dlja vyvoda obeix tetrad :

__disable_interrupts();
OUT_DATA_PORT;
__enable_interrupts();

и сообшить результат.


При чтении порта РВ4 я вижу то, что быо выдано на эту линию в обработчике дисплея только в том случае, если прерывание возникло во время обмена с дисплеем.
Go to the top of the page
 
+Quote Post
_artem_
сообщение May 17 2006, 11:27
Сообщение #26


учащийся
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249



Вложенные прерывания разрешены ? Конкретно знаете на какой инструкции прерывание срабатывает с проблемой?


--------------------
Зачем лаять на караван , когда на него можно плюнуть?

Go to the top of the page
 
+Quote Post
otrog
сообщение May 17 2006, 11:54
Сообщение #27


Местный
***

Группа: Свой
Сообщений: 232
Регистрация: 22-02-06
Из: Воронеж
Пользователь №: 14 589



В общем так:
Самый простой выход из ситуации это, как уже говорилось
Цитата
запрещать прерывания, на время работы с LCD

Если это недопустимо и если точно известно, что период следования прерываний больше времени работы обслуживателя LCD, то можно сделать так:
Код
char flag = 0; // флаг разрешения обслуживания LCD
.................
while ( flag == 0 ); // ждать, пока небыло прерывания
[LCD] // процедура обслуживания LCD
flag = 0; // запретить обслуживание LCD

.................
// в конце обработчика прерывания
if ( flag == 0 ) { flag = 1; } // если был запрет на обслуживание LCD, то разрешить его.


Успехов.


--------------------
Истина рождается в спорах; но когда страсти кипят, истина испаряется.
Go to the top of the page
 
+Quote Post
Sergio66
сообщение May 17 2006, 15:35
Сообщение #28


Местный
***

Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526



Я только что проделал такой эксперимент - я отключтл дисплей, отключил доп. устройство и запустил программу так, как будто все подключено. Только функция работы с дисплеем выдает все "1" во все линии порта В. В обработчике прервания я вижу PINB в "1"! Т.е. ноги висят в воздухе, я выдаю на них "1", потом переключаюсь на прием, и вижу на них те же "1"!
Может быть я просто имею "битую" микросхему?
Go to the top of the page
 
+Quote Post
defunct
сообщение May 17 2006, 15:49
Сообщение #29


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Sergio66 @ May 17 2006, 18:35) *
Я только что проделал такой эксперимент - я отключтл дисплей, отключил доп. устройство и запустил программу так, как будто все подключено. Только функция работы с дисплеем выдает все "1" во все линии порта В. В обработчике прервания я вижу PINB в "1"! Т.е. ноги висят в воздухе, я выдаю на них "1", потом переключаюсь на прием, и вижу на них те же "1"!
Может быть я просто имею "битую" микросхему?


Нет smile.gif микросхема не битая.
Вы выводите 1 в Port, тем самым вы подключаете внутренний Pull-up резистор, и МК ведет себя совершенно адекватно считывая 1 с соответствующего PinX.

Проведите пожалуйста такой эксперимент как вам посоветовал _artem:

__disable_interrupts();
OUT_DATA_PORT;
__enable_interrupts();

или:

asm("cli");
//вывод обеих тетрад на LCD
asm("sei");

Должно все работать
Go to the top of the page
 
+Quote Post
Laksus
сообщение May 17 2006, 16:30
Сообщение #30


Частый гость
**

Группа: Участник
Сообщений: 146
Регистрация: 16-05-05
Пользователь №: 5 069



После переключения линий порта В на прием, делаю паузу (до 10 мксек), ничего не меняется. Т.о., это не паразитные емкости.
...
DDRB &= ~((1<<PB0) | (1<<PB1) | (1<<PB3) | (1<<PB4));
__delay_cycles(10); //10 тактов генератора
if ((PINB & 0x1b) )
_______________________________
Так все таки, 10мксек или 10тактов,
при 16 МГц это большая разница.
У Вас не указаны значения сопротивлений.
Но если даже предположить, что добавочные сопротивления
тоже 1кОм, то емкость для постоянной времени в 10тактов
будет примерно 300пФ.
Емкость "голого" вывода порядка 10 пФ, так что дорожки
печатной платы и провода шлейфа могут вполне достигнуть
достаточной емкости.
Так что вполне могут быть и паразитные емкости.
____________
Александр
2006 05 17
Go to the top of the page
 
+Quote Post

4 страниц V  < 1 2 3 4 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 11:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.01501 секунд с 7
ELECTRONIX ©2004-2016