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

Поклонники продукции Microchip Technology Inc тусуются тут.
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

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

Сообщение dosikus »

volatile , гадалки вы наши ... :)))
Реклама
Alpout
Открыл глаза
Сообщения: 77
Зарегистрирован: Вт сен 27, 2011 09:27:40

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

Сообщение Alpout »

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

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

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

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

Alpout писал(а):сомневаюсь
НУ и напрасно.
Компилятор оказался умней Вас и тупо вырезал обнуление переменной. Ибо, на самом деле, для чего её обнулять, если она дальше не будет использоваться ?
И совет по volatile тут совсем ни к месту. Это, как раз, тот случай, когда не стоит вмешиваться в работу оптимизатора.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

для разбора лучше давать исходный текст на Си, ассемблерный листинг только мешает понимать, что на самом деле вы делали.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

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

Сообщение dosikus »

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

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

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

Именно к месту
Лёх, тыкать volatile везде где попало - моветон. И ты это знаешь не хуже меня. И учить этому не стоит. volatile нужно применять только там, где он действительно необходим.
Если бы человек сказал, что ему действительно жизненно необходим сброс этой переменной, пояснив почему, то совет по volatile был бы уместен.
В данном случае, оптимизатор сделал своё дело правильно, и от его работы логика программы не изменилась бы.
Ну а то, что переменная у него должна сохранять свои значения и что он не сделал её статической - это уже от неопытности.

ЗЫ: Ну вот, пока писал ответ, ты уже отредактировал свой пост :)
Реклама
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

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

Сообщение dosikus »

Дык что и твой пост теперь не к месту. :)))


Из давнишнего -

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

void   interrupt_handler(void)
 { 
    if(INTCON.T0IF&&INTCON.T0IE)   // timer0 interrupt service -> LED display+keypad driver
       {
         static unsigned char Counter;
         static unsigned char Scan_value; 
         static unsigned int16	Blink_counter;
         //unsigned 	char Beep_counter;
         static unsigned char Debounce_tik;
         unsigned char Temp; 
         static unsigned char Port;
         //static unsigned char Test;
         
         INTCON.T0IF=0;         
         TMR0=TMR0_VAL;
         

          
         Led_PORT=LED_OFF;                          //  display scan driver
         LedScan=Scan_value;
                
         Temp=Led_buffer[Counter];
         #ifdef OK
         if(++Blink_counter & 0x100) Temp ^= (Blink_buffer[Counter] & Temp);
         #else 
         if(++Blink_counter & 0x100) Temp ^= (Blink_buffer[Counter] & ~Temp);
         #endif
         
         Led_PORT=Temp;
         
         Scan_value <<=1;
         Counter++;                            //  
         Counter&=0x03;                        //     
         if(!Counter)
           {
            Scan_value=LED_INIT_POS;
           
           }
Alpout
Открыл глаза
Сообщения: 77
Зарегистрирован: Вт сен 27, 2011 09:27:40

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

Сообщение Alpout »

dosikus писал(а):Сделать count static .
заработало!

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

128:               void interrupt isr() {
   004    00DE     MOVWF 0x5e
   005    0E03     SWAPF 0x3, W
   006    1283     BCF 0x3, 0x5
   007    00A0     MOVWF 0x20
   008    0804     MOVF 0x4, W
   009    00A1     MOVWF 0x21
   00A    080A     MOVF 0xa, W
   00B    00A2     MOVWF 0x22
   00C    2889     GOTO 0x89
129:               static unsigned char dig3;
130:               static unsigned char dig2;
131:               static unsigned char count;
132:               dig3=0;
   089    01CE     CLRF 0x4e
133:               dig2=0;
   08A    01CD     CLRF 0x4d
134:               if (T0IF) {
   08B    1D0B     BTFSS 0xb, 0x2
   08C    28AE     GOTO 0xae
135:               PORTA&=0; //выключили аноды
   08D    0185     CLRF 0x5
136:               TMR0=0;
   08E    0181     CLRF 0x1
137:               if (count==0) {
   08F    08CC     MOVF 0x4c, F
   090    1D03     BTFSS 0x3, 0x2
   091    289C     GOTO 0x9c
138:               PORTA=num[dig3][0];
   092    1003     BCF 0x3, 0
   093    0D4E     RLF 0x4e, W
   094    20B7     CALL 0xb7
139:               PORTC=num[dig3][1];
   095    0D4E     RLF 0x4e, W
   096    3E39     ADDLW 0x39
   097    0084     MOVWF 0x4
   098    0800     MOVF 0, W
   099    0087     MOVWF 0x7
140:               RA0=1;
   09A    1405     BSF 0x5, 0
141:               RA1=0;
   09B    1085     BCF 0x5, 0x1
142:               }
143:               if (count==1) {
   09C    0B4C     DECFSZ 0x4c, W
   09D    28A8     GOTO 0xa8
144:               PORTA=num[dig2][0];
   09E    1003     BCF 0x3, 0
   09F    0D4D     RLF 0x4d, W
   0A0    20B7     CALL 0xb7
145:               PORTC=num[dig2][1];
   0A1    0D4D     RLF 0x4d, W
   0A2    3E39     ADDLW 0x39
   0A3    0084     MOVWF 0x4
   0A4    0800     MOVF 0, W
   0A5    0087     MOVWF 0x7
146:               RA0=0;
   0A6    1005     BCF 0x5, 0
147:               RA1=1;
   0A7    1485     BSF 0x5, 0x1
148:               }
149:               count++; 
   0A8    0ACC     INCF 0x4c, F
150:               if (count==2) {
   0A9    084C     MOVF 0x4c, W
   0AA    3A02     XORLW 0x2
   0AB    1903     BTFSC 0x3, 0x2
151:               count=0;
   0AC    01CC     CLRF 0x4c
152:               } 
153:               T0IF = 0; 
   0AD    110B     BCF 0xb, 0x2
154:                         }
155:               }
   0AE    0822     MOVF 0x22, W
а что дает Static??
Аватара пользователя
shindax
Потрогал лапой паяльник
Сообщения: 378
Зарегистрирован: Сб сен 19, 2009 07:02:19

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

Сообщение shindax »

Аватара пользователя
virus33
Нашел транзистор. Понюхал.
Сообщения: 175
Зарегистрирован: Пт июн 29, 2012 23:48:11

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

Сообщение virus33 »

Потребовалось использовать модуль CCP в режиме захвата. камень 16f877a. Накидал небольшую прошивку, подаю на вход RC2(CCP1) 10кГц, при каждом прерывании модуля CCP должен инвертироваться вывод RB6, а так же на семисегментник выводится трехзначное значение счетчика (0...655).
Прерывания по таймеру 0 и 1 есть, по модулю захвата нет ничего. Код написан согласно ДШ.

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

#include <pic.h>
 
__CONFIG(0x3FFA); 									

int v1,v2,v3,v4,ADCR;								//Числа для каждого знакоместа
char vn;
static	volatile unsigned int  num         @ 0x26;	// программный регистр преобразования ацп
static	volatile unsigned char numL        @ 0x26;	// младший байт
static	volatile unsigned char numH        @ 0x27;	// старший байт

void CPU_SETUP (void){
TRISA = 0b11111111;		//порт А - на вход
TRISB = 0;				//Вывод анодов
TRISC = 0b11111111;
TRISD = 0;
PORTA = 1;          	//очищаем порт А
PORTB = 0;				//очищаем порт В
PORTC = 0;
PORTD = 0;
OPTION = 0b00000000;	//Конфигурация переферии по умолчанию, предделитель таймера 0 на 0
INTCON = 0b11100000; 	//Конфигурация прерываний
T1CON = 0b00001101;
//ADCON0	= 0b10000000;	//Правое выравнивание, канал AN0, включен
ADCON1	= 0b00000111;	//Fosc/32
CCP1CON = 0b00110101;	//Захват по каждому переднему фронту сигнала
PIE1 = 0b00000101;		//Прерывания от CCP1,TMR1
CCP1IF = 0;				//Флаг захвата сброшен
CCP1IE = 1;                              //На всякий случай еще раз включим прерывания
//////////////////////////////////////////////////////////////////////
// 						Регистр настроек OPTION						//
//RBPU   = 1;		//подтягивающие резисторы выкл			бит 7	//
//INTEDG = 0;		//прерывания по заднему фронту сигнала	бит 6	//
//T0CS   = 0;		//внутренний тактовый сигнал таймера 0	бит 5	//
//T0SE   = 0;		//приращение по переднему фронту TMR0	бит 4	//
//PSA    = 0;		//предделитель включен перед TMR0		бит 3	//
//PS2    = 0;		//установка								бит 2	//
//PS1    = 0;		//коэффициента							бит 1	//
//PS0    = 0;		//предделителя TMR0	на 0				бит 0	//
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
//						Регистр прерываний INTCON					//
//GIE  = 1;			//разрешаем глобальные прерывания		бит 7	//
//PEIE = 1;			//разрешаем прерывания периферии		бит 6	//
//T0IE = 1;			//разрешаем прерывания по таймеру 0		бит 5	//
//INTE = 0;			//запрещаем внешние прерывания			бит 4	//
//RBIE = 0;			//запрещаем прерывания по порту В		бит 3	//
//T0IF = 0;			//очищаем флаг таймера 0 				бит 2	//
//INTF = 0;			//очищаем флаг внешнего прерывания		бит 1	//
//RBIF = 0;			//очищаем флаг прерывания на порту В	бит 0	//
//////////////////////////////////////////////////////////////////////
}

void delay(unsigned int p)
{
	unsigned int i;
	for(i=0;i<p;i++){asm("NOP");}
}

void seg7(unsigned char c, unsigned char s)
{
unsigned char t=0;
switch(c%13)        			//  выбор сегментов (катодов)
{
//Таблица символов (чисел, знаков)//
case 0 : {t=0b11000000;} break;
case 1 : {t=0b11111001;} break;
case 2 : {t=0b10100100;} break;
case 3 : {t=0b10110000;} break;
case 4 : {t=0b10011001;} break;
case 5 : {t=0b10010010;} break;
case 6 : {t=0b10000010;} break;
case 7 : {t=0b11111000;} break;
case 8 : {t=0b10000000;} break;
case 9 : {t=0b10010000;} break;
case 10 :{t=0b11111111;} break;	//пустой знак
case 11 :{t=0b10111001;} break;	//знак - 1
case 12 :{t=0b10111111;} break;	//знак - 
}
RB0 = 0;
RB1 = 0;
RB2 = 0;
RB3 = 0;

switch(s)       				//  выбор анода
{
case 1 :{ RB0 = 1;}break;
case 2 :{ RB1 = 1;}break;
case 3 :{ RB2 = 1;}break;
case 4 :{ RB3 = 1;}break;
}
PORTD = t;
}

void write_7seg(int res){
	v2=res/100;				//2е знакоместо
	res=res%100;
	v3=res/10;					//3е знакоместо
	v4=res%10;					//4e знакоместо
}

void main (void)
{
CPU_SETUP();
vn=0;
v1 = 10;
	while(1){}
}

void interrupt pwm_int(void)					// общая процедура прерывания
{
	if(T0IF) 									//	при переполнение TMR0
	{
		vn++;
		switch(vn)
		{
			case 1:seg7(v1,1);break;			//сегмент 1
			case 2:seg7(v2,2);break;			//сегмент 2
			case 3:seg7(v3,3);break;			//сегмент 3
			case 4:{seg7(v4,4);vn = 0;}break;	//сегмент 4
		}
		TMR0=100;
		T0IF=0; 								//	сбрасываем флаг
	}

	if (TMR1IF){
	TMR1IF = 0;
	RB7 = !RB7;
	}

	if (CCP1IF == 1){
	RB6 = !RB6;
	numH = CCPR1H;
	numL = CCPR1L;
	ADCR = num/100;
	write_7seg(ADCR);
	CCP1IF = 0;
	CCP1IE = 1;                      //Вдруг выключилось, надо включить.
//	TMR1H = 0;
//	TMR1L = 0;
	}
}
Alpout
Открыл глаза
Сообщения: 77
Зарегистрирован: Вт сен 27, 2011 09:27:40

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

Сообщение Alpout »

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

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

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

А кто ж Вас заставляет ? Задолбал - пишите на том, у которого нет заёбов :)
К чему вообще Ваш пост ? :roll:
Alpout
Открыл глаза
Сообщения: 77
Зарегистрирован: Вт сен 27, 2011 09:27:40

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

Сообщение Alpout »

Это крик души :)) Писал программу в Си, вроде все работает..Но вот когда начинаешь по временам проверять, рабочая точка куда-то теряется,
и непонятно куда теряются 4-5мкс??? Вроде уже смотришь на Disassembler...но все же в некотоых командах рабочая точка куда-то уходит, а потом опять появляется :? Ща вот начал писать на ассемблере, там уж точно никуда ничег не пропадет :kill:
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25234
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

Сообщение КРАМ »

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

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

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

О какой рабочей точке идёт речь ?
Аргументы предъяв в студию, со всеми объяснениями(тесты, скриншоты, что делали, какой результат обязан был быть, какой есть на самом деле, ...). Иначе это всё похоже на некомпетентные стоны "ничего не работает, компиляторы - говно, ...", коими тут завален весь форум.
Alpout
Открыл глаза
Сообщения: 77
Зарегистрирован: Вт сен 27, 2011 09:27:40

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

Сообщение Alpout »

Допустим рабочая точка находится тут (см. скрин)
1.JPG
(155.09 КБ) 528 скачиваний
, аннулируем StopWatch. Далее нажимаю StepInto. Стрелка пропадает, типо прыгает в адрес 0х63(этого адреса нет в дизассемблере)
2.JPG
(155.97 КБ) 281 скачивание
, а стопватч тикает, как будто с адреса 0х63 выполняются некоторые команды. Я дальше тыкаю в StepInto и через 10 мкс появляется стрелка
3.JPG
(151.24 КБ) 371 скачивание
и так частенько в других командах. Что там выполняет программа...непонятно, а мне эти 10мкс также важны, теоретически я же его не учитывал, как могу догадаться, что в каких то командах у меня будут потери)))
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25234
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

Сообщение КРАМ »

Библиотека присоединена как obj. Поэтому ее дизасма нет вообще, но дебаггер его реально исполняет.
если бы библиотека была в исходниках, то открылось бы окно файла, содержащего библиотеку с этой функцией. В этом окне стрелка бы и двигалась.
Но можно увидеть и этот "невидимый" участок. Откройте окно Program Memory и там стрелка никуда исчезать не будет :wink:
Alpout
Открыл глаза
Сообщения: 77
Зарегистрирован: Вт сен 27, 2011 09:27:40

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

Сообщение Alpout »

КРАМ писал(а):Библиотека присоединена как obj. Поэтому ее дизасма нет вообще, но дебаггер его реально исполняет.
если бы библиотека была в исходниках, то открылось бы окно файла, содержащего библиотеку с этой функцией. В этом окне стрелка бы и двигалась.
Но можно увидеть и этот "невидимый" участок. Откройте окно Program Memory и там стрелка никуда исчезать не будет :wink:
Спасибо, счас понял, буду разбираться. Хотя я уже начал писать на Асме :lol:
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

Alpout писал(а):а мне эти 10мкс также важны
О каких 10-ти тактах может быть речь, когда Вы используете вложенные друг в друга циклы, обращение к двумерным массивам и умножение ? :facepalm:
Что Вы там пытались вообще расчитать ?
Ну и второе. Если дебажете на Си, так и прыгайте по СИшным строкам. Зачем лезть в дизасм, чтобы узнать время выполнения ?
vinni_puh
Встал на лапы
Сообщения: 99
Зарегистрирован: Ср мар 25, 2015 09:12:45

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

Сообщение vinni_puh »

Добрый день!
Порылся вот в этом:
>>http://www.labkit.ru/html/C_for_PIC
ОК, 3-х сегментником управлять научился), с выведением автоинкрементированных чисел от 0 до 9 и отображением дежурной индикации. ИМХО для первых 3 часов ковыряния неплохо, с учетом того, что в протеус реальную плату перенес, чтобы под нее кодить как КИТ куплю.

А дальше? Плиз, если кто знает, требуется тычек носом в основные моменты... Какие еще есть стартаповские руководства?)
Ну вот к примеру, попытался сдалать:

void function(char *DI_GIT){...}
char digi[4]="10";
function(digi); - не компилится - не нравится указатель (char *DI_GIT). На компе GCC свободно кушает. про strlen() вообще молчу.

И itoa() выдает предупреждение - ошибка преобразования. Хоть слава Богу atoi() без проблем съелось... spritf() на МК применять буду в виде отдельного исключения... Для чисел только itoa().
Ответить

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