完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
鸿哥讨教几个问题啊!!!
用PIC2520接收GPS发送的串口信息,一开机的时候使能RCIE,可以正常进串口中断,但是如果暂时不接收即将RCIE清零,过一小段时间后则将RCIE置高,但是这个时候却再也进不去串口中断程序了啊!!!!!! 另外求教PIC单片机用什么编译器啊?我用的是PICC啊感觉上好像不是非常专业啊。。。 |
|
|
|
|
|
|
|
|
|
期待中!
|
|
|
|
|
|
|
|
|
|
|
|
认真学习鸿哥的第六篇,如何接住别人串口发来的一堆数据有感。
因为自己是菜鸟,所以只有不断的试验,阅读无数的代码然后自己写,才能在试验中,学到知识。 经过对鸿哥的程序分析,我写出了自己独特思路的串口接收程序,利用了串口接收缓冲技术,同时程序还有一个新思想,那就是定时器复用技术(1个定时器,可以实现程序中需要的几乎所有任意时间的延时,可是定时器实现的哦); 为表示对鸿哥帖子的热爱,把我的思想和源码,发布如下。 /////////////////////////////主程序//////////////////////////////////////////////////////////////// #include"define.H" #include"sio.h" #include"time.h" void main() { sio_init(); //串口初始化 InitTimer0(); //定时器T0初始化 while(1) { sio_service(); //串口服务函数 } } |
|
|
|
|
|
/////////////////////////////主程序//////////////////////////////////////////////////////////////// #include"define.H" #include"sio.h" #include"time.h" void main() { sio_init(); //串口初始化 InitTimer0(); //定时器T0初始化 while(1) { sio_service(); //串口服务函数 } } /********************************************************* 文件名称:sio.c 主控芯片:STC89C52RC 晶振11.0592MHz 功能描述:串口程序 函数名称:含串口中断函数!其余函数详见头文件sio.h 作者日期:田卫卫 / 2013年2月21日 版 本:V1.0 *********************************************************/ #include"define.h" #include"sio.h" #include"time.h" #define T1MS_1200bps 0xe8; /* (e8,-24,SMOD=0) @1200bps pcon&=0x7f@11.0592MHz*/ #define T1MS_2400bps 0xf4; /* (f4,-12,SMOD=0) @2400bps pcon&=0x7f */ #define T1MS_4800bps 0xfa; /* (fa, -6,SMOD=0) @4800bps pcon&=0x7f */ #define T1MS_9600bps 0xfd; /* (fd, -3,SMOD=0) @9600bps pcon&=0x7f */ #define T1MS_19k2bps 0xfd; /* (fd, -3,SMOD=1) @19.2kbps pcon|=0x80 */ #define SIOADDNUM 3 //协议头数;设置为0,可以关闭协议头。 uchar codeSIOADD[SIOADDNUM]={0xeb,0x00,0xaa}; //定义串口协议头 uchar inbuf[BUFS]; //串口接收缓冲区 uchar buf =0; //统计串口接收到本次数据包的总数量。 /********************************************************* 函数名称:sio_service(); 功能描述:串口服务程序,处理串口接收缓冲区inbuf[]的数据。 输入参数:全局变量buf,TaskMark[0] 包含函数:send(uchardat); 作者日期:田卫卫 / 2013年2月21日 *********************************************************/ void sio_service() { if(TaskMark[0]!= 0) //如果为真,说明收到了数据,而且本次数据包接收已经结束。 { uchari=0,buf_temp=0; //串口缓冲区服务程序当前指向位置。; while(buf_temp < SIOADDNUM) //协议头处理核心:循环SIOADDNUM次,判断协议头。 { if(inbuf[buf_temp] == SIOADD) //协议头处理核心:协议头相同 { i++; //协议头处理核心:指向下一个要判断的协议头 buf_temp++; //协议头处理核心:指向下一个要判断的协议头 } else //协议头处理核心:协议头错误 { buf_temp= 0; //协议头处理核心:清零 buf= 0; //协议头处理核心:清零 break; //协议头处理核心:退出本次循环 } } while(buf_temp < buf) //协议头,如果相等,才会跑到这儿 { ES= 0; //先关中断 send(inbuf[buf_temp]); //调用串口发送函数,把协议头以后所接收到的数据原封不动发给上位机 buf_temp++; //指向下一个要发送的数据 } ES= 1; //刚才关了中断,现在要打开,以备下次接收。 TaskMark[0] = 0; //此任务的定时标志清零 buf= 0; //关键:统计串口接收到本次数据包的总数量--清零。 } } /********************************* 函数名:sio_int(siointerrupt) 功能:中断+缓冲区方式接收串口数据,把收到的一个字节放在inbuf[bufnum]中. *********************************/ void sio_int() interrupt 4 { ES=0; if(RI) /* RI==1 */ { if(buf < BUFS) //小于缓冲区溢出上限,为真可以接收 { inbuf[buf]= SBUF; buf++; TaskCount[0]= 10; // 启动一个定时器中断延时:单位ms TaskMark[0] = 0; //启动此任务的定时器 } else //大于或等于缓冲区上限,说明本次接收的数据可能被截掉了:错误! { beep= 0; // 蜂鸣器响;切勿删除:可作为串口稳定性的参考。 } RI=0; } ES=1; } /********************************* 函数名:send(uchardat) 功能:向串口发送数据 *********************************/ void send(uchar dat) { SBUF=dat; while(!TI); TI=0; } /********************************* 函数名:sel_bps(selectbps) 功能:设置串口波特率 sel为选择通讯速率: 0=1200,1=2400,2=4800,3=9600,4=19.2k *********************************/ void sel_bps(uchar sel) { switch(sel) { case 0:PCON&=0x7f; TH1=T1MS_1200bps; /* T1 use sio */ TL1=T1MS_1200bps; break; case 1:PCON&=0x7f; TH1=T1MS_2400bps; /* T1 use sio */ TL1=T1MS_2400bps; break; case 2:PCON&=0x7f; TH1=T1MS_4800bps; /* T1 use sio */ TL1=T1MS_4800bps; break; case 3:PCON&=0x7f; TH1=T1MS_9600bps; /* T1 use sio */ TL1=T1MS_9600bps; break; case 4:PCON|=0x80; TH1=T1MS_19k2bps; /* T1 use sio */ TL1=T1MS_19k2bps; break; } } /********************************* 函数名:tran_init()(tranmitinitialize) 功能:串口初始化 串口通讯参数初始化 包含子函数:sel_bps *********************************/ void sio_init() /* 通讯有关参数初始化 */ { /* 定时器初始化 */ TMOD=0x21; /* T1=MODE2,sio; T0=MODE1,16bit,use time */ sel_bps(3);/* 选择通讯速率:0=1200,1=2400,2=4800,3=9600,4=19.2k*/ /* SCON寄存器设置 */ SM0=0; SM1=1;/* SM0=0 SM1=1,mode1,10bit */ SM2=0;/* data int,无校验(TB8=bit_duble偶) */ REN=1;/* 允许串口接收 */ TI=0; /* 清空发送中断标志位 */ RI=0; /* 清空接收中断标志位 */ /* IE、IP寄存器设置 */ PS=1; /* SIO int high 优先级 */ ET1=0;/* 关 定时器1串口中断 */ ES=1; /* 开串口中断 */ EA=1; /* 开全局中断 */ TR1=1;/* 启动 定时器1 */ } /********************************************************* 文件名称:sio.h 主控芯片:STC89C52RC 晶振11.0592MHz 功能描述:串口程序 函数名称:含串口中断函数!其余函数详见下部分。 作者日期:田卫卫 / 2013年2月21日 版 本:V1.0 *********************************************************/ #ifndef _SIO_H_ #define _SIO_H_ #define BUFS 33 //串口缓冲区数量 extern uchar inbuf[BUFS]; //串口接收缓冲区 extern uchar buf; //统计串口接收到本次数据包的总数量。 void sio_init(); /* 通讯有关参数初始化 */ void sel_bps(uchar sel); //串口波特率设置 void send(uchar dat); //串口发送 void sio_service(); //串口服务 #endif /********************************* 文件名称:time.C 主控芯片:STC89C52RC 功能描述:延时函数 作者日期:田卫卫 / 2013年2月15日 版 本:V1.0 *********************************************************/ #include"define.H" #include"time.h" #include uint TaskCount[TASK_NUM]; //定义变量:为定时任务存放定时值; uchar TaskMark[TASK_NUM]; //标志位,0表示时间没到,1表示定时的时间到。 /*/////////////////////////////////////////////////////////////////////////////////////// void main(void) { InitTimer0(); } ///////////////////////////////////////////////////////////////////////////////////////// TaskCount[0] = 20; // TO进中断的次数:20次 TaskMark[0] = 0; // 启动此任务的定时器 ///////////////////////////////////////////////////////////////////////////////////////*/ void InitTimer0(void) { TMOD= 0x21; TH0= 0xFC; TL0= 0x18; EA= 1; ET0= 1; TR0= 1; } //////////////////////////////////////////////////////////////////////////////////////// void Timer0Int(void) interrupt 1 { uchari; TH0= 0xFC; TL0= 0x18; for(i=0; i
{ if(TaskCount) { TaskCount--; if(TaskCount == 0) //只有被定时器减的TaskCount,才置标志位! { TaskMark= 0x01; } } } } #ifndef _DELAYMS_H_ #define _DELAYMS_H_ #define TASK_NUM 3 //定时器复用,任务数量。 extern uint TaskCount[TASK_NUM]; //定义变量:为定时任务存放定时值; extern uchar TaskMark[TASK_NUM]; //标志位,0表示时间没到,1表示定时的时间到。 void InitTimer0(); void Delayms(uint xms); /*延时函数,单位 ms*/ void delay(void); /*NOP延时函数,单位 us*/ #endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
549楼,我设计的串口通讯,其实是利用了简单的状态机程序设计思维模式;很简单也容易理解。
首先,定义2个数组,1个用来存放自定义延时初值(每次T0定时器进入中断后,会减,直到0),1个用来放定时时间是否到?状态标志。 初始化定时器,初始化串口之后,一旦串口接收到一个字节的数据,自定义延时初值自动装入,T0就开始1ms减1…… 如果串口不断的接收数据,那么每次串口接收后,都会把新值装入T0中断中,T0永远减不到0; 串口服务程序放主循环中,进入的标志就是:串口接收到数据后,延时了一定时间,标志位置位代表没数据接收了。 (串口接收-T0开始减-串口接收-T0开始减--无数据接收--T0减到0,表示串口无数据接收,串口服务置标志位。) |
|
|
|
|
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
求解外围电路实现的是4脚给持续低电平复位并正常工作,高电平不工作的原因
2076 浏览 1 评论
3489 浏览 3 评论
PIC1946程序有一个变量在运行过程中恢复初始值其他变量保持不变
2329 浏览 2 评论
2754 浏览 0 评论
PIC16F1825的RC5引脚,在主程序中操作无效,在中断中可以改变是为什么?
4012 浏览 5 评论
960浏览 0评论
用XC8编译PIC18F25K80时提示下面Error,求怎么解决这个问题
6345浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 03:20 , Processed in 0.942360 second(s), Total 92, Slave 82 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号