Схема управления 2 ШИМ + 8 SG на PIC18F2550 - РАДИОСХЕМЫ

     простые интересные РАДИОСХЕМЫ сделанные своими руками

» ДАТАШИТ
Например: TDA2050


» РАДИОБЛОГИ
Схема управления 2 ШИМ + 8 SG на PIC18F2550
Простой ночник на светодиодах
Индукционный нагреватель для плавки и закалки металла своими руками
Простейший лазертаг
Тестер источников питания или разрядник АКБ
Стабилизатор тока для паяльника
Вольтметр с растянутой шкалой. Расчёт диапазона измерений
Самодельная штанга для металлодетектора



Схема управления 2 ШИМ + 8 SG на PIC18F2550

Всем доброго времени суток. На сайте "Радиосхемы" выложено немало интересного и полезного в плане схемотехники, готов тоже поделиться своими наработками с радиолюбителями. Вот принципиальная схема управления 2 ШИМ (широтно-импульсная модуляция) + 8 SG на микроконтроллере PIC18F2550.

Код программы написан на mikroC

// Upravlenie #define CCP2_RC1 // Вывод ШИМ №1. #define CCP1_RC2 // Вывод ШИМ №2. #define dv1 LATB.F0 // Направление двигателя №1. #define dv2 LATB.F1 // Направление двигателя №2. #define dv1_t TRISB.F0 // Направление вывода двигателя №1. #define dv2_t TRISB.F1 // Направление вывода двигателя №2. #define SG1 LATB.F7 // Вывод руля №1. #define SG2 LATB.F6 // Вывод руля №2. //#define SG3 LATB.F5 // Вывод руля №3. //#define SG4 LATB.F4 // Вывод руля №4. //#define SG5 LATB.F3 // Вывод руля №5. //#define SG6 LATB.F2 // Вывод руля №6. //#define SG7 LATB.F1 // Вывод руля №7. //#define SG8 LATB.F0 // Вывод руля №8. #define SG1_T TRISB.F7 // Направление вывода руля №1. #define SG2_T TRISB.F6 // Направление вывода руля №2. //#define SG3_T TRISB.F5 // Направление вывода руля №3. //#define SG4_T TRISB.F4 // Направление вывода руля №4. //#define SG5_T TRISB.F3 // Направление вывода руля №5. //#define SG6_T TRISB.F2 // Направление вывода руля №6. //#define SG7_T TRISB.F1 // Направление вывода руля №7. //#define SG8_T TRISB.F0 // Направление вывода руля №8. #define bufAdd 0x100 char buf[10] absolute bufAdd; // Буфер приемника USART. char myUartStep; char temp, step; #define sg1_data buf[1] // Значение руля №1. #define sg2_data buf[2] // Значение руля №2. #define ccp1_data buf[3] // Значение ШИМ №1. #define ccp2_data buf[4] // Значение ШИМ №2. #define PeriodCCPx 0xFB #define SG_Timer0 #define UartFSR_Num 2 #define ReadIf MyStatus.F0 #define ReadEnd MyStatus.F1 #define StatSG MyStatus.F2 #include "built_in.h" #include "Delay.h" #include "Шим-2.h" #define nop1 asm{NOP} //#include "PIC18_EEPROM.h" #include "PIC18_EUSART.h" void interrupt(){ // Прерывания. if_SgTmr // SG signal. else myRCIF // Прием по Eusart. else if(PIR1.TMR1IF){ if(schim1)schim1--; else dv1 = 0; if(schim2)schim2--; else dv2 = 0; PR2 = PeriodCCPx; PIR1.TMR1IF = 0; } } void main() { ADCON2 = 0x2C; ADCON1 = 0x0E; // ADC0, ADCON0 = 0; OSCCON = 0x63; // Задаем скорость процессора. // Инициализация выводов управления. LATA = 0; LATB = 0; LATC = 0; TRISA = 0xFF; dv1_t = 0; dv2_t = 0; // TRISB = 0xFF; TRISC = 0xB8; myUartInit; // Инициализация модуля UART (9600 bps) CCPxInit(); // Инициализация ШИМ. TMR1H = 0xFF; TMR1L = 0xFF; T1CON = 0xB1; PIE1.TMR1IE = 1; // Разрешить прерывания от TMR1. INTCON.F7 = 1; // Разрешить все прерывания. INTCON.F6 = 1; // Разрешить все прерывания. // Основной цикл программы. Uart_W_Text("Start!\r"); while(1){ if(buf[0] && !myUartStep){ if((FSRU - bufAdd) > 0) sgt[1] = SG_Val(buf[0]); if((FSRU - bufAdd) > 1) { if(buf[1].F7){dv1 = 0; schim1 = buf[1] << 1;} else{dv1 = 1; schim1 = ~(buf[1] << 1);} } if((FSRU - bufAdd) > 2) sgt[2] = SG_Val(buf[2]); if((FSRU - bufAdd) > 3) { if(buf[3].F7){dv2 = 0; schim2 = buf[3] << 1;} else{dv2 = 1; schim2 = ~(buf[3] << 1);} } PR2 = PeriodCCPx; // Задаем период ШИМ. buf[0] = 0; FSRU = bufAdd; SG_Start; } if(!ADCON0.F1){ if(temp != ADRESH){ temp = ADRESH; Uart_W_Text("VDD-"); Uart_W_16(temp); Uart_W(13); } ADCON0 = 3; } } } Библиотека ШИМ: #ifndef PredelCCPx #define PredelCCPx 3 // Пределитель таймера 1:16. #endif #ifndef PeriodCCPx #define PeriodCCPx 0xF0 // Период ШИМ. #endif #define TimerCCPx T2CON.TMR2ON // Бит вкл./выкл. Таймера. #define TimerCCPxON TimerCCPx = 1 // Включение Таймера. #define TimerCCPxOF TimerCCPx = 0 // Выключение Таймера. #define schim1 SchIM1 #define SchIM1 CCPR1L #define schim2 SchIM2 #define SchIM2 CCPR2L // Прерывания таймера. #if defined (SG_Timer0) #define TMRL TMR0L #define TMRH TMR0H #define SG_TimerOnOf T0CON.TMR0ON #define SG_TimerOn T0CON.TMR0ON = 1 #define SG_TimerOf T0CON.TMR0ON = 0 #define SG_TimerIE INTCON.TMR0IE #define SG_TimerIF INTCON.TMR0IF #define SG_TimerCon T0CON = 8 #elif defined (SG_Timer1) #define TMRL TMR1L #define TMRH TMR1H #define SG_TimerOnOf T1CON.TMR1ON #define SG_TimerOn T1CON.TMR1ON = 1 #define SG_TimerOf T1CON.TMR1ON = 0 #define SG_TimerIE PIE1.TMR1IE #define SG_TimerIF PIR1.TMR1IF #define SG_TimerCon T1CON = 0x80 #elif defined (SG_Timer3) #define TMRL TMR3L #define TMRH TMR3H #define SG_TimerOnOf T3CON.TMR3ON #define SG_TimerOn T3CON.TMR3ON = 1 #define SG_TimerOf T3CON.TMR3ON = 0 #define SG_TimerIE PIE2.TMR3IE #define SG_TimerIF PIR2.TMR3IF #define SG_TimerCon T3CON = 0x80 #else #error Не определен таймер - SG. #endif #define if_SgTmr if(SG_TimerIE && SG_TimerIF){SgTmrIf(); SG_TimerIF = 0;} #if defined (SG8) int sgt[9]; #elif defined (SG7) int sgt[8]; #elif defined (SG6) int sgt[7]; #elif defined (SG5) int sgt[6]; #elif defined (SG4) int sgt[5]; #elif defined (SG3) int sgt[4]; #elif defined (SG2) int sgt[3]; #elif defined (SG1) int sgt[2]; #endif char SG_step; #define SG_Start {SG_step = 50; SG_TimerIE = 1; SG_TimerOn;} #define SG_Val(zn) ~(((int)zn << 3)+ 484) void SgTmrIf(){ #ifdef SG1 if(SG1){ SG1 = 0; #ifdef SG2 TMRH = hi(sgt[2]); TMRL = lo(sgt[2]); SG2 = 1; } else if(SG2){ SG2 = 0; #ifdef SG3 TMRH = hi(sgt[3]); TMRL = lo(sgt[3]); SG3 = 1; } else if(SG3){ SG3 = 0; #ifdef SG4 TMRH = hi(sgt[4]); TMRL = lo(sgt[4]); SG4 = 1; } else if(SG4){ SG4 = 0; #ifdef SG5 TMRH = hi(sgt[5]); TMRL = lo(sgt[5]); SG5 = 1; } else if(SG5){ SG5 = 0; #ifdef SG6 TMRH = hi(sgt[6]); TMRL = lo(sgt[6]); SG6 = 1; } else if(SG6){ SG6 = 0; #ifdef SG7 TMRH = hi(sgt[7]); TMRL = lo(sgt[7]); SG7 = 1; } else if(SG7){ SG7 = 0; #ifdef SG8 TMRH = hi(sgt[8]); TMRL = lo(sgt[8]); SG8 = 1; } else if(SG8){ SG8 = 0; #endif // #ifdef SG8 #endif // #ifdef SG7 #endif // #ifdef SG6 #endif // #ifdef SG5 #endif // #ifdef SG4 #endif // #ifdef SG3 #endif // #ifdef SG2 TMRH = hi(sgt[0]); TMRL = lo(sgt[0]); if(SG_step)SG_step--; } else{ TMRH = hi(sgt[1]); TMRL = lo(sgt[1]); SG1 = 1; } #else SG_step = 0; #endif // #ifdef SG1 if(!SG_step){ SG_TimerIE = 0; // Запретить прерывания. SG_TimerOf; // Остановить таймер. } } void SgInit(){ #ifdef SG1_T SG1_T = 0; // Направление вывода SG-1. sgt[1] = ~1500; // Начальное положение SG-1. #ifdef SG2_T SG2_T = 0; // Направление вывода SG-2. sgt[2] = ~1500; // Начальное положение SG-2. #ifdef SG3_T SG3_T = 0; // Направление вывода SG-3. sgt[3] = ~1500; // Начальное положение SG-3. #ifdef SG4_T SG4_T = 0; // Направление вывода SG-4. sgt[4] = ~1500; // Начальное положение SG-4. #ifdef SG5_T SG5_T = 0; // Направление вывода SG-5. sgt[5] = ~1500; // Начальное положение SG-5. #ifdef SG6_T SG6_T = 0; // Направление вывода SG-6. sgt[6] = ~1500; // Начальное положение SG-6. #ifdef SG7_T SG7_T = 0; // Направление вывода SG-7. sgt[7] = ~1500; // Начальное положение SG-7. #ifdef SG8_T SG8_T = 0; // Направление вывода SG-8. sgt[8] = ~1500; // Начальное положение SG-8. sgt[0] = ~8000; // Пауза после SG-8. #else // #ifdef SG8_T sgt[0] = ~9500; // Пауза после SG-7. #endif // #ifdef SG8_T #else // #ifdef SG7_T sgt[0] = ~11000; // Пауза после SG-6. #endif // #ifdef SG7_T #else // #ifdef SG6_T sgt[0] = ~12500; // Пауза после SG-5. #endif // #ifdef SG6_T #else // #ifdef SG5_T sgt[0] = ~14000; // Пауза после SG-4. #endif // #ifdef SG5_T #else // #ifdef SG4_T sgt[0] = ~15500; // Пауза после SG-3. #endif // #ifdef SG4_T #else // #ifdef SG3_T sgt[0] = ~17000; // Пауза после SG-2. #endif // #ifdef SG23_T #else // #ifdef SG2_T sgt[0] = ~18500; // Пауза после SG-1. #endif // #ifdef SG2_T #endif // #ifdef SG1_T SG_TimerCon; // Настройка таймера SG. SG_TimerOn; // Включить таймер. SG_TimerIE = 1; // Резрешить прерывания. SG_step = 50; // Кол-во тактов на SG. } void CCPxInit(){ #ifdef SG1 SgInit(); // Инициализация SG. #endif PR2 = PeriodCCPx; // Задаем период ШИМ. schim1 = 10; schim2 = 10; // Обнуляем длительность ШИМ. TRISC.RC2 = 0; // Настраиваем выводы ШИМ. #if defined (CCP2_RC1) TRISC.RC1 = 0; #elif defined (CCP2_RB3) TRISC.RB3 = 0; #else #error "Не определен вывод ШИМ2 (CCP2_RC1 или CCP2_RB3)" #endif T2CON &= 0xF8; // Настройка TMR2. T2CON |= PredelCCPx; // Настройка TMR2. TimerCCPxON; // Включение Таймера. CCP1CON = 0x0C; // Включение ШИМ1. CCP2CON = 0x0C; // Включение ШИМ2. } Библиотека PIC18_EUSART: char Uart_R(){int i = 0; while(--i){ if(PIR1.RCIF){ R0 = RCREG; if(RCSTA.F1){RCSTA.F4 = 0; RCSTA.F4 = 1;} return; } } return 0; } #define Uart_W(zn) {while(!TXSTA.TRMT); TXREG = zn;} // while(!PIR1.TXIF); void Uart_W_Text(char *zn){ FSR0 = zn; while(INDF0){Uart_W(POSTINC0);} } void Uart_W_16(char zn){char zn1; zn1 = ((zn >> 4) & 0x0F) + 0x30; if(zn1 > 0x39)zn1 += 7; Uart_W(zn1); zn1 = (zn & 0x0F) + 0x30; if(zn1 > 0x39)zn1 += 7; Uart_W(zn1); } void UartMod(){ SSPCON1.SSPEN = 0; Delay_ms_5; // Отключить модуль SSP. TRISC.F6 = 0; TRISC.F7 = 1; // Настроить порты. RCSTA.SPEN = 1; Delay_ms_5; // Включить модуль UART. } void Uart_Init_9600(){ BAUDCON.F3 = 1; //SPBRGH = 0; SPBRG = 103; TXSTA.F2 = 1; TRISC.F7 = 1; TRISC.F6 = 0; TXSTA.F5 = 1; RCSTA = 144; Delay_ms_5; while(PIR1.RCIF)Uart_R(); } // Прием по Eusart в буфер (buf). #ifndef UartFSR_Num #define UartFSR_Num 2 #endif #if (UartFSR_Num == 0) #define FSRU FSR0 #define FSRUH FSR0H #define FSRUL FSR0L #define INDFU INDF0 #define POSTINCU POSTINC0 #define POSTDECU POSTDEC0 #define PREINCU PREINC0 #elif (UartFSR_Num == 1) #define FSRU FSR1 #define FSRUH FSR1H #define FSRUL FSR1L #define INDFU INDF1 #define POSTINCU POSTINC1 #define POSTDECU POSTDEC1 #define PREINCU PREINC1 #elif (UartFSR_Num == 2) #define FSRU FSR2 #define FSRUH FSR2H #define FSRUL FSR2L #define INDFU INDF2 #define POSTINCU POSTINC2 #define POSTDECU POSTDEC2 #define PREINCU PREINC2 #endif // Инициализация модуля UART (9600 bps) // Запуск TMR2 с мах. постделителем. // Разрешить прерывания от TMR2. // Разрешить прерывания по приему Usart #define myUartInit {FSRU = bufAdd; INDFU =0; \ Uart_Init_9600(); T2CON |= 0x78; \ PIE1.TMR2IE = 1; PIE1.RCIE = 1; \ T2CON.TMR2ON = 1;} #define myRCIF if(PIR1.RCIF){ \ int x; INDFU = RCREG; \ if(RCSTA.F1){RCSTA.F4 = 0; RCSTA.F4 = 1;} \ myUartStep = 0x20; x = bufAdd + sizeof(buf); \ if(FSRU < x) FSRU++; INDFU = 0; \ PIR1.TMR2IF = 0;} \ else if(PIR1.TMR2IF){ \ if(myUartStep)myUartStep--; \ PIR1.TMR2IF = 0;}

dimitrijsidorov - 06.01.2019 - Прочитали: 394

        
Ваши комментарии к материалу
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
» ПОИСК СХЕМ



» РАДИОЭЛЕМЕНТЫ

Группа вконтакте Канал ютуб Группа в фэйсбук Мобильная версия © 2010-2019, "Радиосхемы". Все права защищены. Почта