PIC单片机C语言如何快速入门?

99ANYc3cd6
预计阅读时长 23 分钟
位置: 首页 C语言 正文

目录

  1. 为什么用C语言开发PIC?
  2. 开发环境搭建
  3. C语言基础与PIC特殊关键字
  4. 核心外设编程(GPIO, 定时器, UART等)
  5. 实战项目:LED闪烁与串口通信
  6. 进阶主题
  7. 总结与学习资源

为什么用C语言开发PIC?

虽然PIC可以用汇编语言编程,但C语言在现代嵌入式开发中占据绝对主导地位,主要原因如下:

  • 可读性与可维护性:C语言更接近人类语言,代码结构清晰,易于阅读、修改和团队协作。
  • 开发效率高:无需关心复杂的寄存器位操作,C编译器会帮你处理,你只需专注于“做什么”,而不是“怎么做”。
  • 可移植性强:为某个PIC系列(如PIC16)编写的代码,经过少量修改(主要是头文件和配置位),就可以移植到同系列或不同架构(如PIC18, PIC32)的单片机上。
  • 丰富的库函数:Microchip官方和第三方提供了大量的库函数(如MPLAB Harmony),极大地简化了驱动外设的开发工作。
  • 模块化编程:通过.c.h文件,可以轻松地将代码划分为功能模块,使项目结构更清晰。

开发环境搭建

要进行PIC单片机C语言开发,你需要以下两个核心软件:

  1. MPLAB X IDE:这是Microchip官方的集成开发环境,它是一个免费的代码编辑器、项目管理器和编译器前端。
  2. XC编译器:这是Microchip的官方C语言编译器,你需要根据你使用的PIC芯片架构来选择:
    • XC8:用于8位PIC单片机(如PIC10, PIC12, PIC16, PIC18)。
    • XC16:用于16位PIC单片机(如PIC24, dsPIC)。
    • XC32:用于32位PIC单片机(如PIC32)。

安装步骤:

  1. 下载并安装 MPLAB X IDE
  2. 在安装MPLAB X时,它会提示你安装所需的编译器,勾选你需要的XC编译器(对于初学者,XC8是必须的)。
  3. 安装完成后,打开MPLAB X,创建一个新项目,选择你的目标芯片型号,环境就搭建好了。

C语言基础与PIC特殊关键字

标准的C语言语法同样适用于PIC,但PIC的C编译器(如XC8)扩展了一些特殊的关键字,用于直接操作单片机的硬件,这些是PIC C编程的核心。

1 关键数据类型

除了标准的int, char, float等,XC8还定义了一些与硬件相关的数据类型,在头文件(如<xc.h>)中定义:

  • unsigned char:通常用于8位寄存器操作,如端口寄存器。
  • unsigned int:通常用于16位寄存器操作,如定时器寄存器。
  • volatile:非常重要的关键字!告诉编译器这个变量可能会被硬件(如中断)改变,因此编译器不要对其进行优化(不要把它放在寄存器里缓存),所有与硬件寄存器和中断服务程序相关的变量都应该声明为volatile

2 特殊功能寄存器

在PIC中,控制外设(如GPIO、定时器)是通过读写特殊的内存地址——特殊功能寄存器来实现的,在C语言中,我们通过宏定义来访问它们。

<xc.h>头文件中,你会找到类似这样的定义:

#define PORTA        0xF80      // PORTA寄存器的地址
#define TRISA        0xF92      // PORTA方向寄存器的地址

你不需要直接使用地址,而是使用更具可读性的名称:

#include <xc.h> // 必须包含这个头文件
void main() {
    TRISA = 0x00; // 将PORTA的所有引脚设置为输出
    PORTA = 0xFF; // 将PORTA的所有引脚置高电平
}

3 核心关键字

  • #pragma config:这是最重要的指令之一,用于配置单片机的配置位,配置位是单片机上电时的一些基本设置,

    • FOSC:选择时钟源(外部晶振、内部振荡器等)。
    • WDTEN:看门狗是否使能。
    • LVP:是否允许低电压编程。
    • PBADEN:PORTB的引脚是否在低电平时用作模拟输入。
    • 配置位必须在代码的最开始设置,因为它们决定了单片机的基本行为。

    示例:

    #pragma config FOSC = HS     // 使用高速外部晶振
    #pragma config WDTEN = OFF   // 关闭看门狗
    #pragma config PBADEN = OFF  // 将PORTB<5:0>设置为数字I/O
  • __CONFIG:这是旧版(如PIC16)的配置位设置方式,XC8仍然支持,但推荐使用#pragma config

  • __interrupt:用于定义中断服务程序,当中断事件发生时(如定时器溢出、外部引脚电平变化),程序会跳转到这个函数执行。

    示例:

    void __interrupt myISR() {
        // 中断处理代码
        if (TMR0IF) { // 检查TMR0溢出中断标志
            // ...处理代码...
            TMR0IF = 0; // 清除中断标志,非常重要!
        }
    }

核心外设编程

下面我们以最常用的PIC16F877A为例,讲解如何用C语言控制几个核心外设。

1 GPIO (通用输入/输出) - 控制LED

这是最简单的入门实验,假设我们要连接一个LED到RC0引脚。

  1. 设置方向TRISC寄存器控制PORTC的引脚方向。0为输出,1为输入。
    TRISC = 0x00; // 将PORTC的所有8个引脚都设置为输出
  2. 输出电平PORTC寄存器控制PORTC的引脚电平。1为高电平(VDD),0为低电平(VSS)。
    PORTC.F0 = 1; // 将RC0引脚置高,LED亮
    PORTC.F0 = 0; // 将RC0引脚置低,LED灭
    // 或者
    RC0 = 1;      // 使用位操作语法,更简洁

2 定时器 - 实现精确延时

PIC的定时器是其核心功能之一,我们可以用它来产生精确的延时或周期性事件,这里以Timer0为例。

  1. 配置Timer0

    • T0CS:时钟源选择。0为内部指令周期,1为外部T0CKI引脚。
    • T0SE:边沿选择。0为上升沿,1为下降沿。
    • PS2:PS0:预分频器选择,用于减慢定时器的计数速度。

    示例配置:使用内部时钟,1:256预分频

    OPTION_REGbits.T0CS = 0;    // 使用内部时钟
    OPTION_REGbits.PS = 0b111;  // 设置预分频比为1:256
    // 或者直接写值
    OPTION_REG = 0b11000111;   // T0CS=0, PSA=0(分频给TMR0), PS2-PS0=111(1:256)
  2. 使用Timer0延时

    • TMR0寄存器从0开始向上计数,计满(255)后会溢出,并置位TMR0IF中断标志。
    • 我们可以通过计算溢出次数来实现延时。

    示例:延时约1秒

    void delay_1s() {
        unsigned char i;
        for (i = 0; i < 61; i++) { // 循环61次,每次约16.384ms
            TMR0 = 0x3C; // 装入一个初值,例如60 (256-60=196 counts)
            while(!TMR0IF); // 等待TMR0溢出
            TMR0IF = 0; // 清除中断标志
        }
    }

3 UART (串行通信) - 与PC通信

UART可以让PIC与PC或其他设备进行串行通信,方便调试和数据显示。

  1. 配置UART

    • 波特率:需要根据时钟频率和SPBRG寄存器的值计算。
    • 数据位/停止位:通过TXSTARCSTA寄存器配置。

    示例:配置9600波特率,8位数据,1位停止位,无校验

    // 假设使用4MHz晶振
    TXSTA = 0x20; // TXEN=1 (发送使能), SYNC=0 (异步模式), BRGH=1 (高速波特率)
    RCSTA = 0x90; // SPEN=1 (串口使能), CREN=1 (连续接收使能)
    SPBRG = 25;   // 4MHz / (64 * (25+1)) ≈ 2403.8 bps (接近9600,需更精确计算)
    // 对于4MHz, 9600bps, BRGH=1, SPBRG = (4000000 / (16 * 9600)) - 1 = 25.04, 取25
  2. 发送和接收数据

    // 发送一个字符
    void UART_SendChar(char data) {
        while(!TXIF); // 等待发送缓冲区空
        TXREG = data; // 将数据写入发送寄存器
    }
    // 接收一个字符
    char UART_ReceiveChar() {
        while(!RCIF); // 等待接收到数据
        return RCREG; // 读取接收寄存器
    }

实战项目:LED闪烁与串口信息

这个项目结合了GPIO和UART,实现LED闪烁,并通过串口打印信息。

硬件: PIC16F877A, 4MHz晶振, LED接RC0, MAX232芯片用于串口电平转换。

代码:

#include <xc.h>
#pragma config FOSC = HS      // 高速外部晶振
#pragma config WDTE = OFF     // 关闭看门狗
#pragma config PWRTE = ON     // 上电延时定时器使能
#pragma config BOREN = ON     // 掉电检测使能
#pragma config LVP = OFF      // 禁用低电压编程
#pragma config CPD = OFF      // 禁止数据EEPROM代码保护
#pragma config WRT = OFF      // 禁止Flash程序存储器写保护
#pragma config CP = OFF       // 禁止代码保护
#define _XTAL_FREQ 4000000    // 定义晶振频率,方便延时函数使用
// 函数声明
void UART_Init();
void UART_SendString(const char *str);
void main() {
    TRISC = 0x00;      // 设置PORTC为输出
    PORTC = 0x00;      // 初始状态,LED灭
    UART_Init();       // 初始化串口
    UART_SendString("PIC UART Test\r\n"); // 发送欢迎信息
    while(1) {
        RC0 = 1;       // LED亮
        __delay_ms(500); // 使用XC8内置的延时函数
        RC0 = 0;       // LED灭
        __delay_ms(500);
        UART_SendString("LED Toggle\r\n"); // 每次闪烁都发送信息
    }
}
// UART初始化函数
void UART_Init() {
    TXSTA = 0x20;      // 发送使能, 异步模式, 高速波特率
    RCSTA = 0x90;      // 串口使能, 连续接收使能
    SPBRG = 25;        // 4MHz晶振, 9600波特率
}
// UART发送字符串函数
void UART_SendString(const char *str) {
    while (*str != '\0') {
        while(!TXIF); // 等待发送缓冲区空
        TXREG = *str; // 发送当前字符
        str++;        // 指向下一个字符
    }
}

进阶主题

当你掌握了基础后,可以探索更高级的主题:

  • MPLAB Harmony:Microchip官方的、现代化的嵌入式软件框架,它提供了图形化配置工具,可以自动生成驱动代码,大大简化了复杂项目的开发。
  • ADC (模数转换器):用于读取传感器(如温度、光线)的模拟信号。
  • PWM (脉宽调制):用于控制电机速度、调节LED亮度等。
  • I2C / SPI:常用的串行通信协议,用于连接OLED屏幕、EEPROM存储器、传感器等外设。
  • 中断:让CPU在执行主程序的同时,能够及时响应外部事件,提高系统效率。

总结与学习资源

PIC单片机的C语言开发,核心在于理解其硬件架构(寄存器)和编译器扩展#pragma config, __interrupt等),通过标准C语言逻辑来组织代码,通过操作寄存器来控制硬件,掌握GPIO、定时器、UART是入门的关键。

推荐学习资源:

  1. 官方资料

    • Microchip官网:所有数据手册、参考手册、应用笔记的最终来源。
    • MPLAB X IDE和XC编译器文档:官方是最好的老师。
    • Microchip Developer Portal:包含大量教程、示例代码和Harmony框架资料。
  2. 在线社区

    • Microchip官方论坛:可以提问,与官方工程师和开发者交流。
    • Stack Overflow:搜索C语言和嵌入式开发相关的问题。
  3. 书籍

    • 《PIC Microcontroller and Embedded Systems: Using Assembly and C for PIC18》 by Muhammad Ali Mazidi。
    • 《Programming 8-bit PIC Microcontrollers in C》 by Martin P. Bates。

希望这份指南能帮助你顺利开启PIC单片机的C语言编程之旅!祝你学习愉快!

-- 展开阅读全文 --
头像
页如何调用文章描述?
« 上一篇 02-13
织梦dedecms版权如何正确处理?
下一篇 » 02-13

相关文章

取消
微信二维码
支付宝二维码

目录[+]