单片机C语言编程中串口通讯中断与定时器0中断

//交通灯设计

#include <reg51.h>

#define uchar unsigned char
#define uint unsigned int

uchar code tab[16]={
0xC0, //"0"
0xF9, //"1"
0xA4, //"2"
0xB0, //"3"
0x99, //"4"
0x92, //"5"
0x82, //"6"
0xF8, //"7"
0x80, //"8"
0x90, //"9"
0x88, //"A"
0x83, //"B"
0xC6, //"C"
0xA1, //"D"
0x86, //"E"
0x8E, //"F"
};
uchar ucNum=0; //数码管
uchar ucDigiPip[4]={30,40,40,30}; //0北 1东 2西 3南

//延时程序
void delay(uint d) //晶振11.0592MHz下1ms
{
uint i;
TMOD=0x01;
for(i=0;i<d;i++)
{
TH0 =0xfc;
TL0 =0x67;
TR0 =1;
while(!TF0);
TF0 =0;
}
}

//定时器0中断处理程序
void timer0_2ms() interrupt 1 //晶振频率11.0592MHz,约=2ms中断
{
TF0 = 0;
TH0 = 0xF8;
TL0 = 0xCD;

P1 = 1<<ucNum;
//外部数码管组,内部拆分为数码管
if(ucNum%2)
{
P2 = tab[(ucDigiPip[ucNum/2])%10];
}
else
{
P2 = tab[(ucDigiPip[ucNum/2])/10];
}
if(++ucNum > 7)
{
ucNum=0;
}
}
//串行通讯中断4处理程序
void uart_int() interrupt 4
{
uchar i;
if(RI)
{
RI=0;
i=SBUF;
SBUF=i;

}
else
{
TI=0;
}
}
void disp(uchar ucSeg,uchar ucData) //数码管组
{
ucDigiPip[ucSeg]= ucData;
}

void main()
{
uchar i;
//串口通讯中断初始化
TMOD = 0x21;
PCON = 0;
SCON = 0x50;
TH1 = 0xE8;
TL1 = 0xE8; //1200bps

IP = 0x10;
IE = 0x92;
TR1 = 1;

//定时器0中断初始化

TH0 = 0xF8;
TL0 = 0xCD;
TF0 = 0;
TR0 = 1;

while(1)
{
for(i=0;i<4;i++) //i作为数码管组,依次将其数字减1 (实现倒计时)
{
disp(i,ucDigiPip[i]);
if(--ucDigiPip[i]==0)
{
ucDigiPip[i]=60;
}

}
delay(400); //每次倒计时后,延时1s
}
}

/////////////////////////////
//为什么串口中断没有工作?

第1个回答  2014-04-12
首先是你的延时函数里面,不可以再进行设置TMOD

可以直接使用for循环语句的延时控制,虽然时间不是很精确,但不影响各个中断的使用

还有你的串口中断部分,这种写法问题很多

发送数据以及接收数据,都需要等待发送与接收完成的,否则数据会有错误,导致不能发送或接收

另外,IP TF0 TF1 没必要特意加以控制,直接忽略即可
PCON=0最好写成PCON=0x00,方便阅读,也不容易出错

给你改了一下串口中断部分

//串行通讯中断4处理程序
void uart_int() interrupt 4
{
uchar i;

i=SBUF;//接收一位数据
while(!RI);//等待接收完成
RI=0;//置位接收中断申请标志位

SBUF=i;//发送一位数据
while(!TI);//等待发送完成
TI=0;//置位发送申请标志位
}

//延时程序
void delay(uint d) //晶振11.0592MHz下1ms
{
for(;hs>0;hs--)
{ for(hk=200;hk>0;hk--); }
}本回答被提问者采纳
第2个回答  2014-04-12
//交通灯设计
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar code tab[16]={
0xC0, //"0"
0xF9, //"1"
0xA4, //"2"
0xB0, //"3"
0x99, //"4"
0x92, //"5"
0x82, //"6"
0xF8, //"7"
0x80, //"8"
0x90, //"9"
0x88, //"A"
0x83, //"B"
0xC6, //"C"
0xA1, //"D"
0x86, //"E"
0x8E //"F"
};
uchar ucNum=0; //数码管
uchar ucDigiPip[4]={30,40,40,30}; //0北 1东 2西 3南
uchar temp;
bit flag;
//延时程序
void delay(uint d) //晶振11.0592MHz下1ms
{
uint i;
// TMOD=0x01;
for(i=0;i<d;i++)
{
TH0 =0xfc;
TL0 =0x67;
TR0 =1;
while(!TF0);
TF0 =0;
}
}
//定时器0中断处理程序
//定时器0中断处理程序
void timer0_2ms() interrupt 1 //晶振频率11.0592MHz,约=2ms中断
{
TF0 = 0;
TH0 = 0xF8;
TL0 = 0xCD;
P1 = 1<<ucNum;//外部数码管组,内部拆分为数码管
if(ucNum%2)
{
P2 = tab[(ucDigiPip[ucNum/2])%10];
}
else
{
P2 = tab[(ucDigiPip[ucNum/2])/10];
}
if(++ucNum > 7)
{ ucNum=0; }
}
void uart_int() interrupt 4
{
uchar i;
if(RI)
{
RI=0;
i=SBUF;
SBUF=i; // /*RI=0;P1=SBUF;temp=SBUF;flag=1;*/

flag=1;
}
else
{
TI=0;
}
}
void disp(uchar ucSeg,uchar ucData) //数码管组
{
ucDigiPip[ucSeg]= ucData;
}
void main()
{
uchar i; //串口通讯中断初始化
TMOD = 0x21;
PCON = 0X80;
SCON = 0x50;
TH1 = 0xE8;
TL1 = 0xE8; ///应该是2400/
IP = 0x10;
IE = 0x92;
TR1 = 1; //定时器0中断初始化
TH0 = 0xF8;
TL0 = 0xCD;
TF0 = 0;
TR0 = 1;
while(1)
{
for(i=0;i<4;i++) //i作为数码管组,依次将其数字减1 (实现倒计时)
{
disp(i,ucDigiPip[i]);
if(--ucDigiPip[i]==0)
{
ucDigiPip[i]=60;
}
}
delay(400); //每次倒计时后,延时1s
/*
if(flag==1)
{
ES=0;//暂时关闭接收
flag=0;
SBUF=temp;
while(!TI);//等待发送完毕
TI=0;
ES=1;
} */
}
}
//帮你一步一步调试了,是延时函数里面,多了一条TMOD,波特率应该是2400才正确

单片机用C语言编写中断的范例?
TMOD = 0x20; \/\/设置定时器1为自动重载模式,作为波特率发生器 TH1 = 0xXX; \/\/由波特率计算出来的定时值 TL1 = 0xXX; \/\/ SCON = 0x50; \/\/串口模式 ES = 1; \/\/开放串口中断 EA = 1; \/\/总中断使能 TR1 = 1; \/\/ while(1) \/\/等待中断 { if(XXXX){ SBUF = ...

用keil51编译器编写的单片机C语言中断程序void Time0(void) interrupt...
1代表定时计数器0中断 2代表外中断1 3代表定时计数器1中断 4代表串行口中断 所以interrupt 1代表定时计数器产生中断后就转到这个函数里面执行 using 后面的数字是个工作寄存器的代号,也就是R0—R7。如果不写的话由系统自动分配,一般不用去理会 ...

C语言中断怎么调用??
void main(){ EA = 1; \/\/允许CPU中断 ET0 = 1; \/\/定时器0中断打开 TMOD = 0x1; \/\/设定时器0为模式1,16位模式 TH0=0xB1;TL0=0xDF; \/\/设定时值为20000us(20ms)TR0 = 1;while(1){} } \/\/定时器0中断外理中键扫描和显示 void KeyAndDis_Time0(void) interrupt ...

单片机问题
理论上定时器0的中断优先级要比串口的高,你对中断优先级的理解有误。在默认情况下,单片机的5个中断源都是同级的优先级,只在同时申请中断时,先响应定时器T0的中断,但不等于T0的优先级比串口高,而是同级的。在响应了同级的中断时,是不能再响应其它同级的中断的。你的问题解决的办法是:在响应串...

单片机C语言中断函数的定义形式是怎样的?
形式如下:void 中断名(void) inerrupt 中断号 using 工作寄存器组 比如外部中断0 void ext0(void) interrupt 0 using 1 \/\/后面的using 1可以省略,缺省为0 定时器1 void t1isr() interrupt 3

单片机定时器和中断初始化流程是什么样的啊?还有就是TMOD和SCON的初值是...
3、第三步就要打开中断了,使用IE寄存器,我一般是对各个位进行单独设置,这样看起来感觉更好,首先打开总中断EA = 1,这一步是所有中断所必须的,然后打开定时器0中断,ET0 =1;4、这时准备工作都准备好了就要开始启动定时器了,使用TCON寄存器,TR0 = 1,到现在为止就实现了一个50毫秒的定时了;...

c51单片机 用了中断 再用定时器什么意思??有了中断干嘛还要用定时器...
而定时器 一般都是用查询模式的 可以当做时间继电器来用的 chaozi1125 | 发布于2011-09-24 举报| 评论 1 0 首先设置定时器工作方式,给计数器赋初值,然后开总中断,开定时\/计数器中断,启动定时器,然后你该干嘛干嘛,没嘛干就死循环等待中断。在中断里你想干嘛干嘛,但是不能有返回值。下面一C语言为例说明:...

单片机c语言中interrupt4表示什么意思
外部中断0 中断1 定时器1中断 中断2 外部中断1 中断3 定时器2中断 中断4 串口中断 当PC机发给51数据(通过RS232串口)时就会触发这个中断 一般要写个函数响应中断,函数名随便,但是格式必须一定:例如 void UART_Interrupt_Receive(void)interrupt 4 { unsigned char k = 0;if (RI==1){ RI = 0...

51单片机c语言编程中产生中断的条件是什么
void time1_int(void) interrupt 3 \/\/定义定时器1 这里为什么是 0 1 2 3的顺序呢~?其实是单片机内部默认的,顺序依次是:0 外部中断0 1 定时\/计数器0 2 外部中断1 3 定时\/计数器1 4 串行口中断 这个是没有什么理由的,记住就行,以后要定义一个中断的时候,定义的是哪一个,就在后...

c51单片机中断程序中的interrupt1,2,3是由什么决定的?
1、INT0——外部中断0,由P3.2端口引入,低电平或下降沿引起。默认优先级最高。2、INT1——外部中断1,由P3.3端口引入,低电平或下降沿引起。默认优先级第二。3、T0——定时器\/计数器0中断,由T0计数器计满回零引起。默认优先级第三。4、T1——定时器\/计数器1中断,由T1计数器计满回零引起...

相似回答