第11章 C51串行接口程序设计
51单片机的串口通信程序(C语言)
![51单片机的串口通信程序(C语言)](https://img.taocdn.com/s3/m/e10b7dfb5ebfc77da26925c52cc58bd630869373.png)
51单片机的串口通信程序(C语言) 51单片机的串口通信程序(C语言)在嵌入式系统中,串口通信是一种常见的数据传输方式,也是单片机与外部设备进行通信的重要手段之一。
本文将介绍使用C语言编写51单片机的串口通信程序。
1. 硬件准备在开始编写串口通信程序之前,需要准备好相应的硬件设备。
首先,我们需要一块51单片机开发板,内置了串口通信功能。
另外,我们还需要连接一个与单片机通信的外部设备,例如计算机或其他单片机。
2. 引入头文件在C语言中,我们需要引入相应的头文件来使用串口通信相关的函数。
在51单片机中,我们需要引入reg51.h头文件,以便使用单片机的寄存器操作相关函数。
同时,我们还需要引入头文件来定义串口通信的相关寄存器。
3. 配置串口参数在使用串口通信之前,我们需要配置串口的参数,例如波特率、数据位、停止位等。
这些参数的配置需要根据实际需要进行调整。
在51单片机中,我们可以通过写入相应的寄存器来配置串口参数。
4. 初始化串口在配置完串口参数之后,我们需要初始化串口,以便开始进行数据的发送和接收。
初始化串口的过程包括打开串口、设置中断等。
5. 数据发送在串口通信中,数据的发送通常分为两种方式:阻塞发送和非阻塞发送。
阻塞发送是指程序在发送完数据之后才会继续执行下面的代码,而非阻塞发送是指程序在发送数据的同时可以继续执行其他代码。
6. 数据接收数据的接收与数据的发送类似,同样有阻塞接收和非阻塞接收两种方式。
在接收数据时,需要不断地检测是否有数据到达,并及时进行处理。
7. 中断处理在串口通信中,中断是一种常见的处理方式。
通过使用中断,可以及时地响应串口数据的到达或者发送完成等事件,提高程序的处理效率。
8. 串口通信实例下面是一个简单的串口通信实例,用于在51单片机与计算机之间进行数据的传输。
```c#include <reg51.h>#include <stdio.h>#define BAUDRATE 9600#define FOSC 11059200void UART_init(){TMOD = 0x20; // 设置定时器1为模式2SCON = 0x50; // 设置串口为模式1,允许接收TH1 = 256 - FOSC / 12 / 32 / BAUDRATE; // 计算波特率定时器重载值TR1 = 1; // 启动定时器1EA = 1; // 允许中断ES = 1; // 允许串口中断}void UART_send_byte(unsigned char byte){SBUF = byte;while (!TI); // 等待发送完成TI = 0; // 清除发送完成标志位}unsigned char UART_receive_byte(){while (!RI); // 等待接收完成RI = 0; // 清除接收完成标志位return SBUF;}void UART_send_string(char *s){while (*s){UART_send_byte(*s);s++;}}void main(){UART_init();UART_send_string("Hello, World!"); while (1){unsigned char data = UART_receive_byte();// 对接收到的数据进行处理}}```总结:通过以上步骤,我们可以编写出简单的51单片机串口通信程序。
C51编写 串口通信程序
![C51编写 串口通信程序](https://img.taocdn.com/s3/m/0508c969ddccda38376baf30.png)
异步通信的数据格式 :
一个字符帧 空 闲 起 始 位 数据位 校 验 位 停 止 位 空 闲
下一字符 起始位
LSB
MSB
异步通信的特点:不要求收发双方时钟的 严格一致,实现容易,设备开销较小,但 每个字符要附加2~3位用于起止位,各帧 之间还有间隔,因此传输效率不高。
2、同步通信
同步通信时要建立发送方时钟对接收方时钟的直接控制, 使双方达到完全同步。此时,传输数据的位之间的距离均 为“位间隔”的整数倍,同时传送的字符间不留间隙,即 保持位同步关系,也保持字符同步关系。发送方对接收方 的同步可以通过两种方法实现。
串行通信是将数据字节分成一位一位的形 式在一条传输线上逐个地传送。
接 收 设 备
D0 D7
8位顺次传送
发 送 设 备
串行通信的特点:传输线少,长距离传送时 成本低,且可以利用电话网等现成的设备, 但数据的传送控制比并行通信复杂。
7.1.1 串行通信的基本概念
一、异步通信与同步通信
1、异步通信 异步通信是指通信的发送与接收设备使用各自的时钟 控制数据的发送和接收过程。为使双方的收发协调,要求 发送和接收设备的时钟尽可能一致。
面向位的同步格式 :
8位 01111110 8位 地址场 8位 控制场 ≥0位 信息场 16位 校验场 8位 01111110
此时,将数据块看作数据流,并用序列01111110作为开始 和结束标志。为了避免在数据流中出现序列01111110时引起 的混乱,发送方总是在其发送的数据流中每出现5个连续的1 就插入一个附加的0;接收方则每检测到5个连续的1并且其后 有一个0时,就删除该0。 典型的面向位的同步协议如ISO的高级数据链路控制规程 HDLC和IBM的同步数据链路控制规程SDLC。 同步通信的特点是以特定的位组合“01111110”作为帧的 开始和结束标志,所传输的一帧数据可以是任意位。所以传 输的效率较高,但实现的硬件设备比异步通信复杂。
《单片机应用技术(C语言)》课件—6.2 51单片机的串行接口
![《单片机应用技术(C语言)》课件—6.2 51单片机的串行接口](https://img.taocdn.com/s3/m/b810fb9f69eae009581becf0.png)
RI
SCON SM0
SM1 SM2 REN TB8 RB8 TI
RI
可编程位还可用作为对接收到的数据进行校验使用,常用校验 方法:在可编程位装入发送数据的奇偶校验位。 举例:发送数据0x85(10000101B),发送数据包含二进制数1的 个数为奇数,因此奇偶校验位P=1,在发送数据0x85时,将P=1赋 值到可编程位TB8,连同数据共同发出。 对方接收后,只要将实际数据的奇偶关系与RB8进行对比,即可知 道收发过程是否有误。
SM0 SM1 工作方式 功能
说明
波特率
00 01 10
方式0 方式1 方式2
8位同步移位 常用于扩展I/O口 寄存器
fosc/12
10位UART 8位数据、起始位、结 可变(取决于定时器1
束位
溢出率和SMOD)
11位UART 8位数据、起始位、奇 fosc/64或fosc/32
偶校验位、结束位
(取决于SMOD)
RI:接收中断标志位
REN=1; while(RI==0); buffer[i]=SBUF; RI=0;
//接收允许 //查询等待接收标志为1,表示接收到数据 //接收数据 //RI由软件清0
SCON SM0 SM1 SM2 REN TB8 RB8 TI RI
控制寄存器SCON
0x9F 0x9E 0x9D 0x9C 0x9B 0x9A 0x99 0x98 SM0 SM1 SM2 REN TB8 RB8 TI RI
第 n字 符 帧
第 n+ 1字 符 帧
… 0/1 1 0 D0 D1 D2 D3 D4 D5 D6 D7 0/1 1 0 D0 D1 …
起
8位 数 据
பைடு நூலகம்
单片机C51语言及程序设计
![单片机C51语言及程序设计](https://img.taocdn.com/s3/m/991e0551ba68a98271fe910ef12d2af90342a86f.png)
贰
壹
叁
C51编译器在头文件“REG51.H”中定义了全部sfr/sfr16和sbit变量。 用一条预处理命令#include <REG51.H>把这个头文件包含到C51程序中,无需重新定义即可直接使用它们的名称。
应用举例:
片内数据存储器,片外数据存储器和程序存储器。
通常下划线开头的标识符是编译系统专用的,因此在编写C语言源程序时一般不使用以下划线开头的标识符,而将下划线用作分段符。C51编译器规定标识符最长可达255个字符,但只有前32个字符在编译时有效,因此标识符的长度一般不要超过32个字符。
关键字是一种已被系统使用过的具有特定含义的标识符。用户不得再用关键字给变量等命名。C语言关键字较少,ANSI C标准一共规定了32个关键字,见表
变量名具有字母大小写的敏感性,如SUM和sum代表不同的变量。
【存储类别】 数据类型 【存储器类型】 变量名
变量名不得使用标准C语言和C51语言的关键字。
unsigned char data system_status = 0;
//定义system_status为无符号字符型自动变量,该变量位于data区中且初值为0。
sfr或sfr16型 51MCU中有21个SFR,如何定义与这些单元相关的变量?
例如,sfr P0 = 0x80; //定义P0口地址80H sfr PCON = 0x87; //定义PCON地址87H sfr16 DPTR=0x82; //定义DPTR的低端地址82H
单精度浮点数
for
程序语句
构成for循环结构
goto
程序语句
构成goto转移结构
if
程序语句
单片机高级语言C51程序的设计ppt课件
![单片机高级语言C51程序的设计ppt课件](https://img.taocdn.com/s3/m/f84b38c4aaea998fcd220e78.png)
二.C51言语的标识符和关键字
C51扩展的关键字
三.C51的数据类型及运算符
1.根本数据类型的长度
2.C51言语的扩展
3.特殊功能存放器的数据类型
4.DATA 存储类型
5.BDATA 存储类型
6.IDATA 存储类型
7.PDATA和XDATA 存储类型
8.PDATA和XDATA 比较
本章目录3
六.函数 1.函数格式 2.重入函数 3.中断效力函数
七.C51程序设计举例 1.例1---求数学式 2.例2---简单控制 3.例3---延时 4.例4---运用定时器0定时---查询方式 5.例5---运用定时器0定时---中断方式 6.例6---利用定时器1计数 7.C51开发环境 7.1.伟福模拟软件 7.2. uVision3集成开发环境 7.3. C51编译练习程序TEXT.C
例8-5
例8-7(1)
• 按课本图7-14输出正弦波
例8-7(2)
例8-8(1)
例8-8(2)
例8-8(3)
例8-8(4)
十.加一减一综合实际C51程序设计
用如下的电路图,实现:按“加一〞按钮 显示加“1〞,按“加二〞按钮显示加“2〞, 按“减一〞按钮显示减“1〞,按“减二〞按 钮显示减“2〞;计数的最大值为19,最小值 为0;按“清0〞按钮显示“0〞〔清0〕。
电路图
程序〔1〕
#include"reg51.h"//头文件 #include"math.h"//头文件 unsigned char code disp_code[10]={
0x3F, //"0" 0x06, //"1" 0x5B, //"2" 0x4F, //"3" 0x66, //"4" 0x6D, //"5" 0x7D, //"6" 0x07, //"7" 0x7F, //"8" 0x6F, //"9" };
串行通信接口的C51编程实验报告.doc
![串行通信接口的C51编程实验报告.doc](https://img.taocdn.com/s3/m/1c2981e4c8d376eeaeaa3130.png)
int i;
for(i=500;i>0;i--); } void display() {
SegPort=0xff; SegPort=~tab[displaybuf[0]]; bit0=0;bit1=1; delay(); SegPort=0xff; SegPort=~tab[displaybuf[1]]; bit0=1;bit1=0; delay(); SegPort=0xff; }
实 验 #include<reg51.h> 原 始 #define uchar unsigned char 数据 #define uint unsigned int
#define SegPort P0 sbit bit0=P2^0; sbit bit1=P2^1; uchar code tab[16]=
Key(); if(Commflag) {
Commflag=0; DataChange(ReceiveData); } display(); }
}
实验 数据 整理 与分 析
实 验 1.左数码管显示且纪录右按键按动次数 结论 2.右数码管显示且纪录左按键按动次数
佛山职业技术学院
电子信息工程技术专业
《 串行通信接口的 C51 编程实验
》课程实验报告
班别
姓
学号 01 实验室 5—209
日期 2011.3.22 名
组号
同组人员
实验
串行通信接口的 C51 编程实验
成绩评定
名称
教师签名
主 要 计算机
仪器
设备
实验 目的
1、 掌握单片机的串行通信接口软件编程方法 2、 掌握单片机的串行通信接口调试技术。
51单片机教程:单片机串行口通信程序设计
![51单片机教程:单片机串行口通信程序设计](https://img.taocdn.com/s3/m/f252eefa3086bceb19e8b8f67c1cfad6195fe995.png)
51单片机教程:单片机串行口通信程序设计1.串行口方式0应用编程 8051单片机串行口方式0为移位寄存器方式,外接一个串入并出的移位寄存器,就能扩展一个并行口。
单片机串行口通信程序设计硬件连接图例:用8051单片机串行口外接CD4094扩展8位并行输出口,如图所示,8位并行口的各位都接一个发光二极管,要求发光管呈流水灯状态。
串行口方式0的数据传送可采用中断方式,也可采用查询方式,无论哪种方式,都要借助于TI或RI标志。
串行发送时,能靠TI置位(发完一帧数据后)引起中断申请,在中断服务程序中发送下一帧数据,或者通过查询TI的状态,只要TI为0就继续查询,TI为1就结束查询,发送下一帧数据。
在串行接收时,则由RI引起中断或对RI查询来确定何时接收下一帧数据。
无论采用什么方式,在开始通信之前,都要先对控制寄存器SCON进行初始化。
在方式0中将,将00H送SCON就能了。
单片机串行口通信程序设计列子ORG 2000HSTART: MOV SCON,#00H ;置串行口工作方式0MOV A,#80H ;最高位灯先亮CLR P1.0 ;关闭并行输出(避象传输过程中,各LED的暗红现象) OUT0: MOV SBUF,A ;开始串行输出OUT1: JNB TI,OUT1 ;输出完否CLR TI ;完了,清TI标志,以备下次发送SETB P1.0 ;打开并行口输出ACALL DELAY ;延时一段时间RR A ;循环右移CLR P1.0 ;关闭并行输出JMP OUT0 ;循环说明:DELAY延时子程序能用前面我们讲P1口流水灯时用的延时子程序,这里就不给出了。
二、串行口异步通信org 0000HAJMP STARTORG 30HSTART:mov SP,#5fh ;mov TMOD,#20h ;T1: 工作模式2mov PCON,#80h ;SMOD=1mov TH1,#0FDH ;初始化波特率(参见表)mov SCON,#50h ;Standard UART settingsMOV R0,#0AAH ;准备送出的数SETB REN ;允许接收SETB TR1 ;T1开始工作WAIT:MOV A,R0CPL AMOV R0,AMOV SBUF,ALCALL DELAYJBC TI,WAIT1 ;如果TI等于1,则清TI并转WAIT1AJMP WAITWAIT1: JBC RI,READ ;如果RI等于1,则清RI并转READAJMP WAIT1READ:MOV A,SBUF ;将取得的数送P1口MOV P1,ALJMP WAITDELAY: ;延时子程序MOV R7,#0ffHDJNZ R7,$RETEND将程序编译通过,写入芯片,插入实验板,用通读电缆将实验板与主机的串行口相连就能实验了。
c51程序设计
![c51程序设计](https://img.taocdn.com/s3/m/c089c3f0bed5b9f3f80f1c86.png)
1Franklin C-51之南宫帮珍创作1.11.2Franklin C-51数据类型8051系列是8位机, 因而不存在字节校准问题.这意味着数据结构成员是顺序放置的.数据类型的转换:当计算结果隐含着另外一种数据类型时, 数据类型可以自动进行转换, 例如, 将一个位变量赋给一个整型变量时, 位型值自动转换为整型值, 有符号变量的符号也能自动进行处置.这些转换也可以用C语言的标准指令进行人工转换.1.2数据类型的物理结构1.2.1bit“bit”类型只有1位, 不允许有位指针和位数组.位对象始终位于8051 CPU的可寻址RAM空间.如果法式控制流允许, L51将位对象交迭.1.2.2signed/unsigned char;data/idata/pdata 指针“char”类型标量和基于存贮器的“data/idata/pdata”指针具有1个字节长度(8 bits).1.2.3signed/unsigned int/short;xdata/code 指针“int”和“short”类型标量及指向xdata/code区域的指针具有2字节长度(16bits).整型值(或偏移)0x1234以下面方式保管在内存中:地址:+0 +1内容: 0x120x341.2.4signed/unsigned long“long”类型标量长为4个字节(32 bits), 值0x12345678以下面方式放置:地址:+0+1+2+3内容: 0x12 0x34 0x56 0x781.2.5“一般”指针“一般”指针包括3个字节:2字节偏移和1字节存贮器类型:地址:+0 +1 +2内容:存贮器类型偏移高位偏移低位第一个字节代表了指针的存贮器类型, 存贮器类型编码如下:存贮器类型 IDATA XDATA PDATADATACODE值 12 345使用其它类型值可能招致不成预测的法式举措.XDATA类型的0x1234地址作为指针暗示如下:地址:+0+1 +2内容: 0x02 0x12 0x34当用常数作指针时, 必需注意正确界说存贮器类型和偏移.下例将值0x41写入绝对地址为0x8000的外部数据存贮器:#defineXBYTE ((char *)0x20000L)XBYTE[0x8000]=0x41;上例中用其它常数索引或索引变量也起作用.这样, 各种存贮器类型的绝对地址可以一种非常有效的方式访问.但有一个例外, 即SFR.注意:绝对地址界说为“long”型常量, 低16位包括偏移, 高8位标明了xdata类型.为了暗示这种指针, 必需用长整数来界说存贮器类型.C51编译器不检查指针常数, 用户必需选择有实际意义的值. 1.2.6float“float”类型为4个字节(32位), 使用的格式与IEEE-754标准(32位)具有24位精度, 尾数的高位始终为“1”, 因而不保管, 位的分布如下:● 1位符号● 8位指数位23位尾数符号位是最高位, 尾数为最低的位, 内存中按字节存贮如下:地址:+0 +1 +2+3内容:MMMM MMMM MMMM MMMME MMM MMMMS EEE EEEE其中:S:符号位, 1=负, 0=正E:指数(在两个字节中), 偏移为127M:23位尾数, 最高位“1”浮点值——12.5的十六进制为0xC1480000, 它按下面方式存贮:地址:+0+1+2+3内容: 0x00 0x00 0x48 0xc18051不包括捕捉浮点毛病(例外)的中断向量.用户软件因此必需对毛病条件作出适当反应.下面推荐一种方法(也可以用其它可靠法子):“union”用来保管浮点值, 这个“union”必需包括一个“float”和一个“unsigned long”, 以根据IEEE对毛病作出响应.除通常浮点值外, IEEE标准可能犯错的条件以下面二进制值暗示, 为检查可能呈现的计算毛病, 可在计算后进行检查.因为当执行一个运算时考虑了每个运算符的毛病状态而且该状态被送到结果中.NaN0xFFFFFFF不是一个数+INF0x7F80000正无穷(正溢出)-INF0XFF80000负无穷(负溢出)1.3C-51 的扩充界说1.3.1特殊功能寄存器的声明MSC-51 系列包括多种寄存器, 其中一些具有特殊功能, 如按时器, 端口的控制寄存器等, 为了能够直接访问这些寄存器, C51编译器提供了一种界说的自主形式, 这是需要的, 因为这些界说与标准C语言是不兼容的.为了支持这些特殊功能寄存器(SFR)的声明, 引入了关键词“sfr”, 语法如下:sfr-dcl:sfr sfr_name=int_constant例:sfr p0=0x80;sfr p1=0x90;必需注意的是“sfr”后不是一个地址而是一个名字.因此上例中名字P0和P1(port0和port1)界说为特殊功能寄存器并被赋予相应的绝对地址, 名字可按意愿自由选取, 源文件中不应有先界说的sfr名字.“=”号后的地址必需是常数, 不允许带有运算符的表达式, 这个常数表达式必需在特殊功能寄存器的地址范围内, 位于0X80到0XFF之间.8051系列寄存器数量和类型是极其分歧的, 因此建议将所有特另外“sfr”声明放入一个头文件, 头文件包括8051一些系列成员中的SFR界说.进一步的界说可由用户用一文件编纂器发生. 1.3.2对SFR的16位数据访问在新的8051系列产物中, SFR在功能上经常组合为16位的, 为了有效的访问这类SFR, 使用界说“sfr16”, 当“SFR”的高端直接位于低端后时, 对SFR16位的访问是可能的.例如8052的按时器2就是这种情况, 16位声明的语法与“sfr”相同, SFR低地址部份必需作为sfr16的地址:例:sfr16 T2=0xCC/*Timer2:T2L=0CCH, T2H=0CDH */sfr16 RCAP2=0xCA/*RCAP2L=0CAH, PCAP2H=0CBH */本例中, T2(由T2L和T2H组成)和RCAP2(由RCAP2L和RCAP2H组成)被界说为16位SFR, 即使在这种情况下, 声明中的名字后仍不是赋值语句, 而是一个SFR地址, 高字节必需直接位于低字节之后, 这种声明适用于所有新的SFR, 但不能用于Timer0和Timer1.1.3.3SBIT:特殊功能位声明在典范的8051应用问题中, 经常需要独自访问SFR中的位, C51扩充功能使之成为可能, 特殊位, 象SFR一样, 不与标准C 语言兼容, 使用保管字“sbit”可访问位寻址对象.与SFR声明一样, 用保管字“sbit”声明某些特殊位接受符号名, “=”后语句将绝对值地址赋给变量名, 这种地址分配有三种方法:方法1:sfr_name^int_constant当字节是特殊功能寄存器的地址可用这个方法.sfr_name必需是已界说的SFR的名字, “^”后的语句界说了基地址上的特殊位的位置, 该位置必需是一个0~7的数.例: sfr PSW=0xD0;sfr LE=0xA8;sbit OV=PSW^2;sbit CY=PSW^7;方法2:int_constant^int_constant这种方法以一整常数作基地址, 该值必需在0x80~0xFF之间, 并能被8整除, 确定位的位置方法同上.例: sbit OV=0xD0^2;sbit CV=0xD0^7;sbit EA=0xA8^7;方法3: int_constant这种方法是将位的绝对地址赋给变量, 地址必需位于0x80~0xFF之间.例: sbit OV=0xD2;sbit CY=0xD7;sbit EA=0xAF;特殊功能位代表了一个自力的声明类, 它不能与其它声明和位域互换.1.3.4BIT:位标量声明除通常的C数据类型外, C51编译器支持“bit”数据类型, 对此有下列扩充与限制:(1)函数可包括类型为“bit”的参数, 也可将其作为返回值.bit bfunc(bit b0, bit b1){/*……*/return(b1);}注:使用禁止中断(#pragma disable)或包括明确的寄存器组切换(using n)的函数不能返回位值, 在这种情况下, 编译器会识别出来并发生一个毛病信息.(2)位标量声明的语法及C声明的语义static bit dirction_bit;extern bit lock_printer_port;bit display_invers;(3)对位声明的限制●位不能声明为一个指针(bit *bit_poiter)●不存在位数组(bit b_array[5])位声明中允许界说存贮器类型, 位都被放入一个位段, 它总是在8051内部RAM中, 因此存贮器类型限制为DATA或IDATA, 声明为其它存贮器类型都将招致编译犯错.1.3.5可位寻址对象可位寻址对象指可以字节或位寻址的对象, 当对象位于MSC-51可寻址RAM中时会有这种情况, C51允许带“bdata”类型的对象放入可位寻址存贮器中.bdata int ibase; /*位寻址指针 int*/bdata char bary[4]; /*位寻址数组 arrray*/使用“sbit”声明可自力访问可位寻址对象的位:sbit mybit0=ibase^0;sbit mybit15=ibase^15;sbit ary07=bary[0]^7;sbit ary37=bary[3]^7;对象“ibase”和“bary”也可位寻址:ary37=0;/*寻址“bary[3]”中的位7*/ibase=-1;/*寻址字节地址*/mybit15=0;/*寻址“ibase”的位15*/sbit声明要求基址对象的存贮器类型为“bdata”, 否则只有绝对的位声明方法是合法的.位位置(‘^’把持符号后)的最年夜值依赖于指定的基类型, 这个值于char/uchar而言是0~7, 对int/uint/short/ushort而言是0~15, 对long/ulong而言是0~31.在编译器内存贮器类型bdata与data一样把持, 而且只作与可再定位的sbit的运算.注:可位寻址的的段长最年夜不能超越16字节, 可再定位的sbit声明自动转为公共的(PBULIC)以使它们能被其它C模块使用.模块1:sbitary37=bary[3]^7;模块2:externbit ary37;sbit声明也可为结构和函数所用:unionlft{float mf;long ml;} ;bdatastructbad { char ml; union lft u; }tcp;sbit tcpf31=tcp.u.ml^31; /*浮点限制*/sbit tcpml0=tcp.ml^0;sbit tcmpl7=tcp.ml.^7;注:位位置的指定不能直接被float类型所用, 如果需要这样做, 浮点标量必需与一个长整型标量一起放入一个联合中而且位位置必需由长整型题目指定(见上例).1.4存贮器类型C51编译器完全支持8051微处置器及其系列的结构, 可完全访问MCS-51硬件系统所有部份.每个变量可准确地赋予分歧的存贮器类型(data, idata, pdata, xdata, code).访问内部数据存贮器(idata)要比访问外部数据存贮器(xdata)相对要快一些, 因此, 可将经常使用的变量置于内部数据存贮器中, 而将较data char charvar;char code msg[]=”ENTER PARAMETER:”;unsigned long xdata array[100];float idata x,y,z;unsigned char xdata vector[10][4][4];sfr p0=0x80;sbit RI=0x98;char bdata flags;sbit flago=flags^0;如果在变量说明时略去存贮器类型标识表记标帜符, 编译器会自动选择默认的存贮器类型.默认的存贮器类型进一步由控制指令SMALL、COMPACT和LARGE限制.例如:如果声明char charvar, 则默认的存贮器模式为SMALL, charvar放在data存贮器;如果使用COMPACT模式, 则charvar放入idata存贮区;在使用LARGE模式的情况下, charvar被放入外部存贮区或xdata存贮区. 1.5存贮器模式存贮器模式决定了自动变量和默认存贮器类型, 参数传递区和无明确存贮区类型的说明.在固定的存贮器地址变量参数传递是C51的一个标准特征, 在SMALL模式下参数传递是在内部数据存贮区中完成的.LARGRE和COMPACT模式允许参数在外部存贮器中传递.C51同时也支持混合模式, 例如在LARGE模式下生成的法式指针Franklin C-51支持“基于存贮器的”和“一般指针”.1.6.1基于存贮器的指针基于存贮器的指针由C源代码中存贮器类型决定并在编译时确定, 用这种指针可高效访问对象且只需一个字节(idata*, data*, pdata*)或2个字节(code*, xdata*).把持较短指针的代码被缩短, 一般被“内行”编码;库调用不再需要.上面例子说明了指针的一般声明及使用.它们与所有的数据类型和存贮器类型相关.所有用于一般指针的把持同样可用于基于存贮器的指针.1.6.2一般指针“一般”指针需3个字节:1个字节为存贮类型, 2个字节为偏移量.存贮器类型决定了对象所用的8051存贮器空间, 偏移量指向实际地址.一个“一般”指针可访问任何变量而不论它在8051存贮器空间中的位置.这样就允许一般性函数, 如memcpy将数据从任意一个地址拷贝到另一个地址空间.1.6.3基于存贮器的指针与一般指针的转换一个已定位指针可转换为一个一般指针(3字节)及副本.这在某些时候是很有用的.例如库函数包括一个一般指针变量, 象printf(), sprintf(), gets()等包括一个一般指针变量, 如同以前的编译器和库版本一样.这些函数因而广泛适用.例:extern int printf(void *format, …);在printf调用中, 2字节指针自动转换为一个3字节指针, 而printf的原型正需要一个一般指针(3字节)作为其第一参量.注:如果没有函数原型, 函数调用的参量中指针总是转换为一般指针.如果函数确实需要一个短指针作参量, 这会发生毛病, 为了防止在法式中发生这类毛病, 需要使用头文件, 或某些函数声明函数原型.这将保证让编译器转换为所需类型, 否则会发生类型不匹配毛病.1.6.4笼统指针类型用来在每个存贮区访问任意绝对地址, 或来发生绝对CALLs.在这个过程中, 常数类型或字符型、整型都用笼统类型作了原则性修改(类型整理)以允许进行绝对访问或调用.例:char xdata *px;char idata *pi;char code *pc;char c;int i;pc = (void*)main;i = ((int(code*)(void))0xFF00(); /*LCALL 0FF00H*/c = *((char code*)0x8000); /*char [code[0x8000]]*/i = *((int code*)0x1200); /*int from code[0x1200]*/px = *((char xdata *xdata*)0x4000); /*x ptr from xdata[0x4000]*/px = ((char xdata *xdata*)0x4000)[0]; /*同上*/px = ((char xdata *xdata *)0x4000)[1] /*x ptr from xdata[0x4002]*/1.7寄存器组界说8051系列的器件包括4个相同的寄存器组, 每个寄存器组包括8个寄存器(R0~R7), C51编译器可使在一函数中决定用哪一寄存器组成为可能.绝对寄存器的访问可用AREGS/NOAREGS和REGISTERBANK来控制.界说一个带扩展性的函数语法如下:返回类型函数名([参数])[模式][再入][中断 n]using n 再入和中断将在后两节讨论.例:void rb_function(void) using 3;“using”不允许用于外部函数, 它对函数的目标代码影响如下:●函数入口处将以后寄存器保管入栈;●指它的寄存器还会改变;●函数退出前寄存器组被恢复.“using”界说对返回一个寄存器内的值的函数是无用的.编程者必需十分小心以保证任何寄存器切换都只在仔细控制的区域发生.如果不做到这一点将会发生不正确的函数结果.即使当编程者使用同一寄存器组时, 带“using”属性的函数原则上也不能返回一个位值.实际发生的代码决定于编译器及分歧开关条件, 有时用命令发生绝对的寄存器地址, 当需要进行这样的地址计算时, 使用REGISTERBANK指令的影响只是计算Arn寄存器使用的地址, 而必进行实际切换.1.8中断服务法式C51编译器及其对C语言的扩充允许编程者对中断的所有方面进行控制.这种支持能使系统编程者创立高效的中断服务法式, 用户只需在普通和高级方式下关心中断及需要的寄存器组切换把持, C51编译器将发生最合适的代码.1.8.1中断服务法式的界说使用中断服务函数的完整语法如下:返回值函数名([参数])[模式][再入] interrupt n[using n]“interrupt”后接一个0~31的常数, 不允许使用表达式.中断不允许用于外部函数, 它对函数目标代码的影响如下:●当使用函数时, SFR中的ACC、B、DPH、DPL和PSW(当需要时)入栈;●如不使用寄存器组切换, 甚至中断函数所需的所有工作寄存器(Rn)都入栈;●函数退出前, 所有的寄存器内容出栈;●函数由8051控制命令“RETI”终止.1.8.2开发中断过程时的规则●不能进行参数传递, 如果中断过程包括任何参数声明, 编译器将发生一个毛病信息;●无返回值, 如果想界说一个返回值将发生毛病, 然而, 如果返回整型值编译器将不发生毛病信息, 因为整型值是默认值, 因而编译器不能清楚识别.●编译器会识别对中断过程的直接调用并拒绝它们, 在任何情况下不能直接调用中断过程, 因为退出该过程是由把持码RETI完成的.RETI影响8051芯片的硬件中断系统, 由于硬件上没有中断请求存在, 因而这个把持码的结果是不定的而且通常是致命的.由于疏忽, 可能用指针来间接调用它, 这是值得注意的.●编译器从绝对地址8n+3处发生一个中断向量, 其中n为中断号, 该向量包括一个到中断过程的跳转, 向量的发生可由指令NOINTVECTOR压缩.因而用户有能力从自力的汇编模块中提供中断向量.●C51编译器允许0~31个中断, 究竟允许哪些中断依赖于使用的8051系列芯片, 编译器不能检查.●如果中断法式中有浮点运算, 必需坚持浮点寄存器状态,当没有其它法式执行浮点运算时, 可能不保管, 函数“fsave”和“fprestore”用来保管浮点状态.●中断过程调用的函数所使用的寄存器必需与中断过程相同,当没有使用“using”指令时, 编译器会选择一个寄存器组作绝对寄存器访问, 当子法式使用另一个寄存器组时会发生毛病, 用户必需保证按要求使用相应寄存器组, C编译器不会对此检查.例:unsigned int interruptent;unsigned char second;time() interrupt 1 using 2/*按时器0中断服务法式,工作寄存器使用2区*/{if(++interruptcnt==4000) {second++;/*秒计数加一*/interruptcnt=0;/*清中断计数*/}}1.9再入函数再入函数可被递归调用, 调用可发生在任何时候, 即使是在中断过程中.在实时处置的应用问题中经常需要再入函数.使用关键字“reentrant”可有选择地界说函数有再入能力.在存贮器模式的基础上为再入函数在内部或外部存贮器中模拟了一个栈区域.由于MCS-51缺乏合适的寻址方法, 使用栈结构是相当需要的.因而应尽量少用再入函数.界说一再入函数的语法如下:返回值函数名([参数])[模式]reetrant[interrupt n][using n]例:int calc(char i,int b) reentrant {int x;x=table[i];return(x*b);}使用再入函数有如下规定:●不能传递类型为“bit”的参数.也不能声明一个局部标量,再入功能不能包括位把持及MCS-51可位寻址区域.●不能在“alien”函数调用再入函数.●再入函数可同时有其它属性, 如“using”函数模式和“interrupt”.●再入函数不能同时有“alien”属性, 从而遵守PL/M规则.●返回地址及可能的PUSH/POP把持存入MCS-51的栈中或被执行(不在再入栈中).●在同一模块中, 任意模块的再入函数(small reentrant,lage reentrant, compact reentrant)不能与具有分歧模式的再入函数混合.再入函数举例:/*这个再入函数可以从“main”及中断法式中调用*/int calc(char i,int b)reentrant {int x;x=table[i];return(x*b);}1.10参数传递通过CPU的寄存器可传递至多三个参数.这样发生与汇编子法式相当的有效参数机制.如果寄存器被占用, 或说明了“#pragma NOREGPARMS”, 参数变量将使用固定的存贮器位置, 存贮器模式决定了8051存贮器为参数提供的位置.函数的返回值放在CPU固定的寄存器中, 列表如下.这样, 与汇编子法式的接口变得非常容易.1PL/M51接口Franklin C51利用关键字“alien”提供了一个与Intel PL/M-51直接和简单和接口, 关键字“alien”在所有存贮器模式下可用于“extern”和“public”函数.现有的PL/M-51法式利用C语言的强年夜功能可与Franklin C-51连接起来.使用关键字“alien”, C51可用PL/M-51规定的参数传递方式工作.“alien”可用于外部或公共函数, 并可用于任一模式, 这样, 已有的PL/M-51法式可加入到C-51中.Alien函数始终包括一个标准的参数数量, 因此, C中界说的三点(…)记号不被接受, 且会发生一个毛病信息.例:extern alien char plm_function(unsigned char,unsigned int);extern char c_function(unsigned char x,unsigned char y) {return(x*y);}PL/M-51兼容函数必需界说以关键字“alien”.这样, PL/M函数的参数传递及参数返回规定在C编译器中才被考虑.1.12汇编接口参数是通过固定的CPU寄存器传给汇编法式的, 当使用“#pragma NOREGPARMS”时, 则通过固定的存贮器位置传递参数.这样就给汇编与Franklin C-51之间提供了一个非常简洁的接口.返回值在CPU寄存器中.下例为在汇编中用来编码的“toupper”函数, 参数传递发生在寄存器中.UPPERSEGMENTCODE;法式代码段PUBLIC_toupper;入口地址RESGUPPER;选择法式代码段toupper:MOVA,R7;char 参数在寄存器R7中CJNEA,#’a’,UPP1UPP1:JCUPPERTCJNEA,#’z’+1,UPP2UPP2:JNEUPPRETUPPRET:MOVR7,A;char 返回值在寄存器R7中RET;返回C1.13内部函数Franklin C-51支持下列内部函数.内部函数既是再入的又是有效的.表:C51的内部函数1.代码优化Franklin C51可将即使有经验的法式员编制的代码进行优化.用户可选6个优化级, 另外, 用OPTIMIZE(SIZE), NOREGPARMS 和NOAREGS时会影响生成代码的类型.C51的所有优化如下:(1)一般优化:●常数折迭:发生在一个表达式或地址计算中的几个常数值组合为一个常数.●跳转优化:跳转转到最终的目标地址, 以提高法式效率.●死码消除:不成执行代码(死码)可从法式中去失落.●寄存器变量:只要有可能, 自动变量和参量放入寄存器中,为这些变量保管的数据存贮器将去除.●通过寄存器传递参数:寄存器中可传递最多三个参数.●全局公共子式消除:相同的子表达式或地址计算(屡次发生在同一函数中)将被识别出来, 而且只要有可能, 将只计算一次.(2)基于8051的优化:●窥孔(PEEPHOLE)优化:只要能节省存贮空间或执行时间,复杂的运算都将化简.●访问优化:常数和变量直接包括在把持中.●数据覆盖:函数的数据和位移被标识表记标帜为OVERLAYABLE, 被L51用其它数据和位覆盖.●CASE/SWITCH 优化:SWITCH/CASE 语句优化为一个跳转或一串跳转. (3) 代码生成选项:● OPTMIZE (SIZE ):共同的“C ”把持被子法式取代:法式码长被压缩.● NOAREGS :不使用绝对寄存器访问, 法式代码在这种方式下自力于寄存器组.● NOREGPARMS :参数传递总是在本数据段完成, 法式代码与早期C-51版本兼容.1.15 C 库C-51编译器包括6个分歧的编译库, 可根据分歧函数的需要进行优化, 这些库几乎支持所有的ANSI 函数调用.因此, 用此标准的CC51关的修改.用户改变对现有硬件输入和输出结构的两个模块, 就可修改所有库函数, 同样也可以重新很快地构造如“printf ”和“puts ”函数用LCD 显示.L51连接器的检查从而保证所有模块都用一种模式编译并自动选择编译库, 从而使用户完全可以不用分歧库的细节. 1.16 配置文件C51编译器可根据分歧的硬件环境由4个文件作出修改.下列用.如果用户改变一个文件, 可将其编译后与其它目标文件一起连接, 因而不用改动运行库.库中原文件自动忽略.例:文件STARTUP.51开头包括一些C编译结构使用的EQU语句.每个EQU语句的功能描述如下:IDATALEN 声明系统开始时有几多内存需要用0初始化.默认值为80H, 因为几乎每个8051指令至少包括128字节内部RAM.对256字节内部RAM的8052可使用100H.当用户法式在开始时需要使用0初始化的内存时才有需要作改动.如果内存初始化必需坚持对失落电模式系统的完全抑制, IDATALEN应设为0.这种情况下至少得坚持所有位于段?C_LIB_DATA和?C_LIB_DBIT中的变量都置为0.否则有些库函数不能完全发挥作用, ?C_LIB_DATA段的长度因分歧应用问题而分歧,其以后长度可在MAP文件中找到.XDATASTARTXDATALEN标明了需要以0初始化的PDATA区首址和长度, XDATASTART指明了XDATA区首址, XDATALEN标明了需初始化的字节数.PDATASTARTPDATALEN标明了需以0初始化的PDATA区首址及长度, PDATASTART指明了首址, XDATALEN指定了长度. LBPSTACKLBPSTACKTOP 界说了SMALL模式下创立的再入函数使用的栈区.LBPSTACK标明是否对栈指针(变量?C_LBP)初始化,LBPSTACKTOP指明了栈顶首址.对具有256字节内部RAM的8051系统, 当存贮区作首址为0XFF的栈时, 可不初始化.C51不作栈区是否满足特定应用的检查, 用户必需自己进行测试.XBPSTACKXBPSTACKTOP 为在LARGE模式下创立的再入函数界说了栈区, XBPSTACK标明指针(变量?C_XBP)是否初始化,XBPSTACKTOP指定了栈顶地址.当存贮区作为首址为0Xffff(在XDATA区)的栈时, 可不作初始化.同上一样, C51不作栈检查, 需要用户自己测试.PBPSTACKPBPSTACKTOP 为在COMPACT模式下创立的再入函数界说了栈区, PBPSTACK标明栈指针(变量?C_PBP)是否初始化.PBPSTACKTOP指定了栈顶地址.当存贮区作为首址为0Xff(在PDATA区)的栈时, 可不作初始化.同上一样,C51不作栈检查, 需要用户自己测试.PPAGEENABLEPPAGE当在COMPACT模式中用16位寻址XDATA存贮区时需要这些指令.对使用LARGE模式的法式, 可用它提高运行速度或减小代码长度.PPAGEENABLE允许8051端口2的初始化, 对端口2的寻址允许在任意XDATA页256字节变量空间的映射.这两个指令必需和L51的控制指令PDATA一起使用.PDATA指定了XDATA存贮器中PDATA区的首址.例:在STARTUP.A51中, PPAGEENABLE置为1, PPAGE置为10H.这种情况下PDATA区首址为1000H(10H页),而L51必需包括一个值在1000和10FFH之间的控制语句:L51〈输入模块〉PDATA(1050H).注:L51和C51都分歧毛病PPAGE/PDATA指令正确性进行检查, 用户必需保证PPAGE和PDATA包括一个合适的值.INIT.A51:“看门狗”刷新的宏.当系统包括“看门狗”以及用户变量初始化时间比“看门狗”刷新时间要长时, 必需改变这个宏.这种情况下, 宏WATCHCOG必需包括“看门狗”刷新的代码.例:;Watchdog refresh for 80515 systemWATCHDOG MACROSETBWDTSETBSWDTENDM文件PUTCHAR.C包括字符输出的核心法式, 该文件通过串行口输出.这种情况下考虑了XON/XOFF协议, 字符LF()被转为字符串CR, LF, 这在很多终端中是需要的.用户可按自己的要求改变putchar()函数.文件GETKEY.C包括字符输入的核心法式,该文件从串行接口读入一个字符, 不妥准据转换, 用户可根据需要修改getkey()函数. 1.17优化法式本节包括几个怎样提高8051法式效率的注解.定位变量经常访问的数据对象应放入在片内数据RAM中, 这可在任一模式(COMPACT/LARGE)下用输入存贮器类型的方法实现.访问片内数据RAM要比访问外部数据存贮器快很多.片内RAM由寄存器组, 位数据区栈和其它由用户用“data”类型界说的变量共享.由于片内RAM容量的限制(128~256字节, 由使用的处置器决定), 必需权衡利弊以解决访问效率和这些对象的数量之间的矛盾.总是使用可能的最小数据类型8051系列CPU都是8位机, 因此, 显然对具有“char”类型的对象的把持比“int”或“long”类型的对象方便很多.建议编程者只要满足要求, 应尽量使用最小数据类型.C51编译器直接支持所有的字节把持, 因而如果不是运算符要求, 就不作“int”类型的转换, 这可用一个乘积运算来清楚说明, 两个“char类型”对象的乘积与8051把持码“MUL AB”刚好相符.如果用整型量完成同样的运算, 则需要调用库函数.只要有可能, 使用“unsigned”数据类型8051系列CPU其实不直接支持有符号数的运算.因而C51编译器必需发生与之相关的更多的代码以解决这个问题.如果使用无符号类型, 发生的代码要少很多.只要有可能, 使用局部函数变量编译器总是检验考试在寄存器里坚持局中变量.这样, 将索引变量(如FOR和WHILE循环中计数变量)声明为局部变量是最好的, 这个优化步伐只为局部变量执行.使用“unsigned char/int”的对象通常能获得最好的结果.2C51编译器控制指令编译选项可能被控制指令激活、禁止或改变.这些指令可在命令行输入或在源文件上加入#pragma给预处置器.控制指令分为两组, 即首要的和一般的, 并可分为三类:源控制、目标控制、列表控制.见表2.1编译控制指令.“P/G”列标明指令是首要的或是一般的, 首要指令仅呈现一次, 一般指令按需要可呈现屡次.表2.1 编译控制指令。
单片机原理及接口技术(C51编程)串行口的工作原理及应用
![单片机原理及接口技术(C51编程)串行口的工作原理及应用](https://img.taocdn.com/s3/m/c479674b866fb84ae45c8d6c.png)
8.2.1 方式0
2.方式0输入
图8-8 串口方式0外接并行输入、串行输出的同步移位寄存器
8.2.1 方式0
2.方式0输入
参考程序如下:
#include <reg51.h>
#include "intrins.h"
#include<stdio.h>
sbit P1_0=0x90;
sbit P1_1=0x91;
8.2.1 方式0
1.方式0输出 方式0的发送时序见图8-5。
图8-5 方式0发送时序
8.2.1 方式0
1.方式0输出
(2)方式0输出的应用案例 典型应用是串口外接串行输入/并行输出的同步移位寄 存器74LS164,实现并行端口的扩展。 图 8-6为 串 口 方 式 0, 通 过 74LS164输 出 控 制 8个 外 接 LED发光二极管亮灭的接口电路。当串口设置在方式0输出 时 , 串 行 数 据 由 RXD端 ( P3.0) 送 出 , 移 位 脉 冲 由 TXD端 (P3.1)送出。在移位脉冲的作用下,串行口发送缓冲器的 数据逐位地从RXD端串行地移入74LS164中。
1.方式0输出
//串行口中断服务程序
void Serial_Port( ) interrupt 4 using 0 {
if(TI) {
// 如果TI=1,1个字节串行发送完毕
P1_0=1;
// P1_0=1,允许74LS164并行输出,
//流水点亮二极管
SBUF=nSendByte;
8.2.1 方式0
1.方式0输出
参考程序:
#include <reg51.h>
#include <stdio.h>
C51程序设计(完整)
![C51程序设计(完整)](https://img.taocdn.com/s3/m/a76c0e1fc281e53a5802ff45.png)
第1章C51数据类型与运算1.1C51数据类型C51的数据类型如下所示:C51编译器支持的数据类型、长度和值域如下表1-1所示。
与面向数学运算的计算机相比,51单片机对变量类型或数据类型的选择更具有关键性意义。
如果在程序设计中使用大量而不必要的变量类型,这会导致C编译器调用库函数的数量,以处理大量的变量类型和数据类型。
所以必须特别慎重地进行变量和数据类型的选择。
1.2C51数据存储类型C51编译器还可以通过将变量、常量定义成不同的存储类型(data,bdata,idata,pdata,xdata,code)的方法,将它们定义在不同的存储区中。
存储类型与51单片机实际存储空间的对应关系如表1-2所示。
储区中。
片内RAM是存放临时性传递变量或使用频率较高变量的理想场所。
访问片内数据存储器(data、bdata、idata)比访问片外数据存储器(xdata、pdata)相对快一些,因此可将经常使用的变量置于片内数据存储器,而将规模较大的或不常使用的数据置于片外数据存储器中。
C51存储类型及其大小和值域如表1-3所示。
例如:表1-3 C51存储类型及其大小和值域char data var1; /*字符变量var1被定义为data存储类型,定位在片内RAM中*/bit bdata flags; /*位变量flags被定义为data存储类型,定位在片内RAM中的位寻址区*//*(20H~2FH)*/float idata x,y,z; /*浮点变量x,y,z被定义为idata存储类型,定位在片内RAM中,并只能用间接寻址的方法进行访问*/unsigned int pdata dimension; /*无符号整型变量dimension被定义为pdata存储类型,定位在片外RAM中,并用MOVX @Ri访问*/ unsigned char xdata vector[10][4][4]; /*无符号字符三维数组变量vector[10][4][4]被定义为xdata存储类型,定位在片外RAM中,占据10×4×4=160个字节空间*/如果在变量定义时省略存储类型标志符,编译器会自动默认存储类型。
No.5C51程序设计
![No.5C51程序设计](https://img.taocdn.com/s3/m/6e68a65a312b3169a451a4c1.png)
– 指定存储区的指针
• 指定存储区的指针在指针的声明中经常包含一个 存储类型标识符指向一个确定的存储区。 • 例如: char data *str; int xdata *ptr; long code *tab;
• 指定存储区指针存放时不再像通用指针那样需 要保存存储类型,指向idata、data 、bdata 和pdata存储区的指针只需要一个字节存放, 而code和xdata指针也才需要两字节。从而减 少了指针长度,节省了存储空间。
– 如:sfr16 TL0=0x8A;
– 特殊功能寄存器中特定位的定义
• 在C51中可以利用关键字sbit定义可独立寻址访问 的位变量
• 对一般位变量的定义
– 当位变量位于内部RAM的可位寻址区(20H~2FH 单元)时,可以利用C51编译器提供的bdata存储器 类型进行访问 – 带有bdata类型的变量可以进行字节或位寻址,用 sbit指定bdata变量的相应位后就可以进行位寻址。
– 考虑存储器结构 – 正确使用片内外RAM、特殊功能寄存器 – 正确处理接口芯片收发数据 – 不需要具体组织和分配存储器资源 – 结构模块化,思路与思维相同 – 但要与单片机结构相关联,否则不能正确映射
• C程序:
• C51:
– – – –
自动完成存储单元分配(内定义) 可编制常见接口芯片通用驱动函数 可采用模块化设计应用程序 加快开发速度
var=XBYTE[0x8000]; 头文件内定义的函数 XBYTE[0x8000]=0x21;
P71
– 例如:unchared xdta xram[0x8000]_at_0x1000; //在外部RAM1000H开始定义了一个一维数组
单片机c51程序设计
![单片机c51程序设计](https://img.taocdn.com/s3/m/9e0ae968effdc8d376eeaeaad1f34693daef10dd.png)
单片机c51程序设计单片机C51程序设计是一门结合了硬件知识和软件编程技能的学科,它广泛应用于自动化控制、智能设备、嵌入式系统等领域。
C51单片机是指使用C语言进行编程的8051系列单片机,它具备丰富的指令集和灵活的编程方式。
下面将从单片机的基本概念、C51编程基础、程序设计步骤以及实例分析等方面进行介绍。
单片机的基本概念单片机,又称微控制器,是一种集成了处理器核心、存储器、输入/输出接口等的微型计算机系统。
它具有体积小、功耗低、成本低、可靠性高等特点。
C51单片机是基于Intel 8051微控制器架构的,具有8位数据总线和16位地址总线,支持多种外设接口。
C51编程基础1. C语言基础:熟悉C语言的基本语法,如变量声明、条件语句、循环语句、函数等。
2. 数据类型:了解C51单片机支持的数据类型,包括特有寄存器位操作。
3. 内存结构:掌握C51单片机的内存结构,包括内部RAM、外部RAM、程序存储器等。
4. 中断系统:理解中断的概念和中断服务程序的编写。
5. 定时器/计数器:了解如何使用单片机的定时器/计数器进行时间控制和事件计数。
程序设计步骤1. 需求分析:明确程序设计的目标和功能需求。
2. 系统设计:设计系统的整体架构,包括硬件连接和软件模块划分。
3. 编写代码:根据设计编写C51程序代码,包括初始化代码、主函数、中断服务程序等。
4. 调试:使用仿真软件或实际硬件对程序进行调试,确保程序正确运行。
5. 优化:根据调试结果对程序进行优化,提高效率和稳定性。
6. 测试:进行全面的测试,确保程序在各种条件下都能稳定运行。
实例分析以一个简单的LED闪烁程序为例,介绍C51程序设计的基本流程:```c#include <reg51.h>// 定义LED连接的端口#define LED_PORT P1void delay(unsigned int ms) {unsigned int i, j;for (i = ms; i > 0; i--)for (j = 110; j > 0; j--);}void main() {while (1) {LED_PORT = 0xFF; // 关闭所有LED灯delay(500); // 延时500msLED_PORT = 0x00; // 打开所有LED灯delay(500); // 延时500ms}}```在这个例子中,我们首先包含了8051单片机的寄存器定义文件`reg51.h`,定义了LED灯连接的端口为P1。
单片机C51程序设计实验报告书(word文档良心出品)
![单片机C51程序设计实验报告书(word文档良心出品)](https://img.taocdn.com/s3/m/e56445b258f5f61fb6366601.png)
实验一并行输入输出口的使用一、实验目的:学会设计proteus 7仿真电路,学习P1口的使用方法和延时子程序的编写用Keil uVision 3编程实现发光二极管的流水点亮。
二、实验原理:P1口为8位准双向I/O口,它的每一位都可以分别定义为输入线或输出线(作为输入时,口锁存器必须置1)。
P1口作为输出,接8个发光二极管D1~D8经限流电阻分别接至8个引脚。
本实验仿真电路图、流程图如下:三、实验代码:#include<reg51.h>#include<intrins.h> //移位库函数包含于此头文件中void delay(unsigned int d) //定义延时子函数{ while(--d>0);}void main(){ unsigned char i,sel;while(1){ sel=0xfe;for(i=0;i<=8;i++){ P1=sel; //显示变量赋给P1口delay(50000); //延时sel=_crol_(sel,1); //改变显示变量}}}四、实验结论:用while语句实现发光二极管循环流水点亮,从上到下一次点亮。
实验二C51分支程序设计一、实验目的:学习多分支选择结构和switch语句,了解循环的嵌套。
二、实验原理:do while 循环先执行后判断是否循环,switch括号中的表达式的值与某case后的常量表达式的值相同时,就执行它后面的语句,遇到break语句则退出switch语句。
本实验仿真电路图、流程图如下:(仿真电路图)(流程图)三、实验代码:#include <reg51.h>void main(){ char a;do{ P1=0xff;a=P1;a=a&0x03;switch(a){ case 0:P2=0x0e;break;case 1:P2=0x0d;break;case 2:P2=0x0b;break;case 3:P2=0x07;break;}}while(1);}四、实验结论:多分支选择的switch/case语句,可直接处理并行多分支选择问题,从匹配表达式的括号开始执行,不再进行判断。
C51程序设计
![C51程序设计](https://img.taocdn.com/s3/m/33d6499327fff705cc1755270722192e44365866.png)
C51程序设计C51程序设计是指通过C语言编写的用于C51单片机的程序。
C51单片机是一种基于8051架构的单片机,具有广泛的应用领域,如电子产品、嵌入式系统等。
在本文中,我将讲述C51程序设计的完整内容,并且给出1200多字的详细说明。
首先,C51单片机具有的特点主要有:易于学习和使用、低功耗、功能强大、扩展性好、体积小、性能稳定等。
C51单片机的硬件结构包括中央处理器(CPU)、存储器、输入输出(I/O)端口等。
中央处理器是C51单片机的核心部件,负责执行指令和控制系统的运行。
存储器用于存储数据和程序,包括随机存储器(RAM)和只读存储器(ROM)。
输入输出端口用于与外部设备进行数据交互,如LED灯、数码管、键盘等。
其次,C语言是一种高级程序设计语言,被广泛应用于嵌入式系统和各种应用程序的开发。
C语言的基本语法包括数据类型、变量、运算符、控制语句、函数等。
数据类型用于定义变量的类型,如整型、字符型、浮点型等。
变量是用于存储数据的标识符,可以在程序中进行赋值、读取和修改。
运算符用于进行各种算术、逻辑和位运算操作。
控制语句用于控制程序的执行流程,如条件语句、循环语句等。
函数是程序的基本模块,用于封装可重用的代码块。
在C51程序设计中,需要安装C51编译器,常用的有Keil C51、Keil C51是一种功能强大、易于使用的C51编译器,提供了丰富的库函数和调试工具,可以大大简化程序的开发和调试过程。
安装完编译器后,可以使用C语言编写C51程序,通过编译、烧写和运行等步骤,将程序加载到C51单片机中执行。
C51程序的设计步骤主要包括需求分析、程序设计、编码实现、编译和烧写、调试和测试等。
需求分析是明确程序的功能和性能要求,根据需求进行程序设计。
程序设计是将需求转化为具体的算法和数据结构,设计程序的模块和接口。
编码实现是根据设计的程序,使用C语言实现具体的功能和操作。
编译和烧写是将C源代码编译为可执行文件,并将可执行文件加载到C51单片机中执行。
用Keil_C51开发串行口
![用Keil_C51开发串行口](https://img.taocdn.com/s3/m/cc0528f7534de518964bcf84b9d528ea81c72fa5.png)
用Keil C51 C51开发串行口MCS-51单片机的串行口具有两条独立的数据线——发送端TXD 和接收端RXD,它允许数据同时往两个相反的方向传输。
一般通信时发送数据由TXD 端输出,接收数据由RXD 端输入。
MCS-51单片机的串行口既可以用于网络通信,亦可实现串行异步通信,还可以用作同步移位寄存器。
如果在串行口的输入输出引脚上加上电平转换器,就可方便地构成标准的RS-232接口。
MCS-51单片机的串行接口是一个全双工通信接口,它有两个物理上独立的接收、发送缓冲器SBUF,可以同时发送和接收数据。
但是发送缓冲器只能写入,不能读出;接收缓冲器只能读出,不能写入。
两个缓冲器共用一个地址(99H)。
5.4.1 数据通信的基本概念常用于数据通信的传输方式有单工、半双工、全双工和多工方式。
单工方式:数据仅按一个固定方向传送。
因而这种传输方式的用途有限,常用于串行口的打印数据传输与简单系统间的数据采集。
半双工方式:数据可实现双向传送,但不能同时进行,实际的应用采用某种协议实现收/发开关转换。
全双工方式:允许双方同时进行数据双向传送但一般全双工传输方式的线路和设备较复杂。
多工方式:以上三种传输方式都是用同一线路传输一种频率信号,为了充分地利用线路资源,可通过使用多路复用器或多路集线器,采用频分、时分或码分复用技术,即可实现在同一线路上资源共享功能。
根据同步方式,串行数据通信有两种形式,如图5-5所示。
异步通信。
在这种通信方式中,接收器和发送器有各自的时钟,它们的工作是非同步的。
异步通信用一帧来表示一个字符,其内容是一个起始位,紧接着是若干个数据位。
同步通信。
同步通信格式中,发送器和接收器由同一个时钟源控制,在异步通信中,每传输一帧字符都必须加上起始位和停止位,占用了传输时间,若要求传送数据量较大,速度就会慢得多。
同步传输方式去掉了这些起始位和停止位,只在传输数据块时先送出一个同步头(字符)标志即可。
同步传输方式比异步传输方式速度快,这是它的优势。
c51程序设计方法
![c51程序设计方法](https://img.taocdn.com/s3/m/9a5b46f1db38376baf1ffc4ffe4733687e21fc28.png)
c51程序设计方法C51程序设计方法C51程序设计是指使用C语言来进行51系列单片机的程序开发和编程。
在C51程序设计中,我们可以通过编写C语言代码来实现对单片机的控制和操作,包括输入输出、中断处理、时钟控制等功能。
在C51程序设计中,首先需要了解单片机的硬件结构和功能。
单片机是一种集成电路,内部包含了CPU、存储器、输入输出接口、定时器、中断控制器等功能模块。
了解这些硬件模块的特点和使用方法,对于进行C51程序设计至关重要。
在C51程序设计中,我们首先需要选择合适的开发环境和编译工具。
常用的C51开发环境有Keil C51、SDCC等,这些工具提供了编译、调试和下载等功能,方便我们进行程序开发和调试。
在C51程序设计中,我们可以通过编写C语言代码来实现对单片机的控制。
C语言是一种高级语言,具有结构化、模块化和可移植等特点,可以方便地实现复杂的功能。
在编写C51程序时,我们可以使用C语言的各种语法和函数库,如变量声明、条件语句、循环语句、函数调用等,来实现对单片机的各种操作。
在C51程序设计中,我们可以利用单片机的输入输出接口来实现与外部设备的通信。
单片机的输入输出接口可以连接各种传感器、开关、显示器、驱动器等外部设备,通过编写相应的C语言代码,可以实现与这些外部设备的数据交换和控制。
在C51程序设计中,我们还可以利用单片机的中断功能来处理各种事件和异常。
中断是一种特殊的事件,当某个条件满足时,单片机会自动跳转到相应的中断服务程序进行处理。
通过编写中断服务程序,我们可以实现对各种事件的即时响应,提高程序的实时性和可靠性。
在C51程序设计中,我们还可以利用单片机的定时器功能来实现各种定时和计时的功能。
定时器可以产生一定时间间隔的中断信号,通过编写相应的中断服务程序,我们可以实现定时和计时的功能,例如定时采样、定时发送数据等。
在C51程序设计中,我们还可以利用单片机的通信接口来实现与其他设备的数据交换。
单片机C51程序设计.ppt
![单片机C51程序设计.ppt](https://img.taocdn.com/s3/m/7e3b1f00b90d6c85ec3ac659.png)
单片机C51程序设计
C51对外部I/O的访问
假定LCD的端口地址为8000H~8003H则:
#include <absacc.h> // LCD Registers addresses #define LCD_CMD_WR XBYTE[8000] #define LCD_DATA_WR XBYTE[8001] #define LCD_BUSY_RD XBYTE[8002] #define LCD_DATA_RD XBYTE[8003]
数据的存储器模式
指针变量的说明
long xdata * px;
char xdata * data pd; // 指向xdata, 但指针在data
int * px; // 指向idata的整型变量的指针 unsigned int * px; // 指向idata的无符号整型变量的指针
单片机C51程序设计
#include <absacc.h> //LCD Registers addresses #define LCD_CMD_WR XBYTE[8000] #define LCD_DATA_WR XBYTE[8001] #define LCD_BUSY_RD XBYTE[8002] #define LCD_DATA_RD XBYTE[8003] (假定某LCD的端口地址为8000H~8003H)
单片机C51程序设计
主讲 聂雄
单片机C51程序设计
概述 C51程序结构 C51数据类型 数据的存储类型和存储器模式 C51对SFR、可寻址位、存储器和I/O口定义 C51运算符 函数 C语言编程实例 中断程序函数的格式
单片机C51程序设计
概述
C语言是一种通用的程序设计语言,其代码 效率高,数据类型及运算符丰富,并具有很 好看程序结构,适用于各种应用的程序设计。
C51程序设计范文
![C51程序设计范文](https://img.taocdn.com/s3/m/56a8e3be710abb68a98271fe910ef12d2af9a9bc.png)
C51程序设计范文C51程序设计是指使用C语言编程来控制C51单片机的各种功能,包括输入输出、定时器、串口通信、中断等。
C51程序设计的特点之一是语言简洁、易读易写,对程序员来说较为友好。
相比于汇编语言,C51程序设计可以更快速地编写程序,并且具有更好的可读性。
首先,我们需要了解C51单片机的硬件特性。
C51单片机通常有多个GPIO引脚,可以用来控制外部设备。
我们可以通过在程序中设置GPIO引脚的电平来控制外部设备的开关状态。
下面是一个简单的C51程序设计示例,用于控制一个LED灯的亮暗状态:```#include <reg52.h>sbit LED = P1^0; // 定义LED在P1引脚的位置void maiwhile(1)LED=1;//点亮LEDdelay(1000); // 延时1秒LED=0;//熄灭LEDdelay(1000); // 延时1秒}void delay(unsigned int t)unsigned int i, j;for(i = 0; i < t; i++)for(j = 0; j < 1000; j++)}}```在这个示例中,我们首先定义了LED的位置,即P1引脚的第0位。
然后在主函数中,通过循环控制LED灯的亮暗状态。
在每次循环中,我们先将LED引脚设置为高电平,即LED灯点亮,然后延时1秒。
接下来将LED引脚设置为低电平,即LED灯熄灭,再次延时1秒。
通过不断循环这个过程,可以让LED灯以固定的频率闪烁。
这是一个非常简单的例子,但它展示了C51程序设计的基本原理和应用。
实际上,C51程序设计可以实现更为复杂的功能,比如通过按键控制LED的开关,通过串口通信控制外部设备等。
C51程序设计的灵活性使得它成为嵌入式系统开发中的重要工具。
总结一下,C51程序设计是一种基于C语言的嵌入式系统编程语言,用于开发C51单片机的应用程序。
它具有语言简洁、易读易写的特点,适用于多种领域的嵌入式系统开发。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
D7 SCON:
D6
D5
D4
D3
D2 RB8
D1 TI
D0 RI
字节地址:98H 可位寻址
SM0 SM1 SM2 REN TB8
串行接口控制寄存器SCON
11.1.4 特殊功能寄存器PCON
• 特殊功能寄存器PCON的格式,如图所示。PCON的 单元字节地址为87H,不可以进行位寻址。特殊功 能寄存器PCON用于CHMOS型单片机中进行电源控制, 也称为电源控制寄存器。下面分别介绍各位的含 义。
低位在前,高位在后
……
起始位
D0
D1
D2
D3
D4
D5
D6
D7
0/1
停止位
模式ቤተ መጻሕፍቲ ባይዱ的帧格式
11.4.1 模式2的波特率
• 串口的工作模式2是11位异步发送接收方式。模式2下的波特率的 计算公式如下: • 模式2波特率= fosc·2SMOD/64 • 从公式中可以看出,在模式2下,波特率由单片机的振荡频率fosc 和PCON的波特率倍增位SMOD共同决定。当SMOD=0时,波特率为 fosc/64,当SMOD=1时,波特率为fosc/32。串口模式2的波特率不由 定时器来设置,只可选两种:fosc/32或者fosc/64。 • 例如,如果8051单片机外接12MHz的晶振,通过寄存器PCON可以选 择波特率。在C51程序中,则可以采用如下的赋值语句来实现,示 例如下: • PCON=0x00; //设 置SMOD=0 • PCON=0x80; //设 置SMOD=1
11.1 51系列单片机的串行接口
• 51系列单片机内部集成的全双工串行通信接口电 路,常称为UART。该串行接口电路功能很强,不 仅可以进行串行异步数据的发送和接收,也可以 作为一个同步移位寄存器使用。
11.1.1 单片机串行通信概述
• 单片机和外部设备可以采用并行通信和串行通信两种方法进行数据传输。 这两种数据传输方式分别如图所示。其中,并行通信是指数据的各个二进 制位同时进行传输。并行通信传输速度快,效率高,缺点是需要比较多的 数据线,易受外界干扰,传输距离不能太远。串行通信是指数据的各个二 进制位按照顺序一位一位地进行传输。串行通信所需的数据线少,节省硬 件成本以及单片机的引脚资源,并且抗干扰能力强,适合于远距离数据传 输,其缺点是每次发送一个比特,导致传输速度慢,效率比较低。
11.4.2 模式2的数据发送及C51程序设计
• 在串行口的工作模式2中,TXD引脚为数据发送端。 模式2的发送共有9位有效的数据,在启动发送之 前,需要将发送的第9位,即可编程位的数值送入 寄存器SCON中的TB8位。这个编程标志位可以由用 户自己定义,硬件不做任何规定。例如,用户可 以将这一位定义为奇偶校验位或地址/数据标志位。 • 1.模式2的数据发送流程 • 2.采用查询方式的模式2数据发送C51程序设计 • 3.采用中断方式的模式2数据发送C51程序设计
单 片 机 1
P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 P1.7
P1.0 P1.1 P1.2 单 P1.3 片 P1.4 机 P1.5 2 P1.6 P1.7
单 片 机 1 TXD 发送 RXD 接收
单 片 机 接收 RXD 2 发送 TXD
单片机并行通信
单片机串行通信
11.1.2 单片机串行接口的内部结构
串口模式3常用波特率参数设置 fosc(MHz) SMOD值 定时器T1工作模 式 初值
•
波特率(bit/s)
110
110 137.5 1200 2400 4800
6
12 11.986 11.0592 11.0592 11.0592
0
0 0 0 0 0
2
2 2 2 2 2
72H
FEEBH 1DH E8H F4H FAH
低位在前,高位在后。
……
起始位
D0
D1
D2
D3
D4
D5
D6
D7
停止位
……
模式1的帧格式
11.3.1 模式1的波特率
• 串口的工作模式1为10位异步发送接收方式。其串 行移位时钟脉冲由定时器T1的溢出率来决定,因 此,波特率由定时器T1的溢出率和波特率倍增位 SMOD来共同决定。模式1的波特率计算公式如下: • 模式1波特率=T1溢出率·2SMOD/32 • 设置模式1的波特率,需要对定时器T1进行工作方 式设置,以便于得到需要的波特率发生器。一般 使T1工作于模式2,此时为初值自动加载的定时方 式。如果计数器的初始值为X,则每过256-X个机 器周期的时候,定时器T1便将产生一次溢出,溢 出的周期为(256-X)*12/fosc。
低位在前,高位在后
……
D0
D1
D2
D3
D4
D5
D6
D7
……
串行工作模式0的数据帧格式
11.2.1 模式0的波特率
• 8051单片机在串口模式0下,每个机器周期产生一 个移位时钟,对应着一个比特数据的发送和接收。 因此,此时波特率固定为8051单片机振荡频率的 1/12,其波特率的计算公式如下: • 串口模式0波特率=fosc/12 • 例如,对于24MHz的外部晶体振荡频率,模式0可 以获得24MHz /12=2Mbit/s的波特率。 • 同时,在串口模式0下,波特率不受波特率倍增位 SMOD的影响。因此,在C51程序设计时只要指定串 口工作于模式0便完成了串口速率的设置,而无需 再设置波特率。
11.4 串行口工作模式2的C51程序设计
• 串行口的工作模式模式2为固定波特率的串行异步 通信方式,在模式2中数据帧的格式,如图所示。 一帧数据由11位构成,按照顺序分别为:起始位1 位、8位串行数据(低位在前)、可编程位1位、 停止位1位。在程序中可以设置控制寄存器SCON的 SM0=1和SM1=0来实现。
11.5 串行口工作模式3的C51程序设计
• 串行口的工作模式模式3为11位异步发送接收方式, 在模式3中数据帧的格式,如图所示。一帧数据由 11位构成,按照顺序分别为:起始位1位、8位串 行数据(低位在前)、可编程位1位、停止位1位。 在程序中可以设置控制寄存器SCON的SM0=1和 SM1=1来实现。
11.5.3 模式3的数据接收及C51程序设计
• 串口的工作模式3是11位异步发送接收方式,单片 机RXD引脚为数据接收端。模式3的串行数据接收 过程和模式2基本类似。 • 1.模式3的数据接收流程 • 2.采用查询方式的模式3数据接收C51程序设计 • 3.采用中断方式的模式3数据接收C51程序设计
串 行 控 制 寄 存 器 (98H) RXD(P3.2)
移位寄存器
单片机串行口内部结构
11.1.3 串行接口控制寄存器SCON
• 串行控制寄存器SCON的格式及各位的含义,如图 所示。控制寄存器SCON的字节地址为98H,可进行 位寻址。该寄存器用于选择串行通信的工作方式 和某些控制功能,包括接收/发送控制及设置状态 标志等。下面分别介绍各位的用途。
• 51系列单片机的全双工串行口主要由数据发送缓 冲器、发送控制器TI和接收控制器RI等组成,其 结构如图所示。
内部8051 CPU总线
SBUF (99H) 发送缓冲器 波 特 率 发 生 器 TI 接收缓冲器 SBUF (99H)
移位寄存器
TXD(P3.1)
发送控制器TI 串行口中断
接收控制器RI
11.3.3 模式1的数据接收及C51程序设计
• 串行口的工作模式1为10位异步发送接收方式,单片机RXD 引脚为数据接收端。模式1接收数据中的定时信号可以有两 种,接收移位脉冲和接收字符的检测脉冲。 • 串行口模式1接收数据时的接收移位脉冲,由定时器1的溢 出信号和波特率倍增位SMOD来共同决定,即由定时器1的溢 出率经过16分频或32分频得到。 • 接收字符的检测脉冲,其频率是接收移位脉冲的16倍。在 接收一位数据的时候,有16个检测脉冲,以其中的第7、8 和9个脉冲作为真正的接收信号的采样脉冲。对这三次采样 结果采取三中取二的原则来确定所检测到的值。由于采样 的信号总是在接收位的中间位置,这样便可以抑制干扰, 避免信号两端的边沿失真,也可以防止由于通信双方时钟 频率不完全相同而带来的接收错误。
D7 PCON: SMOD
D6 -
D5 -
D4 -
D3 GF1
D2 GF0
D1 PD
D0 IDL
字节地址:87H 不可位寻址
PCON的格式
11.2 串行口工作模式0的C51程序设计
• 51系列单片机串行口的工作模式0是同步移位寄存 器输入/输出方式,模式0的数据帧格式,如图所 示。从图中可以看出,模式0中的数据以8位为一 帧,没有起始位和停止位,发送时低位在前,高 位在后。在程序中可以设置控制寄存器SCON的 SM0=0和SM1=0来将串行口设置为工作模式0。
并行数据输出 8051单片机
RXD TXD P2.1
DATA CLK STB
CD4094
扩展并行输出口
14.2.3 模式0的数据接收及C51程序设计
• 对于模式0的数据接收,单片机的TXD引脚都用于 发送同步移位脉冲,而8位串行数据是通过RXD引 脚来输入。 • 1.模式0的数据接收流程 • 2.采用查询方式模式0数据接收的C51程序设计 • 3.采用中断方式模式0数据接收的C51程序设计
并行数据输入 8051单片机
RXD TXD P2.2
Q8 CLK
P/S
CD4014
扩展并行输入口
11.3 串行口工作模式1的C51程序设计
• 串行口的工作模式1是波特率可变的串行异步通信 方式,工作模式1下数据帧的格式,如图11.10所 示。数据帧由10位组成,按顺序分别为起始位、8 位数据位、停止位。数据在传输时,低位在前, 高位在后。在程序中可以设置控制寄存器SCON的 SM0=0和SM1=1来将串口设置为工作模式1。