-
Notifications
You must be signed in to change notification settings - Fork 0
/
CODE.C
162 lines (139 loc) · 3.56 KB
/
CODE.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#define PWM_MIN_DUTY 80
#define PWM_START_DUTY 200
#include <stdint.h>
void AH_BL();
void AH_CL();
void BH_CL();
void BH_AL();
void CH_AL();
void CH_BL();
void bldc_move();
uint8_t bldc_step = 0;
uint16_t motor_speed, i, j;
void Interrupt()
{
// BEMF debounce
int8_t j;
for(j = 0; j < 10; j++) {
if(bldc_step & 1) {
if(!C1OUT_bit) j -= 1;
}
else {
if(C1OUT_bit) j -= 1;
}
}
bldc_move();
C1ON_bit = 1; // clear the mismatch condition
C1IF_bit = 0; // Clear comparator 1 interrupt flag bit
}
void bldc_move() // BLDC motor commutation function
{
switch(bldc_step){
case 0:
AH_BL();
CM1CON0 = 0xA2; // Sense BEMF C (pin RA3 positive, RB3 negative)
break;
case 1:
AH_CL();
CM1CON0 = 0xA1; // Sense BEMF B (pin RA3 positive, RA1 negative)
break;
case 2:
BH_CL();
CM1CON0 = 0xA0; // Sense BEMF A (pin RA3 positive, RA0 negative)
break;
case 3:
BH_AL();
CM1CON0 = 0xA2; // Sense BEMF C (pin RA3 positive, RB3 negative)
break;
case 4:
CH_AL();
CM1CON0 = 0xA1; // Sense BEMF B (pin RA3 positive, RA1 negative)
break;
case 5:
CH_BL();
CM1CON0 = 0xA0; // Sense BEMF A (pin RA3 positive, RA0 negative)
break;
}
bldc_step++;
if(bldc_step >= 6)
bldc_step = 0;
}
// set PWM1 duty cycle function
void set_pwm_duty(uint16_t pwm_duty)
{
CCP1CON = ((pwm_duty << 4) & 0x30) | 0x0C;
CCPR1L = pwm_duty >> 2;
}
// main function
void main()
{
ANSEL = 0x10; // configure AN4 (RA5) pin as analog
PORTD = 0;
TRISD = 0;
// ADC module configuration
ADCON0 = 0xD0; // select analog channel 4 (AN4)
ADFM_bit = 0;
INTCON = 0xC0; // enable global and peripheral interrupts
C1IF_bit = 0; // clear analog coparator interrupt flag bit
// PWM
CCP1CON = 0x0C; // configure CCP1 module as PWM with single output & clear duty cycle 2 LSBs
CCPR1L = 0; // clear duty cycle 8 MSBs
// Timer2 module configuration for PWM frequency of 19.53kHz & 10-bit resolution
TMR2IF_bit = 0; // clear Timer2 interrupt flag bit
T2CON = 0x04; // enable Timer2 module with presacler = 1
PR2 = 0xFF; // Timer2 preload value = 255
// Motor start
set_pwm_duty(PWM_START_DUTY); // Set PWM duty cycle
i = 5000;
while(i > 100)
{
j = i;
while(j--) ;
bldc_move();
i = i - 50;
}
ADON_bit = 1;
C1IE_bit = 1; // enable analog coparator interrupt
while(1)
{
GO_DONE_bit = 1; // start analog-to-digital conversion
delay_ms(50); // wait 50 ms
motor_speed = (ADRESH << 2) | (ADRESL >> 6); // read ADC registers
if(motor_speed < PWM_MIN_DUTY)
motor_speed = PWM_MIN_DUTY;
set_pwm_duty(motor_speed); // set PWM duty cycle
}
}
void AH_BL()
{
CCP1CON = 0; // PWM off
PORTD = 0x08;
PSTRCON = 0x08; // PWM output on pin P1D (RD7), others OFF
CCP1CON = 0x0C; // PWM on
}
void AH_CL()
{
PORTD = 0x04;
}
void BH_CL()
{
CCP1CON = 0; // PWM off
PORTD = 0x04;
PSTRCON = 0x04; // PWM output on pin P1C (RD6), others OFF
CCP1CON = 0x0C; // PWM on
}
void BH_AL()
{
PORTD = 0x10;
}
void CH_AL()
{
CCP1CON = 0; // PWM off
PORTD = 0x10;
PSTRCON = 0x02; // PWM output on pin P1B (RD5), others OFF
CCP1CON = 0x0C; // PWM on
}
void CH_BL()
{
PORTD = 0x08;
}