51单片机串口程序详解中断

基于51单片机的串口中断发送数据帧
很少看到有资料写如何以中断的方式发送一帧数据,如果以等待的发送数据帧,对高速运行的单片机来说是很浪费时间的,下面就介绍一种使用中断方式发送数据帧,操作平台采用51 mcu
首先定义一个数据帧的结构体,该结构体可以做为一个全局变量,所有的发送都要经过这个结构体:
//结构体&&
struct&{&&
char&busy_//忙标志,若在发送数据时置位1,即在开始发送置位1,发送结束置位0&&
int&//索引,指向需要发送数组的位置&&
int&//整个数据帧的长度&&
char&*//指向需要发送的数据帧,建议为全局变量,否则一旦开始发送,必须等到发送结束,即判断busy_falg为0&&
发送数据的函数,这里有个缺点,就是还是要使用while来检测串口是否忙碌,不过这样比占用系统时间来发送要好的多了:
//发送一帧&&
void&SendBuf(char&*buf,int&length)&&
while(busy_falg);//查询发送是否忙,否则循环等待&&
send_buf.length&=&&&
send_buf.index&=&0;&&&
send_buf.buf&=&&&
send_buf.busy_falg&=&1;&&
SBUF&=&send_buf.buf[0];//写入SBUF,开始发送,后面就自动进入中断发送&&
串口中断发送函数,注意设置空闲标志位,避免多任务时多个发送帧调用了同一个结构体:
void&SerialInt()&interrupt&4&&&&&//串口中断&&
if(RI&==&1)&&//串口接收&&
RI&=&0;&&&&
else&if(TI&==&1)//串口发送&&
send_buf.index++;&&
if(send_buf.index&==&send_buf.length)&&
send_buf.busy_falg&=&0;//发送结束&&
SBUF&=&send_buf.buf[send_buf.index];//继续发送下一个&&
串口中断发送就是这样简单,注意busy_falg和index的使用。
发布评论请先
首先说一下独立键盘检测,在单片机外围电路中 ,通常用到的按键都是机械弹性开关,当开关闭合时,线路导通....
对于独立按键的博文中所提到的配合数码管显示的实例中,由于我们数码管显示函数display() 位于主....
本文主要介绍了ili9806e芯片手册。
本文主要介绍了51单片机历程之protues仿真100例 .
英飞凌充分发挥其在设计面向高实时控制应用的单片机方面深厚的技术专长,有史以来第一次,将之与行业标准内....
矩阵键盘又称为行列式键盘,它是用4条I/O线作为行线,4条I/O线作为列线组成的键盘。
在行线和列....
本设计是一个以单片机AT89C51为核心部件的电子钟,可以在液晶屏上显示时间和字符,并可任意调整时间....
本文主要介绍了基于单片机的小功率直流电机调速设计。
本文主要介绍了单片机典型系统设计与制作实例解析。
本文主要介绍了基于STC89C52单片机的控制系统设计。
本文实现了基于遗传算法的硬件演化过程。通过Mcu随机产生种群,选择好的基因进行交叉变异产生后代,然....
打开包装可以看到开发板也有类似风格,薄薄小小的一块,但是芯片的各个管脚都引了出来,方便用户开发,不方....
本文主要介绍了单片机结构原理基础知识。
本文主要介绍了单片机应用系统开发实例。
  从20世纪70年代中期起,微型计算机发展开始形成两大分支:一类是个人计算机,也称为PC机(Per....
在目前MCU应用领域里,很多场合都离不开开关信号,这些开关信号的实现都是通过按键操作实现。而传统的按....
效率上来说,延时消抖花费时间在无意义延时上,而相对较好的定时轮询还是不可避免的在轮询,而现在这种方式....
本文档的主要内容详细介绍的是CDK单片机开发板的使用手册,软件例程和硬件原理图的概述....
本文档的主要内容详细介绍的是CDK开发板全部资料软件例程,使用手册,原理图的资料概述....
本文档的主要内容详细介绍的是CST的单片机开发板资料和实例以及硬件原理图的详细概述。
本文档的主要内容详细介绍的是CDK的单片机开发板的资料概述包括了:软件例程,使用手册....
本文档的主要内容详细介绍的是CDK的软件例程,使用手册和硬件原理图的详细资料概述
在单片机应用系统中,需要对一些模拟信号(如电流、电流、温度、压力等)进行检测,将模拟信号转换为数字信....
采用Protel 99软件对HG6型单片机实验板原理图进行绘制,Protel 99的原理图编辑器提供....
这里IDATALEN只是一个标号而已,和idata不是一回事!你要是愿意,这段程序里的IDATALE....
我们都知道,在程序中,延时会影响单片机的实时性能,导致效率明显降低,但是在GPF这个芯片的开发中,系....
果然,TensorFlow Mobile的老大,满脑子还是便携设备的事。Pete Warden,是谷....
瑞萨电子在北京赛区举办一场瑞萨电子技术研讨会,本视频为瑞萨2009大赛B题MMC-1模块介绍。
瑞萨电子在北京赛区举办一场瑞萨电子技术研讨会,本视频为瑞萨单片机技术概述、2009大赛B题MMC-1....
设置好,单击应用,关闭该对话框,然后重新单击调试按钮进行调试。这次程序就可以保存到芯片内的闪存了。但....
瑞萨电子在北京赛区举办一场瑞萨电子技术研讨会,本视频为瑞萨16位单片机讲座。
瑞萨电子在北京赛区举办一场瑞萨电子技术研讨会,本视频为题目为Easy MCU Easy RF
启动代码通常都烧写在flash中,它是系统一上电就执行的一段程序,它运行在任何用户c代码之前。
本文档的主要内容详细介绍的是单片机的开发工具包括了KEIL编程软件,开发板驱动, 程序烧入软件,常用....
单片机学习计划 无论学习什么东西,都要给自己制定明确的计划,不然,就非常容易半途而弃,因此我给自己制....
MSP430 在电表应用领域具有完备的解决方案
MSP430f5xx系列单片机提供突破性性能和超低功率、帮助客户开发高级便携应用的全新一代产品。
MSP430 是一款超低功耗单片机,非常适合便携式产品以及便携式医疗产品的应用。设计便携式医疗产品通....
本文档的主要内容详细介绍的是基于单片机的的自制放大模块电子称的详细资料概述包括了烧写程序,和电路图,....
特性:<1μA LPM3 待机模式;<1μs 0-16MH零功耗 BOR;振荡器失效保护;增强....
MSP430 单片机外围模块 - LCD [利尔达]
TPS54620 是业内尺寸最小的单芯片 6A 17V 降压转换器,它具有集成 FET。 这款效率高....
TI 基于 MSP430 微处理器的电容式触摸按键方案
MSP430F149IPM是TI公司设计生产的一款超低功耗的16位单片机。具有低电压、超低功耗;快速....
单片机仿真器是指以调试单片机软件为目的而专门设计制作的一套专用的硬件装置。
超声波指向性强,能量消耗缓慢,在介质中传播的距离比较远,因此超声波常用于障碍物的距离测量。由于超声波....
用AVR单片机来产生正弦波信号 使用AVR定时/计数器的PWM功能设计要点 一、定时/计数器PWM设....
干扰源,指产生干扰的元件、设备或信号,用数学语言描述如下:du/dt,di/dt大的地方就是干扰源。....
从简单的led 闪烁、数码管显示、pwm 到中断、串口通信(单片机与单片机通信,单片机与pc 机通信....
家电中普遍采用的都是单转子类型的电机,如空调压缩机等。在普通算法的驱动下,单转子结构的电机会引发系统....
供应链服务
版权所有 (C) 深圳华强聚丰电子科技有限公司
电信与信息服务业务经营许可证:粤B2-51单片机学习笔记(六)_串口中断通信+定时器2串口中断
09:49:37来源: eefocus 关键字:&&&&
默认使用1作为串口通信的波特率发生器、定时器1中断通信,串口与定时器1冲突,在遇到定时器不够用的时候可以用定时器2
void DelayMs(unsigned int i);
void SerialInit();
void SendByte(unsigned char sbyte);
void SendString(unsigned char *pstr);
void main(void)
SerialInit();
//注:必需要无限循环
//单片机时钟周期:11.0592MHz
以时钟1作为波特率发生器
void SerialInit(){
TMOD=0x20;
//设置T1工作方式为方式2
TH1=0 //给定时器高位装初值
TL1=0 //给定时器低位装初值
//开定时器
//以上是设置波特率
//设置串口通讯方式为方式1
//串口是否接收数据的开关
EA=1; //总中断打开,采用查询法时不用打开中断
ES=1; //串口中断开关,采用查询法时不用打开中断
//单片机时钟周期:11.0592MHz
以时钟T2作为波特率发生器
void SerialInit(){
PCON &= 0x7F;
//波特率不倍速 SMOD=0
SCON = 0x50;
//方式1,8位数据,可变波特率,接收允许
RCAP2H = 0xFF;
RCAP2L = 0xDC;
EA=1; //总中断打开,采用查询法时不用打开中断
//串口中断开关,采用查询法时不用打开中断
//串口中断函数:
void SerialPortInte(void) interrupt 4 //采用串口中断法收发数据
//RI=1,判定为串口接收到了数据,RI要清零,
rbyte=SBUF;
if(rbyte==0x0A){
SendString("换行");
}else if(rbyte==0x0D){
SendString("回车");
SendByte(rbyte);
//串口发送一个字节:
void SendByte(unsigned char sbyte)
SBUF= //发送数据
while(!TI); //等待发送完成
TI=0; //清零发送标志位
//串口发送一个字符串:
void SendString(unsigned char *pstr) //定义指针
while(*pstr!=&#39;\0&#39;) //字符串是否发完
SendByte(*pstr);//发送字符串数据
pstr++; //指向下一个字符
void DelayMs(unsigned int i)
//延时i ms
while(i--)
for(j = 0; j < 125; j++);
关键字:&&&&
编辑:什么鱼
引用地址:
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
关注eeworld公众号快捷获取更多信息
关注eeworld服务号享受更多官方福利
网友正在学习IC视频
EEWORLD网友正在观看&&视频
EEWORLD网友正在观看&&视频
EEWORLD网友正在观看&&视频
EEWORLD网友正在观看&&视频
EEWORLD网友正在观看&&视频
相关关键词
热门关键词
大学堂最新课程
汇总了TI汽车信息娱乐系统方案、优质音频解决方案、汽车娱乐系统和仪表盘参考设计相关的文档、视频等资源
热门资源推荐
频道白皮书
何立民专栏
北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。后使用快捷导航没有帐号?
请完成以下验证码
查看: 1862|回复: 3
51单片机串口中断与定时中断同时开启,只有定时中断好用,串口无法通讯
在线时间1 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
只能实现定时器中断,无法实现串口中断发送数据,但屏蔽掉定时器中断服务子程序后串口中断就好用,求大神帮忙看看哪里出了问题。
发送端程序
#include &REG52.h&//通用89C52头文件
sbit bz = P2^4 ; //端口定义
bit&&send_ed = 1 ;
sbit LED = P1^7 ;
/***************************************************************************/
void init()
& & & & & & & & PS=1;
& & & && &&&TMOD=0x21;& & & & & & //定时器1和2工作方式2(8位定时/计数)
& & & & & & PCON=0x00;& &&&//SMOD=0,不加倍
& & & & & & SCON=0x50;& &&&//串口工作方式1,允许接收& && &&&
& & & & & & TH1=0& &&&//定时器1设置初值,波特率9600bit/s,
& & & & & & TL1=0
& & & & & & TR1=1;& && && & & & //启动定时器T1
& & & & & & EA=1;& & & & //打开总中断
& & & & & & ES=1;& & & & //打开串口中断
& & & && &&&TH0 =(65536 - 5000) / 256;&&
& && &&&TL0 = (65536 - 5000)% 256;& &&&
& && &&&ET0 = 1;&&
& && &&&TR0 = 1;&&
void fasong()
& & & & & & & & & & & & if(bz==0)
& & & & & & & & & & & & {
& & & & & & & & & & & & fe = 0;
& & & & & & & & & & & & }
& & & & & & & & & & & & else
& & & & & & & & & & & & {
& & & & & & & & & & & & fe = 1;
& & & & & & & & & & & & }
& & & & & & & & & & & & if(send_ed == 1)
& & & & & & & & & & & & {
& & & & & & & & & & & & ES=1;
& & & && && && &SBUF =& & & & //发送数据
& && &&&& & & & send_ed = 0;
& & & & & & & & & & & & ES=0;
& & & & & & & & & & & & }
void main(void)//主函数
& & & && &
& && &&&init();
& & & & & & while(1)& & & & //主循环
& & & & & & {
& && &&&fasong();
& & & & & & }
void ser() interrupt 4//串口发送,中断方式
& & & && &&&EA = 0;
& && &&&if(TI == 1);& & & & //等待发送完成
& & & & & & TI=0;& & & & //清空发送标志位
& & & & & & & & send_ed = 1;
& & & & & & & & EA = 1;
& & & & void timer0() interrupt 1&&
& & & & {&&
& & & & TH1 = (65536 - 5000) / 256;&&
& & & & TL1 = (65536 - 5000) % 256;&&
& & & & LED = !LED;& &
接收端程序
#include &REG52.h&//通用89C52头文件
sbit bz = P1^0 ;&&
bit new_rec = 0;
sbit LED = P1^7 ;
/***************************************************************************/
void init()
& & & & & & & & PS=1;
& & & && &&&TMOD=0x21;& & & & & & //定时器1和2工作方式2(8位定时/计数)
& & & & & & PCON=0x00;& &&&//SMOD=0,不加倍
& & & & & & SCON=0x50;& &&&//串口工作方式1,允许接收& && &&&
& & & & & & TH1=0& &&&//定时器1设置初值,波特率9600bit/s,
& & & & & & TL1=0
& & & & & & TR1=1;& && && & & & //启动定时器T1
& & & & & & EA=1;& & & & //打开总中断
//& & & & & & ES=1;& & & & //打开串口中断
& & & && &&&TH0 =(65536 - 5000) / 256;&&
& && &&&TL0 = (65536 - 5000)% 256;& &&&
& && &&&ET0 = 1;&&
& && &&&TR0 = 1;&&
void jieshou()
& & & && & & & & & if(new_rec == 1)
& & & & & & & & ES=1;
& & & && &&&fe=SBUF;& & & & //接收数据
& && &&&new_rec = 0;
& & & & & & & & ES=0;
& & & & & & & & if(fe == 1)&&bz = 0;
& & & & & & & & & & & && &
& && &&&if(fe == 0)&&bz = 1;
void main(void)//主函数
& & & & & & & & init();
& & & & & & while(1)& & & & //主循环
& & & & & & {
& & & & & & & & & & & & jieshou();
& & & & & & }
/***************************************************************************/
void ser() interrupt 4//串口接收,中断方式
& & & & & & & & EA = 0;
& & & & & & & & if(RI == 1) //如果收到.
& & & & & & & && &
& && &&&RI = 0;& && &//清除标志.
& & & & & & & && &
& & & & & & new_rec = 1;
& & & & & & & & EA = 1;
/***************************************************************************/
void timer0() interrupt 1&&
& & TH1 = (65536 - 5000) / 256;&&
& & TL1 = (65536 - 5000) % 256;&&
& & LED = !LED;& && &&&
在线时间1974 小时
威望44374分
芯币46132枚
E金币1842枚
TA的帖子TA的资源
注意中断优先级设置,同时要尽量简化中断服务程序。
上传了一些书籍资料,也许有你想要的:
在线时间1541 小时
威望6512分
芯币24155枚
E金币400枚
TA的帖子TA的资源
& && && && && && & if(new_rec == 1)
& && && && && & ES=1;
& && && && &fe=SBUF;& && &&&//接收数据
这里应该有括号
另外这里& && && && && &
if(fe == 1)&&bz = 0;& && && && && && && && &&&
if(fe == 0)&&bz = 1;
也没看明白,直接做SBUF的逻辑就行了,没必要倒来倒去。
在线时间10 小时
TA的帖子TA的资源
一粒金砂(中级), 积分 22, 距离下一级还需 178 积分
一粒金砂(中级), 积分 22, 距离下一级还需 178 积分
看不懂C语言~~~~~~~~~~~~
技术导师勋章
论坛威望大于30000或网友提名:坛子里公认的技术导师
EEWORLD 官方微信
Powered by51单片机学习笔记(六)_串口中断通信+定时器2串口中断
默认使用 1作为串口通信的波特率发生器、定时器1中断通信,串口与定时器1冲突,在遇到定时器不够用的时候可以用定时器2 #include &reg52.h& void DelayMs(unsigned int i); void SerialInit(); void SendByte(unsigned char sbyte); void SendString(unsigned char *pstr); void main(void) { SerialInit(); while(1); //注:必需要无限循环 } /* // 时钟周期:11.0592MHz 以时钟1作为波特率发生器 void SerialInit(){ TMOD=0x20; //设置T1工作方式为方式2 TH1=0 //给定时器高位装初值 TL1=0 //给定时器低位装初值 TR1=1; //开定时器 //以上是设置波特率 SM0=0; //设置串口通讯方式为方式1 SM1=1; REN=1; //串口是否接收数据的开关 EA=1; //总中断打开,采用查询法时不用打开中断 ES=1; //串口中断开关,采用查询法时不用打开中断 } */ //单片机时钟周期:11.0592MHz 以时钟T2作为波特率发生器 void SerialInit(){ PCON &= 0x7F; //波特率不倍速 SMOD=0 SCON = 0x50; //方式1,8位数据,可变波特率,接收允许 T2CON = 0x34; RCAP2H = 0xFF; RCAP2L = 0xDC; TH2 = 0xFF; TL2 = 0xDC; EA=1; //总中断打开,采用查询法时不用打开中断 ES = 1; //串口中断开关,采用查询法时不用打开中断 } //串口中断函数: void SerialPortInte(void) interrupt 4 //采用串口中断法收发数据 { if(RI){ //RI=1,判定为串口接收到了数据,RI要清零, RI=0; rbyte=SBUF; if(rbyte==0x0A){ SendString("换行"); }else if(rbyte==0x0D){ SendString("回车"); }else{ SendByte(rbyte); } } } //串口发送一个字节: void SendByte(unsigned char sbyte) { SBUF= //发送数据 while(!TI); //等待发送完成 TI=0; //清零发送标志位 } //串口发送一个字符串: void SendString(unsigned char *pstr) //定义指针 { while(*pstr!='\0') //字符串是否发完 { SendByte(*pstr);//发送字符串数据 pstr++; //指向下一个字符 } } void DelayMs(unsigned int i) //延时i ms { while(i--) { for(j = 0; j & 125; j++); } }
原文链接:
责任编辑:
声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
今日搜狐热点关于单片机串口中断程序_百度知道
关于单片机串口中断程序
现在我们在做一个东西,是关于GPS接收的。单片机(51)通过串口和GPS模块的串口相连,GPS会每隔大约1秒发一次数据,一次包含五个卫星的信息。由于信息不是都要的,而且需要判断起始位结束位。所以中断程序不是仅仅一个接收存储,有一些判断加标志位的语句。我...
我有更好的答案
当MCU接收到GPS发来的一个字节时触发中断,进入中断程序,(在进入中断程序时串口照样接收,中断程序是往串口缓存区读的数据,并且读数据时相当快的,永远不用担心还在读的时候数据被新来的给覆盖了)将该接收的字节提取出放在一个缓冲区内,缓冲区是你自己定义的一个数组或字符串,谁你喜好,如你所述GPS是每隔1秒发送一次数据的,此时你可以在主程序中设计当0.5秒没有接收到GPS所发的数据时,就将缓冲区内的数据读出处理,并清空缓冲区,这样其实中断程序只管接收数据,主函数只管处理数据,两不相冲。
采纳率:32%
1 GPS可以设置 回发几条信息
有的GPS上电就回发5条信息
可以通过一些指令 让他回发1条或2条信息,如果gps带掉电存储
就可以吧设置存储进去 如果不带
那应该有对应的加掉电存储的接口,修改下电路 让该GPS能吧设置存进去 下次上电 就按你的要求回发设置的信息,如果不带接口 那就换GPS吧 他的技术肯定不成熟2 如果以上不能做到,GPS
1秒回发一次数据
时间对单片机已经足够处理了中断只接收数据,主程序在按照要求调用对应的子程序,到下次串口数据来时时间足够3 如果还不行
那就说明你的单片机编程思路有问题了,肯定时间太多延时那就用定时器做为一个钟表
做每件事情都可以用时间长短来衡量
就如现实中的始终
开始做一件事 看下表 检测时间到了
看事情是否完成
进入中断后一般都要关闭中断,这样可以避免中断冲突。而且就算不关闭中断,对于同级中断CPU是不会响应的,所以不用担心强行退出中断。
中断程序,还是一个一个的接收存储,但是,是要进行“滑动”存储。不能等到收齐了一批数据再退出中断。主程序,要判断这个“滑动的区域”中,那个是一批数据的“头”;由此,找到经纬度、高度、时间等有用的信息。
其他1条回答
为您推荐:
其他类似问题
您可能关注的内容
&#xe675;换一换
回答问题,赢新手礼包&#xe6b9;
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 单片机串口中断怎么写 的文章

 

随机推荐