Програмирование pic на СИ.

Поклонники продукции Microchip Technology Inc тусуются тут.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение Аlex »

Самый хороший учитель - это время. Правильно понимаете, что со временем и опыт придёт и код будет становиться более "прозрачным". ТАк что, не переживайте по этому поводу, просто занимайтесь любимым делом и всё :)
Реклама
Darkmaster
Встал на лапы
Сообщения: 137
Зарегистрирован: Вс окт 11, 2009 09:54:59
Откуда: Пенза

Re: Програмирование pic на СИ.

Сообщение Darkmaster »

Здравствуйте дамы и господа :)
разбирался я тут с АЦП в pic'ах ..и вот застрял на преобразовании результата Ацп в вольты.
А именно :для перевода нам надобно Результат Ацп умножить на Опорное напряжение и это в Разделить на количество отсчетов.(ADC*Uоn/1023)типа того.
Нужно получить результат в вольтах формата х.хх
переменную какого типа следует использовать для хранения результата и как получить 2 (или сколько нужно) знака после запятой?
Вроде понятно описал проблему )
читал статьи-уроки -это ужос а не уроки.То берут некие значения без пояснении и ссылок на что либо то еще чего.
Надеюсь на вашу помощь Коты :)

Котам пасибо :)
ответ найден и вроде понятно стало .будем шкодить
Интересная,однако,штука
Реклама
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение Аlex »

Если заранее известно количество знаков после запятой, то лучше использовать целочисленные типы. А результат хранить как умноженный на 10 в степени кол-ва разрядов. Т.е. при 1 знаке после запятой - *10, при 2-ух знаках - *100, при 3-ёх - *1000, и т.д...
Darkmaster
Встал на лапы
Сообщения: 137
Зарегистрирован: Вс окт 11, 2009 09:54:59
Откуда: Пенза

Re: Програмирование pic на СИ.

Сообщение Darkmaster »

Аlex писал(а):Т.е. при 1 знаке после запятой - *10, при 2-ух знаках - *100, при 3-ёх - *1000, и т.д...
пасибо.
именно с этим разобрался.Целые рулят.
Ишо бы оптимизировать умножения/деление
Интересная,однако,штука
Реклама
Эиком - электронные компоненты и радиодетали
driver_gv
Потрогал лапой паяльник
Сообщения: 399
Зарегистрирован: Сб авг 08, 2009 23:02:57
Откуда: Ростов-на-Дону
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение driver_gv »

Умножить на 10 - это три сдвига влево и два сложения для PIC16 , у 18-х есть аппаратный умножитель.
__________________
Все, что нельзя запрограммировать на ассемблере, приходится паять
Реклама
Darkmaster
Встал на лапы
Сообщения: 137
Зарегистрирован: Вс окт 11, 2009 09:54:59
Откуда: Пенза

Re: Програмирование pic на СИ.

Сообщение Darkmaster »

driver_gv писал(а): для PIC16
да,читал об этом.Компилятор Hi-tech 9.71..pic16.интересно он (компилятор) тоже сдвиг делает или нет ,может кто в курсе ? (то есть я пишу 5/100 а он автоматом сдвигает.)

засада получается..
Подумал я было
do
variable=variable>>10
while(variable2<количество раз)
но че то ни так ни сяк..это вместо деления на 1000
можно ли по такому принципу как то?
Интересная,однако,штука
Реклама
electronik_tver
Открыл глаза
Сообщения: 54
Зарегистрирован: Пн авг 05, 2013 12:18:46

Re: Програмирование pic на СИ.

Сообщение electronik_tver »

Подскажите пож как лучше сделать, есть устройство на pic16f877, хайтек, с, в программе необходимо отсчитывать параллельно несколько временных участков, с достаточно немаленькими величинами, например на время горения экрана после последней нажатой кнопки 30сек, время на закрытие задвидки 4мин, время работы механизма 10мин и тд, трех таймеров на все не хватит да и делители дикие получаются, устройство уже собрано, речь о реконструкции кода, еще в составе есть часы реального времени, обмен работает, теоретически можно подать секундные импульсы с часов на t0cki и задействовать tmr0, сейчас все работает по принципу узнал на часах время, прибавил нужный отрезок и жду когда это время наступит, но это топорно както, простой пример вдруг время собъется, как вообще пишутся программы с параллельными временными отрзками, хочется красиво сделать, интересует общий подход
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Re: Програмирование pic на СИ.

Сообщение uldemir »

Зависит от дискретности. Если для таких интервалов дискретность в 1 сек. приемлема, то делаете таймер с прерыванием в 1 сек и в обработчике отсчитываете интервалы.

Вот, например, в моём проекте в таймере контролирующем динамическую индикацию попутно отсчитывается частота мигания символов, дребезга клавиатуры и задержка оставленного режима отображения до перехода в основной.

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

#pragma interruptlow tmr0routine
void tmr0routine(void) {
[skip]
	blink_cnt++;
	if (kbddelay  != 0)  kbddelay--;
	if (showdelay != 0) showdelay--;

	INTCONbits.TMR0IF = 0;
}
electronik_tver
Открыл глаза
Сообщения: 54
Зарегистрирован: Пн авг 05, 2013 12:18:46

Re: Програмирование pic на СИ.

Сообщение electronik_tver »

спасибо, ну да логично, то есть если я правильно понимаю когда нужно я задаю kbddelay или другой переменной нужное время а с каждым тиком они все дружно уменьшаются и мне остается ловить их обнуление и реагировать в соответствии с задачей?
spongebob
Грызет канифоль
Сообщения: 289
Зарегистрирован: Пт мар 20, 2009 12:25:47
Откуда: Ivanovo
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение spongebob »

Доброго всем дня или ночи.
Вопрос такой. Как организовать побитовую работу с байтом на подобие структуры?
Например у меня есть байт (FLAGS) с флагами состояния программы. Есть функции для работы с битами (установить бит в 1, установить бит в 0, проверить состояние бита, инвертировать бит).
Каждый бит тоже имеет свое имя. Например:
#define WORK 0
#define MODE 1
И т.д.
Соответственно работа с каждым битом представляет собой вызов функции BitSet0 или другой с параметрами (байт, бит). Функции определены типа так:
#define BitSet1(reg, bit) reg |= (1<<bit)

А хочется простой доступ, с меньшей писаниной. Например FLAGS.WORK=1 и т.п.

Не будет ли реализация подобной хотелки требовать больше памяти и ресурсов и лучше оставить все как есть? А если нет, то как подобное раелизовать?
Спасибо!
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Re: Програмирование pic на СИ.

Сообщение uldemir »

Ну так и пишите:

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

struct {
  volatile unsigned char sec_event   : 1;
  volatile unsigned char adcready    : 1;
} flag;
потом можно к ним обращаться

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

if (flag.sec_event == 1) {
      flag.sec_event = 0;
Насчет оптимальности - это к конкретному компилятору.
spongebob
Грызет канифоль
Сообщения: 289
Зарегистрирован: Пт мар 20, 2009 12:25:47
Откуда: Ivanovo
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение spongebob »

Это уже не бит в байте получается. И в случае чего в один байт того же еепром не влезет.
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Re: Програмирование pic на СИ.

Сообщение uldemir »

А что тогда???? :shock: вот это " :1" как раз и говорит, что тот чар сек_эвент занимает один бит. Более того, я таким образом обращаюсь к битам регистров, которые уж точно "один байт": INTCONbits.TMR0IF = 0; И этот INCONbits описан точно так же.
Аватара пользователя
shindax
Потрогал лапой паяльник
Сообщения: 378
Зарегистрирован: Сб сен 19, 2009 07:02:19

Re: Програмирование pic на СИ.

Сообщение shindax »

spongebob писал(а):Это уже не бит в байте получается...
https://ru.wikipedia.org/wiki/%D0%91%D0 ... 0%BB%D0%B5
Аватара пользователя
Gray64
Встал на лапы
Сообщения: 96
Зарегистрирован: Вт май 27, 2008 21:15:01
Откуда: Украина
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение Gray64 »

Всем доброго дня.
Есть проблема. Ну это для меня проблема, а для знающих наверное не стоит выеденного яйца :) .
Есть вот такой исходник:
Спойлер//Добавим файл с описанием регистров МК
#include <pic.h>

//Укажем слово конфигурации
__CONFIG (INTIO &WDTDIS &PWRTEN &MCLREN &BOREN &LVPDIS &UNPROTECT);

//Опишем переменные
const unsigned char step_table[4]={0b00010000,0b00100000,0b01000000,0b10000000};//Таблица состояний ключей
unsigned char cur_step;//Номер состояния в таблице

static void interrupt
isr(void){//Подпрограмма обработки прерываний
//Так как вектор прерывания у PIC16F628 общий, то функцию обработки внешнего прерывания
//начнём с проверки флага INTF, который устанавливается аппаратно при возникновении
//внешнего прерывания
if(INTF){//Если было внешнее прерывание
INTF = 0; //Сбрасываем флаг прерывания
if ((PORTB & 0b00000010) == 2){//Если нужно крутить по часовой, то
cur_step++;//увеличиваем указатель на элемент таблицы(массива)
if(cur_step == 4)cur_step = 0;//Если это последнее значение таблицы(массива), то идём в её начало
}

if((PORTB & 0b00000010) == 0){//Если нужно крутить против часовой, то
if(cur_step == 0) cur_step = 4;//Если текущее значение - это первое значение в таблице(в массиве), то идём в её конец
cur_step--;//уменьшаем указатель на элемент таблицы(массива)
}
}
}

void Init_CPU(void){//Настройка МК
CMCON = 0x07; //Отключаем встроенные компараторы
OPTION = 0b10000000 ;//Отключаем встроенные резисторы, внешнее прерывание INT - по спаду
TRISA = 0b11111111;//Весь порт А - на ввод
PORTB = 0x00; //Выводим в порт В нули
TRISB = 0x03; //Весь порт В кроме 2-х младших разрядов - на вывод
INTE = 1;//Разрешаем внешние прерывания
}

void main(void){//После сброса МК программа начнёт выполняться с этого места
Init_CPU();//Настроим МК
GIE = 1;//Глобальное разрешение прерываний
while(1){//Вечный цикл
PORTB = step_table[cur_step];//Выводим в порт значение из таблицы
};
}
В общем это "крутилка" для униполярнго шагового двигателя. Полное описание тут http://it-en.ru/cnc/doc/1.html Надо поменять табличку "шагов" для него. Так как я в Си полный ноль, для начала решил просто откомпилировать исходник, без всяких изменений, напартачить всегда успею. Создал проэкт в MPLAB, добавил исходник, но при компиляции выдаёт следующее:
Error [1091] C:\Program Files\HI-TECH Software\PICC\9.71a\sources\float.c; 86. main function "_main" not defined
Функция не определена. Что надо дописать-переписать?

Добавлено: Вопрос снят, всё ОК, накосячил при установке ПО... :(
Глаза боятся а руки делают!
Alpout
Открыл глаза
Сообщения: 77
Зарегистрирован: Вт сен 27, 2011 09:27:40

Re: Програмирование pic на СИ.

Сообщение Alpout »

Привет, Всем! :) Не понимаю 1, почему не компилируется Си команда? В дизассемблере так выглядит

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

148:               if (count==2) {
   142    0824     MOVF 0x24, W
   143    3A02     XORLW 0x2
149:               count=0;
150:               } 
конкретнее команда count=0
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение Аlex »

Она, скорее всего, компилируется. Просто в дизасемблере её не видно.
Попробуйте пошагать в режиме отладки и посмотрите, выполняется ли она.
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Re: Програмирование pic на СИ.

Сообщение Siarzhuk »

Alpout писал(а):

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

148:               if (count==2) {
   142    0824     MOVF 0x24, W
   143    3A02     XORLW 0x2
149:               count=0;
150:               } 
Подозреваю, что в строках 151, 152, 153 ... листинга и будет искомое. КМК в 142,143 - всего лишь _подготовка_ к сравнению. :)
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Alpout
Открыл глаза
Сообщения: 77
Зарегистрирован: Вт сен 27, 2011 09:27:40

Re: Програмирование pic на СИ.

Сообщение Alpout »

Не не не ребята. Программа перешагивает команду!!! Эта команда внутри обработки прерывания, т.е.

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

128:               void interrupt isr() {
   004    00DE     MOVWF 0x5e
   005    0E03     SWAPF 0x3, W
   006    1283     BCF 0x3, 0x5
   007    00A0     MOVWF 0x20
   008    080A     MOVF 0xa, W
   009    00A1     MOVWF 0x21
   00A    292B     GOTO 0x12b
129:               unsigned char dig3, dig2, count;
130:               dig3=0;
131:               dig2=0;
   12B    01A3     CLRF 0x23
132:               if (T0IF) {
   12C    1D0B     BTFSS 0xb, 0x2
   12D    2945     GOTO 0x145
133:               PORTA&=0; //выключили аноды
   12E    0185     CLRF 0x5
134:               TMR0=0;
   12F    0181     CLRF 0x1
135:               if (count==0) {
   130    08A4     MOVF 0x24, F
   131    1D03     BTFSS 0x3, 0x2
   132    2939     GOTO 0x139
136:               PORTA=num[dig3][0];
   133    083A     MOVF 0x3a, W
   134    0085     MOVWF 0x5
137:               PORTC=num[dig3][1];
   135    083B     MOVF 0x3b, W
   136    0087     MOVWF 0x7
138:               RA0=1;
   137    1405     BSF 0x5, 0
139:               RA1=0;
   138    1085     BCF 0x5, 0x1
140:               }
141:               if (count==1) {
   139    0B24     DECFSZ 0x24, W
   13A    2941     GOTO 0x141
142:               PORTA=num[dig2][0];
   13B    083A     MOVF 0x3a, W
   13C    0085     MOVWF 0x5
143:               PORTC=num[dig2][1];
   13D    083B     MOVF 0x3b, W
   13E    0087     MOVWF 0x7
144:               RA0=0;
   13F    1005     BCF 0x5, 0
145:               RA1=1;
   140    1485     BSF 0x5, 0x1
146:               }
147:               count++; 
   141    0AA4     INCF 0x24, F
148:               if (count==2) {
   142    0824     MOVF 0x24, W
   143    3A02     XORLW 0x2
149:               count=0;
150:               } 
151:               T0IF = 0; 
   144    110B     BCF 0xb, 0x2
152:                         }
153:               }
   145    0821     MOVF 0x21, W
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Re: Програмирование pic на СИ.

Сообщение uldemir »

У вас эта переменная динамическая. Компилятор её соптимизировал? Потому как по выходу из прерывания она уничтожается, так нафига её обнулять?

p.s. Поставили бы повыше уровень оптимизации и сравнение тоже исчезло бы...
Ответить

Вернуться в «PIC»