跳转到内容

嵌入式系统/PIC编程

来自维基教科书,开放的书籍,开放的世界

本模块假设

  • 您,读者,了解一些使用 C 和汇编的编程知识。
  • 您拥有 MPLAB ICD 2 和 PICDEM 2 Plus 演示板。
  • 您已 选择了一个 PICmicro 微控制器,并希望对其进行编程。(本书中的示例将重点介绍 PIC18F452 微控制器,因为它随演示板一起提供。相同流程适用于大多数其他 PICmicro。)

在开始之前,

  • Microchip Technology Inc 安装最新的 MPLAB IDE 和 MPLAB C18 编译器。在编写本书时,最新的 MPLAB 版本是 7.40。

简单 I/O 入门

[编辑 | 编辑源代码]

我们将从使用 PORTA 和 PORTB 的简单输入输出程序开始。让我们点亮电路板上的 LED。我们应该将值 0x0A 分配给 PORTB。这将点亮 RB3 和 RB1 上的 LED。每次按下 RA4 上的开关按钮时,值将被取反;因此 LED 将在 RB3/RB1 和 RB2/RB0 之间切换。

首先,启动 MPLAB IDE。在菜单栏中,选择“项目”→“项目向导”。点击“下一步”,然后选择 PIC18F452 作为您的设备。再次选择“下一步”。在“活动工具套件”下,选择 Microchip C18 工具套件,在“工具套件内容”下选择 MPLAB C18 C 编译器 (mcc18.exe)。现在,我们必须给项目命名并为其选择一个目录。由于我们将进行简单的 I/O 操作,让我们将其命名为 Simple_IO。然后选择一个目录。在这种情况下,我将使用 c:\example\simpleIO。点击“下一步”按钮。我们没有要添加到项目中的任何文件。所以,再次点击“下一步”按钮。现在,我们已经完成了项目向导。点击“完成”按钮。

项目设置完成后,我们应该创建一个名为 SimpleIO.c 的 C 文件。在菜单栏中,选择“文件”→“新建”。新编辑器弹出后,选择“文件”→“另存为”。在新的窗口中,将新创建的文件保存为 SimpleIO.c。在“项目窗口”(其中 Simple_IO.mcv 是标题)中,右键单击“源文件”。从菜单中选择“添加文件...”。从您刚才保存的位置选择 SimpleIO.c。在同一个窗口中,选择“链接器脚本”,然后从菜单中选择“添加文件...”。在 Microchip C18 C 编译器目录下(默认情况下是 C:\MCC18),转到 c:\安装目录/lkr 并输入 18f452.lkr 作为文件名。将以下代码输入编辑器。

#include <p18f452.h>

// Configurations
#pragma config OSC = HSPLL, OSCS = ON, PWRT = ON, BOR = OFF, WDT = OFF, LVP = OFF

// Main body
void main() {

    // Initializing ports
    PORTA = 0;
    PORTB = 0;

    // Set RA4 as input and RB3-RB0 as output
    TRISA |= 0x10;
    TRISB &= 0xF0;

    // Set value 0x0A to PORTB
    PORTB = 0x0A;
	
    // If button is pressed, toggle PORTB
    while(1) {
        if(PORTAbits.RA4 != 0)
            PORTB = ~PORTB;
    }
}

点击工具栏上的“保存”按钮,或从菜单栏中选择“文件”→“保存”。接下来,点击“项目”→“全部构建”或工具栏顶部的“全部构建”按钮。确保在“输出”窗口中没有错误或警告。将您的 MPLAB ICD 2 连接到您的电脑,并将 PICDEM 2 Plus 演示板连接到 ICD(请参阅提供的说明书)。现在,选择“调试器”→“选择工具”→“MPLAB ICD 2”。确保输出窗口中没有错误。接下来,点击“调试器”→“编程”来对微控制器进行编程。成功对微控制器进行编程后,点击“调试器”→“运行”。您也可以点击工具栏上的“运行”按钮。在演示板上,RB3 和 RB1 上的 LED 应该亮起。

现在,在演示板上多次按下 RA4 上的开关。注意到有什么不对劲吗?LED 会闪烁,但不会一直地在 RB3/RB1 和 RB2/RB0 之间切换。如果您只是按下开关而没有松开,所有 LED 都会亮起。这不是我们想要的结果。让我们再次查看代码,找出问题所在。请注意,在 while 循环中,只要 RA4 读取到 0,PORTB 上的值就会被反转。由于微控制器以 16 MHz 的速度运行,快速按下开关,最多可能消耗 500us,可能会导致 PORTB 中的值反转超过 1000 次。这就是为什么 LED 似乎会在每次按下开关时随机亮起的原因。必须修改代码以检测开关的按下和松开。

LED 闪烁

[编辑 | 编辑源代码]

材料

  • 来自“PIC16F877A 入门”的电路
  • 100 欧姆电阻
  • LED

电路

  1. 引脚 RB7 连接到电阻
  2. 电阻连接到 LED
  3. LED 连接到地

代码

//all these # below set up the PIC
#include <16F877A.h>
#device adc=8
#FUSES NOWDT      //No Watch Dog Timer
#FUSES HS         //Highspeed Osc > 4mhz
#FUSES PUT        //Power Up Timer
#FUSES NOPROTECT  //Code not protected from reading
#FUSES NODEBUG    //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP      //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD      //No EE protection
#use delay(clock=20000000) 				// Sets crystal oscillator at 20 megahertz
#use rs232(baud=9600, xmit=PIN_C6, invert) //Sets up serial port output pin & baud rate

//main program starts here
void main() {
   //Infinite program loop starts.  LED blinks forever.
   while(true){
      output_high(PIN_B7);    //send a “1” to pin RB7, making RB7 “High” at 5v
				//this will turn on the LED hooked to RB7
      delay_ms(500);  		//wait half a second, delays for 500ms 
      output_low(PIN_B7);     //send a “0” to pin RB7, making RB7 “Low” at 0v
      delay_ms(500);		//wait half a second, delays for 500ms
   }
}

说明

您可以轻松地添加更多 LED,并使它们以不同的模式闪烁。为了使代码更易读,请使用

#define RED_LED   PIN_B7
#define GREEN_LED PIN_B6
…
…
output_high(RED_LED);
output_high(GREEN_LED);

编译器,汇编器

[编辑 | 编辑源代码]

进一步阅读

进一步阅读

[编辑 | 编辑源代码]

嵌入式系统

华夏公益教科书