C51串口通讯程序
- 格式:txt
- 大小:2.21 KB
- 文档页数:1
51单片机的串口通信程序(C语言) 51单片机的串口通信程序(C语言)
在嵌入式系统中,串口通信是一种常见的数据传输方式,也是单片
机与外部设备进行通信的重要手段之一。本文将介绍使用C语言编写
51单片机的串口通信程序。
1. 硬件准备
在开始编写串口通信程序之前,需要准备好相应的硬件设备。首先,我们需要一块51单片机开发板,内置了串口通信功能。另外,我们还
需要连接一个与单片机通信的外部设备,例如计算机或其他单片机。
2. 引入头文件
在C语言中,我们需要引入相应的头文件来使用串口通信相关的函数。在51单片机中,我们需要引入reg51.h头文件,以便使用单片机
的寄存器操作相关函数。同时,我们还需要引入头文件来定义串口通
信的相关寄存器。
3. 配置串口参数
在使用串口通信之前,我们需要配置串口的参数,例如波特率、数
据位、停止位等。这些参数的配置需要根据实际需要进行调整。在51
单片机中,我们可以通过写入相应的寄存器来配置串口参数。
4. 初始化串口
在配置完串口参数之后,我们需要初始化串口,以便开始进行数据
的发送和接收。初始化串口的过程包括打开串口、设置中断等。
5. 数据发送
在串口通信中,数据的发送通常分为两种方式:阻塞发送和非阻塞
发送。阻塞发送是指程序在发送完数据之后才会继续执行下面的代码,而非阻塞发送是指程序在发送数据的同时可以继续执行其他代码。
6. 数据接收
数据的接收与数据的发送类似,同样有阻塞接收和非阻塞接收两种
方式。在接收数据时,需要不断地检测是否有数据到达,并及时进行
处理。
7. 中断处理
在串口通信中,中断是一种常见的处理方式。通过使用中断,可以
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
//uchar const table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar p[]={0x01,0x03,0x25,0x23,0x00,0x01};
/* CRC 高位字节值表*/
uchar const crchi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0/**/,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
51单片机和计算机之间实现串口通信的电路图
串口通讯参考程序如下:
来源:深入浅出AVR单片机
#include
unsigned char UART_RX; //定义串口接收数据变量
unsigned char RX_flag; //定义穿行接收标记
/**************************************************************************************** *****
函数名:UART串口初始化函数
调用:UART_init();
参数:无
返回值:无
结果:启动UART串口接收中断,允许串口接收,启动T/C1产生波特率(占用)
备注:振荡晶体为12MHz,PC串口端设置[ 4800,8,无,1,无]
/**************************************************************************************** ******/
void UART_init (void){
EA = 1; //允许总中断(如不使用中断,可用//屏蔽)
ES = 1; //允许UART串口的中断
TMOD = 0x20; //定时器T/C1工作方式2
SCON = 0x50; //串口工作方式1,允许串口接收(SCON = 0x40 时禁止串口接收)
TH1 = 0xF3; //定时器初值高8位设置
TL1 = 0xF3; //定时器初值低8位设置
PCON = 0x80; //波特率倍频(屏蔽本句波特率为2400)
c51 printf使用方法
C51是一款高性能的单片机,它具有强大的功能和广泛的应用场景。在C51编程过程中,printf是一种非常常用的调试方式,可以使程序输出信息在串口终端中显示出来。但是,printf的使用方法并不是那么显而易见,需要一些技巧和方法才能正确使用。本文将从步骤上详细介绍C51中的printf使用方法。
1、先定义一个串口进行初始化,因为printf要通过串口发送数据给上位机,先要定义一个串口进行初始化。UART是一种常见的串口通信方式,在C51的编程中也是最常用的一种。在初始化串口的时候需要设置一些参数,如波特率、校验位等等,这些参数需要根据实际情况来选择。
2、定义一个函数,这个函数将主要用来将数据发送给串口,因为printf函数需要调用这个函数来发送数据。这个函数的实现主要包括将要发送的数据保存到缓冲区,然后把缓冲区的数据通过串口发送出去。需要注意的是,这个函数的设计要尽量简单,不要过于复杂,否则会影响程序的运行效率。
3、定义一个宏,这个宏将起到重要的作用,它将使printf函数输出的信息在屏幕上显示。这个宏将用来格式化传入的各种参数,在消息传输时起到很大的作用。宏定义时需要指定一些参数,这些参数需要根据具体的需求来确定。
4、使用printf函数,最后一步是使用printf函数将消息输出到屏幕上。在使用printf函数时,需要注意传入的参数要根据之前定义的宏来格式化。如果传入的参数没有被正确格式化,将无法正确地在屏幕上显示。
总之,printf是C51中非常重要的调试方式,它可以帮助程序员查看程序运行状态,了解程序执行情况。但是,printf的使用方法需要一些技巧和方法才能正确使用。只有掌握了这些方法,才能在C51编程中更加轻松地使用printf函数。
例子1 #include #include unsigned char ch;bit read_flag= 0 ; void init_serialcom( void ) //串口通信初始设定{ SCON = 0x50 ; //UART为模式1,8位数据,允许接收TMOD |= 0x20 ; //定时器1为模式2,8位自动重装PCON |= 0x80 ; //SMOD=1; TH1 = 0xFD ; //Baud:19200 fosc="11".0592MHz IE |= 0x90 ; //Enable Serial Interrupt TR1 = 1 ; // timer 1 run TI=1; } //向串口发送一个字符 void send_char_com( unsigned char ch) { SBUF=ch; while (TI== 0); TI= 0 ; } //串口接收中断函数 void serial () interrupt 4 using 3 { if (RI) { RI = 0 ; ch=SBUF; read_flag= 1 ; //就置位取数标志 }} main() { init_serialcom(); //初始化串口 while ( 1 ) { if (read_flag) //如果取数标志已置位,就将读到的数从串口发出 { read_flag= 0 ; //取数标志清0 send_char_com(ch); } } } 例子2// 单片机串行口发送/接收程序,每接收到字节即发送出去// 和微机相接后键入的字符回显示在屏幕上// 可用此程序测试//#include #define XTAL 11059200 // CUP 晶振频率#define baudrate 9600 // 通信波特率void main(void){unsigned char c;TMOD = 0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率TH1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate)));TL1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate))); // 定时器0赋初值SCON = 0x50;PCON = 0x00; TR1 = 1;IE = 0x00; // 禁止任何中断while(1){while(RI == 0);RI = 0;c = SBUF; // 从缓冲区中把接收的字符放入c中SBUF = c; // 要发送的字符放入缓冲区 while(TI == 0);TI = 0;}} 例子3////////////////////////////////////////////////////////////////////////////////////////////////////E51Pro.c//Easy 51Pro编程器主程序,负责通讯,管理编程操作///////////////////////////////////////////////////////////////////////////////////////////////////#include BYTE ComBuf[18];//串口通讯数据缓存,发送和接收都使用UINT nAddress;//ROM中地址计数UINT nTimeOut;//超时计数ProWork pw;//编程器一般操作void Delay_us(BYTE nUs)//微秒级延时<255us{TH0=0;TL0=0;TR0=1;while(TL0{}TR0=0;}void Delay_ms(UINT nMs)//豪秒级的延时<65535ms{UINT n=0;
51单片机串口通信实例
一、原理简介
51 单片机内部有一个全双工串行接口。什么叫全双工串口呢?一般来说,只能接受或只能发送的称为单工串行;既可接收又可发送,但不能同时进行的称为半双工;能同时接收和发送的串行口称为全双工串行口。串行通信是指数据一位一位地按顺序传送的通信方式,其突出优点是只需一根传输线,可大大降低硬件成本,适合远距离通信。其缺点是传输速度较低。
与之前一样,首先我们来了解单片机串口相关的寄存器。
SBUF 寄存器:它是两个在物理上独立的接收、发送缓冲器,可同时发送、接收数据,可通过指令对SBUF 的读写来区别是对接收缓冲器的操作还是对发送缓冲器的操作。从而控制外部两条独立的收发信号线
RXD(P3.0)、TXD(P3.1),同时发送、接收数据,实现全双工。
串行口控制寄存器SCON(见表1) 。
表1 SCON寄存器
表中各位(从左至右为从高位到低位)含义如下。
SM0 和SM1 :串行口工作方式控制位,其定义如表2 所示。
表2 串行口工作方式控制位
其中,fOSC 为单片机的时钟频率;波特率指串行口每秒钟发送(或接收)的位数。
SM2 :多机通信控制位。该仅用于方式2 和方式3 的多机通信。其中发送机SM2 = 1(需要程序控制设置)。接收机的串行口工作于方式2 或3,SM2=1 时,只有当接收到第9 位数据(RB8)为1 时,才把接收到的前8 位数据送入SBUF,且置位RI 发出中断申请引发串行接收中断,否则会将接受到的数据放弃。当SM2=0 时,就不管第位数据是0 还是1,都将数据送入SBUF,并置位RI 发出中断申请。工作于方式0 时,SM2 必须为0。
下面是我学习C51单片机串口通讯时自己练习编写的下位机程序,已通过测试!大家可以根据这个思路编写其他的控制程序。#include#define uchar unsigned char#define uint unsigned intsbit P00=P0^0;sbit P01=P0^1;sbit P02=P0^2;sbit P03=P0^3;sbit P04=P0^4;sbit P05=P0^5;sbit P06=P0^6;sbit P07=P0^7;sbit P20=P2^0;sbit P21=P2^1; bit recfinish=0;bit recflag=0;uchar rec[5];uchar i=0;uchar j=0;uchar sum=0;void init();void send();void delayms(uint);void main(){ init(); while(1){ if(recfinish==1){ for(j=0;j<4;j++){sum=sum+rec[j];}if((rec[0]==0x40)&&(rec[1]==0x43)&&((sum&0xFF)==rec[4])) /* 数据校验 */{ switch(rec[3]){ case 0x01: P00=0;break; /* 上 */case 0x02: P01=0;break; /* 下 */case 0x04: P02=0;break; /*左 */case 0x08: P03=0;break; /*右 */case 0x60: P04=0;break; /*光圈大 */case 0x80: P05=0;break; /*光圈小 */case 0x40: P06=0;break; /*聚焦大 */case 0x30: P07=0;break; /*聚焦小 */case 0x10: P20=0;break; /*变倍大 */case 0x20: P21=0;break; /*变倍小 */case 0x70: P0=0xFF;P20=1;P21=1; break; /*停 */}} recfinish=0;sum=0; }// else// {// delayms(2000);// P0=0xFF;// } }}void init(){SCON=0x50; /* 串口工作方式1,允许接收 */TMOD=0x20; /* T1工作在方式2 */PCON=0x00; /* 波特率不倍增 */TH1=0xFA; /* 4800 */TL1=0xFA;EA=1; /* 允许中断 */ES=1; /* 允许串口中断 */TR1=1; /* 启动定时器 */}void send() { uchar k; for(k=0;k<5;k++){SBUF=rec[k];while(!TI);TI=0;} } void delayms(uint x){ uchar y;while(x--)for(y=120;y>0;y++); }void com() interrupt 4{uchar dat;ES=0;while(!RI); dat=SBUF;RI=0; if((dat==0x40)&&(i==0)) /* 判断帧头 */{ rec[i]=dat;i++; recflag=1; }else { if(recflag==1){if(i<5){rec[i]=dat; /*继续接受数据*/i++;// }// else // { if(i>=5){ recfinish=1; /*设置接受完标志*/recflag=0;i=0;send();}}}}ES=1;}/*测试数据如下40 43 03 01 87 上 P00 140 43 03 02 88 下 P01 240 43 03 04 8A 左 P02 440 43 03 08 8E 右 P03 8 40 43 03 70 F6 停 P0 10/*******************************************************************/协议格式如下同步数据 同步数据(特定功
12864(ST7920)串口C51程序 //12864F(7920)的串行模式C51范例 #include #include sbit E_CLK =P3^0;//clock input 同步时钟输入端 sbit RW_SID=P3^1;//data input/output 串行数据输入、输出端 //sbit RS_CS =P3^5;//chip select 片选端 //sbit PSB =P3^6;//serial mode select 串口模式 sbit RST =P1^2; void delay(unsigned int n) { unsigned int i; for(i=0; i } //串行发送一字节数据 void SendByte(unsigned char dat) { unsigned char i; for(i=0;i <8;i++) { E_CLK=0; if(dat&0x80)RW_SID=1;else RW_SID=0; E_CLK=1; dat=dat < <1; } } //串行接收一字节数据 unsigned char ReceieveByte(void) { unsigned char i,d1,d2; for(i=0;i <8;i++) { E_CLK=0;delay(100); E_CLK=1; if(RW_SID)d1++; d1=d1 < <1; } for(i=0;i <8;i++) { E_CLK=0;delay(100); E_CLK=1; if(RW_SID)d2++; d2=d2 < <1; } return (d1&0xF0+d2&0x0F); } //读取标志位BF bit ReadBF(bit bf) { unsigned char dat; SendByte(0xFA);//11111,01,0 RW=1,RS=0 dat=ReceieveByte(); if(dat> 0x7F)bf=1;else bf=0; return bf; } //写控制命令 void SendCMD(unsigned char dat) { // while(ReadBF){;} // RS_CS=1; SendByte(0xF8);//11111,00,0 RW=0,RS=0 同步标志 SendByte(dat&0xF0);//高四位 SendByte((dat&0x0F) < <4);//低四位 // RS_CS=0; } //写显示数据或单字节字符 void SendDat(unsigned char dat) { // while(ReadBF){;} // RS_CS=1; SendByte(0xFA);//11111,01,0 RW=0,RS=1 SendByte(dat&0xF0);//高四位 SendByte((dat&0x0F) < <4);//低四位 // RS_CS=0; } /* 写汉字到LCD 指定的位置 x_add显示RAM的地址 dat1/dat2显示汉字编码 */ void display(unsigned char x_add,unsigned char dat1,unsigned char dat2) { SendCMD(x_add);//1xxx,xxxx 设定DDRAM 7位地址xxx,xxxx到地址计数器
#include <reg52.h>
#include<intrins.h>
#include <stdio.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
sbit 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 */
stc c51 串口通信协议常用校验计算以及一些常用方法
一、引言
随着嵌入式系统应用的不断普及,STC C51 单片机因其高性能、低功耗等特点在众多领域得到广泛应用。串口通信作为一种常见的数据传输方式,在STC C51 应用中占有重要地位。本文将介绍STC C51 串口通信协议的常用校验计算方法,并通过实际应用案例,分析如何在实际项目中实现高效、稳定的串口通信。
二、STC C51 串口通信协议简介
1.串口通信基本原理
串口通信是通过在两条信号线(数据线和时钟线)之间传输数据来实现设备间的通信。数据传输过程中,需要遵循一定的通信协议,如波特率、数据位、停止位和奇偶校验等。
2.STC C51 串口通信特点
STC C51 单片机内部集成了全双工UART 模块,支持异步通信。其具有以下特点:
1)支持多种数据传输格式:数据位、停止位、奇偶校验等可自定义;
2)波特率发生器:内部集成波特率发生器,可根据需要设置不同的波特率;
3)硬件支持流控制:支持硬件握手信号(RX、TX),实现数据传输的可靠性控制;
4)低功耗:待机模式下,UART 模块功耗较低,有利于降低系统整体
功耗。
三、常用校验计算方法
1.奇偶校验
奇偶校验是一种简单而有效的校验方法。在数据传输过程中,附加一位校验位,使得数据中的1的个数为奇数或偶数。接收端根据校验位和数据位的奇偶性进行校验,若不一致,则表示数据传输出现错误。
2.循环冗余校验(CRC)
CRC 是一种基于二进制多项式的校验方法。发送端根据数据生成一个校验码,附加在数据末尾,接收端对接收到的数据进行CRC 校验,若校验结果与预期值不符,则表示数据传输出现错误。
stc c51 串口通信协议常用校验计算以及一些常用方
法
STC C51 是一种基于8051 内核的单片机,广泛应用于各种嵌入式系统。在串口通信中,为了保证数据的正确传输,通常需要使用校验位来检测数据传输过程中可能出现的错误。以下是一些常用的校验计算方法以及一些常用的方法:
1. 奇校验:
o 定义:在数据字节的最高位(第8位)为校验位。该位确保数据中1的个数为奇数。
o 规则:如果字节中的1的个数是偶数,那么奇校验位为1;如果字节中的1的个数是奇数,那么奇校验位为0。
o 优点:简单易懂,易于实现。
o 缺点:对于数据中连续的多个0,可能会产生错误的奇校验结果。
2. 偶校验:
o 定义:在数据字节的最高位(第8位)为校验位。该位确保数据中1的个数为偶数。
o 规则:如果字节中的1的个数是奇数,那么偶校验位为1;如果字节中的1的个数是偶数,那么偶校验位为0。
o 优点:对于数据中连续的多个0,可以避免错误的偶校验结果。
o 缺点:可能会增加多余的1,从而使得接收方无法正确识别信号电平。
3. 无校验:
o 定义:不使用额外的校验位。
o 优点:简单、不需要额外的校验位。
o 缺点:无法检测传输错误。
4. 软件校验:
o 在发送端对数据进行简单的加和,然后取反(如果是偶数),或减去最大值(如果是奇数),得到一个校验和。接收端进行相同的计算,并与发送端的校验和进行比较,以检测错误。
5. 硬件校验:
o 使用硬件电路(如RS-485 转换器)来实现校验和检测。这通常更可靠,但也需要额外的硬件成本。
6. 校验方法的选用:
51单片机串口通信软件程序集
串口通信的单片机程序
beep bit p3.7 ;蜂鸣器定义
org 00h
jmp main
org 23h ;串行中断入口地址
jmp com_int ;串行中断服务程序
;*********** 主程序开始*******************
org 30h
main: mov sp,#30h ;设置堆栈
lcall rest ;初始化
lcall comm ;串口初始化
jmp $ ;原地等待
; ************* 初始化*********************
rest: mov p0,#00h ;禁止数码管显示
mov p2,#255
clr beep ;禁止蜂鸣器
mov p1,#255 ;禁止LED显示
RET ;返回
; ************** 串口初始化*****************
;设置串行口工作方式1,定时器1作为波特率发生器
;波特率设置为2400 ;
comm: mov tmod,#20h ;设置定时器T1工作方式2
mov tl1,#0f3h ;定时器计数初值,波特率2400
mov th1,#0f3h ;定时器重装值
setb ea ;允许总的中断
setb es ;允许串行中断
mov pcon,#00h ;波特率不倍增
mov scon,#50h ;设置串口工作方式1,REN = 1 允许接收
setb tr1 ;定时器开始工作
ret ;返回
;*************** 串口中断服务程序***********
; 如果接收0FF 表示上位机需要联机信号,单片机发送0FFH作为
C51单片机和电脑串口通信电路图与源码
51单片机有一个全双工的串行通讯口,所以单片机和电脑之间可以方便地进行串口通讯。进行串行通讯时要满足一定的条件,比如电脑的串口是RS232电平的,而单片机的串口是TTL电平的,两者之间必须有一个电平转换电路,我们采用了专用芯片MAX232进行转换,虽然也可以用几个三极管进行模拟转换,但是还是用专用芯片更简单可靠。我们采用了三线制连接串口,也就是说和电脑的9针串口只连接其中的3根线:第5脚的GND、第2脚的RXD、第3脚的TXD。这是最简单的连接方法,但是对我们来说已经足够使用了,电路如下图所示,MAX232的第10脚和单片机的11脚连接,第9脚和单片机的10脚连接,第15脚和单片机的20脚连接.
串口通讯的硬件电路如上图所示
在制作电路前我们先来看看要用的MAX232,这里我们不去具体讨论它,只要知道它是TTL和RS232电平相互转换的芯片和基本的引脚接线功能就行了。通常我会用两个小功率晶体管加少量的电路去替换MAX232,可以省一点,效果也不错,下图就是MAX232的基本接线图。
按图7-3加上MAX232就可以了。这大热天的拿烙铁焊焊,还真的是热气迫人来呀:P串口座用DB9的母头,这样就可以用买来的PC串口延长线进行和电脑相连接,也可以直接接到电脑com口上。
为了能够在电脑端看到单片机发出的数据,我们必须借助一个WINDOWS软件进行观察,这里我们利用一个免费的电脑串口调试软件。本串口软件在本网站可以找到
软件界面如上图,我们先要设置一下串口通讯的参数,将波特率调整为4800,勾选十六进制显示。串口选择为COM1,当然将网站提供的51单片机实验板的串口也要和电脑的COM1连接,将烧写有以下程序的单片机插入单片机实验板的万能插座中,并接通51单片机实验板的电源。
引言:单片机串口通信程序是一种用于实现单片机与外部设备进行数据传输的通信方式。它通过串口接口将数据以串行的形式传输,实现了高效、可靠的数据交互。本文将详细介绍单片机串口通信程序的实现原
理、步骤和注意事项。
概述:单片机串口通信程序主要包括串口初始化、发送数据、接收数据和中断处理等部分。其中,串口初始化是设置串口通信的参数,发送数据和接收数据是具体的数据传输操作,中断处理则是处理串口中断事件的相关操作。
正文:
一、串口初始化
1.确定串口通信的波特率:波特率是指单位时间内传输的比特数,需要根据通信双方的需求确定合适的波特率。
2.设置数据位、停止位和校验位:数据位决定了每个字节中实际有效数据的位数,通常为8位;停止位用于判断一个字节的结束,通常为1位;校验位用于检测和纠正数据传输过程中的错误。
3.打开串口:通过使能相应的寄存器位,开启串口功能。
二、发送数据
1.准备要发送的数据:将要发送的数据存储在缓冲区中,可以是一个字节、多个字节或一个字符串。
2.判断发送缓冲区是否为空:检查发送缓冲区是否已被发送完毕,如果为空则可以开始发送新的数据。
3.将数据发送到串口寄存器:将准备好的数据写入串口寄存器,启动数据传输。
4.等待数据发送完毕:通过检查发送完成标志位,判断数据是否已经成功发送完毕。
三、接收数据
1.等待接收缓冲区非空:通过检查接收缓冲区是否有新的数据接收到,判断是否可以开始接收数据。
2.读取接收缓冲区的数据:通过读取串口寄存器中的数据,获取已接收到的数据。
3.处理接收到的数据:对接收到的数据进行相应的处理操作,可以是存储、显示或其他操作。