//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);
}
}
希望高手能指点一下,万分感谢!! |