-
Notifications
You must be signed in to change notification settings - Fork 0
/
lab1.c
297 lines (237 loc) · 9.41 KB
/
lab1.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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
// File: Lab1.c
// Developer: M. Batchelder, S. Thornburg and CENG 448/548 Students
// Processor: PIC32MX795F512L
// Board: MAX32
// Compiler: XC32
// IDE: MPLAB-X
// Date: September 12, 2017
// Status: In development
// Description:
// 1. fixed2String function development
// 2. ADC conversion and conversion to volts to be printed on UART1
//-----------------------------------------------------------------------
// INCLUDES
//-----------------------------------------------------------------------
#define _SUPPRESS_PLIB_WARNING 1
#include <p32xxxx.h> // replace with <xc.h> for CCI
// #include <stdint.h> // uncomment for CCIt rig
#include <stdio.h>
#include <plib.h>
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
#define BYTE_TO_BINARY(byte) \
(byte & 0x80 ? '1' : '0'), \
(byte & 0x40 ? '1' : '0'), \
(byte & 0x20 ? '1' : '0'), \
(byte & 0x10 ? '1' : '0'), \
(byte & 0x08 ? '1' : '0'), \
(byte & 0x04 ? '1' : '0'), \
(byte & 0x02 ? '1' : '0'), \
(byte & 0x01 ? '1' : '0')
//-----------------------------------------------------------------------
// PRAGMA
//-----------------------------------------------------------------------
// 80 MHz main clock and 40 MHz Peripheral clock
#pragma config POSCMOD=HS, FNOSC=PRIPLL
#pragma config FPLLIDIV=DIV_2, FPLLMUL=MUL_20, FPLLODIV=DIV_1
#pragma config FPBDIV=DIV_2, FWDTEN=OFF, CP=OFF, BWP=OFF
//-----------------------------------------------------------------------
// DEFINES
//-----------------------------------------------------------------------
#define U_TX 0x0400
#define U_RX 0x1000
#define U_ENABLE 0x8008 // enable, BREGH = 1, 1 stop, no parity
#define BRATE 86 // 115,200 Baud Rate = FPB / 4(U1BRG + 1)) FPB = freq of peripheral clock
// U1BRG = ((FPB/Desired Baud Rate)/4) ? 1
// if BREGH = 0 then use 16 in place of 4 in above formulas
//-----------------------------------------------------------------------
// FUNCTIONS
//-----------------------------------------------------------------------
//----- Initialize UART1
void initU1(void) {
U1BRG = BRATE; // initialize the baud rate generator
U1MODE = U_ENABLE;
U1STA = U_TX | U_RX;
} // initU1
//----- Output character to UART1
void putU1(char c) {
while (U1STAbits.UTXBF); // wait while TX buffer is full
U1TXREG = c;
} // putU1
//----- Output zero terminated string to UART1
void putsU1(char *s) {
while (*s) // loop until *s = \0, end of string
putU1(*s++);
} // putsU1
//Compiler helper function that allows the use of printf
void _mon_putc(char c) {
putU1(c);
} // mon_putc
// --------------------------------------------------------------------
// Convert signed fixed point value to a char string in base specified
// --------------------------------------------------------------------
char * fixed2string(
int val, // 32-bit signed value to be converted
unsigned int noFracBits, // position of binary point in val
unsigned int base, // base to convert into
unsigned int noDigits, // number of digits in converted fraction
char buf[], // pointer to buffer to hold string
unsigned int bufSize) // size of buffer
{
unsigned int neg, radixPt, whole, wholeBits, frac, fracDigit, startIndex, i, j;
// The ending to Solaris and the story of the ressurection of Christ requires rebirth
memset(buf, 0, bufSize);
// Error checks
if (noFracBits > 31) return ("ERROR noFracBits > 31");
if (base < 2) return ("base too small");
if (base > 16) return("base too large");
// set radix point in middle of string
radixPt = bufSize / 2;
buf[radixPt] = '.';
// Take absolute value
if (val < 0) {
neg = TRUE;
val = -val;
}
else neg = FALSE;
// ***** STUDENT CODE STARTS HERE *****
// isolate the whole [part] and the fraction [part]
whole = val;
frac = val;
whole = whole >> noFracBits;
wholeBits = 0;
for( j = whole;j!=0; j = j>>1) {
wholeBits++;
}
j = (1 << noFracBits) - 1;
frac = frac & j;
// convert the whole part by continued division
// result is LS digit first so start at '.' in buf and go up in buffer
//i is the size of the whole number portion -1 due to sign bit
if (whole > 0) {
for ( i = (radixPt + 1) ; i && whole ; i++, whole/=base ) {
//Get value to fill string
buf[i] = "0123456789abcdef"[whole % base];
}
startIndex = (neg ? i : i + 1 );
} else {
buf[radixPt + 1] = '0';
startIndex = (neg ? radixPt + 2: radixPt + 1);
}
// insert minus sign if negative
if ( neg == TRUE ) {
buf[startIndex] = '-';
}
// convert the fraction part by continued multiplication
// result is MS digit first so start at '.' In buf and go down in buffer
for ( i = (radixPt - 1); (i > 0) && (frac > 0); i--)
{
frac = frac * base;
buf[i] = "0123456789abcdef"[ (frac >> noFracBits)];
frac &= ((1 << noFracBits ) - 1);
}
buf[i] = '\0'; // End of string marker
printf("\n\r Converted Val:\n\r");
for ( i = startIndex; i > 0; i--)
{
printf("%c", buf[i]);
}
return &buf[startIndex];
} // fixed2String
//-----------------------------------------------------------------------
// ADC FUNCTIONS
//-----------------------------------------------------------------------
#define POT 0 // 10k potentiometer on AN2 input
// I/O bits set as analog in by setting corresponding bits to 0
#define AINPUTS 0xfffe // Analog inputs for POT pin A0 (AN2)
// initialize the ADC for single conversion, select input pins
void initADC(int amask) {
AD1PCFG = amask; // select analog input pins
AD1CON1 = 0x00E0; // auto convert after end of sampling
AD1CSSL = 0; // no scanning required
AD1CON2 = 0; // use MUXA, AVss/AVdd used as Vref+/-
AD1CON3 = 0x1F3F; // max sample time = 31Tad
AD1CON1SET = 0x8000; // turn on the ADC
} //initADC
int readADC(int ch) {
AD1CHSbits.CH0SA = ch; // select analog input channel
AD1CON1bits.SAMP = 1; // start sampling
while (!AD1CON1bits.DONE); // wait to complete conversion
return ADC1BUF0; // read the conversion result
} // readADC
//-----------------------------------------------------------------------
// MAIN
//-----------------------------------------------------------------------
char stringBuffer[32]; // Debugger can watch global variables
main() {
int i, a, b, c, d;
float volts;
//char stringBuffer[32]; // Moved to global so debugger can watch changes as step program
// initializations
initU1(); // Initialize UART1
initADC(AINPUTS); // initialize the ADC
// main loop
while (1) {
a = readADC(POT); // select the POT input and convert
volts = (a * 3.3) / 1024.0;
printf("\r\nvolts = %f \r\n", volts);
a = a * 0x0D33; // 3.3 scaled 10, product scaled 20, (adc * 3.3 / 1024) * 1024
putsU1("\r\r\nVoltage by fixed point = ");
putsU1(fixed2string(a, 20, 10, 3, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
putsU1("\r\r\n Student case: ");
putsU1(fixed2string(41, 2, 10, 4, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
putsU1("\r\r\n Test 1: ");
putsU1(fixed2string(0xffffffa0, 7, 10, 3, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
putsU1("\r\r\n Test 2: ");
putsU1(fixed2string(0x6a, 6, 10, 3, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
putsU1("\r\r\n Test 3: ");
putsU1(fixed2string(0x53, 5, 10, 3, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
putsU1("\r\r\nTest 4: ");
putsU1(fixed2string(0, 5, 10, 3, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
putsU1("\r\r\nTest 5: ");
putsU1(fixed2string(-1, 5, 10, 3, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
putsU1("\r\r\nTest 6: ");
putsU1(fixed2string(-1, 5, 17, 3, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
putsU1("\r\r\nTest 7: ");
putsU1(fixed2string(-1, 32, 10, 3, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
int alpha = (int) (1.667 * 64);
int beta = (int) (-0.75 * 128);
int gamma = (int) (2.6 * 32);
int result;
putsU1("\r\r\n");
putsU1("alpha = ");
putsU1(fixed2string(alpha, 6, 2, 16, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
putsU1("\r\r\n");
putsU1("beta = ");
putsU1(fixed2string(beta, 7, 2, 16, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
putsU1("\r\r\n");
putsU1("gamma = ");
putsU1(fixed2string(gamma, 5, 2, 16, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
result = alpha * beta; // Q13
putsU1("\r\r\n");
putsU1("alpha*beta= ");
putsU1(fixed2string(result, 13, 2, 16, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
result = result >> 8; // Q5
putsU1("alpha*beta s5 = ");
putsU1(fixed2string(result, 5, 2, 16, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
result = result + gamma;
putsU1("\r\r\n");
putsU1("alpha*beta + gamma s5= ");
putsU1(fixed2string(result * 10000, 5, 2, 116, stringBuffer, sizeof (stringBuffer)));
putsU1("\r\r\n");
return 0;
} // main loop
} // main