程序是怎样从PC下载到MCU的

引言

单片机程序一般用C编写,从程序编写到程序运行,要通过两个步骤:编译和烧写。编译是将C编写的单片机程序,编译成单片机可以识别的二进制代码。烧写是把编译好的二进制文件,通过烧录程序或者硬件,存储到单片机的ROM内存中。通常这两步都有专业软件来完成,对开发者是不可见的。但为了更加高效地开发单片机程序,我们有必要深入地了解编译和烧写过程。

C程序的编译

开发单片机一定会接触Keil C51,它是一款强大的51单片机集成开发环境(IDE)。51单片机虽然支持同一套指令集,但是由于各公司生产的单片机在内存、架构上都有区别,因此不能共用一套代码。而Keil C51集成了多种单片机的型号,可以针对不同的单片机编译对应的二进制文件。

二进制文件的烧写

编译后的二进制文件,并不能直接写到单片机的ROM中,还需要通过串口进行传输,一般有以下几种方法:

  1. 把单片机当做一个ROM芯片,早期的单片机都是如此。将单片机放在通用编程上编程时,就像给28C256这样的ROM中写程序的过程一样。只是不同的单片机使用的端口,编程用的时序不一样。

  2. 像AT89S52或AVR单片机一样,在单片机上有SPI接口,这时用专用的下载线将程序烧写到单片机中。这时不同的是,单片机的CPU除了执行单片机本身的指令之外,还能执行对ROM进行操作的特殊指令,如ROM擦除、烧写和校验指令。在编程ROM时,下载线先通过传输这些指令给CPU执行(擦除ROM、读入数据、烧写ROM、和校验ROM),这样完成对单片机的ROM的烧写。此外,现在普遍使用的JTAG仿真器也是这样,单片机的CPU能执行JTAG的特殊指令,完成对ROM的烧写操作。

  3. 引导程序,即单片机中已经存在了一个烧写程序。启动单片机时首先运行这程序,程序判断端口状态,如果符合“要烧写ROM”的状态存在,就从某个端口(串口、SPI等等)读取数据,然后写入到单片机的ROM中。如果没有“要烧写ROM”的状态,就转到用户的程序开始执行。像AVR单片机的bootloader方式、STC的串口下载方式,还有其他单片机的串口编程等等都是这样。

STC单片机的烧写流程

其中“检测P3.0有没有合法下载命令流”,指的是为ISP_TRIG寄存器赋值的命令。当为ISP_TRIG赋0x46H和0xB9H时,ISP读写功能被触发,可以对程序寄存器进行进一步的读写,从而控制FLASH的读写。具体的实现方案可以参考Github上的stcflash项目。