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

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

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


» РАДИОБЛОГИ
Проверка жидкокристаллического дисплея 1602 (HD44780)
ЭВМ «Таймыр»
Переделка USB паяльника с Али-экспресс
Простой индикатор напряжения автомобильного АКБ на светодиодах
Импульсный блок питания на одном транзисторе
Дополнительная батарея для продления времени работы блютус наушников
Еще раз про ЛУТ технологию
Переделка многооборотного подстрочного резистора в регулируемый



Схема управления 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 - Прочитали: 1614

        
Ваши комментарии к материалу
1 Tygra   (07.04.2019 09:22)
Что такое 8SG ?

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



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

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