这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 帮看看基于stc12c5a60s2的简单内部A/D转换程序错误在哪?

共20条 2/2 1 2 跳转至
高工
2014-06-01 12:10:33     打赏
11楼

楼主,我贴一段程序,之前用过的。

串口部分是模拟的,波特率9600,注意一下宏定义的晶振频率要和你的系统一致。

 

/************* 本程序功能说明 **************

P1口 做ADC输入,从串口输出结果(ASCII),9600,8,N,1.

可户只需要更改 MAIN_Fosc 来适应自己的系统。

******************************************/

/************* 用户系统配置 **************/

#define MAIN_Fosc 22118400L //定义主时钟, 模拟串口和和延时会自动适应。5~35MHZ

/************* 以下宏定义用户请勿修改 **************/
#include "reg51.H"
#define uchar unsigned char
#define uint unsigned int
/******************************************/

sfr P1ASF     = 0x9D; //12C5204AD/S2系列模拟输入(AD或LVD)选择
sfr ADC_CONTR = 0xBC; //带AD系列
sfr ADC_RES   = 0xBD; //带AD系列
sfr ADC_RESL  = 0xBE; //带AD系列

// 7       6      5       4         3      2    1    0   Reset Value
//sfr ADC_CONTR = 0xBC; ADC_POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2 CHS1 CHS0 0000,0000 //AD 转换控制寄存器 
#define ADC_OFF() ADC_CONTR = 0
#define ADC_ON (1 << 7)
#define ADC_90T (3 << 5)
#define ADC_180T (2 << 5)
#define ADC_360T (1 << 5)
#define ADC_540T 0
#define ADC_FLAG (1 << 4) //软件清0
#define ADC_START (1 << 3) //自动清0

#define ADC_CH0 0
#define ADC_CH1 1
#define ADC_CH2 2
#define ADC_CH3 3
#define ADC_CH4 4
#define ADC_CH5 5
#define ADC_CH6 6
#define ADC_CH7 7


/************* 本地变量声明 **************/
sbit P_TXD1 = P3^1;


/************* 本地函数声明 **************/
void Tx1Send(uchar dat);
void PrintString(unsigned char code *puts);
void  delay_ms(unsigned char ms);
uint GetAdc8(uchar channel); //channel = 0~7


void TX_ADC(uchar chn, uint adc)
{
// Tx1Send('A');
// Tx1Send('D');
// Tx1Send(chn+'0');
// Tx1Send('=');
Tx1Send(adc / 1000 + '0');
Tx1Send(adc % 1000 /100 + '0');
Tx1Send(adc % 100 / 10 + '0');
Tx1Send(adc % 10 + '0');
Tx1Send(0x0d);
Tx1Send(0x0a);
}

/********************* 主函数 *************************/
void main(void)
{
uint j;

// PrintString("****** STC12C5204AD系列ADC程序 2011-02-27 ******\r\n"); //上电后串口发送一条提示信息

P1ASF = ((1 << ADC_CH0)); //12C5204AD系列模拟输入(AD)选择
ADC_CONTR = ADC_90T | ADC_ON;

while(1)
{ 
GetAdc8(0); // P1.0 ADC, 丢弃
j = GetAdc8(0); // P1.0 ADC
TX_ADC(0,j);

Tx1Send(0x0d);
Tx1Send(0x0a);
}
}

/********************* 做一次ADC转换 *******************/
uint GetAdc8(uchar channel) //channel = 0~7
{
uchar i;

ADC_RES = 0;

ADC_CONTR = (ADC_CONTR & 0xe0) | ADC_START | channel; 

for(i=0; i<250; i++) //13T/loop, 40*13=520T=23.5us @ 22.1184M
{
if(ADC_CONTR & ADC_FLAG)
{
ADC_CONTR &= ~ADC_FLAG;
return (ADC_RES*4+ADC_RESL);
}
}while(--i);
return 0; //错误
}

//========================================================================
// 函数: void  delay_ms(unsigned char ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数.
// 返回: none.
// 版本: VER1.0
// 日期: 2010-12-15
// 备注: 
//========================================================================
void  delay_ms(unsigned char ms)
{
     unsigned int i;
do{
      i = MAIN_Fosc / 14000;
  while(--i) ;   //14T per loop
     }while(--ms);
}

/********************** 模拟串口相关函数************************/

void BitTime(void) //位时间函数
{
uint i;
i = ((MAIN_Fosc / 100) * 104) / 140000L - 1; //根据主时钟来计算位时间
while(--i);
}

//模拟串口发送
void Tx1Send(uchar dat) //9600,N,8,1 发送一个字节
{
uchar i;
EA = 0;
P_TXD1 = 0;
BitTime();
for(i=0; i<8; i++)
{
if(dat & 1) P_TXD1 = 1;
else P_TXD1 = 0;
dat >>= 1;
BitTime();
}
P_TXD1 = 1;
EA = 1;
BitTime();
BitTime();
}

void PrintString(unsigned char code *puts) //发送一串字符串
{
    for (; *puts != 0; puts++)  Tx1Send(*puts); //遇到停止符0结束
}





 

 

 


助工
2014-06-01 12:27:15     打赏
12楼
崩溃了,还是不行,光强传感器模块没问题呀!你有没有以前写的程序,我能不能直接用,急求拜托了

专家
2014-06-01 13:58:34     打赏
13楼
//本示例在Keil开发环境下请选择Intel的8052芯片型号进行编译
//假定测试芯片的工作频率为18.432MHz

#include "reg51.h"
#include "intrins.h"

#define FOSC    18432000L
#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  AUXR       =   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_SPEEDL  0x20            //360个时钟
#define ADC_SPEEDH  0x40            //180个时钟
#define ADC_SPEEDHH 0x60            //90个时钟

void InitUart();
void InitADC();
void SendData(BYTE dat);
BYTE GetADCResult();
void Delay(WORD n);
void ShowResult();

void main()
{
    InitUart();                     //初始化串口
    InitADC();                      //初始化ADC

    while (1)
    {
        ShowResult();               //显示ADC结果
    }
}

/*----------------------------
发送ADC结果到PC
----------------------------*/
void ShowResult()
{
    SendData(GetADCResult());       //显示ADC高8位结果
//    SendData(ADC_LOW2);           //显示低2位结果
}

/*----------------------------
读取ADC结果
----------------------------*/
BYTE GetADCResult()
{
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | 0 | ADC_START;
    _nop_();                        //等待4个NOP
    _nop_();
    _nop_();
    _nop_();
    while (!(ADC_CONTR & ADC_FLAG));//等待ADC转换完成
    ADC_CONTR &= ~ADC_FLAG;         //Close ADC

    P2 = ADC_RES;

    return ADC_RES;                 //返回ADC结果
}

/*----------------------------
初始化串口
----------------------------*/
void InitUart()
{
    SCON = 0x5a;                    //设置串口为8位可变波特率
#if URMD == 0
    T2L = 0xd8;                     //设置波特率重装值
    T2H = 0xff;                     //115200 bps(65536-18432000/4/115200)
    AUXR = 0x14;                    //T2为1T模式, 并启动定时器2
    AUXR |= 0x01;                   //选择定时器2为串口1的波特率发生器
#elif URMD == 1
    AUXR = 0x40;                    //定时器1为1T模式
    TMOD = 0x00;                    //定时器1为模式0(16位自动重载)
    TL1 = 0xd8;                     //设置波特率重装值
    TH1 = 0xff;                     //115200 bps(65536-18432000/4/115200)
    TR1 = 1;                        //定时器1开始启动
#else
    TMOD = 0x20;                    //设置定时器1为8位自动重装载模式
    AUXR = 0x40;                    //定时器1为1T模式
    TH1 = TL1 = 0xfb;               //115200 bps(256 - 18432000/32/115200)
    TR1 = 1;
#endif
}

/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
    P1ASF = 0x00;                   //不设置P1口为模拟口
    ADC_RES = 0;                    //清除结果寄存器
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
    Delay(2);                       //ADC上电并延时
}

/*----------------------------
发送串口数据
----------------------------*/
void SendData(BYTE dat)
{
    while (!TI);                    //等待前一个数据发送完成
    TI = 0;                         //清除发送标志
    SBUF = dat;                     //发送当前数据
}

/*----------------------------
软件延时
----------------------------*/
void Delay(WORD n)
{
    WORD x;

    while (n--)
    {
        x = 5000;
        while (x--);
    }
}

 



助工
2014-06-01 20:49:42     打赏
14楼

谢了!好高深,菜鸟的我看不懂,得向你好好学习!


助工
2014-06-01 21:05:34     打赏
15楼
哪一个是A/D通道呀?真心看不懂!

高工
2014-06-01 21:09:33     打赏
16楼
#define ADC_CH0 0   对应P1.0 #define ADC_CH1 1    对应P1.1 以此类推

院士
2014-06-02 10:00:15     打赏
17楼
解决了没有呢

助工
2014-06-02 13:05:39     打赏
18楼
嗯,知道了

助工
2014-06-02 13:08:24     打赏
19楼
还没,我写的程序和网上搜的基本一样,就那么几行,可就是找不出错误,哎··········感觉A/D真心的好难!

助工
2014-06-02 13:11:07     打赏
20楼
今晚交作品,没时间了,别的都没问题,就差一个A/D转换程序,真的好遗憾!

共20条 2/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]