STC单片机串口2中断引起程序复位问题
单片机型号STC12C5A16S2,使用串口2通信时一接送数据程序就复位了,希望高手指点。下面是代码
#include"stc_new_8051.h"
#include"intrins.h"
#include"uart.h"
#include"delay.h"
#include"jhd_12864.h"
#define SYSCLK 50000 //定时50ms,12MHz一个时钟周期为1us,50ms=50000*1us
#define __MAX_LEN_ 6 // 数据最大长度
/* 以下为程序协议中使用的握手信号 */
#define __RDY_ 0x06 // 主机开始通信时发送的呼叫信号
#define __BUSY_ 0x15 // 从机忙应答
#define __OK_ 0x00 // 从机准备好
#define __SUCC_ 0x0f // 数据传送成功
#define __ERR_ 0xf0 // 数据传送错误
#define PlaceIncatorLight P2 //翻身位置指示灯配置于P2口
#define MassageAndTimeIncatorLight P1 //按摩和定时指示灯配置于P1口
#define Flash_time 8//50ms*X显示刷新时间
#define LCD_time 600//背光关闭时间50ms*X
sbit LCD_CON = P0^5;//P0.5 --> LCD_CON 背光控制
bit BitBusy = 0;
bit BitLCDtimer = 0;//背光计时标志
unsigned char ReceiverData;
unsigned char buf;
unsigned char str;
unsigned char Timer_clock = 0;//定时器时钟变量
unsigned int Timer_LCD = 0;//背光计时时钟
unsigned char shuzu_three =
{0xff,0xf7,0xef,0xdf,0xbf,0xfe,0xfd,0xfb,0x7f,0xbe,0xdd,0xeb,0x00};//侧翻功能指示灯和CPR指示灯
//0全灭//1水平//2左侧30%//3左侧50%//4左侧100%//5右侧100%//6右侧50%//7右侧30%//8CPR//9左右100%//10左右50%//11左右30%//12全亮
unsigned char shuzu_four =
{ //0 1 2 3 4
/*0*/0xff,0xfe,0xfd,0xfb,0xf7,
/*1*/0xef,0xee,0xed,0xeb,0xe7,
/*2*/0xdf,0xde,0xdd,0xdb,0xd7,
/*3*/0xbf,0xbe,0xbd,0xbb,0xb7,
/*4*/0x7f,0x7e,0x7d,0x7b,0x77
};//按摩指示灯和定时指示灯
/*******************************************************************************************************
** 函数名称: void Init_IO(void)
** 功能描述: I/O口初始化
** 入口参数: 无
** 出口参数: 无
********************************************************************************************************/
void init_io(void)
{
P0M1=0xc0; //P0.0->CS推挽,P0.1->RES推挽,P0.2->A0推挽,P0.3->SCL准双向,P0.4->SDA准双向,P0.5->LCD_CON推挽
P0M0=0x27; //其他为高阻
P1M1=0x00;
P1M0=0xff; //P1.0~P1.7设为推挽
P2M1=0x00;
P2M0=0xff; //P2.0~P2.7设为推挽
P3M1=0xff; //P3口全部设为高阻
P3M0=0x00;
P4M1=0xc3; //P4.2和P4.3设为双向I/O,P4.4和P4.5设为推挽
P4M0=0x30;
P4SW=0x70; //设置P4脚全部为I/O口
}
/*******************************************************************************************************
** 函数名称: void Timer_init(void)
** 功能描述: 定时器初始化
** 入口参数: 无
** 出口参数: 无
********************************************************************************************************/
/*void Timer_init(void)
{
//中断
IE = 0x02;//开总中断,开定时器0
//定时器
TMOD = 0x01;//定时器0工作在方式1,16定时器,2^16=65536
TH0 = (65536-SYSCLK)/256;//8位界点2^8=256,"/"取高8位,"%"取低8位
TL0 = (65536-SYSCLK)%256;
//TCON = 0x10;//启动定时器0
TCON = 0x00;//启动定时器0
}*/
/*******************************************************************************************************
** 函数名称: void Data_p(unsigned char d_in)
** 功能描述: 数据十位和个位处理,并求得ASCII码
** 入口参数: 100以内的2位数
** 出口参数: 无
********************************************************************************************************/
void Data_p(unsigned char d_in)
{
unsigned char sw,gw;
sw=(d_in/10)%10;
gw=d_in%10;
if(sw==0)
{
str=' ';
}
else
{
str=sw+48;
}
str=gw+48;
str='\0';//数组以空结束,便于函数strlen计算其长度
}
/*******************************************************************************************************
** 函数名称: void LCD_dis_p(void)
** 功能描述: LCD显示处理
** 入口参数: 无
** 出口参数: 无
********************************************************************************************************/
/*void LCD_dis_p(void)
{
/*Data_p(ReceiverData);
Display_Font(0,0,&str);
Data_p(array_1);
Display_Font(2,0,&str);
Data_p(array_3);
Display_Font(2,48,&str);
Data_p(array_4);
Display_Font(6,0,&str);
Data_p(array_5);
Display_Font(6,48,&str);*/
//Display_Font(2,0,"Set Left Right");
/*Data_p(array_1*5);
Display_Font(4,0,&str);
Data_p(Leftairp_v);
Display_Font(4,56,&str);
Data_p(Rightairp_v);
Display_Font(4,112,&str); */
//Display_Font(6,0,"mmHgmmHgmmHg");
//}
/*******************************************************************************************************
** 函数名称:
** 功能描述:
** 入口参数: 无
** 出口参数: 无
********************************************************************************************************/
void P2P_s(unsigned char *buf)
{
unsigned char i,ecc,len;
ReceiverData=0xff;
while(ReceiverData!=__RDY_)
{
while(!(S2CON & 0x01));
S2CON = S2CON & 0xfe;
ReceiverData = S2BUF;
}
if(BitBusy)//判断系统是否忙
{
send_UART_two(__BUSY_);//是,则发送忙信号
}
else
{
send_UART_two(__OK_);//否则,发送可以接收数据信号
while(!(S2CON & 0x01));//等待中断
S2CON = S2CON & 0xfe;//清除接收中断标志
len = S2BUF;//读取数据长度
ecc = len;
ReceiverData = 0xff;
while(ReceiverData!=__SUCC_)//如果接收不成功则继续接收
{
for(i=0;i<len;i++)//接收数据
{
while(!(S2CON & 0x01));
S2CON = S2CON &0xfe;
*buf = S2BUF;
ecc = ecc^(*buf);//求校验
buf++;
}
buf-=len;//返回buf的首地址,便于下次接收数据
while(!(S2CON & 0x01));
S2CON = S2CON & 0xfe;
ReceiverData= S2BUF;
ecc = ReceiverData^ecc;
if(ecc!=0)
{
ReceiverData = 0xff;
send_UART_two(__ERR_);//校验错误,发送错误信号
}
else
{
ReceiverData = __SUCC_;
send_UART_two(__SUCC_);//校验正常,发送成功信号,以结束本次数据传输
}
}
}
}
/*******************************************************************************************************
** 函数名称: void timer0_init(void) interrupt 1
** 功能描述: 定时器0中断处理函数
** 入口参数: 无
** 出口参数: 无
********************************************************************************************************/
/*void timer0_init(void) interrupt 1
{
TH0 = (65536-SYSCLK)/256;//8位界点2^8=256,"/"取高8位,"%"取低8位
TL0 = (65536-SYSCLK)%256;
Timer_clock++;
if(BitLCDtimer)
{
Timer_LCD++;
if(Timer_LCD>LCD_time)
{
BitLCDtimer = 0;
LCD_CON = 1;
}
}
}*/
/*******************************************************************************************************
** 函数名称: void main(void)
** 功能描述: 主函数
** 入口参数: 无
** 出口参数: 无
********************************************************************************************************/
void main(void)
{
init_io();
delay_us(100);
//Timer_init();
//delay_us(100);
//JHD_12864_init();//LCD初始化
//delay_us(100);
serial_port_two_initial();
delay_us(100);
LCD_CON=0;//开背光
BitLCDtimer = 1;//标志置1
//Display_Picture(3,8,4,7);//载入飞漫logo图片
PlaceIncatorLight = shuzu_three;//翻身灯全亮
MassageAndTimeIncatorLight = 0x00;//按摩和定时灯全亮
delay_ms(500);//延时500ms
//Display_Clear();//清楚屏幕,以更新显示
BitBusy=1;//当显示时处于忙状态
PlaceIncatorLight = shuzu_three;//翻身和CPR灯
MassageAndTimeIncatorLight = shuzu_four;//按摩和定时灯
//LCD_dis_p();//LCD显示处理
//LCD_CON = 1;
BitBusy=0;//显示结束位空闲状态
EA = 1;//开总中断
while(1)
{
P2P_s(&buf);
if(buf)
{
LCD_CON = 0;
Timer_LCD = 0;
BitLCDtimer = 1;
}
BitBusy=1;//当显示时处于忙状态
PlaceIncatorLight = shuzu_three];//翻身和CPR灯
MassageAndTimeIncatorLight = shuzu_four]];//按摩和定时灯
BitBusy=0;//显示结束位空闲状态
}
}
这个程序编译后data=65.2 xdata = 0 code = 670 此时程序能正常收发
当把数组直接用code定义后其长度为806就会出错了,但是该型号的单片机有16K存储空间。望高手指点指点,谢谢! 看端口初始化是否为推挽输出。可以用镊子短接txd和rxd到低,stc的端口设置几个系列是反的。 端口我设置为准双向的,这个有什么讲究吗? 我也在用STC双串口的芯片,我发现不能同时在一个串口中断里调用另一个串口,会出问题。
我是在第一个串口里把要发的东西写到缓存里,然后等中断返回后,在主程序里调用串口2再发,这样才没问题。 我只用了一个串口,是用的串口2,很奇怪的问题,我的主机程序能正常工作,从机带LCD的就不能正常工作。 xielong4183 发表于 2011-10-28 17:13 static/image/common/back.gif
我只用了一个串口,是用的串口2,很奇怪的问题,我的主机程序能正常工作,从机带LCD的就不能正常工作。 ...
考虑下功耗的问题,是否同时开启引起电压下降造成了低电压复位。
页:
[1]