Прошу помощи в соединение мк с памятью
- Реклама
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18675
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Не знаю, как там в примерах к курсам, но среди программистов давным-давно имеется 2 традиционных подхода для хранения текстовой информации:
1. ASCIIZ - строка символов с нулем в конце. Т.е. ноль обозначает конец данных. Поставил ноль на первое место в твоем "массиве" - это равносильно тому, что данных в массиве нет, сам массив при этом можно не очищать. Принцип, традиционный для языка Си.
2. Строка типа "Длина-данные" - самый первый байт массива обозначает количество символов, следующих за ним. Первый байт 0 - строка пуста, не ноль - значит есть сколько-то символов, причем всегда известно, сколько именно (в первом случае кол-во символов неизвестно). Принцип, характерный для Pascal-подобных строк.
У каждого подхода свои плюсы и минусы. Выбирай любой и реализовывай.
1. ASCIIZ - строка символов с нулем в конце. Т.е. ноль обозначает конец данных. Поставил ноль на первое место в твоем "массиве" - это равносильно тому, что данных в массиве нет, сам массив при этом можно не очищать. Принцип, традиционный для языка Си.
2. Строка типа "Длина-данные" - самый первый байт массива обозначает количество символов, следующих за ним. Первый байт 0 - строка пуста, не ноль - значит есть сколько-то символов, причем всегда известно, сколько именно (в первом случае кол-во символов неизвестно). Принцип, характерный для Pascal-подобных строк.
У каждого подхода свои плюсы и минусы. Выбирай любой и реализовывай.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- moLCHec
- Мявтор!
- Сообщения: 825
- Зарегистрирован: Вс дек 18, 2005 20:04:42
- Откуда: Свердловская обл.
- Контактная информация:
Библиотеку для работы с памятью писал сам, это уже вторая первая немного глючила. Делал я девай на PC-ой клаве, таких проблем не было т.к. заранее известно максимальная длина строки например при вводе 3-х значного значения курсор на 4-е просто не переводится. При редактировании строки символы просто заменяются, при нажатии Enter из времменой строки результата ввода возвращается.
примерно так
char *gets()
{
char temp[4]={0,0,0,0}, pos=0;
int key=0;
while(1)
{
key=scankey();
if(key==ENTER) return temp;
if(key==ESC) return "ESC";
if(isprint(key)){ //проверяем является ли символ печатаемым диапазон 0х10...0x7f и 0xc0...0xff
//здесь выводим символы и проч
}
}
}
PS по поводу I2C индикаторов не юзал так что ничего сказать не могу работал с граф на ks0108 и с символьными по 4-х битной. Моё мнение применение здесь I2C индикатора не очень то удачно т.к. при работе с памятью при отладке наверняка будут возникать ошибки на шине, при этом может не удатся обратиться к индикатору и её собсвенно отобразить чтоб проанализировать. Когда у меня случалось подобное у меня вообщее не получалось обратиться ни к чему (на шине висел датчик и память) программное отключение интерфейса и задержка результатов не давали приходилось просто отключать и включать питание.
примерно так
char *gets()
{
char temp[4]={0,0,0,0}, pos=0;
int key=0;
while(1)
{
key=scankey();
if(key==ENTER) return temp;
if(key==ESC) return "ESC";
if(isprint(key)){ //проверяем является ли символ печатаемым диапазон 0х10...0x7f и 0xc0...0xff
//здесь выводим символы и проч
}
}
}
PS по поводу I2C индикаторов не юзал так что ничего сказать не могу работал с граф на ks0108 и с символьными по 4-х битной. Моё мнение применение здесь I2C индикатора не очень то удачно т.к. при работе с памятью при отладке наверняка будут возникать ошибки на шине, при этом может не удатся обратиться к индикатору и её собсвенно отобразить чтоб проанализировать. Когда у меня случалось подобное у меня вообщее не получалось обратиться ни к чему (на шине висел датчик и память) программное отключение интерфейса и задержка результатов не давали приходилось просто отключать и включать питание.
Настоящий кот всегда либо голоден,
либо невыспался ...
либо невыспался ...
-
начинающий пояльщик
- Первый раз сказал Мяу!
- Сообщения: 24
- Зарегистрирован: Вт мар 20, 2007 19:09:54
Позвольте задать несколько глупых вопросов - вот код из библиотеки
TWDR=adr/256;
ClrBit(TWCR,0b00110000); //старший адрес памяти
SetBit(TWCR,0b10000100);
Delay_mks(100);
_temp=TWSR&0b11111100;
if(_temp!=0x28) return _temp;
TWDR=(adr&0x00FF);
ClrBit(TWCR,0b00110000); //младший адрес памяти
SetBit(TWCR,0b10000100);
Delay_mks(100);
вопросы:
1) что это за старший и младший адрес памяти? зачем они нужны?
2) зачем после каждой(не только этой) операции посылать старт?
3) после задержки 100мкс идет проверка ответа памяти?
И зачем переодически посылаются 2 стопа подряд?
Вы извените пожалуйста за дуратские вопросы, просто я много чего не понимаю.
TWDR=adr/256;
ClrBit(TWCR,0b00110000); //старший адрес памяти
SetBit(TWCR,0b10000100);
Delay_mks(100);
_temp=TWSR&0b11111100;
if(_temp!=0x28) return _temp;
TWDR=(adr&0x00FF);
ClrBit(TWCR,0b00110000); //младший адрес памяти
SetBit(TWCR,0b10000100);
Delay_mks(100);
вопросы:
1) что это за старший и младший адрес памяти? зачем они нужны?
2) зачем после каждой(не только этой) операции посылать старт?
3) после задержки 100мкс идет проверка ответа памяти?
И зачем переодически посылаются 2 стопа подряд?
Вы извените пожалуйста за дуратские вопросы, просто я много чего не понимаю.
1. двухбайтовая величина состоит из 2 байтов - у AVR - левый называют старший в нем биты 15_8 двухбайтного числа, а правый младший в нем биты 7_0
2. надо смотреть диаграмы в даташите того устройства с кем идет связь и смотреть когда что выставлять на i2c.
3. Похоже да. И если ответ не равен 0x28 то его возвращает функция из которой этот код.
2. надо смотреть диаграмы в даташите того устройства с кем идет связь и смотреть когда что выставлять на i2c.
3. Похоже да. И если ответ не равен 0x28 то его возвращает функция из которой этот код.
- Реклама
- moLCHec
- Мявтор!
- Сообщения: 825
- Зарегистрирован: Вс дек 18, 2005 20:04:42
- Откуда: Свердловская обл.
- Контактная информация:
Вопросы вполне резонные
Ответы:
у AT24C512 64кбайт памяти т.е. максимальное значение адресса 65536 это составляет 2 байта, посылаем первый если устройство(память) выдаёт ответ на шину что байт приняло посылаем второй байт адресса и т.д. после того как даннные в память записали формируем стоп, два раза для надёжности глючит его иногда при одном. Поскольку устройств на шине несколько памяти надо сообщить что данный сеанс связи закончен т.е. послать стоп. При посылке Старт все устройства на шине просыпаются и ждут их ли по аддресу зовут если нет ложаться дальше спать. примерно так. Для большего понимания почитай как вообще организована шина, ведомое устройство всегда должно выдавать код на шину что приняло байт данных и др. В инете есть книга Ефтифеева или как его там по AVR там про TWI написано хорошо. Так же конкретно по памяти советую книгу Белова "Проектирование устройств на микроконтроллерах", там подробно написано, но под 51-е контроллеры. Его страничка в инете есть и по мылу можно с ним связаться отвечает довольно оперативно.
Ответы:
у AT24C512 64кбайт памяти т.е. максимальное значение адресса 65536 это составляет 2 байта, посылаем первый если устройство(память) выдаёт ответ на шину что байт приняло посылаем второй байт адресса и т.д. после того как даннные в память записали формируем стоп, два раза для надёжности глючит его иногда при одном. Поскольку устройств на шине несколько памяти надо сообщить что данный сеанс связи закончен т.е. послать стоп. При посылке Старт все устройства на шине просыпаются и ждут их ли по аддресу зовут если нет ложаться дальше спать. примерно так. Для большего понимания почитай как вообще организована шина, ведомое устройство всегда должно выдавать код на шину что приняло байт данных и др. В инете есть книга Ефтифеева или как его там по AVR там про TWI написано хорошо. Так же конкретно по памяти советую книгу Белова "Проектирование устройств на микроконтроллерах", там подробно написано, но под 51-е контроллеры. Его страничка в инете есть и по мылу можно с ним связаться отвечает довольно оперативно.
Настоящий кот всегда либо голоден,
либо невыспался ...
либо невыспался ...
-
начинающий пояльщик
- Первый раз сказал Мяу!
- Сообщения: 24
- Зарегистрирован: Вт мар 20, 2007 19:09:54
- moLCHec
- Мявтор!
- Сообщения: 825
- Зарегистрирован: Вс дек 18, 2005 20:04:42
- Откуда: Свердловская обл.
- Контактная информация:
ClrBit(TWCR,0b00110000);
SetBit(TWCR,0b10000100);
Устанавливаем/сбрасываем неоходимые разряды регистра TWCR, в зависимости от битов контроллер производит необходимые действия например формирует СТАРТ, ПОВСТАРТ или посылает байт данных и пр. iEEP это глобальная переменная в которую записывается результат(из неё же берётся при записи) тут у меня неточность небольшая на самом деле в коде должна быть INT_EEP которую объявляем в начале файла, ну или бъявить в начале файла iEEP. Таким образом после вызова функции чтения результат находится в переменной iEEP, перед записью в память нужно присвоить iEEP значение которое необходими записать. Обращаю внимание что функции char WriteEEP(unsigned int adr) и char ReadEEP(unsigned int adr) записывают/читают двухбайтное значение т.е. тип int. char *ReadEEPstr(unsigned int adr,const char n) и char WriteEEPstr(const unsigned int adr,char str[],const char n) записывают/читают строку. параметр const лучше убрать в объявлении функции, почему объяснять много. И вот ещё один ньюанс при записи строки нужно учитывать что последовательно записываются данные до конца станицы, т.е. если конец стриницы 0xfff а мы с адресса 0xffe начнём записывать 4-х знаковую строку то последние два запишутся в начало текущей страницы, при чтении такое не наблюдается. размеры страниц смотри в даташите. Дело в том что значения для ускорения обмена записываются в ОЗУ памяти и по окончании сеанса связи записываются в EEPROM. У Белова это очень подробно и понятно описано. НУ надеюсь всё понятно если что пиши.
SetBit(TWCR,0b10000100);
Устанавливаем/сбрасываем неоходимые разряды регистра TWCR, в зависимости от битов контроллер производит необходимые действия например формирует СТАРТ, ПОВСТАРТ или посылает байт данных и пр. iEEP это глобальная переменная в которую записывается результат(из неё же берётся при записи) тут у меня неточность небольшая на самом деле в коде должна быть INT_EEP которую объявляем в начале файла, ну или бъявить в начале файла iEEP. Таким образом после вызова функции чтения результат находится в переменной iEEP, перед записью в память нужно присвоить iEEP значение которое необходими записать. Обращаю внимание что функции char WriteEEP(unsigned int adr) и char ReadEEP(unsigned int adr) записывают/читают двухбайтное значение т.е. тип int. char *ReadEEPstr(unsigned int adr,const char n) и char WriteEEPstr(const unsigned int adr,char str[],const char n) записывают/читают строку. параметр const лучше убрать в объявлении функции, почему объяснять много. И вот ещё один ньюанс при записи строки нужно учитывать что последовательно записываются данные до конца станицы, т.е. если конец стриницы 0xfff а мы с адресса 0xffe начнём записывать 4-х знаковую строку то последние два запишутся в начало текущей страницы, при чтении такое не наблюдается. размеры страниц смотри в даташите. Дело в том что значения для ускорения обмена записываются в ОЗУ памяти и по окончании сеанса связи записываются в EEPROM. У Белова это очень подробно и понятно описано. НУ надеюсь всё понятно если что пиши.
Настоящий кот всегда либо голоден,
либо невыспался ...
либо невыспался ...
-
начинающий пояльщик
- Первый раз сказал Мяу!
- Сообщения: 24
- Зарегистрирован: Вт мар 20, 2007 19:09:54
Огромное спасибо!!! Понял обсалютно все из библиотеки!!! Я написал программу, которая должна сканировать кнопки, реагировать на их нажатие обращатся к памяти, и в конце создавать массив(многомерный) содержащий 2 строки и 16 столбцов. Этот массив будет выводится на экран(присмотрел знакосинтезирующий 16х2).
Вобщем просьба ткнуть меня носом в ошибки.
Вобщем просьба ткнуть меня носом в ошибки.
- Вложения
-
- mk.c
- (3.73 КБ) 430 скачиваний
- moLCHec
- Мявтор!
- Сообщения: 825
- Зарегистрирован: Вс дек 18, 2005 20:04:42
- Откуда: Свердловская обл.
- Контактная информация:
Я когда в своём коде то ковыряюсь после долгого перерыва напрягаюсь очень, не говоря про чужой. Все ошибки при работе вылезут сами, именно при отладке повышается уровень, потом уже буишь интуицией чуять что там не так. При отладке полезно выводить промежуточные результаты и анализировать их. Пойми сразу мало что работает, у меня бывало уже обкатанный код на другом кристалле не сразу начинал работать. Главно не брезгай лишний раз глянуть в книгу или даташит и если даже код тебе Визарт создаёт смотри что он там написал. Удачи!
Настоящий кот всегда либо голоден,
либо невыспался ...
либо невыспался ...
-
начинающий пояльщик
- Первый раз сказал Мяу!
- Сообщения: 24
- Зарегистрирован: Вт мар 20, 2007 19:09:54


