打印
[AVR单片机]

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

[复制链接]
2402|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Jackson_lv|  楼主 | 2012-11-29 13:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//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);
}

}

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

}

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

}

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

相关帖子

沙发
dqyubsh| | 2012-11-29 20:55 | 只看该作者
这是AVR版,发错地了。

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
Jackson_lv + 2 赞一个!
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

80

帖子

0

粉丝