/
main.c
161 lines (132 loc) · 5.27 KB
/
main.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
/*
* File: main.c
* Author: wenceslaoshaw-cortezshaw-cortez
*
* Created on September 11, 2014, 2:20 PM
*/
/*******************************************************************************
** Files to Include
*******************************************************************************/
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <delays.h>
#include <math.h>
#include "system.h"
#include "user.h"
#include "globals.h" // Holds global variables
#include "timers.h"
#include "pwm.h"
#include "config.h"
/*******************************************************************************
** GLobals and #Defines
*******************************************************************************/
#define USE_OR_MASKS // For using peripheral library
#define EncoderCount 0x0BDC// Load value to count 62500 times to TMR0 overflow (25ms)
#define EncoderTS 1.0 // Total sample time for RPS calculation (s). EncoderTS = EncoderCount*EncoderTScount
#define EncoderTScount 20 // Number of times to overflow TMR0 until EncoderTS is timed
int CHA; // Preserve state of Channel A from encoder
int CHB; // Preserve state of Channel B from encoder
int OLD_ROT; // Preserve state of current rotation in case encoder bounces
int CCWTurn; // Counts how many CCW turns have occured on the encoder
int CWTurn; // Counts how many CW turns have occured on the encoder
const int CountPerRev = 500;// Total counts per revolution (based on encoder specs)
const int EncoderPoll = 128; // Total number of counts until direction of encoder rotation is determined
double PartialRot; // Holds fraction of revolution that has occured
double RPS; // Holds rev/s value
const int QEM[16] = {0,-1,1,2,1,0,2,-1,-1,2,0,1,2,1,-1,0};
int CHAcount;
int TMR0count; // Counts how many timers TMR0 overflows to reach EncoderTS
/*******************************************************************************
** Main
*******************************************************************************/
int main(void) {
//--------------
// Initialization
char LCDinit[] = {0x33,0x32,0x28,0x01,0x0c,0x06,0x00}; //Array holding initialization string for LCD
char Msg1[] = {0x84,'C','U','N','T','\0'};
char Msg2[] = {0xC5,'R','P','S','\0'};
char Msg3[10]; // Msg for displaying RPS to LCD (size 10 in case dealing with large numbers)
InitApp(); // Initialize Ports
DisplayLCD(LCDinit,1); // Initialize LCD
//--------------
// Message on LCD
DisplayLCD(Msg1,0); // Display message on LCD
DisplayLCD(Msg2,0); // Display message 2
//--------------
// Initialize encoder variables
CHA = PORTBbits.RB5; // Initialize channel A
CHB = PORTBbits.RB4; // Initialize channel B
OLD_ROT = 0; // Initialize state of rotation
CCWTurn = 0; // Initialize CCW count
CWTurn = 0; // Initialize CW count
RPS = 0.0; // Initialize RPS value
CHAcount = 0; // Channel A counter
//--------------
// Setup PWM cycle to motor
PR2 = 0x9B; // Open pwm1 at period = 1 ms
CCP1CONbits.DC1B1 = 0; // Set duty cycle of pwm1
CCP1CONbits.DC1B0 = 0; // ...
CCPR1L = 0b00000100; // ...
//-------------
// Set timer and interrupts
TMR0count = 0; // Set counter for TMR0
WriteTimer0(EncoderCount);// Load Timer0
InitInterrupts(); // Initialize timer interrupts for Port B encoder
//--------------
// Loop phase: Display RPS on LCD
while(1)
{
WaitHalfSec();
WriteLCD(0xC0,5,RPS,Msg3); // Display RPS on LCD
}
//--------------
// Exit main
CloseTimer0();
return (EXIT_SUCCESS);
}
/*******************************************************************************
** Interrupt Service Routines
*******************************************************************************/
//------------------
// High Priority Interrupts
void high_priority interrupt high_isr(void)
{
/* TODO Add High Priority interrupt routine code here. */
/* Determine which flag generated the interrupt */
}
//-----------------
// Low Priority Interrupts
void low_priority interrupt low_isr(void)
{
if(INTCONbits.RBIF == 1)
{
//ReadEncoder(); // Sample encoder
if (CHA == PORTBbits.RB5)
{
}
else
{
CHAcount++; // Count Channel A pulses
}
INTCONbits.RBIF = 0; // Clear Interrupt Flag
}
else if (INTCONbits.TMR0IF == 1)
{
if (TMR0count == EncoderTScount)
{
//RPS = (fabs(PartialRot))/EncoderTS; // Compute rps by #rotations/sampletime = rev/sec
//PartialRot = 0.0; // Clear revolution value
RPS = ((double)CHAcount)/CountPerRev; // In 0.5 seconds counting half of 500 pulses
CHAcount = 0;
TMR0count = 0; // Clear TMR0 counter
}
else
{
TMR0count++; // Increment TMR0 counter
}
WriteTimer0(EncoderCount); // Reload timer0
INTCONbits.TMR0IF = 0; // Clear Interrupt Flag
}
}