打印
[国产单片机]

stc125a60s2单片机的A/D转换和串口通信发生冲突了

[复制链接]
1595|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Jackson_lv|  楼主 | 2012-11-29 11:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//AD.h
#ifndef _AD_H
#define _AD_H


sfr ADC_CONTR  = 0xBC;          //ADC控制寄存器
sfr ADC_RES    = 0xBD;          //ADC高8位转换结果寄存器
sfr ADC_LOW2   = 0xBE;          //ADC低2位转换结果寄存器
sfr P1ASF      = 0x9D;          //P1引脚功能控制寄存器
//sfr IP         = 0xB8;          //中断优先级控制寄存器低
sfr IPH        = 0xB7;          //中断优先级控制寄存器高
sfr IP2H       = 0xB6;          //中断优先级控制高字节寄存器
sfr IP2        = 0xB5;          //中断优先级控制寄存器


#define ADC_POWER   0x80  //ADC电源控制位
#define ADC_FLAG    0x10  //ADC完成标志
#define ADC_START   0x08  //ADC开始控制位
#define ADC_SPEEDLL 0x00  //540时钟周期
#define ADC_SPEEDL        0x20  //360时钟周期
#define ADC_SPEEDH        0x40  //180时钟周期
#define ADC_SPEEDHH        0x60  //90时钟周期


#endif

//Uart.h
#ifndef _UART_H
#define _UART_H
#include"define.h"


#define FOSC 11059200L
#define BAUD 9600

bit busy;

extern void SendData(UINT8 dat);
extern void Init_U();
extern void Uart_Isr();


/*********************************************************
               发送一节数据函数                                         
***********************************************************/
void SendData(UINT8 dat)
{
       while(busy);//当串口忙碌时,就一直等待
           ACC = dat;//将数据传到ACC
           busy=1;
           SBUF=ACC;//将数据传到SBUF
}



/*******************************************
               串口初始化                                         
*********************************************/

void Init_U()
{         

         SCON=0x50;
         TMOD=0x20;
         TH1=TL1=-(FOSC/12/32/BAUD);//设定自动重装值
         TR1=1;
         
}



/*******************************************
               串口中断函数                                         
*********************************************/
void Uart_Isr() interrupt 4 using 1
{
          if(TI)
          {
                TI=0; //手动置0不再进入中断
                        busy=0;        //说明串口处于空闲
          }
}

#endif

//AD.c
#include<reg52.h>
#include<intrins.h>
#include"define.h"
#include"Uart.h"
#include"AD.h"


UINT8 ch = 0;


void Delay(UINT8 n)
{
      UINT8 x;
          while(n--)
          {
                x = 5000;
                        while(x--);
          }
}

void Delay_xs(UINT8 s)
{
          UINT16 m, n, l;
          for(m = s;m > 0;m--)
          {
              for(n = 1000;n> 0;n--)
                  {
                      for(l = 115;l>0;l--);
                   }
          }

}


void adc_isr() interrupt 5 using 1
{
                 ADC_CONTR &= !ADC_FLAG;           //ADC转换结束标志位清零
         P0 =0x00;
         for(ch = 0;ch < 8;ch++)
         {
         SendData(ch);
         SendData(ADC_RES);
         }
         ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START |ch;//
         
}



void InitADC()
{
                P1ASF = 0xff;                //设置P1口为输入状态,P1.0~P1.7均输入检测电压
        ADC_RES = 0;                           //清楚之前的数据
        ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START |ch;//
        Delay(2);

}

void main()
{         
   
        Init_U();       
        InitADC();
        IE = 0xa0;
        while(1);               
}

这个程序是根据stc125a60s2的datasheet改编的,它里面的晶振是18.432,我改成11.0592了。我分别试过A/D转换和串口通信,单独工作的时候都是可以了。但是同时开这两个中断的时候,串口中断就不起作用了。
主函数如下时,串口能接受到数据。之前认为问题出在,串口传输数据是在死循环里实现的,A/D转换是在死循环外实现的。但是当我注释掉//EA = 1;//ES = 1;加上IE = 0xa0;又接受不到了。
void main()
{         
   
        Init_U();       
        InitADC();
        EA = 1;
        ES = 1;
        while(1)
        {
                 SendData(0x01);
        }

}

希望高手能指点一下,万分感谢!!

相关帖子

沙发
logokfu| | 2012-11-30 20:36 | 只看该作者
这个简单,把AD转换采用采用查询方法就可以了,不用中断。

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
Jackson_lv + 2 神马都是浮云
板凳
Jackson_lv|  楼主 | 2012-12-2 15:34 | 只看该作者
**kfu 发表于 2012-11-30 20:36
这个简单,把AD转换采用采用查询方法就可以了,不用中断。

好的,迟点试试,先谢了

使用特权

评论回复
地板
tianm| | 2012-12-4 11:06 | 只看该作者
要避免中断冲突

使用特权

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

本版积分规则

16

主题

80

帖子

0

粉丝