Свежие обсуждения
Микроконтроллеры

Ликбез по С для микроконтроллеров PIC

1 62 64

Вот именно что медленно, хотелось бы в реальном времени так сказать...

 

Посмотрите знатоки, могут ли быть здесь "подводные камни"?
Написано в CWAVR на СИ и симуляция в Протеус 7.6 SP0

214877.zip

 

Доброго всем времени суток!
Решил освежить тему, так как осваиваю Си. Среда разработки MPLAB IDE 8.30, компилятор CCS, моделирование Proteus 7.6 SP4.
Вопрос собственно в реализации приема через RS-232 на PIC16F628. С отправкой боле-менее всё понятно, но вот с приёмом..
Может есть у кого готовые примеры по приему, или ткните носом что не так.

P.S. Шпака курил несколько раз, но инфы в примерах очень скудно...

238430.zip

 

а что принимать хотите?
Прием одного байта - getc();. Или Вы scanf хотите?
Посмотрите на мои первые шаги к USB микроконтроллеру, там есть пример общения через COM-порт. На то, что он виртуальный (USB-COM) не обращайте внимание (просто в уме отбрасывайте "usb_cdc_"; например, "usb_cdc_getc()" читайте как "getc()" и др.).

Есть и функции, которые позволяют упростить прием чисел, например для чисел с плавающей точкой:
void GetFloat(void)
{
unsigned char sbuf[10];

gets(sbuf); // Принимаем строку, до символа перевода каретки и пишем в буфер
T=atof(sbuf); //Преобразуем содержимое буфера в число с плавающей точкой
printf("%f *C\n\r", T); // Выводим результат
}

 

To Сергей К - спасибо большое за отклик.
Вроде все получилось, но интересно то, что в Протеусе (7.6 sp0) у меня не моделировалось, но после установки SP4 всё Ок.
Буду копать дальше. Вот проект который у меня заработал, может и не всё как надо, подскажите пож-ста где не так. В общем пинки приветствуются.
Да... вопрос:
правильно ли я работаю с прерываниями?

#include "C:\DimmerPicF877_TMR\Dist_628\Dist_628.h"
#fuses HS, NOWDT
#use delay(clock=4000000)
#use RS232(baud=9600, parity=N, xmit=PIN_B2, rcv=PIN_B1, stream=DATA_STREAM)
char buffer[5];

#int_RDA
void RDA_isr(void){
clear_interrupt(int_RDA);
fgets(buffer, DATA_STREAM); // получяем из буфера приема строку и кидаем её в buffer
fputs(buffer, DATA_STREAM); // отправляем её в терминал (для контроля пакета)

If (buffer[0]==0x0A){
If (buffer[1]=='K') // если символ "K", значит наш пакет

If (buffer[2]=='U') { // если символ "U", значит кнопка "UP"
OUTPUT_HIGH(PIN_A0);}
If (buffer[2]=='D'){// если символ "D", значит кнопка "DOWN"
OUTPUT_HIGH(PIN_A1);}
If (buffer[2]=='S'){// если символ "S", значит кнопка "SELECT CANAL"
OUTPUT_HIGH(PIN_B4);}
If (buffer[2]=='P'){// если символ "P", значит кнопка "POWER ON/OFF"
OUTPUT_HIGH(PIN_B5);}
}
enable_interrupts(GLOBAL);
}

void main()
{ setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// enable_interrupts(INT_TBE);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

buffer[0]=0;
buffer[1]=0;
buffer[2]=0;
buffer[3]=0;
buffer[4]=0;

while(1){
DELAY_MS(100);
OUTPUT_LOW(PIN_A0);
OUTPUT_LOW(PIN_A1);
OUTPUT_LOW(PIN_B4);
OUTPUT_LOW(PIN_B5);
}
}

 

Че-то не прицепилось.... вот собственно проектик.

238655.zip

 

Sergey_Samara: правильно ли я работаю с прерываниями?
Формально, может и правильно (я не работаю с CSS, про тонкости могу не знать), есть замечание по сути.
Не очень классно заниматься разбором строки в прерываниях. Сейчас может работать, а при разрастании программы - нет. Ошибки при перекрытии прерываний не очень легко выловить. Считали буфер и выходим. А разбор (который, возможно, лучше делать не побайтным ручным сравнением а чем-то вроде strcmp) уже в фоне.

 

я тоже не знаю ццс. но - где обработка ошибок -на отсутствие стопового бита и переполнение буфера ?
clear_interrupt(int_RDA); - какой флаг Вы здесь сбрасываете и зачем ?

 

urry: clear_interrupt(int_RDA); - какой флаг Вы здесь сбрасываете и зачем ?
Тут как раз понятно. эта функция вызывается по прерыванию RDA (по большому счету пофиг, что это значит), это прописано директивой #int_RDA. Вызвавшее прерывание и сбрасывается, чтобы снова можно было сюда зайти не сразу после выхода, а когда прерывание случится. Эт нормально.

 

rfc: Не очень классно заниматься разбором строки в прерываниях
Спасибо за конструктивное замечание - обязательно учту.

urry: какой флаг Вы здесь сбрасываете и зачем ?
Вот перевод функции clear_interrupt( ) из хелпа компилятора:
Очищает флаг прерывания для данного уровня. Эта функция проектируется для использования со специфическим прерыванием, поэтому исключая уровень GLOBAL как возможный параметр. Некоторые чипы, которые имеют прерывание на изменении для индивидуальных выводов, позволяют выводу быть указанным подобно INT_RA1.
Т.е. это сброс флага int_RDA прерывания по приему. Собственно и вопрос правильно ли я делаю?
Дальше, больше...)))
Вообще как производить обработку нескольких прерываний для PIC, например есть прерывание от таймера, внешнее прерывание и прерывание по приему через USART, можно в общих чертах?