打印
[51单片机]

8031单片机配合使用外部程序存储器和外部数据存储器问题

[复制链接]
5083|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chenjianmal|  楼主 | 2013-11-25 16:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
yangfan19641964| | 2013-11-25 16:46 | 只看该作者
绝对与外部程序存储器无关。应该是中断程序有问题,或者是硬件问题,比如信号下拉后恢复不回来。例如,时钟芯片DS12887闹钟中断后,必须读C命令寄存器才能恢复高电平。又如,有些单片机内部上拉能力不够,当被拉成低电平后无法靠内部上拉电阻自动恢复成高电平、需要外接上拉电阻。

使用特权

评论回复
板凳
chenjianmal|  楼主 | 2013-11-25 16:52 | 只看该作者
yangfan19641964 发表于 2013-11-25 16:46
绝对与外部程序存储器无关。应该是中断程序有问题,或者是硬件问题,比如信号下拉后恢复不回来。例如,时钟 ...

硬件问题我觉得可以排除了  我也使用了STC89C52这款单片机 不使用外部程序存储器,同样的程序也能正常运行

使用特权

评论回复
地板
ayb_ice| | 2013-11-25 17:20 | 只看该作者
这和外部程序存储器没有关系

使用特权

评论回复
5
ayb_ice| | 2013-11-25 17:21 | 只看该作者
chenjianmal 发表于 2013-11-25 16:52
硬件问题我觉得可以排除了  我也使用了STC89C52这款单片机 不使用外部程序存储器,同样的程序也能正常运 ...

你用STC89C52外挂一样有问题

使用特权

评论回复
6
chenjianmal|  楼主 | 2013-11-25 17:30 | 只看该作者
ayb_ice 发表于 2013-11-25 17:21
你用STC89C52外挂一样有问题

能具体说说吗  以前很少用外部程序存储器,对着不是很清楚

使用特权

评论回复
7
airwill| | 2013-11-25 19:26 | 只看该作者
中断服务程序的问题的可能性大, 看楼主先怎么排除是中断服务程序的问题?

使用特权

评论回复
8
chenjianmal|  楼主 | 2013-11-26 14:19 | 只看该作者
本帖最后由 chenjianmal 于 2013-11-26 14:20 编辑
airwill 发表于 2013-11-25 19:26
中断服务程序的问题的可能性大, 看楼主先怎么排除是中断服务程序的问题?

我的中断服务程序采用的是调用某一个模块函数
//串口中断入口
void Uart_Gets(void)interrupt 4
{
        RI=0;        
        ES=0;     //关串行口中断
        if(SBUF != P1)
                ES=1;                                //非本机地址,继续监听
        else
                Serial_Pro();
}
/************************************************************
**函数名称:uchar Serial_Pro(void)         
**参数说明:void
**函数功能:串口中断处理函数
**函数返回:void
************************************************************/
void Serial_Pro(void)
{
        uchar temp;
        SM2=0;                                                                   //取消监听状态
        Serial_Send_Data(P1);        //发回从机地址                 
        temp = Serial_Rec_Data();
        switch(temp)
        {
                case 0xff:                                //接收到复位命令
                        break;
                case 0x01:                                //接收到01H命令
                        if(rrdy == 1)
                        {
                                Serial_Send_Data(0x01);        //接收准备好发送状态字
                                while(Serial_Rec_Str());
                        }
                        else
                        {
                                Serial_Send_Data(0x00);
                                //temp = Serial_Rec_Data();
                        }
                        break;
                case 0x02:                                //接收到02H命令
                        if(trdy == 1)
                        {
                                Serial_Send_Data(0x02);        //发送准备好发送状态字
                                while(Serial_Send_Str());
                        }
                        else
                        {
                                Serial_Send_Data(0x00);
                                //temp = Serial_Rec_Data();
                        }
                        break;
                default:                                        //接收到非法命令
                        Serial_Send_Data(0x80);
                        break;
        }
        SM2 = 1;
        ES = 1;                                        //开串行口中断
}
我一直有点怀疑是中断程序中改变了某个参数,但查看了很多遍  仿真 实际下载运行都没查出来
我认为中断服务程序的逻辑结构上有点问题,但具体的还没找出来

使用特权

评论回复
9
ayb_ice| | 2013-11-26 14:46 | 只看该作者
就LZ这串口程序框架,没有问题是奇迹
没有兴趣继续看下去

使用特权

评论回复
10
airwill| | 2013-11-26 15:16 | 只看该作者
稍稍有点复杂, 得结合你的实际数据来看了.
可以先用个简单的中端服务来测试, 再一步步地实现你的功能.
或者借助仿真器来找问题点.

使用特权

评论回复
11
yangfan19641964| | 2013-11-26 16:46 | 只看该作者
串口中断是双中断源,接收一个字节与发送完一个字节都会进入串行中断。标准的结构是:

   if (RI)
    {
             RI=0;
             接收处理
    }
    else
    {
             TI=0;
             发送处理
     }

你回送0x01与0x02后执行等待程序(想必里面在判断TI并清零吧)。但回送0x00与0x80直接退出中断。当发送完后会进入中断执行:

   RI=0;

不出问题才怪

使用特权

评论回复
12
yangfan19641964| | 2013-11-26 16:49 | 只看该作者
顺便说一句,你的程序除了发送处理不得法外(这也是初学者的通病),程序结构是非常规范的。首先一点,括号就对得很齐。

使用特权

评论回复
13
chenjianmal|  楼主 | 2013-11-27 10:12 | 只看该作者
airwill 发表于 2013-11-26 15:16
稍稍有点复杂, 得结合你的实际数据来看了.
可以先用个简单的中端服务来测试, 再一步步地实现你的功能.
或者 ...

ok  谢谢啊  我先慢慢用板子调试一下 简化一下逻辑结构试试

使用特权

评论回复
14
chenjianmal|  楼主 | 2013-11-27 10:13 | 只看该作者
yangfan19641964 发表于 2013-11-26 16:49
顺便说一句,你的程序除了发送处理不得法外(这也是初学者的通病),程序结构是非常规范的。首先一点,括号 ...

能否说一下初学者容易犯的问题,希望在以后有所提高

使用特权

评论回复
15
yangfan19641964| | 2013-11-27 10:25 | 只看该作者
chenjianmal 发表于 2013-11-27 10:13
能否说一下初学者容易犯的问题,希望在以后有所提高

不知道Serial_Send_Data、Serial_Rec_Data、while(Serial_Rec_Str());这三个函数的内容

使用特权

评论回复
16
yangfan19641964| | 2013-11-27 10:32 | 只看该作者
我们在向上位机回送应答或数据时,不可能死等:  while(!TI);   TI=0;
而是发了就返回,待发完时进入发送中断去处理。

当然了,如果只是一个应答数据还简单,发送中断只需写一句 TI=0;  就行了。
如果需要连续回传多个字节,就涉及到全双工通讯的方法了。需要设一个队列表,用几个指针。

使用特权

评论回复
17
yangfan19641964| | 2013-11-27 10:37 | 只看该作者
初学者的通病就是只会照搬教科书上的方法,
SBUF=xxx;
while(!TI);   TI=0;

在一个实际的电子产品中,这个方法要么无法达到实际需求、要么极大降低了产品的性能。

使用特权

评论回复
18
yangfan19641964| | 2013-11-27 10:43 | 只看该作者
话又说回来,现在写教材的大概也不会全双工通讯。
事实上,这十多年来我在江浙地区、广州、深圳、成都与很多从业者技术交流后,在这里说一句大话:我发现只有我一人会全双工通讯。
其实,在我原单位(中国测试技术研究院),我们从来都是采用全双工通讯。

使用特权

评论回复
评分
参与人数 1威望 +6 收起 理由
dong_abc + 6
19
raysin| | 2013-11-27 11:58 | 只看该作者
yangfan19641964 发表于 2013-11-27 10:37
初学者的通病就是只会照搬教科书上的方法,
SBUF=xxx;
while(!TI);   TI=0;

完全同意. 入门级的教科书上的方法是教学用途, 不是实际使用的,

实际使用时, 要特别留意中断服务和延时副程式.


使用特权

评论回复
20
戈卫东| | 2013-11-27 12:23 | 只看该作者
这么古老的东西现在还找的到么?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

29

帖子

0

粉丝