STC51单片机学习笔记8——stc12c56 串口显示AD(多路ad)

stc12c56 串口显示AD(多路ad).

 AD中断设置

AUXR:

 ADC_CONTR:

//#define ADC_POWER 0x80后面不能加分号,不然就会错。其他定义必须加分号!!!
//烧写程序时,一定要选用外部晶振(烧写软件默认为内部晶振(5M~6M))
//烧写时,有时候写不进去,尝试断开地线,然后接上上电
/*****************************************************
              关于以下两个问题的说明
    a=ADC_LOW2&0x03;//如果是dat=ADC_DATA<<2+ADC_LOW2&0x03;就会出错!莫名其妙!
    dat=ADC_DATA*4+a;    //如果是dat=ADC_DATA<<2+a 。就乱窜,一直飚过1024!而且串口老死!
    从这两个问题可以看出,如果直接对某个8位寄存器进行操作,它会将中间产生的值,直接
    放到该寄存器里,对于寄存器里的的数据不要直接操作,应该先读出来,在内存中处理数据 。
    对寄存器的操作不要用<<、>>等等,也不要使用很长的公式(dat=ADC_DATA<<2+ADC_LOW2&0x03)
*****************************************************/

#include<reg51.h>
#include<intrins.h>

sfr ADC_CONTR = 0xc5;
sfr ADC_DATA =0xc6;
sfr ADC_LOW2 =0xbe;
sfr P1M0 =0x91;
sfr P1M1= 0x92;

sfr AUXR=0x8e;
//sfr AUXR1=0xA2;
//sfr BRT=0x9c;
sbit Led=P1^4;

#define ADC_POWER 0x80
#define ADC_FLAG  0x10
#define ADC_START 0x08
#define ADC_SPEEDLL 0x00
#define    ADC_SPEEDL  0x20
#define ADC_SPEEDH  0x40     //这个速度,读出的数据噪声很大
#define ADC_SPEEDHH 0x60

#define RELOAD_COUNT      0xf3 //4M晶振,smod=0,9600bps 实际波特率=4000000/(256-243)/32=9615.误差=15/9600=0.16%
                              //具体计算看《STC12C5A60S2》第79页及其之后
unsigned char ch=0;            //用于ad通道选择
unsigned char ch_times=0;    //选中某一个ad通道时,前几次采样值不稳定,噪声太大,需要去除

void serial_port_initial(void);
void send_UART(unsigned char i);
void UART_Interrupt_Receive(void);
void delay(unsigned char n);
void initADC(void);
void print_uint(unsigned int num);
void Long_delay();

void main()
{
  Long_delay();//防止pc运行串口驱动时,与本程序自行向pc发送数据产生冲突,从而产生的混乱
  Led=0;
  serial_port_initial();
  initADC();
   AUXR=0x50; //T1定时器不分频,1T的速度,设置EADCI中断允许
   IE=0xa0;                 //设置EADC_SPI中断和EA总中断允许
   while(1)    
   ;
    
}

void serial_port_initial(void)      // 使用独立波特率发生器作为波特率发生器
{
  SCON=0x50;//8位可变波特率,无奇偶校验位
  TMOD=0X21;
  AUXR=0x40; //T1定时器不分频,1T的速度
  TH1=RELOAD_COUNT;
  TL1=RELOAD_COUNT;
  //TR1=1;
  EA=1;          // 开总中断
}

void send_UART(unsigned char i)
{
  ES=0;       // 关串口中断
  TI=0;    // 清零串口发送完成中断请求标志
  SBUF=i;    
  while(TI==0);     //   等待发送完成
  TI=0;            //  清零串口发送完成中断请求标志
  //ES=1;        //     允许串口中断
}

void print_uint(unsigned int num)
{
  unsigned char w5,w4,w3,w2,w1;
    
     w5=num/10000;
     w4=num%10000/1000;
     w3=num%1000/100;
     w2=num%100/10;
     w1=num%10;
     send_UART('0'+w5);
     send_UART('0'+w4);
     send_UART('0'+w3);
     send_UART('0'+w2);
     send_UART('0'+w1);
     send_UART(' ');
}


void delay(unsigned char n)
{
   unsigned char x;
   while(n--)
   {
     x=100;
     while(x--);
   }
}

void initADC()
{
  ch=0;
  //P1=P1M0=P1M1=0xff;    //P1口设置为开漏型,做AD
   P1=P1M0=0xef;
   P1M1=0x00;      //P1.0/2/3口设置为高阻输入,做AD. P1.4作准双向口,做led指示灯
   ADC_DATA=0;
  //此句不对,不能用或。ADC_CONTR=ADC_POWER|ADC_SPEEDL|ADC_START|ch|0xef;
  ADC_CONTR=0x88;//ADC_CONTR=ADC_POWER|ADC_SPEEDL|ADC_START|ch|0xef
  delay(2);
}

void adc_isr() interrupt 5
{
  unsigned int dat;
  unsigned char a;
  AUXR=0x40; //T1定时器不分频,1T的速度,设置EADCI中断禁止
  if(ch_times==10)
  {
    a=ADC_LOW2;//如果是dat=ADC_DATA<<8+ADC_LOW2&0x03;就会出错!莫名其妙!(在看到这的时候,忽然觉得好像是先算的8+ADC_LOW2&0x03···)
    a=a&0x03;
    dat=ADC_DATA*4+a;    //如果是dat=ADC_DATA<<2+a 。就他妈的乱窜,一直飚过1024!
    TR1=1;//开启定时器1 ,开启串口
    send_UART(ch+0x30);
    send_UART(':');
    print_uint(dat);
    delay(2);    //如果没有延时,串口就会混乱!
    TR1=0;//关闭定时器1
    ch_times=0;
    ch++;
    if(ch==4)
      ch=0;
  }
  ADC_CONTR=0x88+ch; //开启下一次转换
  ch_times++;          
  AUXR=0x10; //设置EADCI中断允许
}
void Long_delay()
{
  unsigned char i,j,k;
  for(k=0;k<50;k++)
    for(i=0;i<255;i++)
      for(j=0;j<255;j++)
        ;
}

完整资料打包:

STC51单片机学习笔记8-stc12c56串口显示AD(多路ad)资源-单片机文档类资源-CSDN下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fengyuzhe13

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值