Вопросы синтаксиса

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
kostya740
Родился
Сообщения: 19
Зарегистрирован: Пн ноя 03, 2008 23:26:41

Вопросы синтаксиса

Сообщение kostya740 »

программирую в CodeVision AVR. есть вопросы:
1. почему я не могу присвоить указателю на масив char константное слово? пример:
char* mass = "tuta tekst";
mass = "novii tekst"; <<< тут ошибка.
Неужели нету перегруженого оператора равно для таких присваиваний?
2. Как перегрухить операторы и функции?
Пример:
void summa(int a, int b);
void summa (char a, char b); <<< тут ошибка.
как правельно в компиляторе перегружать функции? и возможно ли вообще их перегружать? Неужели прийдеться заводить кучу разных имен фукций? И с опреаторами как дела обстоят?

3. Как схематически сделать пин порта вводом и выводом одновременно?
Я хочу, чтоб ввод или вывод пина указывался юзером по RS-232. Но при этом схематически ничего не перепаивать. нагрузки на вывод достаточно 100мА. Курил на листике всякое, ничего путного не выходит.

Заранее спасибо.
Аватара пользователя
Aheir
Модератор
Сообщения: 4517
Зарегистрирован: Пн апр 03, 2006 11:43:25
Откуда: Санкт - Петербург
Контактная информация:

Сообщение Aheir »

А что мешает в качестве параметров функции void summa(int a, int b); использовать char? Ну можно написать для чаровой переменной (int)a при ее передаче функции.

Про 100мА на вывод - забудьте, читайте даташит.
Переконфигурация выводов - регистры PORTx и DDRx - см. даташит
Оптимизм х (Опыт + Знания) = const
kostya740
Родился
Сообщения: 19
Зарегистрирован: Пн ноя 03, 2008 23:26:41

Сообщение kostya740 »

Aheir писал(а):А что мешает в качестве параметров функции void summa(int a, int b); использовать char? Ну можно написать для чаровой переменной (int)a при ее передаче функции.


а если я хочу передать массив? а если я хочу указатель передать?
как вообще перегружать функции? не заводжить же для каждой функции новое имя.

Aheir писал(а):Про 100мА на вывод - забудьте, читайте даташит.
Переконфигурация выводов - регистры PORTx и DDRx - см. даташит


Вы не поняли.
Мне нужно сделать коробочку с клемами пронумероваными. Для коробочки я пишу софт и прошивку. в софте юзер будет выбирать, порт номер 1 будет входом или выходом.
как мне схематически это сдлеать? на выходе должен быть транзюк маломощный. вроде как получаеться, если на один порт коробочки задействовать пару пинов контроллера.
Но хочеться задействовать один пин.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

я не большой спец по Си, но по-моему перегрузка операторов и функций введена только в С++

на счет ввода-вывода можно попробовать следующую схему (см. файл). если порт МК в режиме ввода, то сигнал извне поступает на него через резистор (достаточно малоомный). если порт МК работает на вывод - то транзисторы умощняют его. при этом не надо 2 порта, хватит и одного.
Вложения
123.PNG
(692 байт) 342 скачивания
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
kostya740
Родился
Сообщения: 19
Зарегистрирован: Пн ноя 03, 2008 23:26:41

Сообщение kostya740 »

ARV меня понял. спасибо за схемку. попробую погонять. А нету случайно такой сборки транзисторов в корпусе диповом например, а возможно даже несколько пар таких?
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

ARV писал(а):...
на счет ввода-вывода можно попробовать следующую схему (см. файл). если порт МК в режиме ввода, то сигнал извне поступает на него через резистор (достаточно малоомный). если порт МК работает на вывод - то транзисторы умощняют его. при этом не надо 2 порта, хватит и одного.

Небольшое дополнение (если позволите). Как я понимаю при такой схеме, в случае настройки вывода коробочки на вход, вывод мк должен быть в высокоимпедансном состоянии т.к. подключение внутренней или внешней подтяжки может привести к открыванию одного из транзисторов внешним (входным) сигналом. Т. е. в данном случае использоване подтягивающих резисторов может привести к тому, что в режиме "вход" транзисторы будут управляться внешним сигналом.
kostya740
Родился
Сообщения: 19
Зарегистрирован: Пн ноя 03, 2008 23:26:41

Сообщение kostya740 »

Итак я победил второй свой проэкт, по изучению МК. Первым был бегущая строка с обучалки кошака.
Я хоть и программист, но программить на МК нечто другое, но похожее.
Выкладываю на обозрение свой код. прошу попинать, где чего мыжно былоб укоротить, написать более грамотно.
Чесно украден с этого форума код програмного ресета. Но был он в асме, вроде я правельно портировал в Си. Вроде работает, прошу проверить. Как второй свой проэкт в Си, управиля гдето за 5-6 часов.

Данный проэкт сделн чисто ради експеремента. Когда будет закончен окончательно, погоняю дома и разберу на запчасти.
Идея такова. Сделать коробочку, к ней подключить розетки и выключатели в квартире. Через RS-232 по средствам АТ команд управлять нагрузками, читать какие нагрузки сейчас работают, какие нет. Дабы использоваться контроллер по максимуму, было предложено, чтоб пин порта был и входом и выходом одновременно. Только АТ командой можно настроить порт так, как нужно пользователю. Желания писать под все порты меги8535 небыло сегодня. Код напиман только под порт А. Повтаряю, это не законченый продукт. Это я так учусь, придумывая себе задачки и их расхлебывая.
Вложения
USART-TEST.c
Исходник с пояснениями для гурру
(14.78 КБ) 302 скачивания
123.PNG
Выходной каскад пина, предложенный гурру ARV
(692 байт) 393 скачивания
kostya740
Родился
Сообщения: 19
Зарегистрирован: Пн ноя 03, 2008 23:26:41

Сообщение kostya740 »

нуже, неужели никто не посмотрел? или так все хорошо написано, что нету замечаний?
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

kostya740 писал(а):нуже, неужели никто не посмотрел? или так все хорошо написано, что нету замечаний?

Вот смотрю:
1. Зачем при использовании прерывания по приему символа ждать окончания приема? Оно (прерывание) и так вызовется только когда прием символа будет закончен. Т. е. строчка

Код: Выделить всё

while ( !(UCSRA & (1<<RXC)) ); // Ждем, чтоб прошлый прием удался
лишняя.
2. Отправку массивов сделал бы тоже по прерыванию. Преимущества - указал с какого адреса и сколько байт отправлять, и спокойно занимайся своими делами. Главное предусмотреть индикацию занятости передатчика, т. е. пока одна строка передается вторую отправить нельзя.

В общем больше замечаний по логике нет, правда по правильности и красивости кода сказать не могу, ибо не силен в С.
Еще родилась такая мысл, а что если усилить реализацию распознавания команд (для этого проекта будет конечно излишеством, но для будушего и в образовательных целях пойдет).
Мысль такая: сделать распознавание команд по мнемонике сравнением массивов символов, составить таблицу команд и в соответствии с распознаной мнемоникой выполнять ту или иную команду. Данный подход позволить добавлять команды в проект (если это потребуется) "малой кровью".
kostya740
Родился
Сообщения: 19
Зарегистрирован: Пн ноя 03, 2008 23:26:41

Сообщение kostya740 »

с замечанием первым зогласен. Я не знал, что в прерывание он зайдет только если прошлый прием был удачным. решил перестраховаться. видать зря. А по второму неясно. Как мне передать параметр в прерывание? использовать глобальную переменную для это, думаю кощунство. И я так считаю, первоочередная задача устройства, выполнить команду, а не дать ответ юзеру.

Не понял про мнемоники? как они передаваться будут? какой формат? вообще враза "распознавание команд по мнемонике" не совсем мне понятна.
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

kostya740 писал(а):с замечанием первым зогласен. Я не знал, что в прерывание он зайдет только если прошлый прием был удачным. решил перестраховаться. видать зря. А по второму неясно. Как мне передать параметр в прерывание? использовать глобальную переменную для это, думаю кощунство. И я так считаю, первоочередная задача устройства, выполнить команду, а не дать ответ юзеру.

Не понял про мнемоники? как они передаваться будут? какой формат? вообще враза "распознавание команд по мнемонике" не совсем мне понятна.

Как я понимаю передаются у вас тоже массивы, поэтому в прерывание можно передать указатель на массив, и число байт, я думаю, что две глобальных переменных общим "объемом" 4 байта не такая уж страшная вещь. В любом случае это было только предложение, в вашем коде криминала нет, может быть в данном случае передача по прерыванию и не нужна. Уверен, что вариант с прерываниями заставит задуматься и придется отлаживать, поэтому выбирать вам (наверное, в данном случае его польза только в ключе самообразования).
По-поводу мнемоник - для данной задачи этого делать не стоит, опять же только для самообразования. Попробую пояснить. Например у нас есть список мнемоник команд во флеш в виде строк с 0 на конце. При анализе принятая команда сравниваетя с каждой из мнемоник во флеш, при совпадении запускается команда соответствующая текущей строке (мнемонике). Поскольку число мнемоник во флеши нам известно, также известен порядок их следования, то можно анализировать совпадения в цикле, счетчик которого будет увеличиваться при достижении конца строки (символа null). Для анализа совпадений написать ф-ю или использовать библиотечную (если есть). Как только принятая команда совпадет с одной из строк мы по счетчику цикла определяем номер команды и по этому номеру выполняем функцию, соответствующую команде. В-общем уже поздно, вы определитесь хотите-ли вы двигаться в направлении мнемоник, если да, то я попытаюсь подробно пояснить свою мысль и помочь (чем могу с кодом). Кстати понимаете ли вы asm? Мне было-бы проще объяснить с примерами на нем, чем на С. В общем если вы заинтересуетесь может быть завтра я и примеры кода сочиню, а сегодня все, спать :) .
kostya740
Родился
Сообщения: 19
Зарегистрирован: Пн ноя 03, 2008 23:26:41

Сообщение kostya740 »

смысл я понял. не знал, что масив заранее известных команд называеться мнемониками.
Можно конечно свою ф-ю написать, не думаю что это будет быстрее. А вот код меньше получиться явно, я так думаю. завтра попробую вашим методом, сравним размер.
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

kostya740 писал(а):смысл я понял. не знал, что масив заранее известных команд называеться мнемониками.
Можно конечно свою ф-ю написать, не думаю что это будет быстрее. А вот код меньше получиться явно, я так думаю. завтра попробую вашим методом, сравним размер.

Небольшое замечание, мнемоника команды - это ее символьное имя ну например add r16, r17. Здесь add - мнемоника. Т. е. в нашем случае будет массив мнемоник.
kostya740
Родился
Сообщения: 19
Зарегистрирован: Пн ноя 03, 2008 23:26:41

Сообщение kostya740 »

результат моим первым методом таков:
EEPROM - 16 байт
FLASH - 1670 байт

метод массива мнемоник. Изменения:
1. Добавился массив мнемоник - command_mnemonic[].
2. Добавилась функция вычисления сходства - strcompare()
3. Изменена функция ReadComand().

результат методом два таков:
EEPROM - 28 байт
FLASH - 1646 байт

Правельность работы второго вариант непроверял на железе. компилиться без ошибок.
Как мне кажеться, второй вариант больше нагрузит процессор. Использовании функции strcompare() вредит производительности.
Вложения
USART-TEST.c
вторая версия с использованием мнемоник
(15.07 КБ) 311 скачиваний
BerZerK-ku
Мучитель микросхем
Сообщения: 492
Зарегистрирован: Вт июл 22, 2008 08:10:54

Сообщение BerZerK-ku »

kostya740 писал(а):нуже, неужели никто не посмотрел? или так все хорошо написано, что нету замечаний?

По хорошему, прерывания надо делать как можно короче и желательно не использовать в них вызов функций.
Для вашего случая: в прерывании по приему символа в УАПП заменить функцию ReadComand(); на флаг, а саму функцию выполнять в основном цикле по флагу.
Ну и передачу по УАПП удобнее организовывать в прерываниях.
И еще, по умолчанию почти все, если не все, регистры устанавливаются в 0х00 (в даташите приведены значения для всех регистров), поэтому необходимость в такой громоздкой инициализации отпадает.
smac
Мучитель микросхем
Сообщения: 459
Зарегистрирован: Вс июн 01, 2008 12:16:38

Сообщение smac »

kostya740 писал(а):...
Правельность работы второго вариант непроверял на железе. компилиться без ошибок.
Как мне кажеться, второй вариант больше нагрузит процессор. Использовании функции strcompare() вредит производительности.

Я задумал немного другой вариант, сечас нет времени, вечером попробую выразить мысль, возможно получится короче. В данном случае использование switch конечно сильно загрузит процессор.
kostya740
Родился
Сообщения: 19
Зарегистрирован: Пн ноя 03, 2008 23:26:41

Сообщение kostya740 »

BerZerK-ku писал(а):По хорошему, прерывания надо делать как можно короче и желательно не использовать в них вызов функций.
Для вашего случая: в прерывании по приему символа в УАПП заменить функцию ReadComand(); на флаг, а саму функцию выполнять в основном цикле по флагу.
Ну и передачу по УАПП удобнее организовывать в прерываниях.
И еще, по умолчанию почти все, если не все, регистры устанавливаются в 0х00 (в даташите приведены значения для всех регистров), поэтому необходимость в такой громоздкой инициализации отпадает.


Огромное спасибо за критику. Мысль понятна, буду переписывать.
BerZerK-ku
Мучитель микросхем
Сообщения: 492
Зарегистрирован: Вт июл 22, 2008 08:10:54

Re: Вопросы синтаксиса

Сообщение BerZerK-ku »

kostya740 писал(а):2. Как перегрухить операторы и функции?
Пример:
void summa(int a, int b);
void summa (char a, char b); <<< тут ошибка.
как правельно в компиляторе перегружать функции? и возможно ли вообще их перегружать? Неужели прийдеться заводить кучу разных имен фукций? И с опреаторами как дела обстоят?

Про перегрузку функций знаете, а как применить - нет :) ?! В данном случае функции как раз должны содержать одинаковые имена и "<<< тут ошибка" у вас не будет.
Пример:

Код: Выделить всё

void strcopy(char* Str1, char* Str2){
  char i=0;
  do{
    Str2[i]=Str1[i];
    i++;
  }while(Str1[i]!=0x00);
}
void strcopy(char __flash* Str1, char* Str2){
  char i=0;
  do{
    Str2[i]=Str1[i];
    i++;
  }while(Str1[i]!=0x00);
}
KeeLoq
Родился
Сообщения: 3
Зарегистрирован: Вс ноя 09, 2008 23:38:11

Сообщение KeeLoq »

Здравствуйте еще раз!
У меня снова к Вам вопросик:
Стоит такая задача - принять последовательные данные с одной из ножек tiny2313 (например INT0), настроенной как внешнее прерывание по фронту импульса. Это я реализовал, правда еще не проверял, но думаю вопросов с этим не будет. Вопрос - как принятые последовательно биты организованно сложить в какую-нибудь переменную(без разницы по типу), чтобы потом обработать этот "массив битов", затем также считать из неё каждый битик в отдельности и отправить уже в другую ножку МК. В справочнике cvavr написано что побитовые операции работают только с первыми 32 регистрами, вот и не знаю как на Си организовать такое... зарезервировать какой-нибудь регистр, чтобы компилятор "не знал" о нем и побитно его набивать в процессе приёма данных, а потом копировать в другую переменную, очищать этот регистр, и так по кругу? Если так, то как зарезервировать регистр в Си? Подскажите, пожалуйста? :)
BerZerK-ku
Мучитель микросхем
Сообщения: 492
Зарегистрирован: Вт июл 22, 2008 08:10:54

Сообщение BerZerK-ku »

KeeLoq писал(а):Здравствуйте еще раз!
У меня снова к Вам вопросик:
Стоит такая задача - принять последовательные данные с одной из ножек tiny2313 (например INT0), настроенной как внешнее прерывание по фронту импульса. Это я реализовал, правда еще не проверял, но думаю вопросов с этим не будет. Вопрос - как принятые последовательно биты организованно сложить в какую-нибудь переменную(без разницы по типу), чтобы потом обработать этот "массив битов", затем также считать из неё каждый битик в отдельности и отправить уже в другую ножку МК. В справочнике cvavr написано что побитовые операции работают только с первыми 32 регистрами, вот и не знаю как на Си организовать такое... зарезервировать какой-нибудь регистр, чтобы компилятор "не знал" о нем и побитно его набивать в процессе приёма данных, а потом копировать в другую переменную, очищать этот регистр, и так по кругу? Если так, то как зарезервировать регистр в Си? Подскажите, пожалуйста? :)

В IAR регистры резервируются так: Project Options->С/С++ Compiler->Code->Number of register to lock for global variables.
В вашем случае это не надо. Т.к. Си сам все за вас сделает.
Например вот так можно заполнить побитно 0 и 1 переменную Temp:

Код: Выделить всё

for(char i=0; i<8; i++){
 if (i&0x01) Temp|=(1<<i);
 else Temp&=~(1<<i);
}
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»