用STC12C5A60S2模拟一个串口

lwj006 2010-07-24 02:31:10
请问哪位高手用STC12C5A60S2单片机,我用这个单片机模拟串口双机通信,具体方法是用PCA定时器(其他定时器已被占用了)和外部中断0来模拟,可是接收不到数据,哪位高手能帮我改一改,都弄了两三个星期了,还没弄出来,请求各路高手帮忙,感激不尽!
#include<12C5A60S2.h>

#define uchar unsigned char
#define uint unsigned int


sbit BT_SND =P3^3;
sbit BT_REC =P3^2;//外部中断0接口
sbit led=P1^0;

/**********************************************

IO 口模拟232通讯程序

占用 定时器0 外部中断0

**********************************************/


#define F_TM F0
#define TIMER0_ENABLE CR=1; CL=0;CH=0; // 0x40 0x02
#define TIMER0_DISABLE CR=0;

uchar tmpbuf2[3];
uchar num;
//
//发送一个字符
//
void PSendChar(unsigned char input)
{
unsigned char j=8;
TIMER0_ENABLE; //启动
BT_SND=0; //start bit
F_TM=0;
while(!F_TM);
//发送8位数据位
while(j--)
{
BT_SND=(bit)(input&0x01);//先传低位
F_TM=0;
while(!F_TM);
input=input>>1 ;
}
BT_SND=(bit)1 ;
F_TM=0;
while(!F_TM);

TIMER0_DISABLE; //停止timer
}
//
//接收一个字符
//
unsigned char PGetChar()
{

uchar Output,i=8;
TIMER0_ENABLE;
F_TM=0;
while(!F_TM); //等过起始位
//接收的时候程序执行到这里就不执行了,停在这里了,不知道为什么?!
//接收8位数据位
while(i--)
{
Output>>=1 ;
if(BT_REC)Output|=0x80 ; //先收低位
F_TM=0;
while(!F_TM);
}

return Output;

}

void ext0_pca()
{
CMOD=0X00;
CCON=0X00;
CL=0; //定时器赋初值
CH=0; //同上
CCAP0L=0x5f; // 比较匹配数值1152 0xc0
CCAP0H=0; // 比较匹配数值1152 0x06

CCAPM0=0X49;//设置PCA位定时模式

EA=1; //开总中断
CR=0;//关闭启动计数器阵列,用到的时候在打开

EX0=1;// 使能外部中断0
IT0=1 ;// 设置外部中断0为边沿触发方
// CCF0=0;


}

void main()
{


ext0_pca();
PSendChar(0xaa);

while(1)
{
P0=tmpbuf2[1];

}

}

void EXT0()interrupt 0
{
EX0=0 ; //屏蔽外部中断0

tmpbuf2[1]=PGetChar(); //从模拟串口读取数据,存放到tmpbuf2数组中

IE0=0 ; //防止外部中断响应2次,防止外部中断函数执行2次
EX0=1 ; //打开外部中断0
}

void PCA_Routine() interrupt 7
{
if(CCF0==1)
{
F_TM=1;
CCF0=0;
CL=0;
CH=0;
}
}




两片单片机,一个作为发送,另一个接收,接收的时候总是停在 while(!F_TM); //等过起始位 ,这句,不知为什么,进入外部中断0以后我已经把外部中断0关闭掉了,怎么就近不到PCA定时器中断函数里呢?进不去while(!F_TM); 就一直等待。这是怎么回事呢?感谢高手能指点。
...全文
632 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
meiyawei08 2011-05-27
  • 打赏
  • 举报
回复
我也在用串口呢
lfwendula0 2011-04-22
  • 打赏
  • 举报
回复
还行吧
lwj006 2010-07-26
  • 打赏
  • 举报
回复
呵呵,大家都说怎么不用那两个串口,我忘了告诉大家,那两个串口都已经被用上了。
wzlxx 2010-07-25
  • 打赏
  • 举报
回复
在你的程序中我有些疑惑???
都注释出来了。
#include<12C5A60S2.h>

#define uchar unsigned char
#define uint unsigned int


sbit BT_SND =P3^3;
sbit BT_REC =P3^2;//外部中断0接口
sbit led=P1^0;

/**********************************************

IO 口模拟232通讯程序

占用 定时器0 外部中断0

**********************************************/


#define F_TM F0 /*多个F0是干什么的???????while中他能改变还能改变F_TM的数值么么?????*/
#define TIMER0_ENABLE CR=1; CL=0;CH=0; // 0x40 0x02
#define TIMER0_DISABLE CR=0;

uchar tmpbuf2[3];
uchar num;
//
//发送一个字符
//
void PSendChar(unsigned char input)
{
unsigned char j=8;
TIMER0_ENABLE; //启动
BT_SND=0; //start bit
F_TM=0;
while(!F_TM);
//发送8位数据位
while(j--)
{
BT_SND=(bit)(input&0x01);//先传低位
F_TM=0;
while(!F_TM);
input=input>>1 ;
}
BT_SND=(bit)1 ;
F_TM=0;
while(!F_TM);

TIMER0_DISABLE; //停止timer
}
//
//接收一个字符
//
unsigned char PGetChar()
{

uchar Output,i=8;
TIMER0_ENABLE;
F_TM=0;
while(!F_TM); //等过起始位
//接收的时候程序执行到这里就不执行了,停在这里了,不知道为什么?
/*可以看出发送的时候不死机,接收的时候在此死机,应该说明中断函数没问题。
既然中断函数没问题,接收的数据更不会有问题,那问题就出在程序的接收算法当中。*/
//接收8位数据位
while(i--)
{
Output>>=1 ;
if(BT_REC)Output|=0x80 ; //先收低位
F_TM=0;
while(!F_TM);
}

return Output;

}

void ext0_pca()
{
CMOD=0X00;
CCON=0X00;
CL=0; //定时器赋初值
CH=0; //同上
CCAP0L=0x5f; // 比较匹配数值1152 0xc0
CCAP0H=0; // 比较匹配数值1152 0x06

CCAPM0=0X49;//设置PCA位定时模式

CR=0;//关闭启动计数器阵列,用到的时候再打开

EX0=1;// 使能外部中断0
IT0=1 ;// 设置外部中断0为边沿触发方
/*外部中断为为边沿触发,怎么接收数据呢?中断接收????中断触发前的数据如果全是0(或是全是1)怎么办?中断触发后的数据如果全是1(或是全是0),怎么再接收??*/
// CCF0=0;

EA=1; //开总中断

}

void main()
{


ext0_pca();
PSendChar(0xaa);

while(1)
{
P0=tmpbuf2[1];

}

}

void EXT0()interrupt 0
{
EX0=0 ; //屏蔽外部中断0

tmpbuf2[1]=PGetChar(); //从模拟串口读取数据,存放到tmpbuf2数组中

IE0=0 ; //防止外部中断响应2次,防止外部中断函数执行2次
EX0=1 ; //打开外部中断0
}

void PCA_Routine() interrupt 7
{
if(CCF0==1)
{
F_TM=1;
CCF0=0;
CL=0;
CH=0;
}
}
/*在程序中没有看到看门狗之类的东东,没有的话程序会不会一直到while(F_TM)处,单片机就重启
了,程序从头开始执行到while处又重启,一直无限循环。*/
dong20072 2010-07-25
  • 打赏
  • 举报
回复
看到这个标题,想来批评你一下,那个单片机本来就有两个串口,你还要模拟,模拟的总线既烦琐,而且效率也低!
Great_Bug 2010-07-24
  • 打赏
  • 举报
回复
51里面,中断是否被服务,由一个用户无法访问的寄存器决定. 当一个中断得到服务,或一条RETI指令被执行时,这个寄存器才会更新. 开启或关闭某个中断,不会对它有影响.
Great_Bug 2010-07-24
  • 打赏
  • 举报
回复
你在外部中断0的ISR里面等待F_TM变成1
这个F_TM必须在PCA中断的ISR里面才会变成1
你又没有设置PCA的高优先级
于是外部中断0的ISR永远在等待
PCA中断永远不会得到服务
Great_Bug 2010-07-24
  • 打赏
  • 举报
回复
S2本来就有两个UART啊,不用那样费事的吧?

27,374

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧