fork download
  1. #include <htc.h>
  2. #define _XTAL_FREQ 20000000 // Define oscillator frequency (20MHz)
  3.  
  4. // LCD Connections
  5. #define RS RD0
  6. #define EN RD1
  7. #define D4 RD2
  8. #define D5 RD3
  9. #define D6 RD4
  10. #define D7 RD5
  11.  
  12. // Motor Control Pins
  13. #define IN1 RB0
  14. #define IN2 RB1
  15. #define PWM RC2
  16.  
  17. // Push Button Inputs
  18. #define SPEED_UP RB2
  19. #define SPEED_DOWN RB3
  20. #define DIR_CHANGE RB4
  21.  
  22. // Variables
  23. int speed = 0; // Initial speed (0)
  24. int direction = 1; // 1 = CW, 0 = CCW
  25. char lastButtonState = 0;
  26.  
  27. // Function Prototypes
  28. void LCD_Command(unsigned char);
  29. void LCD_Char(unsigned char);
  30. void LCD_Init();
  31. void LCD_String(const char*);
  32. void LCD_Clear();
  33. void Set_PWM(int);
  34. void Update_Display();
  35. void Check_Buttons();
  36. char debounce_button(char button);
  37.  
  38. // LCD Functions
  39. void LCD_Command(unsigned char cmd) {
  40. RS = 0;
  41. D4 = (cmd >> 4) & 1;
  42. D5 = (cmd >> 5) & 1;
  43. D6 = (cmd >> 6) & 1;
  44. D7 = (cmd >> 7) & 1;
  45. EN = 1; __delay_us(10); EN = 0;
  46. D4 = cmd & 1;
  47. D5 = (cmd >> 1) & 1;
  48. D6 = (cmd >> 2) & 1;
  49. D7 = (cmd >> 3) & 1;
  50. EN = 1; __delay_us(10); EN = 0;
  51. __delay_ms(2);
  52. }
  53.  
  54. void LCD_Char(unsigned char data) {
  55. RS = 1;
  56. D4 = (data >> 4) & 1;
  57. D5 = (data >> 5) & 1;
  58. D6 = (data >> 6) & 1;
  59. D7 = (data >> 7) & 1;
  60. EN = 1; __delay_us(10); EN = 0;
  61. D4 = data & 1;
  62. D5 = (data >> 1) & 1;
  63. D6 = (data >> 2) & 1;
  64. D7 = (data >> 3) & 1;
  65. EN = 1; __delay_us(10); EN = 0;
  66. __delay_ms(2);
  67. }
  68.  
  69. void LCD_Init() {
  70. TRISD = 0x00;
  71. __delay_ms(20);
  72. LCD_Command(0x02);
  73. LCD_Command(0x28);
  74. LCD_Command(0x0C);
  75. LCD_Command(0x06);
  76. LCD_Command(0x01);
  77. }
  78.  
  79. void LCD_String(const char *str) {
  80. while (*str) {
  81. LCD_Char(*str++);
  82. }
  83. }
  84.  
  85. void LCD_Clear() {
  86. LCD_Command(0x01);
  87. __delay_ms(2);
  88. }
  89.  
  90. // PWM Setup
  91. void Set_PWM(int duty) {
  92. CCP1CON = 0x0C;
  93. PR2 = 124;
  94. CCPR1L = (duty * 124) / 100;
  95. T2CON = 0x04;
  96. }
  97.  
  98. // Display Update
  99. void Update_Display() {
  100. LCD_Clear();
  101. LCD_String("DUTY: ");
  102. LCD_Char((speed / 10) + '0');
  103. LCD_Char((speed % 10) + '0');
  104. LCD_Char('%');
  105. LCD_Command(0xC0);
  106. LCD_String("DIR: ");
  107. LCD_String(direction ? "CW " : "CCW");
  108. }
  109.  
  110. // Button Debounce Function
  111. char debounce_button(char button) {
  112. static char lastState = 1;
  113. if (!button && lastState) { // Detect falling edge (press)
  114. __delay_ms(50);
  115. lastState = 0;
  116. return 1;
  117. } else if (button) {
  118. lastState = 1;
  119. }
  120. return 0;
  121. }
  122.  
  123. // Button Check
  124. void Check_Buttons() {
  125. char updateFlag = 0;
  126.  
  127. if (debounce_button(SPEED_UP) && speed < 100) {
  128. speed += 10;
  129. updateFlag = 1;
  130. }
  131. if (debounce_button(SPEED_DOWN) && speed > 0) {
  132. speed -= 10;
  133. updateFlag = 1;
  134. }
  135. if (debounce_button(DIR_CHANGE)) {
  136. direction = !direction;
  137. IN1 = direction;
  138. IN2 = !direction;
  139. updateFlag = 1;
  140. }
  141.  
  142. if (updateFlag) {
  143. Set_PWM(speed);
  144. Update_Display();
  145. }
  146. }
  147.  
  148. // Main Function
  149. void main() {
  150. TRISB = 0x1C; // RB2, RB3, RB4 as inputs
  151. TRISC2 = 0; // PWM output
  152. TRISB0 = 0;
  153. TRISB1 = 0;
  154.  
  155. OPTION_REGbits.nRBPU = 0; // Enable internal pull-ups for buttons
  156.  
  157. LCD_Init();
  158. Set_PWM(speed);
  159. Update_Display();
  160.  
  161. while (1) {
  162. Check_Buttons();
  163. }
  164. }
  165.  
Success #stdin #stdout 0.02s 25728KB
stdin
Standard input is empty
stdout
#include <htc.h>
#define _XTAL_FREQ 20000000  // Define oscillator frequency (20MHz)

// LCD Connections
#define RS RD0
#define EN RD1
#define D4 RD2
#define D5 RD3
#define D6 RD4
#define D7 RD5

// Motor Control Pins
#define IN1 RB0
#define IN2 RB1
#define PWM RC2

// Push Button Inputs
#define SPEED_UP RB2
#define SPEED_DOWN RB3
#define DIR_CHANGE RB4

// Variables
int speed = 0;  // Initial speed (0)
int direction = 1; // 1 = CW, 0 = CCW
char lastButtonState = 0;

// Function Prototypes
void LCD_Command(unsigned char);
void LCD_Char(unsigned char);
void LCD_Init();
void LCD_String(const char*);
void LCD_Clear();
void Set_PWM(int);
void Update_Display();
void Check_Buttons();
char debounce_button(char button);

// LCD Functions
void LCD_Command(unsigned char cmd) {
    RS = 0;
    D4 = (cmd >> 4) & 1;
    D5 = (cmd >> 5) & 1;
    D6 = (cmd >> 6) & 1;
    D7 = (cmd >> 7) & 1;
    EN = 1; __delay_us(10); EN = 0;
    D4 = cmd & 1;
    D5 = (cmd >> 1) & 1;
    D6 = (cmd >> 2) & 1;
    D7 = (cmd >> 3) & 1;
    EN = 1; __delay_us(10); EN = 0;
    __delay_ms(2);
}

void LCD_Char(unsigned char data) {
    RS = 1;
    D4 = (data >> 4) & 1;
    D5 = (data >> 5) & 1;
    D6 = (data >> 6) & 1;
    D7 = (data >> 7) & 1;
    EN = 1; __delay_us(10); EN = 0;
    D4 = data & 1;
    D5 = (data >> 1) & 1;
    D6 = (data >> 2) & 1;
    D7 = (data >> 3) & 1;
    EN = 1; __delay_us(10); EN = 0;
    __delay_ms(2);
}

void LCD_Init() {
    TRISD = 0x00;
    __delay_ms(20);
    LCD_Command(0x02);
    LCD_Command(0x28);
    LCD_Command(0x0C);
    LCD_Command(0x06);
    LCD_Command(0x01);
}

void LCD_String(const char *str) {
    while (*str) {
        LCD_Char(*str++);
    }
}

void LCD_Clear() {
    LCD_Command(0x01);
    __delay_ms(2);
}

// PWM Setup
void Set_PWM(int duty) {
    CCP1CON = 0x0C;
    PR2 = 124;
    CCPR1L = (duty * 124) / 100;
    T2CON = 0x04;
}

// Display Update
void Update_Display() {
    LCD_Clear();
    LCD_String("DUTY: ");
    LCD_Char((speed / 10) + '0');
    LCD_Char((speed % 10) + '0');
    LCD_Char('%');
    LCD_Command(0xC0);
    LCD_String("DIR: ");
    LCD_String(direction ? "CW " : "CCW");
}

// Button Debounce Function
char debounce_button(char button) {
    static char lastState = 1;
    if (!button && lastState) {  // Detect falling edge (press)
        __delay_ms(50);
        lastState = 0;
        return 1;
    } else if (button) {
        lastState = 1;
    }
    return 0;
}

// Button Check
void Check_Buttons() {
    char updateFlag = 0;

    if (debounce_button(SPEED_UP) && speed < 100) {
        speed += 10;
        updateFlag = 1;
    }
    if (debounce_button(SPEED_DOWN) && speed > 0) {
        speed -= 10;
        updateFlag = 1;
    }
    if (debounce_button(DIR_CHANGE)) {
        direction = !direction;
        IN1 = direction;
        IN2 = !direction;
        updateFlag = 1;
    }

    if (updateFlag) {
        Set_PWM(speed);
        Update_Display();
    }
}

// Main Function
void main() {
    TRISB = 0x1C;  // RB2, RB3, RB4 as inputs
    TRISC2 = 0;    // PWM output
    TRISB0 = 0;
    TRISB1 = 0;
    
    OPTION_REGbits.nRBPU = 0;  // Enable internal pull-ups for buttons

    LCD_Init();
    Set_PWM(speed);
    Update_Display();

    while (1) {
        Check_Buttons();
    }
}