sc15w单片机ADC调不出来10位
sc15w408as用例程里的程序,设置的是10位的,为啥显示是8位的。u16 Get_ADC10bitResult(u8 channel) //channel = 0~7
{
u16 adc;
u8 i;
if(channel > ADC_CH7) return 1024; //错误,返回1024,调用的程序判断
ADC_RES = 0;
ADC_RESL = 0;
ADC_CONTR = (ADC_CONTR & 0xe0) | ADC_START | channel;
NOP(4); //对ADC_CONTR操作后要4T之后才能访问
for(i=0; i<250; i++) //超时
{
if(ADC_CONTR & ADC_FLAG)
{
ADC_CONTR &= ~ADC_FLAG;
if(PCON2 &(1<<5)) //10位AD结果的高2位放ADC_RES的低2位,低8位在ADC_RESL。
{
adc = (u16)(ADC_RES & 3);
adc = (adc << 8) | ADC_RESL;
}
else //10位AD结果的高8位放ADC_RES,低2位在ADC_RESL的低2位。
{
adc = (u16)ADC_RES;
adc = (adc << 2) | (ADC_RESL & 3);
}
return adc;
}
}
return 1024; //错误,返回1024,调用的程序判断
}
要10位ADC, 改用 STC15H2K64S4, STC8G1K08 sc15w408as这个型号的没没有10位么? 要10位ADC,
改用【 STC15H2K64S4, STC8G1K08】,
是真10位 ADC
早期的 STC15W系列的ADC 没到这水平
如果是STC15的话,试试这样写
/**************************************
功能描述:ADC口初始化
入口参数:无
返回值:无
***************************************/
void ADC_config(void)
{
ADC_CONTR|=0x80; //开AD转换电源
Delay_ms(10); //适当延时等待AD转换供电稳定
P1ASF|=0x01; //选择P1.0作为模拟功能AD使用
ADC_CONTR|=0x00; //选择P1.0作为AD转换通道输入使用
ADC_CONTR|=0x60; //AD转换速度为90个时钟周期转换一次
ADC_CONTR&=0xEF; //清AD转换完成标志
EADC=0; //禁止ADC转换中断
CLK_DIV|=0x20; //ADC转换结果ADC_RES存高2位,ADC_RESL存低8位
ADC_CONTR|=0x08; //启动AD转换,ADC_START=1
}
/**************************************
功能描述:ADC口检测AD转换值函数
入口参数:无
返回值:ADC 10位数据
***************************************/
u16 Get_ADC10bitResult(void)
{
u16 AD_Dat=0;
ADC_CONTR&=0xEF; // 将ADC_FLAG清0
//10位AD结果的高2位放ADC_RES的低2位,低8位在ADC_RESL
AD_Dat = ADC_RES; //将ADC_RES低2位移到应在的第9位和第10位
AD_Dat <<= 8;
AD_Dat|= ADC_RESL; //将ADC_RESL的8位移到应在的低8位
ADC_CONTR|=0x08; //重新启动AD转换,ADC_START=1。
return AD_Dat;
} Yim_Hom 发表于 2024-5-19 18:36
如果是STC15的话,试试这样写
/**************************************
谢谢,我试一下 前行者 发表于 2024-5-19 18:50
谢谢,我试一下
客气,如果不熟的话,可以先用一种移位方式,能读出来10位AD,说明成功了,然后再用另一种移位方式读成功。如果两种方式都可以了,再去if。。。else。。。选择移位方式。
//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz
#include "reg51.h"
#include "intrins.h"
#define FOSC 11059200UL
#define BAUD 115200
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define URMD 0 //0:使用定时器2作为波特率发生器
//1:使用定时器1的模式0(16位自动重载模式)作为波特率发生器
//2:使用定时器1的模式2(8位自动重载模式)作为波特率发生器
sfr T2H = 0xd6; //定时器2高8位
sfr T2L = 0xd7; //定时器2低8位
sfr P1M1 = 0x91; //PxM1.n,PxM0.n =00--->Standard, 01--->push-pull
sfr P1M0 = 0x92; // =10--->pure input,11--->open drain
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xB1;
sfr P3M0 = 0xB2;
sfr P4M1 = 0xB3;
sfr P4M0 = 0xB4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;
sfrAUXR = 0x8e; //辅助寄存器
sfr ADC_CONTR = 0xBC; //ADC控制寄存器
sfr ADC_RES = 0xBD; //ADC高8位结果
sfr ADC_LOW2 = 0xBE; //ADC低2位结果
sfr P1ASF = 0x9D; //P1口第2功能控制寄存器
#define ADC_POWER 0x80 //ADC电源控制位
#define ADC_FLAG 0x10 //ADC完成标志
#define ADC_START 0x08 //ADC起始控制位
#define ADC_SPEEDLL 0x00 //540个时钟
#define ADC_SPEEDL0x20 //360个时钟
#define ADC_SPEEDH0x40 //180个时钟
#define ADC_SPEEDHH 0x60 //90个时钟
void InitUart();
void SendData(BYTE dat);
void Delay(WORD n);
void InitADC();
BYTE ch = 0; //ADC通道号
void main()
{
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x00;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
P6M0 = 0x00;
P6M1 = 0x00;
P7M0 = 0x00;
P7M1 = 0x00;
InitUart(); //初始化串口
InitADC(); //初始化ADC
IE = 0xa0; //使能ADC中断
//开始AD转换
while (1);
}
/*----------------------------
ADC中断服务程序
----------------------------*/
void adc_isr() interrupt 5
{
ADC_CONTR &= !ADC_FLAG; //清除ADC中断标志
SendData(ch); //显示通道号
SendData(ADC_RES); //读取高8位结果并发送到串口
// SendData(ADC_LOW2); //显示低2位结果
if (++ch > 7) ch = 0; //切换到下一个通道
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
}
/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
P1ASF = 0xff; //设置P1口为AD口
ADC_RES = 0; //清除结果寄存器
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
Delay(2); //ADC上电并延时
}
/*----------------------------
初始化串口
----------------------------*/
void InitUart()
{
SCON = 0x5a; //设置串口为8位可变波特率
#if URMD == 0
T2L = (65536 - (FOSC/4/BAUD));
T2H = (65536 - (FOSC/4/BAUD)) >> 8;
AUXR = 0x14; //T2为1T模式, 并启动定时器2
AUXR |= 0x01; //选择定时器2为串口1的波特率发生器
#elif URMD == 1
AUXR = 0x40; //定时器1为1T模式
TMOD = 0x00; //定时器1为模式0(16位自动重载)
TL1 = (65536 - (FOSC/4/BAUD));
TH1 = (65536 - (FOSC/4/BAUD)) >> 8;
TR1 = 1; //定时器1开始启动
#else
TMOD = 0x20; //设置定时器1为8位自动重装载模式
AUXR = 0x40; //定时器1为1T模式
TH1 = TL1 = (256 - (FOSC/32/BAUD));
TR1 = 1;
#endif
}
/*----------------------------
发送串口数据
----------------------------*/
void SendData(BYTE dat)
{
while (!TI); //等待前一个数据发送完成
TI = 0; //清除发送标志
SBUF = dat; //发送当前数据
}
/*----------------------------
软件延时
----------------------------*/
void Delay(WORD n)
{
WORD x;
while (n--)
{
x = 5000;
while (x--);
}
}
STC15W408AS, T2 做波特率发生器,用串口送出来看下
使用官方例子,直接下载HEX文件测试,串口接收,文本显示:
页:
[1]