51单片机串口调试实验(C语言)
- 格式:wps
- 大小:18.00 KB
- 文档页数:2
51单片机串口通信异常的调试一例单片机与DSP在硬件结构和程序编写方面存在很多共同之处,所以最近几周试着用了一下51单片机开发板,希望进一步熟悉中断的概念、串口通信、I2C协议、存储扩展等常用的知识。
在进行串口通信的实验时,预期功能不能实现。
实验的设计方案是:通过上位机给单片机发送一个16bit的字符串,单片机对字符串进行接收并立刻回显给上位机,接收并回显完毕后依次将这些字符(只能是0-9,a-f这几个字符,可以重复)在数码管上进行显示。
程序编写完成后,通过上位机发送字符串9876543210abcdef,单片机串口接收并回显9876543210abcde,然后数码管依次显示f9876543210abcde,数码管显示完成后,单片机串口回显的字符串中的e后面又多了一个f。
对实验现象进行分析不难发现,串口的接收和回显功能正常,但是存在2个问题:1.串口接收并回显和数码管显示的时序有点混乱;2.数码管的显示出现异常,本应该依次显示9876543210abcdef,实际上显示的却是f9876543210abcde。
对源代码进行分析发现,时序混乱的原因是中断响应及中断返回的执行时序出现问题,修改代码后问题1被解决。
问题2的解决思路:源代码中,通过串口接收到的字符串被存储在一个一维数组array[16]中,该数组有16个元素,每个元素都是unsigned char型。
在源代码中,先注释掉数码管显示的那一段代码,然后添加串口打印代码,串口打印实现的功能是依次显示array[0]到array[15]这16个元素的值。
编译通过后,将程序烧写到单片机。
使用串口调试助手,以十六进制的形式观察array[0]到array[15]的取值,结果如下:也就是说array[0]存储的值用十六进制显示是0xff,array[1]=9array[2]=8……array[14]=darray[15]=e很明显可以看出array[0]没有按照预期的那样存储字符9。
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单片机串口通信程序。
51实验11-串口通信串口通信,原理图如下:程序:C语言1:/************实现功能*************接收电脑"串口调试助手"发来的信息,显示在发光二极管上(查询方式)**********************************//*************包含头文件**************/ #include<>/*************初始化函数*************/ void init(){TMOD=0x20;//设置定时器1为工作方式2 TH1=0xfd;//T1装初值TL1=0xfd;TR1=1;//启动T1REN=1;//允许串行接收SM0=0;//设置串口为工作方式1SM1=1;}/***************主函数***************/ void main(){init();//初始化while(1){if(RI==1);{RI=0;//接收中断标志位(取消终端申请)P1=SBUF;//读取缓冲寄存器内数据}}}C语言2:/************实现功能*************接收电脑"串口调试助手"发来的信息,显示在发光二极管上(中断方式)**********************************//*************包含头文件**************/ #include<>/*************初始化函数*************/ void init(){TMOD=0x20;//设置定时器1为工作方式2 TH1=0xfd;//T1装初值TL1=0xfd;TR1=1;//启动T1REN=1;//允许串行接收SM0=0;//设置串口为工作方式1SM1=1;EA=1;//开总中断ES=1;//开串口中断}/***************主函数***************/ void main(){init();//初始化while(1){}}void ser() interrupt 4{RI=0;//接收中断标志位(取消终端申请)P1=SBUF;//读取缓冲寄存器内数据}C语言3:/************实现功能*************接收电脑"串口调试助手"发来的信息,并将收到的信息再发给电脑。
51单片机C语言实验及实践教程第一章:硬件资源模块第二章:keil c 软件使用at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅1.闪烁灯at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅2.模拟开关灯at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅3.多路开关状态指示at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅4.广告灯的左移右移at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅5.广告灯(利用取表方式)at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅6.报警产生器at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅7.I/O并行口直接驱动LED显示at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅8.按键识别方法之一at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅9.一键多功能按键识别技术at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅10.00-99计数器at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅11.00-59秒计时器(利用软件延时)at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅12.可预置可逆4位计数器at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅13.动态数码显示技术at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅14.4×4矩阵式键盘识别技术at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅15.定时计数器T0作定时应用技术(一)at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅16.定时计数器T0作定时应用技术(二)at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅17.99秒马表设计at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅18.“嘀、嘀、……”报警声at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅19.“叮咚”门铃at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅20.数字钟(★)at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅21.拉幕式数码显示技术at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅22.电子琴at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅23.模拟计算器数字输入及显示at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅24.8×8LED点阵显示技术at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅25.点阵LED“0-9”数字显示技术at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅26.点阵式LED简单图形显示技术at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅27.ADC0809 A/D转换器基本应用技术at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅28.数字电压表at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅29.两点间温度控制at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅30.四位数数字温度计at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅31.6位数显频率计数器at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅32.电子密码锁设计at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅33.4×4键盘及8位数码管显示构成的电子密码锁at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅34.带有存储器功能的数字温度计-DS1624技术应用at89s51单片机实验及实践课题┅┅┅┅┅┅┅┅┅┅┅35DS18B20数字温度计使用第一章AT89S51单片机实验及实践系统板简介AT89S51单片机实验及实践系统板(以后简介系统板)集成多个硬件资源模块,每个模块各自可以成为独立的单元,也可以相互组合,因此,可以为不同阶层的单片机爱好者及单片机开发者提供不同的开发环境。
本文由lbcumt贡献 doc文档可能在WAP端浏览体验不佳。
建议您优先选择TXT,或下载源文件到本机查看。
Keil C 软件使用 Keil C51 软件是众多单片机应用开发的优秀软件之一,它集编辑,编译,仿真于一体,支持 汇编,PLM 语言和 C 语言的程序设计,界面友好,易学易用。
下面介绍 Keil C51 软件的使用方法 进入 Keil C51 后,屏幕如下图所示。
几秒钟后出现编辑界 启动 Keil C51 时的屏幕 进入 Keil C51 后的编辑界面 简单程序的调试 学习程序设计语言、学习某种程序软件,最好的方法是直接操作实践。
下面通过简单的编 程、调试,引导大家学习 Keil C51 软件的基本使用方法和基本的调试技巧。
1)建立一个新工程 单击 Project 菜单,在弹出的下拉菜单中选中 New Project 选项 2)然后选择你要保存的路径,输入工程文件的名字,比如保存到 C51 目录里,工程文件的名 字为 C51 如下图所示,然后点击保存. 3)这时会弹出一个对话框,要求你选择单片机的型号,你可以根据你使用的单片机来选择,k eil c51 几乎支持所有的 51 核的单片机,我这里还是以大家用的比较多的 Atmel 的 89C51 来 说明,如下图所示,选择 89C51 之后,右边栏是对这个单片机的基本的说明,然后点击确定. 4)完成上一步骤后,屏幕如下图所示 到现在为止,我们还没有编写一句程序,下面开始编写我们的第一个程序。
5)在下图中,单击“File”菜单,再在下拉菜单中单击“New”选项 新建文件后屏幕如下图所示 此时光标在编辑窗口里闪烁, 这时可以键入用户的应用程序了, 但笔者建议首先保存该空白 的文件,单击菜单上的“File”,在下拉菜单中选中“Save As”选项单击,屏幕如下图所示,在 “文件名”栏右侧的编辑框中,键入欲使用的文件名,同时,必须键入正确的扩展名。
#include <reg52.h>#include<intrins.h>#include <stdio.h>#include <math.h>#define uchar unsigned char#define uint unsigned intsbit Key1 = P2^3;sbit Key2 = P2^2;sbit Key3 = P2^1;sbit Key4 = P2^0;sbit BELL = P3^6;sbit CONNECT = P3^7;unsigned int Key1_flag = 0;unsigned int Key2_flag = 0;unsigned int Key3_flag = 0;unsigned int Key4_flag = 0;unsigned char b;unsigned char code Num[21]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00, 0x10,0x89};unsigned char code Disdigit[4] = {0x7F,0xBF,0xDF,0xEF};unsigned char Disbuf[4];void delayms(uint t){uint i;while(t--){/* 对于11.0592M时钟,约延时1ms */for (i=0;i<125;i++){}}}//-----------------------------------------------------void SendData(uchar Dat){uchar i=0;SBUF = Dat;while (1){if(TI){TI=0;break;}}}void ScanKey(){if(Key1 == 0){delayms(100); if(Key1 == 0){Key1_flag = 1; Key2_flag = 0; Key3_flag = 0;Key4_flag = 0;Key1 = 1;}else;}if(Key2 == 0){delayms(100);if(Key2 == 0){Key2_flag = 1; Key1_flag = 0; Key3_flag = 0;Key4_flag = 0;Key2 = 1;}else;}if(Key3 == 0){delayms(50);if(Key3 == 0){Key3_flag = 1; Key1_flag = 0; Key2_flag = 0;Key4_flag = 0;Key3 = 1;}else;}if(Key4 == 0){delayms(50);if(Key4 == 0){Key4_flag = 1;Key1_flag = 0;Key2_flag = 0;Key3_flag = 0;Key4 = 1;}else;}else;}void KeyProc(){if(Key1_flag){TR1 = 1;SendData(0x55);Key1_flag = 0; }else if(Key2_flag){TR1 = 1;SendData(0x11); Key2_flag = 0;}else if(Key3_flag) {P1=0xff;BELL = 0;CONNECT = 1;Key3_flag = 0;}else if(Key4_flag){CONNECT = 0;BELL = 1;Key4_flag = 0;}else;}void Initdisplay(void){Disbuf[0] = 1;Disbuf[1] = 2;Disbuf[2] = 3;Disbuf[3] = 4;}void Display() //显示{unsigned int i = 0;unsigned int temp,count;temp = Disdigit[count]; P2 =temp;temp = Disbuf[count];temp = Num[temp];P0 =temp;count++;if (count==4)count=0;}void time0() interrupt 1 using 2 {Display();TH0 = (65535 - 2000)/256;TL0 = (65535 - 2000)%256;}void main(){Initdisplay();TMOD = 0x21;TH0 = (65535 - 2000)/256;TL0 = (65535 - 2000)%256;TR0 = 1;ET0 = 1;TH1 = 0xFD; //11.0592MTL1 = 0xFD;PCON&=0x80;TR1 = 1;ET1 = 1;SCON = 0x40; //串口方式REN = 1;PT1 = 0;PT0 = 1;EA = 1;while(1){ScanKey();KeyProc();if(RI){Disbuf[0] = 0;Disbuf[1] = 20;Disbuf[2] = SBUF>>4;Disbuf[3] = SBUF&0x0f;RI = 0;}else;}}51单片机串口通信C语言程序2**************************************************************; 平凡单片机工作室;ckss.asm;功能:反复向主机送AA和55两个数;主机使用一个串口调试软件设置19200,n,8,1***************************************************************/#include "reg51.h"#define uchar unsigned char#define uint unsigned int//延时程序//////////////////由Delay参数确定延迟时间*/void mDelay(unsigned int Delay){ unsigned int i;for(;Delay>0;Delay--){ for(i=0;i<124;i++){;}}}//////////////////// 主程序////////////////////void main(){ uchar OutDat; //定义输出变量TMOD=0x20; //TMOD=0TH1=0xf3; //12MHZ ,BPS:4800,N,8,1TL1=0xf3;PCON=0x80; //方式一TR1=1; //?????????????????????????????SCON=0x40; //串口通信控制寄存器模式一OutDat=0xaa; //向串口发送固定数据值for(;;) //循环程序{SBUF=OutDat;//发送数据for(;;){ if(TI) //发送中断位当发送停止位时置1,表示发送完成break;}mDelay(500);TI=0; //清零中断位OutDat=~OutDat; //显示内容按位取反}}。
51单片机c语言教程在本教程中,我们将学习如何在51单片机上使用C语言进行编程。
无论您是初学者还是有一定经验的开发者,本教程都将对您有所帮助。
首先,我们需要了解一些基本概念。
51单片机是一种基于哈弗微电子公司的MCS-51架构的微控制器。
它采用了Harvard结构,即将程序存储器和数据存储器分开。
它具有各种功能和接口,可以满足不同的应用需求。
在使用C语言进行51单片机编程之前,必须安装相应的开发工具。
这里我们推荐使用Keil C51开发环境。
安装完成后,我们就可以开始编写第一个程序了。
#include <reg51.h>void main(){// 在这里编写您的代码}以上是一个简单的C语言程序模板。
我们使用了reg51.h头文件,该文件包含了与51单片机相关的寄存器定义和常量。
接下来,我们可以开始编写具体的功能代码了。
例如,如果我们想要在LED灯上闪烁一个简单的模式,可以使用以下代码:#include <reg51.h>sbit LED = P1^0;void main(){while(1){LED = 0; // 点亮LEDdelay(1000); // 延时1秒LED = 1; // 熄灭LEDdelay(1000); // 延时1秒}}在这个程序中,我们首先定义了一个LED的控制引脚,然后通过循环实现了闪烁的功能。
在每次循环中,我们先点亮LED,然后通过调用延时函数延时1秒,再将LED熄灭,再次延时1秒。
这样就形成了一个简单的LED闪烁效果。
除了控制IO口外,51单片机还可以实现其他各种功能,如定时器、串口通信等。
这些功能的实现也都可以通过C语言来完成。
希望通过本教程,您可以对51单片机的C语言编程有一个基本的了解。
在以后的学习中,您可以深入研究这些知识,并通过实践来提升自己的能力。
祝您学习愉快!。
实验1 Proteus认识实验Proteus ISIS是英国Labcenter公司开发的电路分析与实物仿真软件。
它运行于Windows操作系统上,可以仿真、分析(SPICE)各种模拟器件和集成电路,是目前较好的仿真单片机及外围器件的工具。
下面以制作一个闪烁灯为例给出proteus的使用方法。
1.创建文件双击桌面上的ISIS 7 Professional图标或者单击屏幕左下方的“开始”→“程序”→“Proteus 7 Professional”进入Proteus ISIS集成环境,选择“File”→“Creat New Design”命令,选择Default模板,单击OK并进行保存命名为“Led.DSN”,如图所示。
创建文件2.绘制电路图1)将所需元器件加入到对象选择器窗口。
选择“Library”→“Pick Device/Symbol”命令,弹出“Pick Devices”页面,在“Keywords”输入AT89C51,如图所示。
Pick Devices窗口单击“OK”,元件名出现在“DEVICES”列表中,如图所示。
DEVICES窗口2)在“DEVICES”列表中选择A T89C51,在绘图区域单击鼠标左键摆放元件。
3)同理摆放其它元件,如图所示。
摆放元件4)使用左下角的旋转或反转命令,改变元件方向。
也可用鼠标右键单击元件,进行旋转或反转。
5)在左侧单击图标,列表框中显示可用的终端,单击“Power”摆放电源终端,单击“Ground”摆放接地终端,如图所示。
添加终端6)选中元件,单击鼠标左键,设置元件参数,7)布线,分别单击两个引脚,两个引脚之间会自动走线,也可以手动走线,连接走线后的电路如图所示。
连接走线3.加载目标文件在AT89C51上双击鼠标左键,弹出Edit Component 窗口,点击Program File,添加目标程序在Keil中生成的HEX文件,如图。
加载目标文件4.运行仿真点击OK,单击ISIS编辑环境下方的启动仿真按钮,运行仿真,可观察到实验运行结果,如图9-17所示。
#include <reg52.h> //89C52单片机头文件#include <LCD_code.h> //液晶LCD的字模文件#include <intrins.h>//功能引脚定义sbit A = P0^7; //数据1/命令0选择sbit RW = P0^6; //读1/写0sbit E1 = P0^4; //片选1(Master)sbit E2 = P0^5; //片选2(slave)sbit LED= P0^3; //背光sbit up = P0^0; //向上翻页键sbit down= P0^1; //向下翻页键#define data P2 //液晶并行数据//液晶显示控制命令表#define disp_on 0xAf //显示关闭#define disp_off 0xAe //显示打开#define disp_start_line 0xC0 //显示起始地址(后5位-表示0-31行)#define page_addr_set 0xB8 //页地址设置(0~3)#define col_addr_set 0x00 //列地址设置(0~61)#define status_busy 0x80 //0=ready#define modeRWite 0xEE //写模式#define dynamic_driver 0xA4 //动态驱动#define adc_select 0xA0 //clockwise#define clk32 0xA9 //刷新时钟设置1/32#define clk16 0xA8 //刷新时钟设置1/16#define reset 0xE2 //软件复位#define uchar unsigned char#define uint unsigned int//全局变量,及标志位定义uchar time_counter = 0; //定时器的软件计数器uchar key = 0; //键盘值uchar serial_counter; //串行计数器bit disp_flag = 0; //显示更新标志uchar bdata serial_byte = 0; //串行口标志位定义字节sbit Sflag = serial_byte^0; //串行接收头部标志,一下8个都定义在'serial_byte'内sbit G1flag = serial_byte^1;sbit Pflag = serial_byte^2;sbit G2flag = serial_byte^3;sbit G3flag = serial_byte^4;sbit Aflag = serial_byte^5;sbit DFflag = serial_byte^6;sbit ENflag = serial_byte^7;bit r_flag = 0;unsigned char idata serial_buff[77]; //串行接收缓冲//uchar code head[] = {'$','G','P','G','G','A',','};//bit serial_flag = 0;////液晶操作主要函数//////////////////////////////////////////////////////////////void lcd_init(void)//引用:lcd_init(); 说明:LCD初始化;//////////////////////////////////////////////////////////////////////////////////void lcd_clr(void)//引用:lcd_clr(); 说明:LCD清屏;////////////////////////////////////////////////////////////////////////////////void lcd_init(void); //LCD初始化void lcd_clr(void); //LCD清屏void wait_ready(void); //等待readyvoid draw_bmp(uchar col,uchar layer,uchar width,uchar *bmp); //点阵码显示输出void ASCII2BCD(void); //ASCII码转换为BCD码void logo(void); //开机画面显示/*----------------------------------------------------------------------------中断程序-----------------------------------------------------------------------------*///////////////////////////////////////////////////////////////////////////////////定时器0中断函数,用于控制背光灯延时10S熄灭///////////////////////////////////////////////////////////////////////////////void int_t0() interrupt 1 using 1{ //定时器0中断函数,用于控制背光灯延时10S熄灭TH0 = 0x4C;TL0 = 0x00; //重装定时器0,定时50mStime_counter ++; //软件计数器+1;if (time_counter == 200) //软件计数器定时到10S,关背光,定时器0,清软件计数器{time_counter = 0;LED = 1;TR0 = 0;}}//////////////////////////////////////////////////////////////////////////////////串行口中断函数,用于语句'$GPGGA'判断和此语句的接收///////////////////////////////////////////////////////////////////////////////void serial() interrupt 4 using 2{uchar pp;RI=0;pp=SBUF;if(ENflag==1) //串口接收完毕,可以用来显示,清标志位重新开始{disp_flag=1;serial_byte = 0;}else if(DFflag==1) //'$GPGGA'头判断完毕,开始接收$GPGGA,语句的数据{if(pp==42)ENflag=1; //等待收到'*'结束接收else{serial_buff[serial_counter]=pp; //没收到'*',继续接收,数据放入串口缓冲serial_counter++;}}else if(Aflag==1) //第六个为'A',判断第七个是不是','{if(pp==44)DFflag=1; //第七个个是','开始接收$GPGGA,语句的数据elseserial_byte = 0; //不是',',清标志位}else if(G3flag==1) //第五个为'G',判断第六个是不是'A'{if(pp==65)Aflag=1; //第六个是'A'判断下一个是不是','elseserial_byte = 0; //不是'A',清标志位}else if(G2flag==1) //第四个为'G',判断第五个是不是'G'{if(pp==71)G3flag=1; //第五个是'G'判断下一个是不是'A'elseserial_byte = 0; //不是'G',清标志位}else if(Pflag==1) //第三个为'P',判断第四个是不是'G'{if(pp==71)G2flag=1; //第四个是'G'判断下一个是不是'G'elseserial_byte = 0; //不是'G',清标志位}else if(G1flag==1) //第二个为'G',判断第三个是不是'P'{if(pp==80)Pflag=1; //第三个是'P'判断下一个是不是'G'elseserial_byte = 0; //不是'P',清标志位}else if(Sflag==1) //第一个为'$',判断第二个是不是'G'{if(pp==71)G1flag=1; //第二个是'G'判断下一个是不是'P' elseserial_byte = 0; //不是'G',清标志位}else if(pp==0x24) //判断第一个是不是${Sflag=1; //第一个为$,判断下一个是不是Gserial_counter=0; //串行计数器清零}}/*void serial() interrupt 4 using 2{uchar i,buff;RI = 0;buff = SBUF;if(serial_flag == 1){serial_buff[serial_counter] = buff;serial_counter ++;if(serial_counter > 37){serial_flag = 0;serial_counter = 0;for(i=0;i>7;i++){if(head[i] == serial_buff[i]){disp_flag = 1;}else{disp_flag = 0;i = 8;}}}}else{if(SBUF == '$'){serial_buff[0] = buff;serial_flag = 1;serial_counter ++;}else{serial_flag = 0;serial_counter = 0;}}}*///////////////////////////////////////////////////////////////////////////////////调用方式:void send_mi(uchar instuction)//函数说明:发指令instruction到主窗口(内函数,私有,用户不能直接调用)////////////////////////////////////////////////////////////////////////////////void send_mi(uchar instruction){E2 = 0; //关SlaverE1 = 1; //开Masterwait_ready(); //判断忙A = 0; //指令RW = 0; //写触发data = instruction; //指令码E1 = 0; //关Master}//////////////////////////////////////////////////////////////////////////////////调用方式:void OutMD(uchar i)//函数说明:发数据data到主窗口(内函数,私有,用户不能直接调用)////////////////////////////////////////////////////////////////////////////////void send_md(uchar c){E2 = 0; //关SlaverE1 = 1; //开Masterwait_ready(); //判断忙A = 1; //数据RW = 0; //写触发data = c; //数据E1 = 0; //关Master}//////////////////////////////////////////////////////////////////////////////////调用方式:void send_si(uchar instruction)//函数说明:发指令instruction到从窗口(内函数,私有,用户不能直接调用) ////////////////////////////////////////////////////////////////////////////////void send_si(uchar instruction){E1 = 0; //关MasterE2 = 1; //开Slaverwait_ready(); //判断忙A = 0; //指令RW = 0; //写触发data=instruction; //指令码E2 = 0; //关Slaver}//////////////////////////////////////////////////////////////////////////////////调用方式:void send_sd(uchar data)//函数说明:发数据data到从窗口(内函数,私有,用户不直接调用)////////////////////////////////////////////////////////////////////////////////void send_sd(uchar c){E1 = 0; //关MasterE2 = 1; //开Slaverwait_ready(); //判断忙A = 1; //数据RW = 0; //写触发data = c; //数据E2 = 0; //关Slaver}//////////////////////////////////////////////////////////////////////////////////等待ready:等待LCD内部操作完成,判忙////////////////////////////////////////////////////////////////////////////////void wait_ready(void){A = 0; //指令RW = 1; //读_nop_(); //空操作,产生汇编里面的nopwhile(data & status_busy); //读入LCD状态,1=忙,一直等待LCD内部操作完成}//////////////////////////////////////////////////////////////////////////////////调用方式:void lcd_init(void)//函数说明:122x32LCD初始化,开机后仅调用一次////////////////////////////////////////////////////////////////////////////////void lcd_init(void){send_mi(reset); //复位m-left,s-rightsend_si(reset);send_mi(disp_off); //关闭显示send_si(disp_off);send_mi(dynamic_driver);//动态驱动send_si(dynamic_driver);send_mi(clk32); //1/32占空比send_si(clk32);send_mi(adc_select); //clockwisesend_si(adc_select);send_mi(modeRWite); //写模式结束send_si(modeRWite);send_mi(col_addr_set); //归回零列,设定显示起始行首send_mi(disp_start_line);send_si(col_addr_set);send_si(disp_start_line);send_mi(disp_on); //开显示send_si(disp_on);}//////////////////////////////////////////////////////////////////////////////// //调用方式:void lcd_clr(void)//函数说明:清屏//////////////////////////////////////////////////////////////////////////////// void lcd_clr(void){uchar i, page;for (page=0;page<4;page++){send_mi(page_addr_set|page);//设置页从0-3send_si(page_addr_set|page);send_mi(0); //主窗口设置为0列send_si(0); //从窗口设置为0列for (i=0;i<62;i++) //全部写入0x00{send_md(0x00);send_sd(0x00);}}}//////////////////////////////////////////////////////////////////////////////// //调用方式:void set_page(uchar page)//函数说明:同时设置主(右)从(左)显示页为0-3页//////////////////////////////////////////////////////////////////////////////// void set_page(uchar page){send_mi(page_addr_set|page);send_si(page_addr_set|page);}//////////////////////////////////////////////////////////////////////////////////调用方式:void SetAddress(uchar address)//函数说明:同时设置主(右)从(左)列地址为0-61列////////////////////////////////////////////////////////////////////////////////void set_address(uchar address){send_mi(address&0x7F); //&0x7F,考虑到防止越限send_si(address&0x7F);}//////////////////////////////////////////////////////////////////////////////////调用方式:void putchar_l(uchar c)//函数说明:在左页(主窗口)当前地址画一个字节(8点)////////////////////////////////////////////////////////////////////////////////void putchar_l(uchar c){send_md(c);}//////////////////////////////////////////////////////////////////////////////////调用方式:void putchar_r(uchar c)//函数说明:在右页(从主窗口)当前地址画一个字节(8点)////////////////////////////////////////////////////////////////////////////////void putchar_r(uchar c){send_sd(c);}//////////////////////////////////////////////////////////////////////////////////调用方式:void draw_bmp(uchar col,uchar layer,uchar width,uchar *bmp)//函数说明:画一个图,横坐标是col,layer表示上下层,width是图形的宽,高固定16 // bmp是图形指针// 使用Zimo3Pro软件,采用纵向取模,字节倒序得到数据。
51实验11-串口通信串口通信,原理图如下:程序:C语言1:/************实现功能*************接收电脑"串口调试助手"发来的信息,显示在发光二极管上(查询方式)**********************************//*************包含头文件**************/#include<reg52.h>/*************初始化函数*************/void init(){TMOD=0x20;//设置定时器1为工作方式2TH1=0xfd;//T1装初值TL1=0xfd;TR1=1;//启动T1REN=1;//允许串行接收SM0=0;//设置串口为工作方式1SM1=1;}/***************主函数***************/void main(){init();//初始化while(1){if(RI==1);{RI=0;//接收中断标志位(取消终端申请) P1=SBUF;//读取缓冲寄存器内数据}}}C语言2:/************实现功能*************接收电脑"串口调试助手"发来的信息,显示在发光二极管上(中断方式)**********************************//*************包含头文件**************/#include<reg52.h>/*************初始化函数*************/ void init(){TMOD=0x20;//设置定时器1为工作方式2 TH1=0xfd;//T1装初值TL1=0xfd;TR1=1;//启动T1REN=1;//允许串行接收SM0=0;//设置串口为工作方式1SM1=1;EA=1;//开总中断ES=1;//开串口中断}/***************主函数***************/ void main(){init();//初始化while(1){}}void ser() interrupt 4{RI=0;//接收中断标志位(取消终端申请) P1=SBUF;//读取缓冲寄存器内数据}C语言3:/************实现功能*************接收电脑"串口调试助手"发来的信息,并将收到的信息再发给电脑。