stc89c52rc单片机串口中断发送问题
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar code ptrData[] ={0x7e,0x04,0xa1,0x00,0x00,0x7e}; //命令
sbit djz = P2^4; //电机正转
uint txbuffer[]; //串口发送缓存区
uint bufferhead,bufferCt; //发送状态标志
void init()
{
TMOD = 0x21; //定时器1工作方式2,定时器0工作方式1(用于延迟)
SCON = 0x50;
TH1 = 0xfd; //串口9600波特率初值
TL1 = 0xfd;
TR1=1;
EA =1;
ES =1;
bufferhead=bufferCt=0;
}
void delay(uint i)
{
uchar j;
while(i--)
{
for(j=0;j<115;j++) //1ms基准延时程序
{ ; }
}
}
void uart_senddata(uchar j)
{
uint i;
for(i=0;i<6;i++)
{
if(i!=4)
{
txbuffer[bufferCt]=ptrData[i];//循环添加待发送数据
bufferCt++;
}
if(i==4)
{
txbuffer[i]=j;
bufferCt++;
}
}
TI=1; //命令数据存缓存期完毕后,立刻触发串口发送中断
}
void main()
{
init();
delay(200);
uart_senddata(4);
delay(100);
while(1)
{
djz=0;
delay(500);
djz=1;
delay(500);
}
}
void uart_int(void) interrupt 4
{
if(TI) //等待中断触发
{
TI=0;
if(bufferCt)
{
SBUF=txbuffer[bufferhead++];
bufferCt--;
if(bufferCt==0)
{
bufferhead = 0; //当发送数据个数大于16时,bufferhead清零
}
}
}
}
单片机运行熟读变得相当相当慢是啥子意思?
你是不是烧录的时候没有设置晶振的参数啊
打错字啦,就是单片机的运行速度变得慢了许多!比如像我让主程序点一个led灯,我让led亮灭的时间为500毫秒,结果程序跑起来后led亮灭时间变成了好几秒钟!
我用的stc-isp下载软件,对于这个单片机不需要设置晶振参数啊
单片机变慢有可能是程序运行的时候不断进入中断,中断函数不断打断主函数的运行,因此看上去好像单片机速度变慢了。
我就是让单片机while(1)前面发送了几个数据,但是数据发完了的话TI就被软件置零了,就不会再进发送中断了!是不是这么理解的呢?
我也看不懂你的程序,不过有一点,如果你的单片机也接收数据,那么串口中断里面也要对串口接收触发的中断进行处理,就是清RI,如果不清除则不断触发中断。
你把那延时函数的j<115改为j<111看看
谢谢您帮助,8楼的回答解决了问题!
谢谢你的帮助,还真是这个RI搞的鬼!
问题解决就好,一般串口中断都要判断TI和RI.清零再做出对应的中断操作。
一般串口发送是不用中断的窝,因为发送是主动的。接收才用中断,因为接收是被动的。可以参考stc官网手册,发送一般用
SBUF = temp;
while(!TI);
TI =0 ;
这样的结构。
恩恩,这个我知道,主要是开始我发这个数据的时候,时间有点长,照成我的数码管在扫描显示的时候发生抖动!当时是想到这么写,所以就这么弄了,用数码管中断扫描显示也能达到目标!只是上次遇到这个,想摸清这个原因!不过同样谢谢你的热心回答,谢谢!
小编V5 学习了真的要好好学习了
可以用定时器中断不断扫描数码管,那么就不会出现抖动了。
恩恩,我两个都用了中断!对了,再问哥您一个问题咯!
我把这个电路的信号输出端(J1-2脚)接在了stc89c52单片机的外部中断口1口,可是每当出现一个物体遮挡过去之后,单片机的外部中断1服务函数执行了好几次,我设置的外部中断是单片机下降沿触发!我的服务函数里面没有加去抖延迟,因为中断函数里面不想出现那些延迟什么的函数,中断里加延迟感觉太不靠谱了。影响单片机其他程序的运效率!您有什么好的建议吗?也不知道rs触发器能不能做到硬件去抖!还有什么办法可以用硬件去掉这个电路电平变化的过程产生的抖动?或者程序上怎么修改比较好?
这是我的中断服务函数代码:
void tuiqiu() interrupt 2 //检测上升沿触发,快进快
{
//假如没有加延迟去抖,下面的函数会被执行多次,中断里不加延迟!
if(score_over>0)
{
if(T10s_flag==1) //到了十秒的时间,说明电机要开始反转了
{
count=201; //从第二个十秒开始
}
else
count=0;
if(score_over>0)
{
uart_senddata(m+5); //发送地址位
m++;
if(m==13)
m=0;
score_over--;
if(score_over==0)
{
djz=0; //停止电机
djf=0;
TR2=0; //关定时器2
T10s_flag=0; //10秒标志位清零
count=0; //10秒计数值清零
m=0;
}
}
}
}
看了半天都没看懂你的电路时怎么工作的。Q1和D1是什么?实在不软件去抖动就加个rs触发器硬件去抖动吧。另附计数器模块电路给你参考下。
产生抖动的根本原因就是串口发送和数码管扫描这两个任务相互干扰。不知你有没了解过单片机上的多任务处理,像keil自带的rtxTiny微型操作系统,或者像ucosII操作系统。这样就可以实现多任务并,比起使用定时器中断扫描,程序流程会更加直观。
Q1是9013,npn三极管,这个电路实现的功能就是红外接收管接收到了红外信号,然后J1-2端就输出一个低电平,但是结果发现这个低电平相当不稳,抖动比较厉害,多次触发了外部中断!