Skinny Latte PIC Board: blinking LEDs and playing Greensleeves

Tom Biery sent me one of his nice Skinny Latte boards (thanks Tom!), see his YouTube video. This page demonstrates some C programs for it written by me. A short introduction how to install MPLAB (but there are better videos on YouTube on this topic) and the example programs running on the board:

Installing MPLAB and HI-Tech C compiler

If you want to test the programs yourself, you'll need the parts from the Skinny Latte board (see schematic below; you can use a breadboard, too) and a PIC programmer, like the PICkit 2. Then download MPLAB for free from http://ww1.microchip.com/downloads/en/DeviceDoc/MPLAB_IDE_v8_66.zip (or newer versions). The HI-Tech C compiler is included in the download.

The board

This is the board with a PIC16F628A, running the Hello World! application.

Schematic

Layout

"Hello World!" application

First a simple application, which blinks the LEDs with 1 Hz.

Project file with source code: SkinnyLatte-HelloWorld.zip

You can program the PIC with the program button in the toolbar, too:

Don't forget to release the reset, if the MCLR pin is configured as reset.

The program:


// include MCU specific things
#include <htc.h>

// chip configuration
__CONFIG(
	CP_OFF &  // Code protection off
	LVP_OFF &  // Low-Voltage Programming Enable bit
	BOREN_OFF &  // Brown-out Detect disabled
	MCLRE_OFF &  // RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD
	PWRTE_ON &  // PWRT enabled
	WDTE_OFF &  // Watchdog Timer disabled
	FOSC_HS  // // XT oscillator: Crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN
);

// define the oscillator frequency for the __delay_ms function
#define _XTAL_FREQ 18432000

// main function
void main(void)
{
	// configure first four bits of RA and RB to output
	TRISA = 0xf0;
	TRISB = 0xf0;

	// blink LEDs with 1 Hz
	while (1) {
		// turn on first 4 LEDs on PORTA, second 4 LEDs on PORTB off
		PORTA = 0x0f;
		PORTB = 0x00;

		// wait half a second
		__delay_ms(500);

		// first 4 LEDs on PORTA off, second 4 LEDs on PORTB on
		PORTA = 0x00;
		PORTB = 0x0f;

		// wait half a second
		__delay_ms(500);
	}
}


The first lines are the config bits. You can specify it in Configure->Configuration Bits, too, but it is better to specify it in the source code, because then the source code can be reused without knowing the project file. You can find the definitions in C:\Program Files (x86)\HI-TECH Software\PICC\9.81\include\pic16f628a.h. See the datasheet of the PIC for a detailed description of all configurations.

After the config bit definition, you can define the frequency with which you use the microcontroller. This is used for the __delay_ms macro. The main program configures the direction of PORTA and PORTB and then there is an infinite loop for blinking the LEDs.

Button Counter

The next example counts the number of button push events up to 15 and displays it with the RB0 to RB3 LEDs. It counts falling edges at RB4. Debouncing is done by delaying after detecting an edge. Now the MCLR pin is configured as reset, so you can use the MCLR button to reset the PIC: counter.c

Sound synthesis

The PIC16F628A has a PWM and capture/compare output on pin RB3, which can be used to create a square wave sound. Connect a piezo speaker, maybe from an old gift card, to RB3 and GND, and then use this program: greensleeves.c

The program is more difficult to understand, because it uses the timer 1 and the capture compare modul to generate a high precision output frequency on RB3. First, timer 1 is enabled, which is a free running 16 bit counter. It counts from 0 to 65535 (0xffff) and then starts again at 0. No prescaler is used, so it counts with Fosc/4 = 16,000,000 Hz = 4,000,000 Hz. The capture/compare module is configured as compare mode, with setting or clearing the RB3 pin on compare match, which sets CCP1IF, too. The software waits for this event and then adds the next cycle time, and changes the set/clear bit for the next half cycle.

So e.g. to generate 78.125 Hz, you have to load the compare register CCPR1 with 16,000,000 Hz / 4 / 2 / 78.125 Hz = 25,600. The first compare matches after 1 / 4,000,000 Hz * 25,600 seconds = 6.4 ms. This changes the RB3 pin, so the cycle time is 12.8 ms. The resulting frequency on RB3 is 1 / 0.0128 s = 78.125 Hz. The following timing diagram illustrates this:

The CCPR1 register is updated some small time after the RB3 pin change, due to latency and jitter, but the generated frequency is exact, because it is compared each system cycle by hardware and adding the half cycle time guarantees to match again at the next half cycle.

This is the Excel sheet for the Greensleeves song with the note pitch and duration: piano.freq.3a.xlsx


15. July 2011, Frank Buß