Showing posts with label PIC. Show all posts
Showing posts with label PIC. Show all posts

Monday, February 8, 2016

dsPIC30F Blink LED

I needed to get up to speed fast on how to add a timer interrupt for an imporved blink routine for the LED hanging off of my microchip dsPIC30F4012 PIC. I planned to make something fancy, but first I just needed to figure out whether there were timer interrupts in this PIC (there are, in fact there are five, and they appear on the block diagram on the datasheet), how to configure them in my C program, and whether some where better than others to use. The last question hasn't been answered for me yet, there are hints that the first timer might be different, maybe that it is directly driven by the system clock and the other ones might be driven by the instruction clock, but at this point I don't care because all of the examples that I found online used the first timer and so that was what I used.

Here are the links that I pored over to get enough examples that I was able to build my own code. The hard part was figuring out what applied to my particular PIC and what was for a PIC that was sufficiently different that I couldn't use it:

This is a nice tutorial in that an LED blinker is first shown as terrible code (piles of for loops to create a delay), then an interrupt handler. However, for some reason the author seems to be using the interrupt handler to time the delay which seems odd since the LED blink code could well have just been in there too.http://www.electronics-base.com/projects/complete-projects/195-microchip-microcontroller-dspic30f4013-blink-led-example-using-timer-complete-project

The original question in this forum thread is hilariously badly written, and the answers are all also bad except for one, which is full of wisdom. It's also not for my PIC: http://www.microchip.com/forums/m840532.aspx

This is probably the best example; although not exactly like what I wanted to do, it's for a PIC30F, it shows setup code for the timer, it explains about the prescaler and other built-in settings and how to use them. It also shows blinks both with a timer interrupt and in a simple loop using the delightful __delay32 function which I immediately also read up on: https://batchloaf.wordpress.com/2012/04/12/simple-timer-1-interrupt-example-for-the-dspic30f4011/

Here's another post by the same guy that did the one above; it has the blink example in it, but more importantly it has a ton of stuff about setting up programming (albeit with a much earlier version of the IDE): https://batchloaf.wordpress.com/dspic30f4011_super_example/

Here's a little bit more about __delay32(): http://www.microchip.com/forums/m486992.aspx

here's another nice example, just an LED blinker using a timing interrupt, with another person's example of using all the setup parameters for the timer: https://batchloaf.wordpress.com/2010/12/05/timer-1-interrupt-example-for-the-dspic30f4011/

Here's a whole reference manual just for the PIC30 timers, but it's so wordy that I just couldn't fight through to any answers about what was different about the different timers! Also all of their example code is in assembly, which is only a little helpful for my need to do this in C: http://ww1.microchip.com/downloads/en/DeviceDoc/70059D.pdf

The first example in this very professional-looking tutorial is another LED blinker using Timer 1. All of the examples that I found used Timer 1. There was information about how it's possible to join Timers 2&3 or 4&5 to make 32-bit counter/timers, which made me wonder what happens if that's not what you want to do, another question about the other timers that I was too rushed to find the answer to: http://www.mikroe.com/chapters/view/52/chapter-4-timers/

Here's something that I found while trying to learn if the other timers get the system clock or the instruction clock. The question is actually about a PIC33, but for some reason one of the commenters thinks that it's about the PIC30 and answers accordingly. However, it is unclear once again if his answer applies only to the first timer or all of them: http://www.microchip.com/forums/m156502.aspx

Here's an example for a Timer 2 module, but it's for a PIC16, so is only slightly helpful for my case: http://www.pcbheaven.com/picpages/The_Timer_Modules_Timer2/

Another PIC16 Timer2 example. This one is interesting because it shows a IDE utility called "Code Configurator" which might be helpful to learn how to use: http://microchip.wikidot.com/8bit:mcctimer2

Some test slides from an online class that start some examples for a PIC30F: http://academic.eng.au.edu/~nott/nott/MicroClass/Lectures/7.pdf

A powerful collection of timer examples, including setup of a PIC30F timer2/timer3 combination to blink an LED, although I'm not sure why a 32 bit counter would be needed for a .5Hz blink: https://www.pantechsolutions.net/project-kits/user-guide-programming-in-c-for-dspic30f4011

Some nice timer and interrupt examples, but for a PIC24: http://www.kibacorp.com/First%20Experiments%20Part%202.pdf

Here is my final C code. It's fancy; the objective was to have a slow blink pattern with an option for triggering a single fast blink. I created a 8Hz timer interrupt and then used globals to count through a 64-state counter, defining the slow blink on as the lower 32 states and the slow blink off as the upper 32 states. If the timer interrupt wakes up and a request for a fast blink ("activity_request") is set, it figures out what the last on/off state was, then either starts on a series of interrupt-driven states that turn the LED off, then on, then off, or if it was already off it just turns it on and off. The resulting visual effect is exactly what I was looking for.
int timer_counter = 0;
int activity_lead_off = 0;
int activity_on = 0;
int activity_request = 0;
int led_is_on = 0;

// Timer 1 interrupt service routine for LED blinking algorithm
void __attribute__((__interrupt__, __auto_psv__)) _T1Interrupt(void)
{
if (activity_lead_off == 1){
SetLed();
led_is_on = 1;
activity_on = 1;
activity_lead_off = 0;
} else if (activity_on == 1) {
ClearLed();
led_is_on = 0;
activity_on = 0;
} else if (activity_request == 1) {
activity_request = 0;
if (led_is_on == 1){
ClearLed();
led_is_on = 0;
activity_lead_off = 1;
} else {
SetLed();
led_is_on = 1;
activity_on = 1;
}
} else {
if (timer_counter < 32){

SetLed();
led_is_on = 1;
} else {
ClearLed();
led_is_on = 0;
}
}
if (timer_counter < 63) {

timer_counter++;
} else {
timer_counter = 0;
}
// Clear Timer 1 interrupt flag
_T1IF = 0;
}

void SetActivity()
{
if (activity_on == 0) {
activity_request = 1;
}
}


int main()
{
// Initialize Timer 1 for 8 calls/second
// PR1 AND tckps ARE SET TO CALL INTERRUPT EVERY 125ms
// Period = PR1 * prescaler * Tcy.
// Some documentation indicates that Tcy is crystal clock period
// Clock crystal is 7.3728MHz, Tcy = 135.633 nsec
T1CON = 0; // Clear Timer 1
T1CONbits.TCKPS = 3; // Set Timer 1 Prescaler 1:256
PR1 = 3600; // Set Timer 1 Period
_T1IP = 1; // Set Timer 1 interrupt priority
_T1IF = 0; // Clear Time 1 interrupt flag
_T1IE = 1; // Enable Timer 1 interrupt
T1CONbits.TON = 1; // Turn on Timer 1

.
.
.

}

Sunday, January 24, 2016

pic microcontroller programming tutorial microchip

Some of my favorite tutorials for to program the PIC microcontroller. The TL;DR is figure out what microcontroller I have (it's a dsPIC30F6012A), download the IDE from Microchip, select the previous project, make changes and save it as a new project, hit compile until it doesn't fail compilation, plug in the IDE3 in circuit debugger, select it, find the refresh button to get the IDE to recognize the debugger cable, hit build for download which will do the download.

Some links:

An immense collection of tutorials for PIC16 microcontroller: http://pic-microcontroller.com/pic16-microcontrollers-video-tutorial-series/

An overview page from Microchip that doesn't really tell much that wasn't already obvious: https://www.microchip.com/pagehandler/en_us/designsupport/programming

A video for an earlier version of the Microchip IDE. This video helps penetrate the mysterious complexity of the IDE: https://www.youtube.com/watch?v=mUofSucHx_E

Another helpful video, again not for my version of the IDE but they make so many updates to the IDE that it's not a mystery. Fortunately, some things get carried through various versions: https://www.youtube.com/watch?v=dGc0BMCoeVg&spfreload=1

Somebody who had the same problem as me of needing to get started quickly without having to plow through long manuals. The second reply turned out to be a great list of tutorials: http://www.microchip.com/forums/m139145.aspx

A list of amazingly complete tutorials, alas for a different PIC than I have: http://www.amqrp.org/elmer160/lessons/index.html

A search that I did on Microchip's site when my compilation was having trouble finding a particular header. I think that the eventual solution was to correctly import the entire build directory for the previous project, which had everything properly set up. http://www.microchip.com/search/searchapp/searchhome.aspx?q=spi.h: No such file or directory&resperpage=10&id=2

Another search for how to solve an error message that I was getting. None of the answers in this tread were helpful to me, but they seemed to contain a lot of smart background information I might want to review later. My problem was solved by just reusing the setup from the previous project: http://www.microchip.com/forums/m594491.aspx

One of the problems that I had was that my project wasn't able to find the UART.h and other header files. I don't remember how I solved this; it involved adding a new path or something because the place that these headers were kept changed between the earlier version of the IDE that the program was originally compiled in and the new version that I used.http://www.microchip.com/forums/m766175.aspx
http://www.microchip.com/forums/m773469.aspx
http://www.microchip.com/forums/m528591.aspx

I'm not sure how I ended up looking into what seems to be something to do with graphics libraries, but here's the head of the search that I did: http://microchip.wikidot.com/hif2131:mla-installation

A step-by-step of how I used the MPLAB X IDE to build a project.

1. Start the IDE. For some reason two applications were installed, IDE and IPE. I have no idea what IPE is.

2. If another project is open, select File->Close Project

3. Copy the entire folder containing the old project to be modified to a new folder with the new version name

4. Under File->Open Project, select the new folder. The project will have the old name when it comes up in the "Projects" tab of the navigator pane of the IDE, but you can right click on it and from the context menu select "Rename..." which gives you the option to change the name. An option to "Also Rename Project Folder" is present, but it is not needed because the folder that has been copied already was given the new name in step 3.

5. If not already done, expand the project in the navigator pane to show all the files in the project. Double click on any of the files to edit them.

6. Compile using the hammer or hammer & dustbroom until a clean compile is achieved.

7. Plug the ICD3 adapter into both the programmer connector on the board and a USB port on the PC. *Power on the board with the dsPIC*. In the tiny "Dashboard" pane in the lower right of the MPLAB window, click the "recycle" icon to activate the ICD3 and make it check for a good connection to the dsPIC

8. Click the "Make and Program Device" icon to build the project gain and download it. After the usual build is done, a new tab with the label "ICD 3" will open in the status area and show the status of programming.