AUTOMATIXARON
Introduction to digital signal processing
Aim of the lesson:
In the upcoming digital signal processing lessons, we will mainly use the dsPIC DSC family from Microchip. This lesson aims to familiarise the development platform, the MPLAB X environment and to create a base project usable in the upcoming lessons.
The development board:
The development board:
Our platform is the Explorer 16/32 development board combined with a dsPIC33EP256GP506 general purpose plugin module. The development platform is created in such a way that most of the peripheral are either connected to a device on board (ex.: LCD, potentiometer, temperature sensor), or fanned out (PMOD, MikroBUS, PICTail headers).
The board contains a PIC kit on-board (PKOB), which can be used to program and debug the selected microcontroller without the usage of an external programmer (J32). An FTDI based USB-UART bridge is implemented on the board for easy PC - MCU interfacing (J40).
We will use C programming language mainly for configuration and non time-critical algorithms. The time-critical part will be created in assembly.
Creating the project in MPLAB X:
Open MPLAB X, and create a new Microchip embedded standalone project. For the device, select 16-bit DSC (dsPIC33) Family, dsPIC33EP256GP506 device. Choose Starter kits (PKOB) for hardware tools (we will use the simulator for testing, and switch to PKOB for onboard debugging). Choose XC16 for the compiler.
​Create a header file (main_header.h) to store the configurations, and two c files (main.c and traps.c).
Access PIC configuration bits from Window/PIC memory views, disable watchdog timer, set oscillator to XT (the board has an 8MHz crystal). Set the oscillator source to primary with PLL (XT+PLL), and enable two-speed oscillator (The XT and HS oscillators need 1024 cycles to stabilize until this happens the device is held in reset. If we use the two-speed oscillator, the PIC uses the internal oscillator until the primary stabilizes). Copy the generated code into the main header file. Include stdio and stdlib, both will be useful in the future.
Define the clock frequency and the instruction frequency after the inclusions (#define FOSC 140000000, #define FCY (FOSC/2)).
​
The trap file is used for run-time error handling (oscillator, address, stack, etc. errors), and can be downloaded from here.
​
Next we need to set the oscillator frequency to 140MHz:
​
Writing to OSCCONL will enable us to set up the PLL. CLKDIV sets FRCDIV to FRC/2, PLLPRE to 2 DOZE to 1:8, PLLPOST to 1:2, with DOZE and ROI disabled.
We need to set PLLDIV to 68 (0x44).
The program can continue after the PLL locked.
Programming tip:
Programming tip:
Next we need to initialize the digital GPIOs, making A8, B4, C0, C8, E12, E13 E14 outputs, and C7, D5, D6 inputs with the respective TRIS registers.
The next step is to set up a timer, and test our hardware by flashing an LED:
Here is an example in which I've set up the Timer 1 to generate a 1ms interrupt routine.
And here we can see the timer interrupt request routine, which will flash an LED with 1s period.
Now it would be a good time to test our hardware. Compile the code, and download the generated hex file to the development board. If everything went well, we could see a forest green LED flashing with 1s period.
In the next step, we will use the USART peripheral to create a communication bridge (also bottleneck) between the DSC and PC.
In this example, the USART module is set up with 1 stop bit, no parity bits, 8 data bits, and with auto baud rate disabled. The baud rate is 115200 Baud/s with a normal speed we would have 2% of error, while with high speed 0.6% error, so the latter is used.
The receiver interrupt is enabled, and the transmitter is used without interrupt.
The baud rate is given in the main header with two defines: #define BAUDRATE 115200 and #define BRGVAL ((FCY/BAUDRATE)/4) - 1, which is the expected register value for high-speed operation mode.
We need to write a character handler function for the USART terminal:
Note: The included stdio library lets us to use the USART peripheral with printf and scanf if set up properly.
The final step is to initialize the analog to digital converter.
The ADC module of the DSC is quite the capable peripheral, as one can see here. It has a complex analog input multiplexer, four analog comparators, and four separate sample and hold (S/H) circuits - which would enable us to simultaneously sample four analog signals. The S\Hs are connected to a SAR ADC, which can be used as a single channel 12b 1.1Msps converter, or as a multi-channel 10b 500ksps converter.
The results of the conversion can be read one by one as with any ordinary MCU, or stored in a 16-word conversion buffer - from which we can read the values at once.
In our example we will only use one ADC channel, with +ve being AN0, -ve being AN1.
The AD conversion time must be greater than 76ns - we will choose 100ns, so the ADCS equation from the datasheet can be calculated: Tad = Tcy(ADCS+1), where Tcy = 70M. ADCS = 6, and the total conversion time of one 12b value is Tc = 14Tad = 1.4us.
Let's configure the AN0 and AN1 channels as analog inputs.
We will use the ADC in Q15 format, and GP Timer3 will start the conversion.
ADC sampling begins after conversion.
ADC is used in 12b mode and only CH0 will be converted.
The result of conversion will be written in ADC1BUF0.
+ve = AN0, -ve = AN1.
Clear the interrupt flag, and disable the ADC interrupt routine.
Start the ADC.
​
IMPORTANT: The ADC uses Timer 3 for conversion. Create an InitTimer3 function where the source clock is Fosc/2, and the time-out frequency is 2kHz. Enable the timer interrupt routine. (You can use the given Timer1 example and the device documentation as a starting point).
The Timer3 interrupt should be written in the following order:
-
Clear ADC SAMP register to start a conversion
-
Wait while the conversion is done (AD1CON1 DONE bit is set)
-
Read the converted value from ADC1BUF0
-
Convert the Q15 value to voltage (0V to 3.3V)
-
Send the data to the PC on USART (Attention: 12b data must be sent as 2 bytes)
The main function should call the previously created routines in this order: the oscillator setup, the USART, the ADC, Timer3 and Timer1. After the setup functions an infinite loop must be placed for a continuous cyclic operation.
Summary:
In this exercise, we refreshed some basic microcontroller knowledge, and we've created a starting platform for the upcoming lessons.
At the end of this exercise, you should have a development board which flashed an LED, samples and analog input and sends the converted value on USART with a frequency of 2kHz.