stc12C5A60S2内部AD应用.docx

上传人:b****5 文档编号:6946605 上传时间:2023-01-13 格式:DOCX 页数:15 大小:27.50KB
下载 相关 举报
stc12C5A60S2内部AD应用.docx_第1页
第1页 / 共15页
stc12C5A60S2内部AD应用.docx_第2页
第2页 / 共15页
stc12C5A60S2内部AD应用.docx_第3页
第3页 / 共15页
stc12C5A60S2内部AD应用.docx_第4页
第4页 / 共15页
stc12C5A60S2内部AD应用.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

stc12C5A60S2内部AD应用.docx

《stc12C5A60S2内部AD应用.docx》由会员分享,可在线阅读,更多相关《stc12C5A60S2内部AD应用.docx(15页珍藏版)》请在冰豆网上搜索。

stc12C5A60S2内部AD应用.docx

stc12C5A60S2内部AD应用

stc12C5A60S2内部AD应用

系统说明:

本人想用STC12C5A60S2自带的A/D对电源电压进行检测(暂定3.3V),晶振:

12M,电压从P1.0口输入,检测后的电压值在1602上进行显示,附上硬件大致原理图,硬件部分是照STC12C5A60S2芯片资料上设计,大家看看有错没?

硬件原理简图(原文件名:

clip_image001.gif)

程序的A/D部分也是从官网资料上搬下来的,只自己稍微改了一下对读取到的A/D转换结果的数据处理,液晶部分是前阵子写的搬过来的。

大家帮我看看哪出问题了?

程序如下:

#include

#include"intrins.h"

#defineucharunsignedchar

#defineuintunsignedint

ucharVo;        //A/D转换后换算的电压值

/*DeclareSFRassociatedwiththeADC*/

sfrADC_CONTR  =  0xBC;        //ADCcontrolregister

sfrADC_RES    =  0xBD;        //ADChigh8-bitresultregister

sfrADC_RESL  =  0xBE;            

//sfrADC_LOW2  =  0xBE;        //ADClow2-bitresultregister

sfrP1ASF    =  0x9D;        //P1secondaryfunctioncontrolregister  

                                    

/*DefineADCoperationconstforADC_CONTR*/

#defineADC_POWER  0x80        //ADCpowercontrolbit

#defineADC_FLAG  0x10        //ADCcompleteflag    模数转换结束标志位

#defineADC_START  0x08        //ADCstartcontrolbit      模数转换启动控制位

//转换速度控制位SPEED0和SPEED1,共四种状态,对应四种转换速度

#defineADC_SPEEDLL0x00        //540clocks

#defineADC_SPEEDL  0x20        //360clocks

#defineADC_SPEEDH  0x40        //180clocks

#defineADC_SPEEDHH0x60        //90clocks

uchartCount;

sbitRS=P0^4;

sbitRW=P0^5;

sbitEN=P0^6;

voidDelayMS(uintms)

{

  uinti;

  while(ms--)

  {

      for(i=0;i<120;i++);

  }

}

/*----------------------------

Softwaredelayfunction

----------------------------*/

voidDelay(uintn)

{

  uintx;

  while(n--)

  {

      x=5000;

      while(x--);

  }

}

/*----------------------------

InitialADCsfr

----------------------------*/

voidInitADC()

{

  P1ASF=0x01;            //选择P1.0作为A/D输入通道

  ADC_RES=0;              //清0

  ADC_CONTR=ADC_POWER|ADC_SPEEDLL;  //0x10|0x00=0x10:

开电源和设置A/D转换速度

  Delay

(2);                //ADCpower-onanddelay

}

/*----------------------------

GetADCresult

----------------------------*/

ucharGetADCResult(ucharch)

{

  ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch|ADC_START;//0x00|0x00|ch|0x08:

选择A/D输入通道,开始A/D转换

  _nop_();      //Mustwaitbeforeinquiry,

  _nop_();    //设置ADC_CONTR寄存器后需加4个CPU时钟周期的延时,才能保证值被写入ADC_CONTR寄存器

  _nop_();

  _nop_();

  while(!

(ADC_CONTR&ADC_FLAG));//Waitcompleteflag

  ADC_CONTR&=~ADC_FLAG;      //CloseADC

  Vo=ADC_RES*5*10/256;            //ReturnADCresult(为显示整数,这里将电压值扩大了十倍)

  returnVo;

}

ucharRead_LCD_State()

{

    ucharstate;

    RS=0;

    RW=1;

    EN=1;

    DelayMS

(1);

    state=P2;

    EN=0;

    DelayMS

(1);

    returnstate;                      

}

voidLCD_Busy_Wait()

{

      while((Read_LCD_State()&0x80)==0x80);

    DelayMS(5);

}

voidWrite_LCD_Data(uchardat)    //写数据到1602

{

      LCD_Busy_Wait();

    RS=1;

    RW=0;

    EN=0;

    P2=dat;

    EN=1;

    DelayMS

(1);

    EN=0;

}

voidWrite_LCD_Command(ucharcmd)  //写命令

{

      LCD_Busy_Wait();

    RS=0;

    RW=0;

    EN=0;

    P2=cmd;

    EN=1;

    DelayMS

(1);

    EN=0;

}

voidInit_LCD()    //1602  初始化

{

      Write_LCD_Command(0x38);

    DelayMS

(1);

    Write_LCD_Command(0x01);      //清屏

    DelayMS

(1);

    Write_LCD_Command(0x06);      //

    DelayMS

(1);

    Write_LCD_Command(0x0c);

    DelayMS

(1);

}

voidSet_LCD_POS(ucharp)

{

      Write_LCD_Command(p|0x80);

}

voidDisplay_LCD_String(ucharp,uchar*s)//1602显示

{

      uchari;

    Set_LCD_POS(p);

    for(i=0;i<16;i++)

    {

          Write_LCD_Data(s);

          DelayMS

(1);  

    }

}

voidFormat_DateTime(uchard,uchar*a)

{

      a[0]=d/10+'0';

      a[1]=d%10+'0';

}

//写入液晶第二行

voiddisplay(ucharadd,uchardate)

{

    ucharshi,ge;

    shi=date/10+'0';                    

    ge=date%10+'0';

    Write_LCD_Command(0x80+0x40+add);

    Write_LCD_Data(shi);

    Write_LCD_Data(ge);

}

//写入液晶第一行

voiddisplay1(ucharadd,uchardate)

{

    ucharshi,ge;

    shi=date/10;

    ge=date%10;

    Write_LCD_Command(0x80+add);

    Write_LCD_Data(0x30+shi);  //0x30即48(十进制)对应的ASCAII码为字符‘0’

    Write_LCD_Data(0x30+ge);

}

voidmain()

{

    Init_LCD();            

  InitADC();

                

    while

(1)

    {

        GetADCResult(0);

        Display_LCD_String(0,"dianya:

");

        display1(7,Vo);

        Display_LCD_String(9,"V    ");

        DelayMS(1000);

    }

}

 

程序二:

*文件名:

AD_CAIYANG.C

*功能:

使用AD采集电压显示在LCD

*说明:

转自网络,本人验证通过

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

#include

#defineuintunsignedint

#defineucharunsignedchar

sbitCS=P2^0;//LCD12864串行通信片选

sbitSID=P2^1;//LCD12864串行通信数据口

sbitSCLK=P2^2;//LCD12864串行通信同步时钟信号

sbitPSB=P2^5;//LCD12864并/串选择:

H并行L串行

unsignedinttemp1,sh1,ge1,n1,m1;

unsignedcharad_result_data[10];//AD转换高八位

unsignedcharad_result_low2[10];//AD转换低八位

unsignedcharad_result_total[10];//AD转换总十位

unsignedcharad_average_result;//AD转换十次的平均值

unsignedcharAin,Vin;

unsignedcharb,t,R;

chartp=0;

unsignedcharcodema1[6]={0xb5,0xe7,0xd1,0xb9,0xa1,0xc3};//电压:

unsignedcharcodema2[]={"."};

ucharcodedisp1[]={"提示:

按1键进入"};

ucharcodedisp2[]={"功能选择界面."};

unsignedcharcodenum0[]={0xa3,0xb0};

unsignedcharcodenum1[]={0xa3,0xb1};

unsignedcharcodenum2[]={0xa3,0xb2};

unsignedcharcodenum3[]={0xa3,0xb3};

unsignedcharcodenum4[]={0xa3,0xb4};

unsignedcharcodenum5[]={0xa3,0xb5};

unsignedcharcodenum6[]={0xa3,0xb6};

unsignedcharcodenum7[]={0xa3,0xb7};

unsignedcharcodenum8[]={0xa3,0xb8};

unsignedcharcodenum9[]={0xa3,0xb9};

//-------模块延时程序----------------------------1ms

voiddelay1ms(uintdelay1ms)//STC11F60XE,22.1184M,延时1ms

{

uinti,j;

for(;delay1ms>0;delay1ms--)

for(i=0;i<7;i++)

for(j=0;j<210;j++);

}

voiddelay(uintdelay)//STC11F60XE,22.1184M,延时170us

{

uinti,j;

for(;delay>0;delay--)

for(i=0;i<124;i++);

for(j=0;j<124;j++);

}

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

AD转换程序

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

voidAD_initiate()//初始化函数

{

ES=0;

TMOD=0x21;//定时计数器方式控制寄存器,"自动重装,16位计数器".

SCON=0x50;//串行控制寄存器,方便在串口助手那观察

TH1=0xfa;

TL1=0xfa;

TR1=1;

}

voidADC_Power_On()//AD转换电

{

ADC_CONTR|=0x80;

delay(5);//必要的延时

}

voidget_ad_result()//取AD结果函数,它是十位AD转换,每十次平均,最后取低八位作为AD采样数据

{

uinti,q=0;

for(i=0;i<10;i++)

{

tp=0;

ADC_RES=0;//高八位数据清零,STC12C5A60S2AD数据寄存名与STC12C54××系列不同

ADC_RESL=0;//低两位清零

ADC_CONTR|=0x08;//启动AD转换

while(!

tp)//判断AD转换是否完成

{

tp=0x10;

tp&=ADC_CONTR;

}

ADC_CONTR&=0xe7;

ad_average_result=ADC_RES;

q=q+ad_average_result;

}

ad_average_result=q/10;

//ad_average_result=ad_average_result*4*5000/1024;

}

/************************AD转换结束***********************/

 

voidsend_ad_result()//取AD结果函数发送到串口,方便调试

{

SBUF=n1;

while(TI==0);

TI=0;

delay1ms(100);

//SBUF=R>>4;

}

//---------------------电压采样程序-------------------------

voidcaiyangP10()//测电压

{

P1M0|=0x01;//设P1_0为开漏模式如:

P1_0=#00000000B

P1M1|=0x01;

ADC_CONTR=0xe0;//设置P1.0为输入AD转换口

delay

(2);

get_ad_result();//取转换数据

Vin=ad_average_result;

R=Vin;

}

/*-----------写控制字到LCD12864------------*/

voidwrite_cmd(ucharcmd)

{

uchari;

uchari_data;

i_data=0xf8;//命令控制字:

11111000写指令11111010写数据11111100读状态11111110读数据

CS=1;//片选置高,才能进行读写操作

SCLK=0;

/*----------写命令控制字-----------------*/

for(i=0;i<8;i++)//循环八次,每次读取一位数据

{

SID=(bit)(i_data&0x80);//bit表示取其最高位

SCLK=0;

SCLK=1;//正跳变写入指令

i_data=i_data<<1;//左移一位

}

/*---------------------------------------*/

/*----------写指令高四位-----------------*/

i_data=cmd;

i_data=i_data&0xf0;//把低四位置0

for(i=0;i<8;i++)//循环八次,每次读取一位数据

{

SID=(bit)(i_data&0x80);//bit表示取其最高位

SCLK=0;

SCLK=1;//正跳变写入指令

i_data=i_data<<1;//左移一位

}

/*---------------------------------------*/

/*----------写指令低四位-----------------*/

i_data=cmd;

i_data=i_data<<4;//左移四位,把低四位的数据移到高四位,再把低四位置0

for(i=0;i<8;i++)//循环八次,每次读取一位数据

{

SID=(bit)(i_data&0x80);//bit表示取其最高位

SCLK=0;

SCLK=1;//正跳变写入指令

i_data=i_data<<1;//左移一位

}

/*-----------------------------------------*/

CS=0;//把片选置低

delay1ms(5);//延时是因为没有进行忙检测,适当的延时可以不进行忙检测

}

/*-----------------------------------------*/

/*------------写数据到LCD12864-------------*/

voidwrite_dat(uchardat)

{

uchari;

uchari_data;

i_data=0xfa;

CS=1;

for(i=0;i<8;i++)

{

SID=(bit)(i_data&0x80);

SCLK=0;

SCLK=1;

i_data=i_data<<1;

}

i_data=dat;

i_data=i_data&0xf0;

for(i=0;i<8;i++)

{

SID=(bit)(i_data&0x80);

SCLK=0;

SCLK=1;

i_data=i_data<<1;

}

i_data=dat;

i_data=i_data<<4;

for(i=0;i<8;i++)

{

SID=(bit)(i_data&0x80);

SCLK=0;

SCLK=1;

i_data=i_data<<1;

}

CS=0;

delay1ms(5);

}

/*-----------------------------------------*/

/*--------------显示坐标-------------------*/

voidlcd_pos(ucharx,uchary)//汉字显示坐标,x为哪一行,y为哪一列

{

ucharpos;

if(x==0)

x=0x80;//第一行

elseif(x==1)

x=0x90;//第二行

elseif(x==2)

x=0x88;//第三行

elseif(x==3)

x=0x98;//第四行

pos=x+y;//显示哪一行(总共有4行)哪一竖(总共有8竖,每16列为1竖)

write_cmd(pos);

}

/*-----------------------------------------*/

/*--------------显示8个汉字-------------------*/

voiddisp_hanzi(ucharcode*chn)

{

uchari;

write_cmd(0x30);//基本指令操作方式

for(i=0;i<16;i++)//16列*8个汉字=128(刚好)

write_dat(chn[i]);

}

/*-----------------------------------------*/

/*--------------显示数字-------------------*/

voiddisp_num(ucharcode

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1