你预备写榜首个单片机程序了,在此之前我假定你现已会运用编译器,也会下载程序了。
P.S. 由于这些作业的确很简单,在网上找份教程看看就会了。
一般刚开端学一种单片机的时分,写的榜首个程序都是“点亮榜首个LED”。这个程序很经典,它代表你现已成功学会控制单片机的IO端口,学51单片机亦是如此。代码如下(我运用ATMEL 公司的AT89S52):
#include
sbit LED = P1^0 ;
void Delay(unsigned int t)
{
}
void main(void)
{
}
单片时机从main函数开端履行,所以咱们把思绪拉到main函数。
一开端用了“ LED = 1 ;”,初始化IO端口,让它设定在某个状况。接下来运用一个while大循环句子,调用Delay函数,时刻一到就把LED取反,再回到循环,循环往复。在高档言语里边看起来这个进程形似很简单,小学生都会理解了。可是你知道把它翻译成机器码之后是什么样的吗?在这里我不想把发生的汇编代码贴出来,以免你难以承受。不过我能够把履行进程具体地讲给你听。
首要,一切的CPU,它们在履行指令的时分都是从程序段的0地址(也便是程序最开端的当地)开端的,并且CPU永久只做两件作业,一是从程序区里取出指令,二是履行这条指令,然后再回去取指令。。
这样说很简单嘛,把main函数的代码从程序区的0地址开端一条条寄存不就行了吗。其实不是这样的,一般0地址里寄存的都不会是main函数的实在代码,它会放一条跳转指令(便是一条指令后边跟一个地址,告知CPU要跳到那个当地去作业),这条指令跟着的是main函数的进口地址,把单片机指到main函数真实的地址去履行。为什么要这样做?看下面的图:
程序存储区的固定前面几个地址是要用来寄存中止服务程序的地址的(中止?后边会讲,先不论),称之为“中止向量”。程序在履行进程中遇到中止的时分,它就会依据中止信号的类型跳回到这些固定的地址,再由这些地址里边存储的指令指引,跳转到中止服务程序真实开端的当地去履行。所以,最开端的一系列地址是不能寄存另的东西的,否则程序会乱掉。假如你把main函数界说在这里,没遇到中止之前当然能够正常运转,但假如你在程序中运用了中止,结果就无法想象了。总而言之,main不是放在最开端的当地的!
那它放在哪里?理论上只需避开了中止向量地址的抵触,你能够放在任何当地,你用C言语编写的时分编译器会主动处理这个问题,不必你操心,假如今后你要用汇编写了,你就有必要自己界说main函数的地址了。
好了,那咱们就进入main函数里边看看吧。
依据这段代码,你觉得榜首句应该履行的句子应该是“ LED = 1 ;”,然后是while循环。。BLA..BLA..
错了,进入main函数之后首要要做的作业是初始化相关寄存器。由于芯片刚开端作业的时分,寄存器都处于一种不知道的状况,你有必要首要赋给它一个初值才行,在这个main函数中没有运用变量,所以能够不必初始化内存区,但至少CPU有必要初始化一个很重要的寄存器:SP仓库指针。关于这家伙今后再讲,总归便是先初始化。
初始化完毕之后才开端履行你的真实的代码,先让LED设置为1,然后进入一个循环结构,调用延时函数Delay,等候它履行完毕之后再回来把LED取反,然后回来持续循环往复地履行。
等等,有一个很重要的问题:单片机是怎样延时的?在延时的时刻里它都在干什么?
咱们知道,单片机的一个主要功能便是履行速度,也便是一秒钟能履行多少条指令,一般速度越快代表功能越好,比方51单片机假如你在外面给它接上一个12M Hz的晶振,它的CPU就会以一百万条/秒的速度作业,便是说它履行一条指令要花费一百万分之一秒的时分即一微秒(是不是觉得很快?其实以现在的规范来说现已算很慢了,慢得像乌龟)。依照这个道理,假如咱们想要让单片机延时,比方延时1ms,咱们能够让CPU空转1000次,由于CPU空转一次也需求一条指令的时刻。让它转上1000次之后完毕,那么就相当于它推迟了1ms,延时函数便是这样写出来的,作业原理假如下图:
这便是Delay函数的效果,可是这样的延时不能做到很准确,由于在这段时刻里CPU要履行判别、赋值等等一系列指令,在C言语写的代码里边你不能准确预测到编译器会把你这段代码转换为怎样样的汇编指令,所以你也就无法计算出准确的变量值,只能在一个大约的规模里边选取。尽管C言语写起程序来很便利,但一起它的缺陷也闪现在这里:无法控制编译器写出准确的推迟函数,在有些对时刻要求很高的场合里C言语无法担任,只能用汇编来写;一起用C言语写出的程序发生的机器码一般都比用汇编写的要多,即不行精简,功率不高,在有些单片机里边程序存储容量不高的话就比较费事,不过现在的单片机程序存储容量遍及都比较高了。这样说来用C言语来写一些对时刻性要求不高的程序是很有优势的,开发周期比汇编要高得多。