1 | /**********************************************************************
|
2 | * © 2006 Microchip Technology Inc.
|
3 | *
|
4 | * FileName: main.c
|
5 | * Dependencies: Header (.h) files if applicable, see below
|
6 | * Processor: dsPIC33FJ256GP710
|
7 | * Compiler: MPLAB® C30 v3.00 or higher
|
8 | * Tested On: dsPIC33FJ256GP710 HP16
|
9 | *
|
10 | * SOFTWARE LICENSE AGREEMENT:
|
11 | * Microchip Technology Incorporated ("Microchip") retains all ownership and
|
12 | * intellectual property rights in the code accompanying this message and in all
|
13 | * derivatives hereto. You may use this code, and any derivatives created by
|
14 | * any person or entity by or on your behalf, exclusively with Microchip's
|
15 | * proprietary products. Your acceptance and/or use of this code constitutes
|
16 | * agreement to the terms and conditions of this notice.
|
17 | *
|
18 | * CODE ACCOMPANYING THIS MESSAGE IS SUPPLIED BY MICROCHIP "AS IS". NO
|
19 | * WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
|
20 | * TO, IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
|
21 | * PARTICULAR PURPOSE APPLY TO THIS CODE, ITS INTERACTION WITH MICROCHIP'S
|
22 | * PRODUCTS, COMBINATION WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
|
23 | *
|
24 | * YOU ACKNOWLEDGE AND AGREE THAT, IN NO EVENT, SHALL MICROCHIP BE LIABLE, WHETHER
|
25 | * IN CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE OR BREACH OF STATUTORY DUTY),
|
26 | * STRICT LIABILITY, INDEMNITY, CONTRIBUTION, OR OTHERWISE, FOR ANY INDIRECT, SPECIAL,
|
27 | * PUNITIVE, EXEMPLARY, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, FOR COST OR EXPENSE OF
|
28 | * ANY KIND WHATSOEVER RELATED TO THE CODE, HOWSOEVER CAUSED, EVEN IF MICROCHIP HAS BEEN
|
29 | * ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
|
30 | * ALLOWABLE BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO
|
31 | * THIS CODE, SHALL NOT EXCEED THE PRICE YOU PAID DIRECTLY TO MICROCHIP SPECIFICALLY TO
|
32 | * HAVE THIS CODE DEVELOPED.
|
33 | *
|
34 | * You agree that you are solely responsible for testing the code and
|
35 | * determining its suitability. Microchip has no obligation to modify, test,
|
36 | * certify, or support the code.
|
37 | *
|
38 | * REVISION HISTORY:
|
39 | *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
40 | * Author Date Comments on this revision
|
41 | *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
42 | * Rob Welch 11/28/06 Original Release
|
43 | *
|
44 | *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
45 | * ADDITIONAL NOTES:
|
46 | * Small, bare bones program to guide designers with UART implementation
|
47 | * To run program, plug DB9 cable to Terminal (9600,8,N,1) -
|
48 | * Data sent from TERMINAL END will be represented as binary equivalent
|
49 | * of ASCII on 7 LSB LEDs of HPC16 Explorer board
|
50 | *
|
51 | * Data is sent from HPC16 by pressing S3 - S6. A single letter will
|
52 | * be transmitted upon each keypress.
|
53 | *
|
54 | * Peripheral Library was not utilized, Bit Addressing was used in order
|
55 | * to show all details involved in initialization of UART.
|
56 | *
|
57 | *
|
58 | * The Processor starts with the Internal oscillator without PLL enabled and then the Clock is switched to PLL Mode.
|
59 | *
|
60 | **********************************************************************/
|
61 | #include <p33FJ256GP710.h>
|
62 |
|
63 | _FOSCSEL(FNOSC_FRC); // Internal FRC oscillator
|
64 | _FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_NONE);
|
65 | // Clock Switching is enabled and Fail Safe Clock Monitor is disabled
|
66 | // OSC2 Pin Function: OSC2 is Clock Output
|
67 | // Primary Oscillator Mode: XT Crystanl
|
68 |
|
69 |
|
70 | #define TRUE 1
|
71 | #define FALSE 0
|
72 |
|
73 | unsigned char S3Flag, S4Flag, S5Flag, S6Flag;
|
74 |
|
75 | void __attribute__ ((interrupt, no_auto_psv)) _U2RXInterrupt(void) {
|
76 | LATA = U2RXREG;
|
77 | IFS1bits.U2RXIF = 0;
|
78 | }
|
79 | void __attribute__ ((interrupt, no_auto_psv)) _U2TXInterrupt(void) {
|
80 | IFS1bits.U2TXIF = 0;
|
81 | }
|
82 |
|
83 | void InitClock() {
|
84 | PLLFBD = 38; // M = 40
|
85 | CLKDIVbits.PLLPOST = 0; // N1 = 2
|
86 | CLKDIVbits.PLLPRE = 0; // N2 = 2
|
87 | OSCTUN = 0;
|
88 | RCONbits.SWDTEN = 0;
|
89 |
|
90 | // Clock switch to incorporate PLL
|
91 | __builtin_write_OSCCONH(0x01); // Initiate Clock Switch to
|
92 | // FRC with PLL (NOSC=0b001)
|
93 | __builtin_write_OSCCONL(0x01); // Start clock switching
|
94 | while (OSCCONbits.COSC != 0b001); // Wait for Clock switch to occur
|
95 |
|
96 | while(OSCCONbits.LOCK != 1) {};
|
97 | }
|
98 |
|
99 | void InitUART2() {
|
100 | // This is an EXAMPLE, so brutal typing goes into explaining all bit sets
|
101 |
|
102 | // The HPC16 board has a DB9 connector wired to UART2, so we will
|
103 | // be configuring this port only
|
104 |
|
105 | // configure U2MODE
|
106 | U2MODEbits.UARTEN = 0; // Bit15 TX, RX DISABLED, ENABLE at end of func
|
107 | //U2MODEbits.notimplemented; // Bit14
|
108 | U2MODEbits.USIDL = 0; // Bit13 Continue in Idle
|
109 | U2MODEbits.IREN = 0; // Bit12 No IR translation
|
110 | U2MODEbits.RTSMD = 0; // Bit11 Simplex Mode
|
111 | //U2MODEbits.notimplemented; // Bit10
|
112 | U2MODEbits.UEN = 0; // Bits8,9 TX,RX enabled, CTS,RTS not
|
113 | U2MODEbits.WAKE = 0; // Bit7 No Wake up (since we don't sleep here)
|
114 | U2MODEbits.LPBACK = 0; // Bit6 No Loop Back
|
115 | U2MODEbits.ABAUD = 0; // Bit5 No Autobaud (would require sending '55')
|
116 | U2MODEbits.URXINV = 0; // Bit4 IdleState = 1 (for dsPIC)
|
117 | U2MODEbits.BRGH = 0; // Bit3 16 clocks per bit period
|
118 | U2MODEbits.PDSEL = 0; // Bits1,2 8bit, No Parity
|
119 | U2MODEbits.STSEL = 0; // Bit0 One Stop Bit
|
120 |
|
121 | // Load a value into Baud Rate Generator. Example is for 9600.
|
122 | // See section 19.3.1 of datasheet.
|
123 | // U2BRG = (Fcy/(16*BaudRate))-1
|
124 | // U2BRG = (37M/(16*9600))-1
|
125 | // U2BRG = 240
|
126 | U2BRG = 240; // 40Mhz osc, 9600 Baud
|
127 |
|
128 | // Load all values in for U1STA SFR
|
129 | U2STAbits.UTXISEL1 = 0; //Bit15 Int when Char is transferred (1/2 config!)
|
130 | U2STAbits.UTXINV = 0; //Bit14 N/A, IRDA config
|
131 | U2STAbits.UTXISEL0 = 0; //Bit13 Other half of Bit15
|
132 | //U2STAbits.notimplemented = 0; //Bit12
|
133 | U2STAbits.UTXBRK = 0; //Bit11 Disabled
|
134 | U2STAbits.UTXEN = 0; //Bit10 TX pins controlled by periph
|
135 | U2STAbits.UTXBF = 0; //Bit9 *Read Only Bit*
|
136 | U2STAbits.TRMT = 0; //Bit8 *Read Only bit*
|
137 | U2STAbits.URXISEL = 0; //Bits6,7 Int. on character recieved
|
138 | U2STAbits.ADDEN = 0; //Bit5 Address Detect Disabled
|
139 | U2STAbits.RIDLE = 0; //Bit4 *Read Only Bit*
|
140 | U2STAbits.PERR = 0; //Bit3 *Read Only Bit*
|
141 | U2STAbits.FERR = 0; //Bit2 *Read Only Bit*
|
142 | U2STAbits.OERR = 0; //Bit1 *Read Only Bit*
|
143 | U2STAbits.URXDA = 0; //Bit0 *Read Only Bit*
|
144 |
|
145 | IPC7 = 0x4400; // Mid Range Interrupt Priority level, no urgent reason
|
146 |
|
147 | IFS1bits.U2TXIF = 0; // Clear the Transmit Interrupt Flag
|
148 | IEC1bits.U2TXIE = 1; // Enable Transmit Interrupts
|
149 | IFS1bits.U2RXIF = 0; // Clear the Recieve Interrupt Flag
|
150 | IEC1bits.U2RXIE = 1; // Enable Recieve Interrupts
|
151 |
|
152 | U2MODEbits.UARTEN = 1; // And turn the peripheral on
|
153 |
|
154 | U2STAbits.UTXEN = 1;
|
155 | // I think I have the thing working now.
|
156 | }
|
157 |
|
158 | void InitPorts() {
|
159 | // S3 (portD Pin 6, chosen as trigger for sending 'M' to UART)
|
160 | // S6 (portD Pin 7, chosen as trigger for sending 'C' to UART)
|
161 | // S5 (portA Pin 7, chosen as trigger for sending 'H' to UART)
|
162 | // S4 (portD Pin 13, chosen as trigger for sending 'P' to UART)
|
163 |
|
164 | TRISD = 0x20C0; // D6,7,13 inputs
|
165 | AD1PCFGHbits.PCFG23 = 1; // This is important. RA7 is muxxed with AN23,
|
166 | // So we need to config the pin as DIGITAL
|
167 | TRISA = 0x0080; // only 0th bit needs be output. A7 is input
|
168 | S3Flag = S4Flag = S5Flag = S6Flag = 0; // Some Debounce Flags
|
169 | }
|
170 |
|
171 | void SoftwareDebounce() {
|
172 | if(PORTDbits.RD6 == FALSE) {
|
173 | if( S3Flag == FALSE ) {
|
174 | S3Flag = TRUE;
|
175 | U2TXREG = 'M';
|
176 | }
|
177 | }
|
178 | else {
|
179 | S3Flag = FALSE;
|
180 | }
|
181 | if(PORTDbits.RD7 == FALSE) {
|
182 | if( S6Flag == FALSE ) {
|
183 | S6Flag = TRUE;
|
184 | U2TXREG = 'C';
|
185 | }
|
186 | }
|
187 | else {
|
188 | S6Flag = FALSE;
|
189 | }
|
190 | if(PORTAbits.RA7 == FALSE) {
|
191 | if( S5Flag == FALSE ) {
|
192 | S5Flag = TRUE;
|
193 | U2TXREG = 'H';
|
194 | }
|
195 | }
|
196 | else {
|
197 | S5Flag = FALSE;
|
198 | }
|
199 | if(PORTDbits.RD13 == FALSE) {
|
200 | if( S4Flag == FALSE ) {
|
201 | S4Flag = TRUE;
|
202 | U2TXREG = 'P';
|
203 | }
|
204 | }
|
205 | else {
|
206 | S4Flag = FALSE;
|
207 | }
|
208 | }
|
209 | int main(void) {
|
210 |
|
211 | InitClock(); // This is the PLL settings
|
212 |
|
213 | InitUART2(); // Initialize UART2 for 9600,8,N,1 TX/RX
|
214 |
|
215 | InitPorts(); // LEDs outputs, Switches Inputs
|
216 |
|
217 | while(1) { // The ever versatile Infinite Loop!
|
218 | SoftwareDebounce();
|
219 | }
|
220 | }
|