单片机的外部结构和C语言编程基础说明

发布时间:2023-09-12  

对于51系列单片机,现有四种编程语言支持,即汇编、pl/m,c和basic通常附在pc机上,是初学单片机编程的第一种语言。一个新变量名定 义之后可在程序中作变量使用,非常易学,根据解释的行可以找到 错误而不是当程序执行完才能显现出来。basic由于逐行解释自然很 慢,每一行必须在执行时转换成机器代码,需要花费许多时间不能 做到实时性。basic为简化使用变量,所有变量都用浮点值。basic 是用于要求编程简单而对编程效率和运行速度要求不高的场合。


pl/m是intel从8080微处理器开始为其系列产品开发的编程语言。现在已经没有看到人在使用了, 它很像pascal,是一种结构化语言,但它使用关键字去定义结构。 pl/m编译器好像汇编器一样可产生紧凑代码。pl/m总的来说是“高 级汇编语言”,可详细控制着代码的生成。但对51系列,pl/m不支 持复杂的算术运算、浮点变量而无丰富的库函数支持。学习pl/m无 异于学习一种新语言。


c语言是一种源于编写unix操作系统的语言,它是一种结构化 语言,可产生压缩代码。c语言结构是以括号{}而不是子和特殊符 号的语言。c可以进行许多机器级函数控制而不用汇编语言。与汇编相比,有如下优点:


对单片机的指令系统不要求了解,仅要求对51的存储器结构有 初步了解寄存器分配、不同存储器的寻址及数据类型等细节可由 编译器管理程序有规范的结构,可分为不同的函数。这种方式可 使程序结构化将可变的选择与特殊操作组合在一起的能力,改善了程序的可读性 编程及程序调试时间显著缩短,从而提高效率 提供的库包含许多标准子程序,具有较强的数据处理能将已编好程序可容易的植入新程序,因为它具有方便的模块化编程技术c语言作为一种非常方便的语言而得到广泛的支持,c语言程序本身并不依赖于机器硬件系统,基本上不做修改就可根据单片机的 不同较快地移植过来。是现在最流行的单片机编程语言

51的汇编语言非常像其他汇编语言,有人说单片机编程高手一般都用汇编语言。51的指令系统比第一代微处理 器要强一些。51的不同存储区域使得其复杂一些。尽管懂得汇编 语言不是你的目的,看懂一些可帮助你了解影响任何语言效率的 51特殊规定。例如,懂得汇编语言指令就可以使用在片内ram作 变量的优势,因为片外变量需要几条指令才能设置累加器和数据指针进行存取。要求使用浮点和启用函数时只有具备汇编编程经 验才能避免生成庞大的、效率低的程序,这需要考虑简单的算术 运算或先算好的查表法。最好的软件编程者应是由汇编转用c而不是原来用过标准c语言的人。


单片机的外部结构:

1、 DIP40双列直插;

2、 P0,P1,P2,P3四个8位准双向I/O引脚;(作为I/O输入时,要先输出高电平)

3、 电源VCC(PIN40)和地线GND(PIN20);

4、 高电平复位RESET(PIN9);(10uF电容接VCC与RESET,即可实现上电复位)

5、 内置振荡电路,外部只要接晶体至X1(PIN18)和X0(PIN19);(频率为主频的12倍)

6、 程序配置EA(PIN31)接高电平VCC;(运行单片机内部ROM中的程序)

7、 P3支持第二功能:RXD、TXD、INT0、INT1、T0、T1

单片机内部I/O部件:(所为学习单片机,实际上就是编程控制以下I/O部件,完成指定任务)

1、 四个8位通用I/O端口,对应引脚P0、P1、P2和P3;

2、 两个16位定时计数器;(TMOD,TCON,TL0,TH0,TL1,TH1)

3、 一个串行通信接口;(SCON,SBUF)

4、 一个中断控制器;(IE,IP)

针对AT89C52单片机,头文件AT89x52.h给出了SFR特殊功能寄存器所有端口的定义。教科书的160页给出了针对MCS51系列单片机的C语言扩展变量类型。

单片机C语言编程基础:

1、 十六进制表示字节0x5a:二进制为01011010B;0x6E为01101110。

2、 如果将一个16位二进数赋给一个8位的字节变量,则自动截断为低8位,而丢掉高8位。

3、 ++var表示对变量var先增一;var—表示对变量后减一。

4、 x |= 0x0f;表示为 x = x | 0x0f;

5、 TMOD = ( TMOD & 0xf0 ) | 0x05;表示给变量TMOD的低四位赋值0x5,而不改变TMOD的高四位。

6、 While( 1 ); 表示无限执行该语句,即死循环。语句后的分号表示空循环体,也就是{;}

在某引脚输出高电平的编程方法:(比如P1.3(PIN4)引脚)

#include //该头文档中有单片机内部资源的符号化定义,其中包含P1.3

void main( void ) //void 表示没有输入参数,也没有函数返值,这入单片机运行的复位入口

{

P1_3 = 1; //给P1_3赋值1,引脚P1.3就能输出高电平VCC

While( 1 ); //死循环,相当 LOOP: goto LOOP;

}

注意:P0的每个引脚要输出高电平时,必须外接上拉电阻(如4K7)至VCC电源。

在某引脚输出低电平的编程方法:(比如P2.7引脚)

#include //该头文档中有单片机内部资源的符号化定义,其中包含P2.7

void main( void ) //void 表示没有输入参数,也没有函数返值,这入单片机运行的复位入口

{

P2_7 = 0; //给P2_7赋值0,引脚P2.7就能输出低电平GND

While( 1 ); //死循环,相当 LOOP: goto LOOP;

}

在某引脚输出方波编程方法:(比如P3.1引脚)

#include //该头文档中有单片机内部资源的符号化定义,其中包含P3.1

void main( void ) //void 表示没有输入参数,也没有函数返值,这入单片机运行的复位入口

{

While( 1 ) //非零表示真,如果为真则执行下面循环体的语句

{

P3_1 = 1; //给P3_1赋值1,引脚P3.1就能输出高电平VCC

P3_1 = 0; //给P3_1赋值0,引脚P3.1就能输出低电平GND

} //由于一直为真,所以不断输出高、低、高、低……,从而形成方波

}

将某引脚的输入电平取反后,从另一个引脚输出:( 比如 P0.4 = NOT( P1.1) )

#include //该头文档中有单片机内部资源的符号化定义,其中包含P0.4和P1.1

void main( void ) //void 表示没有输入参数,也没有函数返值,这入单片机运行的复位入口

{

P1_1 = 1; //初始化。P1.1作为输入,必须输出高电平

While( 1 ) //非零表示真,如果为真则执行下面循环体的语句

{

if( P1_1 == 1 ) //读取P1.1,就是认为P1.1为输入,如果P1.1输入高电平VCC

{ P0_4 = 0; } //给P0_4赋值0,引脚P0.4就能输出低电平GND

else //否则P1.1输入为低电平GND

//{ P0_4 = 0; } //给P0_4赋值0,引脚P0.4就能输出低电平GND

{ P0_4 = 1; } //给P0_4赋值1,引脚P0.4就能输出高电平VCC

} //由于一直为真,所以不断根据P1.1的输入情况,改变P0.4的输出电平

}

将某端口8个引脚输入电平,低四位取反后,从另一个端口8个引脚输出:( 比如 P2 = NOT( P3 ) )

#include //该头文档中有单片机内部资源的符号化定义,其中包含P2和P3

void main( void ) //void 表示没有输入参数,也没有函数返值,这入单片机运行的复位入口

{

P3 = 0xff; //初始化。P3作为输入,必须输出高电平,同时给P3口的8个引脚输出高电平

While( 1 ) //非零表示真,如果为真则执行下面循环体的语句

{ //取反的方法是异或1,而不取反的方法则是异或0

P2 = P3^0x0f //读取P3,就是认为P3为输入,低四位异或者1,即取反,然后输出

} //由于一直为真,所以不断将P3取反输出到P2

}

注意:一个字节的8位D7、D6至D0,分别输出到P3.7、P3.6至P3.0,比如P3=0x0f,则P3.7、P3.6、P3.5、P3.4四个引脚都输出低电平,而P3.3、P3.2、P3.1、P3.0四个引脚都输出高电平。同样,输入一个端口P2,即是将P2.7、P2.6至P2.0,读入到一个字节的8位D7、D6至D0。

1、 接电源:VCC(PIN40)、GND(PIN20)。加接退耦电容0.1uF

2、 接晶体:X1(PIN18)、X2(PIN19)。注意标出晶体频率(选用12MHz),还有辅助电容30pF

3、 接复位:RES(PIN9)。接上电复位电路,以及手动复位电路,分析复位工作原理

4、 接配置:EA(PIN31)。说明原因。

发光二极的控控制:单片机I/O输出

将一发光二极管LED的正极(阳极)接P1.1,LED的负极(阴极)接地GND。只要P1.1输出高电平VCC,LED就正向导通(导通时LED上的压降大于1V),有电流流过LED,至发LED发亮。实际上由于P1.1高电平输出电阻为10K,起到输出限流的作用,所以流过LED的电流小于(5V-1V)/10K = 0.4mA。只要P1.1输出低电平GND,实际小于0.3V,LED就不能导通,结果LED不亮。

开关双键的输入:输入先输出高

一个按键KEY_ON接在P1.6与GND之间,另一个按键KEY_OFF接P1.7与GND之间,按KEY_ON后LED亮,按KEY_OFF后LED灭。同时按下LED半亮,LED保持后松开键的状态,即ON亮OFF灭。

#include

#define LED P1^1 //用符号LED代替P1_1

#define KEY_ON P1^6 //用符号KEY_ON代替P1_6

#define KEY_OFF P1^7 //用符号KEY_OFF代替P1_7

void main( void ) //单片机复位后的执行入口,void表示空,无输入参数,无返回值

{

KEY_ON = 1; //作为输入,首先输出高,接下KEY_ON,P1.6则接地为0,否则输入为1

KEY_OFF = 1; //作为输入,首先输出高,接下KEY_OFF,P1.7则接地为0,否则输入为1

While( 1 ) //永远为真,所以永远循环执行如下括号内所有语句

{

if( KEY_ON==0 ) LED=1; //是KEY_ON接下,所示P1.1输出高,LED亮

if( KEY_OFF==0 ) LED=0; //是KEY_OFF接下,所示P1.1输出低,LED灭

} //松开键后,都不给LED赋值,所以LED保持最后按键状态。

//同时按下时,LED不断亮灭,各占一半时间,交替频率很快,由于人眼惯性,看上去为半亮态

}

数码管的接法和驱动原理及单片机编程

一支七段数码管实际由8个发光二极管构成,其中7个组形构成数字8的七段笔画,所以称为七段数码管,而余下的1个发光二极管作为小数点。作为习惯,分别给8个发光二极管标上记号:a,b,c,d,e,f,g,h。对应8的顶上一画,按顺时针方向排,中间一画为g,小数点为h。

我们通常又将各二极与一个字节的8位对应,a(D0),b(D1),c(D2),d(D3),e(D4),f(D5),g(D6),h(D7),相应8个发光二极管正好与单片机一个端口Pn的8个引脚连接,这样单片机就可以通过引脚输出高低电平控制8个发光二极的亮与灭,从而显示各种数字和符号;对应字节,引脚接法为:a(Pn.0),b(Pn.1),c(Pn.2),d(Pn.3),e(Pn.4),f(Pn.5),g(Pn.6),h(Pn.7)。

如果将8个发光二极管的负极(阴极)内接在一起,作为数码管的一个引脚,这种数码管则被称为共阴数码管,共同的引脚则称为共阴极,8个正极则为段极。否则,如果是将正极(阳极)内接在一起引出的,则称为共阳数码管,共同的引脚则称为共阳极,8个负极则为段极。

以单支共阴数码管为例,可将段极接到某端口Pn,共阴极接GND,则可编写出对应十六进制码的七段码表字节数据如右图:

16键码显示的单片机程序

我们在P1端口接一支共阴数码管SLED,在P2、P3端口接16个按键,分别编号为KEY_0、KEY_1到KEY_F,操作时只能按一个键,按键后SLED显示对应键编号。

#include

#define SLED P1

#define KEY_0 P2^0

#define KEY_1 P2^1

#define KEY_2 P2^2

#define KEY_3 P2^3

#define KEY_4 P2^4

#define KEY_5 P2^5

#define KEY_6 P2^6

#define KEY_7 P2^7

#define KEY_8 P3^0

#define KEY_9 P3^1

#define KEY_A P3^2

#define KEY_B P3^3

#define KEY_C P3^4

#define KEY_D P3^5

#define KEY_E P3^6

#define KEY_F P3^7

Code unsigned char Seg7Code[16]= //用十六进数作为数组下标,可直接取得对应的七段编码字节

// 0 1 2 3 4 5 6 7 8 9 A b C d E F

{0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};

void main( void )

{

unsigned char i=0; //作为数组下标

P2 = 0xff; //P2作为输入,初始化输出高

P3 = 0xff; //P3作为输入,初始化输出高

While( 1 )

{

if( KEY_0 == 0 ) i=0; if( KEY_1 == 0 ) i=1;

if( KEY_2 == 0 ) i=2; if( KEY_3 == 0 ) i=3;

if( KEY_4 == 0 ) i=4; if( KEY_5 == 0 ) i=5;

if( KEY_6 == 0 ) i=6; if( KEY_7 == 0 ) i=7;

if( KEY_8 == 0 ) i=8; if( KEY_9 == 0 ) i=9;

if( KEY_A == 0 ) i=0xA; if( KEY_B == 0 ) i=0xB;

if( KEY_C == 0 ) i=0xC; if( KEY_D == 0 ) i=0xD;

if( KEY_E == 0 ) i=0xE; if( KEY_F == 0 ) i=0xF;

SLED = Seg7Code[ i ]; //开始时显示0,根据i取应七段编码

}

}


个人觉得单片机编程入门并不难,但写一个好的程序出来非常的难,她和电脑不同,要考虑到执行效率以及抗干扰等问题。


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>