能帮我看下STC12使用自己AD的程序吗?不知道哪里出错了,

2019-03-24 18:21发布

#include<stc12.h>
#include<intrins.h>

#define uchar unsigned char
#define uint  unsigned int


sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;

void Lcd1602_Delay1ms(uint c);    //误差 0us
void LcdWriteCom(uchar com);   //LCD1602写入8位命令子函数
void LcdWriteData(uchar dat);   //LCD1602写入8位数据子函数
void LcdInit();       //LCD1602初始化子程序
void adInit(void);
unsigned int getAd(unsigned char channel);


unsigned char Num[]="the AD result :";


void main()
{
uint ad,a1,a2,a3,a;
LcdInit();
adInit();
for(a=0;a<15;a++)
  LcdWriteData(Num[a]);
while(1)
{
  ad=getAd(0);
  ad=(ad*5)/1024;
  a1=ad/100;
  a2=ad%100/10;
  a3=ad%10;
  LcdWriteCom(0x80+0x40);
  LcdWriteData('0');
  LcdWriteData(0x30+a2);
  LcdWriteData(0x30+a3);
}

      
}
void adInit(void)
{
        P1ASF=0x07; //P1.0/P1.1/P1.2口全部作为模拟功能AD使用
  P1M0 = 0xff;
        P1M1 = 0xff;
        ADC_RES=0;   //清零转换结果寄存器高8位
        ADC_RESL=0; //清零转换结果寄存器低2位
        ADC_CONTR=0x80;//开启AD电源
        Lcd1602_Delay1ms(1);   //等待1ms,让AD电源稳定
}
unsigned int getAd(unsigned char channel)
{
         ADC_CONTR=0x88|channel;    //开启AD转换1000 1000 即POWER SPEED1 SPEED0 ADC_FLAG   ADC_START CHS2 CHS1 CHS0
         _nop_();
   _nop_();
   _nop_();
   _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器         

         while(!(ADC_CONTR&0x10));    //等待转换完成
        ADC_CONTR&=0xe7;      //关闭AD转换,ADC_FLAG位由软件清0
         return(ADC_RES*4+ADC_RESL);   //返回AD转换完成的10位数据(16进制)
}



其中我省略了1602显示的函数,那几个子函数没有问题的。 每次给单片机上电,P1口滞空,1602就会显示一个值,但是当采集电压的时候,显示的值又不会改变。
此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
hjl240
2019-03-25 10:23
给你一个官网的AD中断代码,你可以看看

/*------------------------------------------------------------------*/
/* --- STC MCU Limited ---------------------------------------------*/
/* --- STC12C5Axx Series MCU A/D Conversion Demo -------------------*/
/* --- Mobile: (86)13922805190 -------------------------------------*/
/* --- Fax: 86-755-82905966 ----------------------------------------*/
/* --- Tel: 86-755-82948412 ----------------------------------------*/
/* --- Web: www.STCMCU.com -----------------------------------------*/
/* If you want to use the program or the program referenced in the  */
/* article, please specify in which data and procedures from STC    */
/*------------------------------------------------------------------*/

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

#define FOSC    18432000L
#define BAUD    9600

typedef unsigned char BYTE;
typedef unsigned int WORD;

/*Declare SFR associated with the ADC */
sfr ADC_CONTR   =   0xBC;           //ADC control register
sfr ADC_RES     =   0xBD;           //ADC hight 8-bit result register
sfr ADC_LOW2    =   0xBE;           //ADC low 2-bit result register
sfr P1ASF       =   0x9D;           //P1 secondary function control register

/*Define ADC operation const for ADC_CONTR*/
#define ADC_POWER   0x80            //ADC power control bit
#define ADC_FLAG    0x10            //ADC complete flag
#define ADC_START   0x08            //ADC start control bit
#define ADC_SPEEDLL 0x00            //420 clocks
#define ADC_SPEEDL  0x20            //280 clocks
#define ADC_SPEEDH  0x40            //140 clocks
#define ADC_SPEEDHH 0x60            //70 clocks

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

BYTE ch = 0;                        //ADC channel NO.

void main()
{
    InitUart();                     //Init UART, use to show ADC result
    InitADC();                      //Init ADC sfr
    IE = 0xa0;                      //Enable ADC interrupt and Open master interrupt switch
                                    //Start A/D conversion
    while (1);
}

/*----------------------------
ADC interrupt service routine
----------------------------*/
void adc_isr() interrupt 5 using 1
{
    ADC_CONTR &= !ADC_FLAG;         //Clear ADC interrupt flag

    SendData(ch);                   //Show Channel NO.
    SendData(ADC_RES);              //Get ADC high 8-bit result and Send to UART

//if you want show 10-bit result, uncomment next line
//    SendData(ADC_LOW2);             //Show ADC low 2-bit result
   
    if (++ch > 7) ch = 0;           //switch to next channel
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
}

/*----------------------------
Initial ADC sfr
----------------------------*/
void InitADC()
{
    P1ASF = 0xff;                   //Set all P1 as analog input port
    ADC_RES = 0;                    //Clear previous result
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
    Delay(2);                       //ADC power-on delay and Start A/D conversion
}

/*----------------------------
Initial UART
----------------------------*/
void InitUart()
{
    SCON = 0x5a;                    //8 bit data ,no parity bit
    TMOD = 0x20;                    //T1 as 8-bit auto reload
    TH1 = TL1 = -(FOSC/12/32/BAUD); //Set Uart baudrate
    TR1 = 1;                        //T1 start running
}

/*----------------------------
Send one byte data to PC
Input: dat (UART data)
Output:-
----------------------------*/
void SendData(BYTE dat)
{
    while (!TI);                    //Wait for the previous data is sent
    TI = 0;                         //Clear TI flag
    SBUF = dat;                     //Send current data
}

/*----------------------------
Software delay function
----------------------------*/
void Delay(WORD n)
{
    WORD x;

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

一周热门 更多>