矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 5799|回复: 19

learning to program PIC (or most other mcus) without spending a penny

[复制链接]
发表于 2010-12-19 21:26:43 | 显示全部楼层 |阅读模式
a few days ago in a different thread, I talked about starting a thread on how to learn a mcu. so here it is.

the mcu we picked is PIC, by Microchip, for no apparent reason. the same process applies to any other MCUs (like AVR or ARM chips), only the tools change slightly.

the goal here is to minimize the investment. It requires no hardware, and only your time and efforts.

The software required are:

1) C compiler: we are using hi-tech C compiler as it is the most popular on the PIC, as well as the most basic one. the demo version is free from hi-tech's website: www.htsoft.com . We are picking the pic10/12/16 series.
2) IDE: you have a couple choices here. you can pick microchip's MPLAB, an official but ancient IDE, or the Eclipse-based but otherwise unsupported hi-tide (from htsoft). I use hi-tide 3.13 and it has been great. Again, it is free for download from www.htsoft.com.
3) simulator: I use Proteus from www.labcenter.com. Again, the demo version is free for download there.

评分

1

查看全部评分

 楼主| 发表于 2010-12-19 21:27:40 | 显示全部楼层
the first thing to do is to download hi-tide 3.13 and install it.

it will offer to download for you the C compiler and you can just say "yes".
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-19 21:32:29 | 显示全部楼层
our target device is pic12f675 - it is a 8pdip device, with upto 5 gpio pins and internal rc oscillator (1%) so you don't need any other parts to run code on this chip.

go to www.microchip.com to download the datasheet. and read the datasheet at least 50x before you start to program the chip.
回复 支持 反对

使用道具 举报

     
发表于 2010-12-20 00:44:30 | 显示全部楼层
but, how to download the hex code into the pic?
回复 支持 反对

使用道具 举报

发表于 2010-12-20 10:28:08 | 显示全部楼层
今年12期无线电杂志有PIC讲座。
回复 支持 反对

使用道具 举报

发表于 2010-12-20 11:01:32 | 显示全部楼层
楼主辛苦了,就是英文的,很多初学者读起来可能吃力.下PICC如果只用来写675使用LITE就可以了,这样就不会有时间的限制.
回复 支持 反对

使用道具 举报

     
发表于 2010-12-20 23:54:18 | 显示全部楼层
是啊,英语退化了,看楼主的帖子也飞了很大的劲,唉,矿坛开个英语角吧?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-26 19:49:42 | 显示全部楼层
now, we are going to create our first PIC project.

1) launch hi-tide;
2) the first time it launches, it will ask you for a "workspace": essentially how / where you want  your projects to be stored. Pick a spot or go with the default setting.
3) once in hi-tide, you can create a new project, by clicking the "new project" icon on the upper left, or File->New->Project. This launches the new project wizard.
4) you will see that a few "lines" are there on the first screen, like "CVS", or "Hi-Tech C", etc. Expand "Hi-Tech C" and you will see a hi-tech compiler (if you have installed it / them). I prefer to use picc9.60pl2. but use whatever you feel comfortable. Click "Next".
5) You will need to give your project a name. whatever works for you is fine. Hi-tide (Eclipse really) allows spaces as a valid character. I use "CR 12F675 Ex1" as my project name. Click "Next".
6) you need to chose the project type. We want to produce a hex file to be burned into the pic. Either "Debug" or "Release" will work. Click "Next".
7) Now, you need to pick your mcu. 12F675 is under "Microchip" so expand it and pick PIC12F675. Click "Next".
8) you can pick a packaging now, and/or main.c. Click "Next".
9) under the "C/C++ Project" window on the left, you will see that now you have a project called "CR 12F675 Ex1". Expand it and you will see a few lines and one of them is main.c. Double-clicking it will bring up the editor window, with the content of main.c in it that looks like this:


========beginning================
#include <htc.h>

void
main(void)
{
        while (1){
                //TODO Auto-generated main function
        }
}
========end==============

that's the basic template for a mcu code.
10). On the lower left, you will see a "Project Information" window. it shows some information pieces, including how big the compiled code is.
11). We are going to enter a simple code, below, into the editor window.

============beginning============

#include <htc.h>

__CONFIG(                                //fuse configuration bits
        MCLRDIS &                        //disable mclr pin - use it as a regular port pin
        WDTDIS &                        //disable watch dog
        BORDIS &                        //disable brown-out
        PWRTEN &                        //enable power-up timer
        INTIO                                //enable internal rc oscillator
        );
       
#define LED_PORT                GPIO        //led on gpio, the only port for this chip
#define LED_DDR                        TRISIO        //output direction register
#define LED0                        (1<<0)        //led on gpio.0

void mcu_init(void) {                        //reset the mcu
        ANSEL = 0x00;                                //all pins as gpio
        CMCON = 0x07;                                //analog comparators off
       
        LED_PORT &=~LED0;                        //clear LED0
        LED_DDR &=~LED0;                        //led0 as output
}
       
void
main(void)
{
        mcu_init();                                        //reset the mcu
        while (1){
                //TODO Auto-generated main function
                LED_PORT ^= LED0;                //flip led0
        }
}
=========end==============

this simple piece of code contains 4 important sections, for any mcu.

a) the header section: it tells the compiler which header file to include. here, we are using a htc compiler to generate code for 12F675, so we will let the compiler sort it through by including just <htc.h>
b) the fuse section: it tells the compiler how we want the fuse to be set on this particular mcu. which fuse to set and how to set them will depend on the chip and the tools you use.
c) the mcu initialization section, via "mcu_init()": this sets up the mcu in a way that we want. many mcu chips boot - up with its port in the analog input mode, analog comparators on, etc. so we need to turn that off.
d) the code execution section, via "main()": this is where the actual work is done.

your mcus may differ, your compilers may differ,  how you implement the four sections are differ (for example, many modern mcus don't have the fuse concept but uses run-time enable/disable bits to turn on / off peripherals. and many avrs boot up with pin default to output so the mcu_init() is usually empty), but it is always a good idea to keep the four sections in place.

12): while in the editor window, press <Ctrl-S> will initiate the compiler, or Project->Build/Build All, etc. will compile the code and you will see the information in the Project Information window is updated accordingly. As the code has no error, it should compile flawlessly and generate the desired .hex / .coff files for us.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-26 20:00:50 | 显示全部楼层
now, we need to confirm that our code, which flips the LED0 pin (GPIO.0 on the chip) actually works.

we are going to use Proteus to do that.

1) launch your Proteus;
2) go to the Component Mode, and Click on the "Pick from Library" icon.
3) in the keyword  window, type in "12F675", and in the results window, double click on PIC12F675 to select it. Click "OK" on the lower right to exit it.
4) you are back at the schematic screen, and place PIC12F675 onto the schematic, anywhere will work.
5) put on two voltage probes on GP0 (the LED0 pin in our code) and GP1 (for comparison purposes).
6) click on the "Graph Mode" icon and pick "Digital", and then drag it on the schematic to create a graph.
7) click one of the probes and drag it onto the graph; repeat the process for the other probe.
8) now, save the design, in the same director as your picc project.
9) back in Proteus, double click the chip and its property window will pop up.
10) click the little folder icon on the "Program File" line and go to the "Release" folder to find your code. You will see two files, one a .hex file and another a .coff file. Either will work for us but .coff retains source level debugging information so that will come in handy later. Pick either one. and clock the box and back to the schematic window.
11) while your cursor icon is over the graph, press the space bard and you will see the simulation of the output.
12) right click on the graph and change your time horizon to 1ms (start time) and 1.1ms (end time).

this is what you got.
CR 1.PNG
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-26 20:05:29 | 显示全部楼层
as you can see, the GP0 pin is oscillating between 1 and 0 at about 125Khz.

yet the GP1 pin is untouched - it is still in the floating input mode, by the way.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-26 20:06:40 | 显示全部楼层
now, change the code slightly, as below, and resimulate it in Proteus and see what happens with GP1,

=============beginning===========================

#include <htc.h>

__CONFIG(                                //fuse configuration bits
        MCLRDIS &                        //disable mclr pin - use it as a regular port pin
        WDTDIS &                        //disable watch dog
        BORDIS &                        //disable brown-out
        PWRTEN &                        //enable power-up timer
        INTIO                                //enable internal rc oscillator
        );
       
#define LED_PORT                GPIO        //led on gpio, the only port for this chip
#define LED_DDR                        TRISIO        //output direction register
#define LED0                        (1<<0)        //led on gpio.0
#define LED1                        (1<<1)        //led on gpio.1
#define LEDs                        (LED0 | LED1)        //all led pins

void mcu_init(void) {                        //reset the mcu
        ANSEL = 0x00;                                //all pins as gpio
        CMCON = 0x07;                                //analog comparators off
       
        LED_PORT &=~LED0;                        //clear LED0
        LED_PORT |= LED1;                        //set led1
        LED_DDR &=~LEDs;                        //leds as output
}
       
void
main(void)
{
        mcu_init();                                        //reset the mcu
        while (1){
                //TODO Auto-generated main function
                LED_PORT ^= LEDs;                //flip led0
        }
}
===========end===============

this is what you should be getting:
CR 2.PNG
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-26 20:09:54 | 显示全部楼层
notice how the code operates on LED0/LED1 and LED_PORT / LED_DDR, rather than specific pins / ports?

that's for code portability. if you were to decide to put LED0 on GPIO5 and LED1 on GPIO4 in the future, all you need to do is to change the definition of LED0 (to (1<<5) and LED1 (to 1<<4) and recompile the code and it will work.

that is ABSOLUTELY critical for embedded programming, in order to maintain code portability.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-26 20:18:54 | 显示全部楼层
to show an example of that, here is the same code, running on a 89C51:

=====beginning============
//#include <htc.h>
#include <regx51.h>
#include "gpio.h"

/*
__CONFIG(                                //fuse configuration bits
        MCLRDIS &                        //disable mclr pin - use it as a regular port pin
        WDTDIS &                        //disable watch dog
        BORDIS &                        //disable brown-out
        PWRTEN &                        //enable power-up timer
        INTIO                                //enable internal rc oscillator
        );
*/
       
#define LED_PORT                P2                //led on P2
#define LED_DDR                        P2                //output direction register
#define LED0                        (1<<0)        //led on P2.0
#define LED1                        (1<<7)        //led on P2.7
#define LEDs                        (LED0 | LED1)        //all led pins

void mcu_init(void) {                        //reset the mcu
        //ANSEL = 0x00;                                //all pins as gpio
        //CMCON = 0x07;                                //analog comparators off
       
        //LED_PORT &=~LED0;                        //clear LED0
        IO_CLR(LED_PORT, LED0);
        //LED_PORT |= LED1;                        //set led1
        IO_SET(LED_PORT, LED1);
        //LED_DDR |= LEDs;                        //leds as output
        IO_OUT(LED_PORT, LEDs);
}
       
void
main(void)
{
        mcu_init();                                        //reset the mcu
        while (1){
                //TODO Auto-generated main function
                LED_PORT ^= LEDs;                //flip leds
        }
}

==========end================

and this is what you get in simulation:

[ 本帖最后由 millwood 于 2010-12-26 20:21 编辑 ]
CR 3.PNG
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-26 20:24:33 | 显示全部楼层
you can actually port this code back to PICC and it will run as well.

the portability is further enhanced via the gpio.h header file, which defines a set of routines that operate on pins.

============gpio.h for picc===============

//port manipulation macros for PIC.

#define IO_SET(port, bits)        port |= (bits)        //set bits on port
#define IO_CLR(port, bits)        port &=~(bits)        //clear bits on port
#define IO_FLP(port, bits)        port ^= (bits)        //flip bits on port

#define IO_GET(port, bits)        (port & (bits))        //get bits on port

#define IO_OUT(ddr, bits)        ddr &=~(bits)        //set bits as output
#define IO_IN(ddr, bits)        ddr |= (bits)        //set bits as input

#define NOP()                        asm("nop")        //nop()

#define sleep()                        asm("sleep");        //put the mcu into sleep

//void (*mcu_reset)(void) = 0x0000;                                 //jump to 0x0000 -> software reset
============end=================

by defining a set of such instructions for different chips, and limit your pin operations to just those macros, you can greatly improve your code's portability.
回复 支持 反对

使用道具 举报

     
发表于 2010-12-29 12:45:37 | 显示全部楼层
DON'T WASTE YOUR TIME ON THIS FORUM! NO ONE WILL UNDERSTAND WHAT THE HELL YOU ARE WRITING!!!  
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-30 19:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表