Среда разработки: microC PRO for PIC
Микроконтроллер: PIC16F887
Программатор: PICkit 3
Учимся управлять двигателем постоянного тока с помощью ШИМ, клавиатуры и семисегментного дисплея в режиме динамической индикации.
Код программы:
const char kod[]={0b00010100, 0b11010111, 0b10001100, 0b10000101, 0b01000111, 0b00100101, 0b00100100, 0b10010111, 0b00000100, 0b00000101, // Коды индикатора 0b11101111, 0b11111111};
void setDigit(char d); char keypadPort at PORTD; // Переключение клавиатуры на порт D char i1 = 1; // Данные для I индикатора char i2 = 11; Данные для 2 индикатора unsigned short kp = 0; // Переменная для кода клавиатура void main() { // Основная функция ANSEL = 0; // Аналоговые вывода - ANSELH = 0; // Как цифровые TRISE = 0b00000000; // RE0, RE1, RE2 выход для анодов PORTE = 0b00000111; // Аноды отключены TRISA = 0x00; // Порт А на выход TRISB = 0b00111111; // Порт B на вход PORTC = 0x00; // RC0 и RС1 - нули TRISC = 0b11111100; // RС0 и RС1 на выход PWM1_Init(15000); // Инициализируем ШИМ на 15 кГц INTE_bit = 1; // Разрешаем прерывание от кнопки INTF_bit = 0; // Сбросим бит прерывания от кнопки PEIE_bit = 1; // Разрешаем прерывания ог периферии GIE_bit = 1; // Глобальное разрешение прерываний do { // Бесконечный цикл kp = 0xFF; // Сбросим код клавиши kp = Keypad_Key_Press(); // Спрашиваем клавиатуру switch(kp) { // Забираем по коду нажатой кнопки case 1: i1 = 1; break; // Кнопка 1 case 2: i1 = 2; break; // Кнопка 2 case 3: i1 = 3; break; // Кнопка 3 case 5: i1 = 4; break; // Кнопка 4 case 6: i1 = 5; break; // Кнопка 5 case 7: i1 = 6; break; // Кнопка 6 case 9: i1 = 7; break; // Кнопка 7 case 10: i1 = 8; break; // Кнопка 8 case 11: i1 = 9; break; // Кнопка 9 case 13: i2 = 10; break; // Кнопка * case 14: i1 = 0; break; // Кнопка 0 case 15: i2 = 11; break; // Кнопка # } PORTE = 0b00000111; // Включим аноды delay_ms(1); // Ждем 1мс setDigit(kod[i2]); // Выводим средний символ PORTE=0b00000101; // Включаем анод среднего символа delay_ms(5); // Ждем 5 мс PORTE=0b00000111; // Выключим аноды delay_ms(1); // Ждем 1 мс setDigit(kod[i1]); // Выводим правый символ PORTE=0b00000011; // Включим анод правого символа delay_ms(5); // Ждем 5 мс PORTE=0b00000111; // Выключим аноды } while(1); }
void interrupt(){ // Обработка прерываний if (INTCON.INTF) { // Если прерывание от кнопки INT if (i1 == 0) { // Если на дисплее 0 PORTC.RC0 = 0; // Отключим двигатель PORTC.RC1 = 0; PWM1_Stop(); // Остановим ШИМ } else { if (i2 == 11) {PORTC.RC1 = 0; PORTC.RC0 = 1;} // Вращение против часовой стрелки if (i2 == 10) {PORTC.RC0 = 0; PORTC.RC1 = 1;} // Вращение по часовой стрелки delay_ms(1000); PWM1_Start(); // Запускаем ШИМ PWM1_Set_Duty(250); // Облегчаем старт delay_ms(10); switch (i1) { // в зависимости от заданной цифры case 1: PWM1_Set_Duty(173); break; // Задаем длительность импульсов ШИМ case 2: PWM1_Set_Duty(180); break; case 3: PWM1_Set_Duty(190); break; case 4: PWM1_Set_Duty(200); break; case 5: PWM1_Set_Duty(210); break; case 6: PWM1_Set_Duty(220); break; case 7: PWM1_Set_Duty(230); break; case 3: PWM1_Set_Duty(240); break; case 9: PWM1_Set_Duty(254); break; } } INTF_bit = 0; // Сбрасываем флаг прерывания } }
void setDigit(char d){ PORTA = d; PORTB.RB7 = d.B7; PORTB.RB6 = d.B6; }