标题:
STC12C2052AD单片机芯片中关于AD转换的相关内容
[打印本页]
作者:
chinayanhui
时间:
2020-3-1 16:55
标题:
STC12C2052AD单片机芯片中关于AD转换的相关内容
使用芯片自带的AD转换器,按芯片说明书中提供的典型线路图连接方案。发现使用查询方式AD转换没有问题,获取的输出转换电压和实际输入电压,大约相差正负0.2V左右。但是使用中断方式,仅在芯片上电触发一次,然后就不动了。代码也检查了N多遍,真心看不出还有什么问题。请问各位大神遇到过这种问题吗?该芯片测得的直流电压会相差这么多吗?谁用过这款芯片?
单片机代码如下:
#include <intrins.h>
#include <STC12C2052AD.H>
#include "UART.H"
volatile uint8 COMMAND;
#define ADC_POWER 0x80 // 1000 0000
#define ADC_FLAG 0x10 // 0001 0000
#define ADC_START 0x08 // 0000 1000
#define ADC_SPEEDLL 0x00 // 0000 0000
#define ADC_SPEEDL 0x20 // 0010 0000
#define ADC_SPEEDH 0x40 // 0100 0000
#define ADC_SPEEDHH 0x60 // 0110 0000
// 延时函数
void Delay(uint16 n)
{
uint16 x;
while(n--)
{
x = 5000;
while(x--);
}
}
// AD中断(这里出现问题,上电触发一次,然后就不再触发)
void AdcISR() interrupt 5
{
ADC_CONTR &= ~ADC_FLAG;
PutChar(ADC_DATA);
// 开始下一次转换
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | 6 | ADC_START;
Delay(10);
}
// 初始化AD
void InitAdc()
{
P1 = P1M0 = P1M1 = 0xFF; // 将所有P1口全部设置为开漏(Open Drain)
ADC_DATA = 0;
// 清空DA转换的结果
//ADC_CONTR = ADC_POWER | ADC_SPEEDHH;
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | 6 | ADC_START;
Delay(10);
}
// 查询方式获取AD的值
uint8 GetAdcResult()
{
ADC_CONTR = ADC_POWER | ADC_SPEEDHH | 6 | ADC_START;
_nop_();
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR & ADC_FLAG));
// 清空位
ADC_CONTR &= ~ADC_FLAG;
// 返回转换结果
return ADC_DATA;
}
// 软件延时500ms
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 22;
j = 3;
k = 227;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
InitUART(); // 初始化串口
InitAdc(); // 初始化ADC
// 中断方式使用AD,使用查询方式时,注释下面两行
AUXR |= 0x10;
IE = 0xB0; // 芯片说明书上给出的是0xA0,会将串口通讯的中断屏蔽,这里我改为了0xB0
while(1)
{
;
// 查询方式使用AD,中断方式注释下面两行
// Delay500ms();
// PutChar(GetAdcResult());
}
}
复制代码
作者:
wulin
时间:
2020-3-1 17:56
没有看到开总中断和开ADC中断
作者:
chinayanhui
时间:
2020-3-1 18:03
刚刚发完帖后,又仔细的检查了一下代码。发现这个问题可能是中断造成的。因为我在中断响应程序中调用了将数据发送到串口的操作,这种操作会触发串口发送数据完成的中断。
我将中断程序改为如下:
void AdcISR() interrupt 5
{
ADC_CONTR &= ~ADC_FLAG;
PutChar(0xFF);
PutChar(0xFE);
PutChar(ADC_DATA);
// 开始下一次转换
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | 6 | ADC_START;
}
复制代码
在串口调试工具中发现接收窗仅打印了一个FF,然后就不动了。
查询手册发现,虽然没有设置串口优先级寄存器的情况下,同级的串口中断的优先级比AD优先执行,但是串口中断并不会打断AD中断的执行。所以程序就停止在了putchar中,因为putchar会等待串口中断执行完成将TI设置为0才往下执行。
所以,在主函数中将串口中断的优先级提高一级就可以正常工作了。
void main()
{
// 中断方式使用AD,使用查询方式时,注释下面两行
PS = 1;
AUXR |= 0x10;
IE = 0xB0; // 芯片说明书上给出的是0xA0,会将串口通讯的中断屏蔽,这里我改为了0xB0
//PADC_SPI = 1; // 高优先级
InitUART(); // 初始化串口
InitAdc(); // 初始化ADC
while(1)
{
;
// 查询方式使用AD,中断方式注释下面两行
// Delay500ms();
// PutChar(GetAdcResult());
}
}
复制代码
作者:
chinayanhui
时间:
2020-3-1 18:06
wulin 发表于 2020-3-1 17:56
没有看到开总中断和开ADC中断
谢谢您,我的问题已经解决了。开AD中断是
AUXR |= 0x10;
IE = 0xB0;
开总中断在是InitUART中做了。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1