加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

《精通51单片机开发技术与应用实例》读书笔记

(2012-12-27 21:22:51)
标签:

学习

Chapter2  51系列单片机基本结构

8051系列单片机主要由中央处理器(CPU)、程序存储器(ROM)数据存储器(RAM)、串行接口、并行I/O接口、定时/计数器、中断系统等几大单元,以及数据总线、地址总线和控制总线组成。

程序存储器(ROM):用于存放用户程序、原始数据或表格等80514M*8bit

数据存储器(RAM):可存放读写的数据、运算的中间结果或用户定义的字型表等8051内部为128个。

216位的可编程定时/计数器,48I/O,一个全双工串行通信口,两个外中断、两个定时器/计数器中断、一个串行中断。并具有2级的优先级供选择。

哈佛(Harvard)结构;ROMRAM分开。

普林斯顿(Princeton)结构,也称冯·洛伊曼结构,程序存储地址和数据存储地址指向同一个存储器的不同物理位置。

 

来源于:http://baike.baidu.com/view/712809.htm

VCCC=circuit 表示电路的意思, 即接入电路的电压;

VDDD=device 表示器件的意思, 即器件内部的工作电压;

VSSS=series 表示公共连接的意思,通常指电路公共接地端电压;

VEEE=electron 表示构成物质的基本粒子之一,因带负电,也写作e,通常指负电压供电;

VDDHH=high 表示高压,即高压供电端。

 1、对于数字电路来说,VCC是电路的供电电压,VDD是芯片的工作电压(通常Vcc>Vdd),VSS是接地点。

 2、有些IC既有VDD引脚又有VCC引脚,说明这种器件自身带有电压转换功能,这个时候Vdd仅仅是给器件内部的数字或模拟系统供电,而Vcc是给包括外设和内部系统供电,所以Vcc的电压必须比Vdd高。

 3、在场效应管(或COMS器件)中,VDD为漏极,VSS为源极,VDDVSS指的是元件引脚,而不表示供电电压。

 4、一般来说VCC=模拟电源,VDD=数字电源,VSS=数字地,VEE=负电源

 

堆栈指针SP是在片内RAM中开辟了一个存储区域,采用8位增量的寄存器,堆栈深度为0~255个存储单元。系统复位后,SP的初始值为07H,即栈底为08H单元,这与工作寄存器区域重叠,必须重新定义SP

由于访问外部RAM是随机的,其访问地址可由工作寄存器R0R1来寻址256B单元或由数据制作DPTR寻址54KB的空间。R0R18位地址由P0口送入地址锁存器输出,DPTR16位地址则由P0口输出低8位地址到锁存器中,P2口则输出高8位地址,读写的数据由P0口输入/输出。(外部RAM起始地址为0000H

E(--)A(--)=1,即接高电平,CPU从片内开始读取程序,当超过片内ROM的容量是,转向外部ROM。所以,外部ROM的地址是接在片内ROM。对于无片内ROM8031来说,必须使E(--)A(--)=0。而数据存储器的片外地址是从0000H开始的(片内的为00H~7FH)

方位片内RAMMOV指令,访问片外用MOVX类指令。

 

 

ALE/PROG(--------)ALE为地址锁存使能端和编程脉冲输入端

PSEN(--------):访问外ROM选通信号

EA(----)/VPP:方位内外ROM选择信号,进行flash编程时,提供flash编程电压。

RD(----),WR(----):读RAM,RAM选通信号。

访问外部ROMRAM各有不同的地址指针PCRiDPTR,各指针又有不同的读或读写选通信号PSEN(--------)RD(----),WR(----)。这就从结构上把ROMRAM的访问分开。

访问外部RAM需选用MOVX类指令,读取ROM中的固定数据,则需选用MOVC类指令。

 

XTAL1XIAL2分别为片内反相放大器的输入、输出端口,其工作频率为0~33MHZ。外接晶体或陶瓷振荡器,并接两个电容后接地即可。具体要求如下:

u       当外接晶体振荡器的时候,电容值一般选择C1=C2=30+10PF

u       当外接晶体振荡器的时候,电容值一般选择C1=C2=40+10PF

单字节单周期指令执行时序,在每个机器周期内,ALE信号出现两次高电平有效信号,第二次读的代码将被丢弃,不适用。

       访问外部ROMP0口作文地址和数据分时复用,它先输出低8位地址,并利用ALE信号使其锁存下来,和P2口的高八位组成16位地址。在 信号有效的情况下,便可以从外部ROM中读取指令,再通过P0口送到单片机中。

       访问外部RAM:先把地址准备好,然后 有效,这样便将外部RAM中的数据送到单片机的P0口。

P0是漏极开路电路,故需外接上拉电阻(5KΩ~10KΩ)才能正常工作。P1P2P3内部都有上拉电阻。当先输出然后输入的时候,应该在输入操作前加一条输出1的指令(使输出驱动电路的FET截止),然后输入才正确。

端口有两种读取方式,读锁存器和读引脚。当指令的目的操作数为I/O口是,该指令所读的便是锁存器重的内容。

并行I/O口的扩展,1.用可编程的I/O口芯片比较贵,使用比较复杂。2.可以采用普通的锁存器、三态门等来进行简单的I/O口扩展。一般扩展的I/O口采用与外部RAM统一编址的方法。用64MBRAM空间的一部分作为扩展I/O端口的地址空间。根据P49页的电路图,其程序

MOV DPTR,#0FEFFH

MOVX A,@DPTR

使用MOVX读指令后, 就会有效,然后数据会准备在P0口上,#0FEFFH只是一个虚拟地址即可。

低功耗设计:1.省电保持模式:将内部振荡器停止工作,内部所有的功能部件均停止工作,但内部RAM和全部的特殊功能寄存器的数据将被保存。2.休眠运行模式:送往CPU内部的时钟信号被封锁,CPU被冻结,其他寄存器的内容不变,各端口的状态也保持不变,片内RAM的数据不丢失,外部设备也可以正常运行。

 

 

访问能位寻址寄存器中的各位是,.位”、“字节地址.位”、“位地址”、“为名称”等来表示。如B.5表示寄存器B的第5位。

 

Chapter4汇编语言程序设计

BIT 位地址符号伪指令,使用格式: 字符名称  BIT   位地址

例如: P20  BIT  P2.0  各部分之间用分隔符隔开,分隔符可以采用空格、冒号、分号(汇编语言程序的格式)。

 

 

Chapter6 单片机C语言程序设计基础

 

 

    C51扩展的关键字

关键字

用途

说明

 

 

 

_at_

地址定位

为变量进行存储器绝对空间地址定位

alien

函数特性声明

用以声明与PL/M51兼容的函数

bdata

存储器类型声明

可位寻址的8051内部数据存储器

bit

位变量声明

声明一个位变量或位类型的函数

code

存储器类型声明

8051程序存储器空间

conpact

存储器模式

指定使用8051外部分页寻址数据存储器空间

data

存储器类型声明

直接寻址的8051内部数据存储空间

idata

存储器类型声明

间接寻址8051内部数据存储空间

intertupt

中断函数声明

定义一个中断服务函数

large

存储模式

指定使用8051外部数据存储空间

pdata

存储器类型声明

分页寻址的8051外部数据存储器

_priority

多任务优先声明

规定RTX51TRX51 Tiny的任务优先级

reentrant

再入函数声明

定义一个再入函数

sbit

位变量声明

声明一个可位寻址变量

sfr

特殊功能寄存器声明

声明一个8位的特殊功能寄存器

sfr16

特殊功能寄存器声明

声明一个16位的特殊功能寄存器

small

储存器模式

指定使用8051内部数据存储空间

_task_

任务声明

定义实时多任务函数

using

寄存器组定义

定义8051的工作寄存器组

xdata

储存器类型声明

8051外部数据存储器

 

 

C51编译器运行使用如下的整型简写形式:short int 简写为short

                                     long int 简写为long

                                     unsigned short int简写为unsigned short

                                     unsigned int 简写为unsigned

                                     unsigned long int 简写为unsigned long

 

来源于:http://www.dzsc.com/dzbbs/20050421/20076519214109898.html

keilprintf默认为向串口输出,需要对串口初始化。

 

 

char str[3];C51编译时,系统将留出3个字符的连续空间,最后一个用来放字符终止符NULL,即“\0”,只有前两个可以自由赋值,若对str[2]也赋值,将导致程序的错误输出。

C51语言中的字符常量是按整型(short型)存储的。

自动变量:默认的变量,所在函数执行时才分配存储空间,执行完后,释放存储空间,这既是为什么函数内部定义的变量,不能够在函数外使用的原因。

外部变量:在整个程序文件的最前面,也称全局变量,在另一个文件中使用时,要加extern关键字来显示声明。

静态变量:用static声明,程序运行期间由系统分配固定的存储空间。

寄存器变量:用register声明,C51中只允许同时定义两个寄存器变量,多余的会自动当做非寄存器变量来处理。

static声明内部函数(只能在本文件中使用),默认的为外部函数(用extern声明)。

 

C51分隔符:起辅助表示和分界的作用。例:用“*”做指针,用“#”做预处理伪指令,用“^”标识特殊寄存器的位,例如:sbit P00=P0^0

       大多数的编译环境下,采用自增和自减操作符所生成的代码,比等价的赋值语句生成的代码执行得要快。例(x++)是先调用x的值,然后再++,即(x++)的值为x

       逻辑运算符:! || &&。它和关系运算符的返回值都是truefalse,且C51规定,非0值为True,0值为Flase

       位运算符是对字或字节的二进制位(bit)进行处理的运算符。所以只能针对C标准中的charint数据类型而言的。

       特殊运算符:“,”运算符,z=(a++,++b+);“?”运算符exp1exp2exp3; &”、“*”、联合操作a+=b;适用于所有的双目操作符。“sizeof”返回变量所占的字节类型长度字节,类型转换运算符,(类型) 表达式。

       运算符的结合性:左结合性,变量(或常量)与左边的运算符结合。凡是单目运算符都是右结合,凡是双目运算符都是左结合,其中“?”、“:”运算符是三目运算符,是右结合的。

 

 

Chapter7 数组

数组名不能与其他变量名同名,数组下标从0开始,C51不支持动态分配数组大小。只能给数组元素逐个赋值,若不初始化,C51会自动处理,外部型和静态型变量的初始值为0自动型和寄存器型变量的初始值为随机数。在声明字符数组,必须声明一个比要存的字符串多一个字符的数组,最后一位用来存储空字符“\0”。

关于多维数组,单片机的CPU要花大量时间计算数组下标。

关于keil无法查看库函数的实现,应该是在lib库中,以一定的格式存放。

 

 

来源于:网络资料

 

       选择C语言启动代码,若使用汇编来编程,则不用。Keil编译后,data后的数据表示使用片内RAM的大小,xdata表示使用外部数据大小,code表示程序的大小。单位为字节。

       指针:1.内存则是按一个字节一个字节进行编址, 如上图所示。每个字节都有个编号,我们称之为内存地址。2. 其实上面的指针是指针变量,而数组名只是一个指针常量。3. 其实,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun 函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。

 

extern char *strcat(char *dest,char *src);由其函数原型可知(来源于网络return address),其返回一个指针类型。

 

函数定义:类型标示符 函数名(); 函数带回来的值的类型,默认为int

指针定义:基类型 *指针变量名;基类型:指向变量的类型*指针标示符

      数组:   类型 数组名[长度]  类型:所有元素为同一类型

 

 

      keil uvision4中头文件可用#include,可在安装目录INC下却是STRING.H。查阅help文档,有一句Include files usually have an extension of .H indicating they are Header files. We recommend you use this standard for your user header files.没有明确,但应该是指可以大小写互换的。

      指针只提供一个地址,在函数指针中,它还要提供参数的格式和类型的信息以及期望的返回值类型,所以,函数指针的声明要比其他数据类型的指针的声明复杂得多。例如:Int (*pfunction)(int),指针的名字叫做pfunction,他要指向的函数具有一个int型参数,将给调用程序返回一个int型的值。调用时只用函数名即可,否则会误认问是函数调用。

Chapter9 结构

    对于多重结构,必须逐级找到最低级的成员才能使用。例如:bob.score.chinese

      位结构

Struct student

{

      char *name;

      ……

      unsigned zhuce :1;     // 位结构定义的一般形式:数据类型 变量名:整型常数(表示二进制位的个数,范围为0~15

      unsigned pay :1;

};

 

Chapter11 C51语言的函数

 

用数组名作为函数参数,要求形参和相对应的实参都必须是类型相同的数组。

指针作为函数参数,实际向函数传递的事变量的地址

C51语言中,使用goto语句也只能在本函数内部使用

字符函数CTYPE.H

字符串函数STRING.H

I/O函数 STDIO.H

数学函数MATH.H

标准函数STDLIB.H

内部函数INTRINS.H

绝对地址访问函数 ABSACC.H

_lrol_    (unsigned long, unsigned char)虽然移动的位为char型,但超过8位似乎也正确。

 

有些变量可以再使用前声明,有些只能在函数模块的最前面声明。这与是否支持C99标准有关。C89C90ANSI C基本上指同一个标准,C992000年的一个标准,现行标准时C11

 

Chapter14 预处理及用户配置文件

条件编译指令 #if#else#endif

#elif命令用于进行多种编译选择

#ifdef#ifndef命令用于判断宏名是否被定义(一般用define定义)。

#pragma命令用于向编译程序传送各种C51语言编译器的控制指令。

 

 

 

Chapter15 C51语言的存储结构

sfr16不能用于定时器01的定义,因为定时器01可以作为两个8位的用,用sfr16后,就无法拆开使用。

uchar xdata *data pstr;  声明了一个存储于data,指向xdata区域的指针。C51中,一般指针可存放于任何存储器中,一般用3个字节进行存放。第一个字节为存储器类型,第二个字节为偏移量的高位,第三个字节为偏移量的低位。使用一般指针可以访问存放在存储器任何位置的数据而不用考虑其存储器类型。

对于有RAM,就有访问效率的问题。

 

Chapter16  51系列单片机的定时器/计数器

 

计数:由于单片机需要两个机器周期来确认一次计数(电平发生变化),所以,外部输入的计数脉冲的最高频率为单片机振荡器频率的1/24,

定时:每个机器周期都将计数器的值加1。计数速率为振荡器频率的1/12

GATE控制信号,决定 信号是否起作用。

方式0,13位计数器。方式1,16位计数器。方式2,自动重载初值。只有T0有方式3,占用了T1的中断(TF1),此时T1可以设置为方式012,用在串行口波特率发生器或不需要中断控制的场合。

 

 

Chapter18 51系列单片机中断系统及其程序设计

51系列单片机,一个中断响应最少需要三个机器周期才能完成。

51系列,外部中断01,定时器01CPU响应中断后,将自动清除该中断请求的标志位。而串行口中断后,需要中断服务程序中用软件设置清除

 

来源于:http://wenku.baidu.com/view/3a5923d628ea81c758f578e4.html51

函数编写注意事项:

void Timer0() interrupt 1 using 1

Timer0   是函数名,随便取的 

interrupt   xx   using   y 

  跟在interrupt   后面的xx   值得是中断号,就是说这个函数对应第几个中断端口,一般在51 

  0   外部中断0   

  1   定时器0 

  2   外部中断1 

  3   定时器1 

  4   串行中断 

实际上编译的时候就是把你这个函数的入口地址放到这个对应中断的跳转地址 

 

using   y   这个y是说这个中断函数使用的那个寄存器组,51里面一般有4   r0   --   r7寄存器,一共有32个,如果你的终端函数和别的程序用的不是同一个寄存器组则进入中断的时候就不会将寄存器组压入堆栈,返回时也不会弹出来节省代码和时间

 

MCS-51中断函数注意如下:

1)中断函数不能进行参数传递,如果中断函数中包含任何参数声明都将导致编译出错。

2)中断函数没有返回值,如果企图定义一个返回值将得不到正确的结果,建议在定义中断函数时将其定义为void类型,以明确说明没有返回值。

3)在任何情况下都不能直接调用中断函数,否则会产生编译错误。因为中断函数的返回是由8051单片机的RETI指令完成的,RETI指令影响8051单片机的硬件中断系统。如果在没有实际中断情况下直接调用中断函数,RETI指令的操作结果会产生一个致命的错误。

4)如果在中断函数中调用了其它函数,则被调用函数所使用的寄存器必须与中断函数相同。否则会产生不正确的结果。

5C51编译器对中断函数编译时会自动在程序开始和结束处加上相应的内容,具体如下:在程序开始处对ACCBDPHDPLPSW入栈,结束时出栈。中断函数未加using n修饰符的,开始时还要将R0~R1入栈,结束时出栈。如中断函数加using n修饰符,则在开始将PSW入栈后还要修改PSW中的工作寄存器组选择位。

6C51编译器从绝对地址8m+3处产生一个中断向量,其中m为中断号,也即interrupt后面的数字。该向量包含一个到中断函数入口地址的绝对跳转。

7)中断函数最好写在文件的尾部,并且禁止使用extern存储类型说明。防止其它程序调用。

 

 

Chapter19 51系列单片机的串行口

串行口工作模式0TXD引脚都用于发送同步移位脉冲,而8位串行数据通过RXD引脚来输出(接收方通过RXD引脚输入)。数据传输时低位在前,高位在后SCON中的SM2必须设置为0,而RB8位和TB8位都不起作用,一般置0即可。它的主要用途是外接同步移位寄存器,易扩展I/O口。

串行口的波特率由第十期T1T2溢出率(并不需要TF1中断标志)来决定。

 

0

阅读 收藏 喜欢 打印举报/Report
前一篇:C语言标准
后一篇:信号处理原理
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有