Страница 34 из 103
Re: Програмирование pic на СИ.
Добавлено: Пн апр 20, 2015 10:59:13
Аlex
Самый хороший учитель - это время. Правильно понимаете, что со временем и опыт придёт и код будет становиться более "прозрачным". ТАк что, не переживайте по этому поводу, просто занимайтесь любимым делом и всё

Re: Програмирование pic на СИ.
Добавлено: Вс май 10, 2015 21:41:43
Darkmaster
Здравствуйте дамы и господа

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

ответ найден и вроде понятно стало .будем шкодить
Re: Програмирование pic на СИ.
Добавлено: Пн май 11, 2015 10:07:44
Аlex
Если заранее известно количество знаков после запятой, то лучше использовать целочисленные типы. А результат хранить как умноженный на 10 в степени кол-ва разрядов. Т.е. при 1 знаке после запятой - *10, при 2-ух знаках - *100, при 3-ёх - *1000, и т.д...
Re: Програмирование pic на СИ.
Добавлено: Пн май 11, 2015 11:42:25
Darkmaster
Аlex писал(а):Т.е. при 1 знаке после запятой - *10, при 2-ух знаках - *100, при 3-ёх - *1000, и т.д...
пасибо.
именно с этим разобрался.Целые рулят.
Ишо бы оптимизировать умножения/деление
Re: Програмирование pic на СИ.
Добавлено: Пн май 11, 2015 11:58:27
driver_gv
Умножить на 10 - это три сдвига влево и два сложения для PIC16 , у 18-х есть аппаратный умножитель.
Re: Програмирование pic на СИ.
Добавлено: Пн май 11, 2015 12:16:17
Darkmaster
driver_gv писал(а): для PIC16
да,читал об этом.Компилятор Hi-tech 9.71..pic16.интересно он (компилятор) тоже сдвиг делает или нет ,может кто в курсе ? (то есть я пишу 5/100 а он автоматом сдвигает.)
засада получается..
Подумал я было
do
variable=variable>>10
while(variable2<количество раз)
но че то ни так ни сяк..это вместо деления на 1000
можно ли по такому принципу как то?
Re: Програмирование pic на СИ.
Добавлено: Вт июл 14, 2015 21:05:53
electronik_tver
Подскажите пож как лучше сделать, есть устройство на pic16f877, хайтек, с, в программе необходимо отсчитывать параллельно несколько временных участков, с достаточно немаленькими величинами, например на время горения экрана после последней нажатой кнопки 30сек, время на закрытие задвидки 4мин, время работы механизма 10мин и тд, трех таймеров на все не хватит да и делители дикие получаются, устройство уже собрано, речь о реконструкции кода, еще в составе есть часы реального времени, обмен работает, теоретически можно подать секундные импульсы с часов на t0cki и задействовать tmr0, сейчас все работает по принципу узнал на часах время, прибавил нужный отрезок и жду когда это время наступит, но это топорно както, простой пример вдруг время собъется, как вообще пишутся программы с параллельными временными отрзками, хочется красиво сделать, интересует общий подход
Re: Програмирование pic на СИ.
Добавлено: Ср июл 15, 2015 05:59:02
uldemir
Зависит от дискретности. Если для таких интервалов дискретность в 1 сек. приемлема, то делаете таймер с прерыванием в 1 сек и в обработчике отсчитываете интервалы.
Вот, например, в моём проекте в таймере контролирующем динамическую индикацию попутно отсчитывается частота мигания символов, дребезга клавиатуры и задержка оставленного режима отображения до перехода в основной.
Код: Выделить всё
#pragma interruptlow tmr0routine
void tmr0routine(void) {
[skip]
blink_cnt++;
if (kbddelay != 0) kbddelay--;
if (showdelay != 0) showdelay--;
INTCONbits.TMR0IF = 0;
}
Re: Програмирование pic на СИ.
Добавлено: Ср июл 15, 2015 09:49:45
electronik_tver
спасибо, ну да логично, то есть если я правильно понимаю когда нужно я задаю kbddelay или другой переменной нужное время а с каждым тиком они все дружно уменьшаются и мне остается ловить их обнуление и реагировать в соответствии с задачей?
Re: Програмирование pic на СИ.
Добавлено: Пн июл 20, 2015 16:03:45
spongebob
Доброго всем дня или ночи.
Вопрос такой. Как организовать побитовую работу с байтом на подобие структуры?
Например у меня есть байт (FLAGS) с флагами состояния программы. Есть функции для работы с битами (установить бит в 1, установить бит в 0, проверить состояние бита, инвертировать бит).
Каждый бит тоже имеет свое имя. Например:
#define WORK 0
#define MODE 1
И т.д.
Соответственно работа с каждым битом представляет собой вызов функции BitSet0 или другой с параметрами (байт, бит). Функции определены типа так:
#define BitSet1(reg, bit) reg |= (1<<bit)
А хочется простой доступ, с меньшей писаниной. Например FLAGS.WORK=1 и т.п.
Не будет ли реализация подобной хотелки требовать больше памяти и ресурсов и лучше оставить все как есть? А если нет, то как подобное раелизовать?
Спасибо!
Re: Програмирование pic на СИ.
Добавлено: Пн июл 20, 2015 16:56:52
uldemir
Ну так и пишите:
Код: Выделить всё
struct {
volatile unsigned char sec_event : 1;
volatile unsigned char adcready : 1;
} flag;
потом можно к ним обращаться
Код: Выделить всё
if (flag.sec_event == 1) {
flag.sec_event = 0;
Насчет оптимальности - это к конкретному компилятору.
Re: Програмирование pic на СИ.
Добавлено: Пн июл 20, 2015 17:20:56
spongebob
Это уже не бит в байте получается. И в случае чего в один байт того же еепром не влезет.
Re: Програмирование pic на СИ.
Добавлено: Пн июл 20, 2015 17:27:32
uldemir
А что тогда????

вот это " :1" как раз и говорит, что тот чар сек_эвент занимает один бит. Более того, я таким образом обращаюсь к битам регистров, которые уж точно "один байт": INTCONbits.TMR0IF = 0; И этот INCONbits описан точно так же.
Re: Програмирование pic на СИ.
Добавлено: Ср авг 05, 2015 05:35:18
shindax
spongebob писал(а):Это уже не бит в байте получается...
https://ru.wikipedia.org/wiki/%D0%91%D0 ... 0%BB%D0%B5
Re: Програмирование pic на СИ.
Добавлено: Вс авг 16, 2015 09:08:27
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
Функция не определена. Что надо дописать-переписать?
Добавлено: Вопрос снят, всё ОК, накосячил при установке ПО...

Re: Програмирование pic на СИ.
Добавлено: Ср авг 19, 2015 07:28:12
Alpout
Привет, Всем!

Не понимаю 1, почему не компилируется Си команда? В дизассемблере так выглядит
Код: Выделить всё
148: if (count==2) {
142 0824 MOVF 0x24, W
143 3A02 XORLW 0x2
149: count=0;
150: }
конкретнее команда count=0
Re: Програмирование pic на СИ.
Добавлено: Ср авг 19, 2015 08:17:12
Аlex
Она, скорее всего, компилируется. Просто в дизасемблере её не видно.
Попробуйте пошагать в режиме отладки и посмотрите, выполняется ли она.
Re: Програмирование pic на СИ.
Добавлено: Ср авг 19, 2015 08:44:05
Siarzhuk
Alpout писал(а):Код: Выделить всё
148: if (count==2) {
142 0824 MOVF 0x24, W
143 3A02 XORLW 0x2
149: count=0;
150: }
Подозреваю, что в строках 151, 152, 153 ... листинга и будет искомое. КМК в 142,143 - всего лишь _подготовка_ к сравнению.

Re: Програмирование pic на СИ.
Добавлено: Ср авг 19, 2015 16:54:53
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
Re: Програмирование pic на СИ.
Добавлено: Ср авг 19, 2015 17:15:31
uldemir
У вас эта переменная динамическая. Компилятор её соптимизировал? Потому как по выходу из прерывания она уничтожается, так нафига её обнулять?
p.s. Поставили бы повыше уровень оптимизации и сравнение тоже исчезло бы...