C8051F352,AD0代码求组

2019-07-16 04:51发布

最近在做一个用C8051F352采集数据,通过AD0转换通过串口和pc通信的任务。遇到了问题,还望论坛中的大侠帮助。

下面是我写的AD0转换的代码,在ANI0.2输入,然后通过串口助手通信。


#include <C8051F350.h>                 
#include <stdio.h>

#define uchar unsigned char
#define uint  unsigned int
                                       //16位寄存器定义
sfr16 TMR2RL = 0xCA;                   // 定时器2重装值
sfr16 TMR2 = 0xCC;                     // 定时器2值
sfr16 ADC0DEC = 0x9A;                  // ADC0 抽取比寄存器

typedef union LONGDATA{                //共同体用于存放返回的ad值         
   uint  result  ;               
   uchar Byte[2] ;              
}LONGDATA;
uchar flag=1;

#define SYSCLK       24500000          // 系统时钟频率 Hz
#define MDCLK         2457600          // 调制时钟分频数
                                       // (2.4576 MHz)
#define OWR                20          // 输出字率 Hz
#define BAUDRATE       9600          // 波特率

void Oscillator_Init (void);
void Port_Init (void);
void UART0_Init (void);
void ADC0_Init(void);
void ADC0_Sigle_Channel_ISR(uchar Channel);

void main(void)
{
  
  static LONGDATA rawValue;
  uint mV;

  PCA0MD &= ~0x40;
  Oscillator_Init();
  Port_Init();                        // 端口初始化
  UART0_Init();                       // 串口通信初始化
  ADC0_Init();                        //  ADC0初始化
  while(1)
  {
     if(flag)
     {
       ADC0_Sigle_Channel_ISR(0x28);
       rawValue.Byte[0]=(uchar)ADC0H;
       rawValue.Byte[1]=(uchar)ADC0M;
       mV = rawValue.result / 26;
       printf("AIN0.2  voltage: %4d mV ",mV);
     }
  }
}

void Oscillator_Init (void)
{
   OSCICN = 0x83;                      // 内部晶振使能,SYSCLK不分频
   CLKSEL = 0x00;                      // 选择内部振荡器
   RSTSRC = 0x04;                      // 时钟丢失检验使能
   
}

void Port_Init (void)
{
   XBR0 = 0x01;                        // UART0 TX0,RX0连接到引脚
   XBR1 = 0x40;                        // 交叉开关使能,弱上拉使能
   P0MDOUT |= 0x10;                    // TX 免推方式
}

void UART0_Init (void)
{
   SCON0 = 0x10;                       // SCON0: 8位波特率可编程uart,
                                       //        停止位的逻辑电平被忽略
                                       //        RX 使能
                                       //        第9位清零
                                       //        RI0 ,TI0标志位清零
   if (SYSCLK/BAUDRATE/2/256 < 1) {
      TH1 = 256-(SYSCLK/BAUDRATE/2);
      CKCON &= ~0x0B;
      CKCON |=  0x08;                  // T1M = 1; SCA1:0 = xx
   } else if (SYSCLK/BAUDRATE/2/256 < 4) {
      TH1 = 256-(SYSCLK/BAUDRATE/2/4);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01
      CKCON |=  0x01;
   } else if (SYSCLK/BAUDRATE/2/256 < 12) {
      TH1 = 256-(SYSCLK/BAUDRATE/2/12);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
   } else if (SYSCLK/BAUDRATE/2/256 < 48) {
      TH1 = 256-(SYSCLK/BAUDRATE/2/48);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
      CKCON |=  0x02;
   } else {
      while (1);                       // Error.  Unsupported baud rate
   }
   TL1 = TH1;                          // Init Timer1
   TMOD &= ~0xf0;                      // TMOD: timer1 8位自动重装
   TMOD |=  0x20;
   TR1 = 1;                            // 启动 Timer1
   TI0 = 1;                            // 表面 TX0 准备好了
}

void ADC0_Init (void)
{
   ADC0MD    = 0x80;                    //ADC0使能,工作在空闲模式
   REF0CN |= 0x03;                     // 使能内部 Vref
   ADC0CN = 0x00;                      // PGA增益为1,单极性工作方式
   ADC0CF = 0x00;                      //  SINC3 滤波器输出,使用内部2.5V  Vref
                                      
   ADC0CLK = (SYSCLK/MDCLK)-1;         // 产生调制时钟分频系数
                                       //  MDCLK = 2.4576MHz
                                      // 根据输出字率确定抽取比
   ADC0DEC = ((unsigned long) MDCLK / (unsigned long) OWR /(unsigned long) 128) - 1;
   ADC0BUF = 0x00;                     // 关闭输入缓冲器
   ADC0MUX = 0x28;                     // 选择 AIN0.2
   ADC0MD = 0x81;                      // 开始内部校准
   while(!AD0CALC);                    // 直到校准完成
   EIE1   &= ~0x08;                     // 关闭中断
   ADC0MD &= ~0x07;                     // 使ADC0处于空闲模式
}

void ADC0_Sigle_Channel_ISR(uchar Channel)
{
  ADC0MUX = Channel;  // 转换通道
  AD0INT = 0;   // 清ADC0中断标志
ADC0MD |= 0x02;   // ADC0单次转换
   // AD0INT = 0;   // 清ADC0中断标志
  while (!AD0INT);
        flag=0;
}



但是很奇怪,运行时候,无论我输入怎么变,输出都是302mv


下面是我仿真时候的,ADC0寄存器的值。
我对照datasheet看了下,好像是ADC0STA寄存器中的AD0SC3置位了,表明ADC0 SINC3 滤波器发生了限幅。但是我不知道什么意思。也不知道怎么修改。还玩哪位大侠用过这个芯片的,帮我看看。或者发个正确的代码给我,小弟感激不尽。

原理图c8051f352 原理图c8051f352
原理图c8051f352 原理图c8051f352
原理图c8051f352 原理图c8051f352
原理图c8051f352 原理图c8051f352
原理图c8051f352 原理图c8051f352
ADC0寄存器 ADC0寄存器
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。