历史上的今天
返回首页

历史上的今天

今天是:2025年02月17日(星期一)

正在发生

2020年02月17日 | 基于STC15w单片机系列 自带的AD转换程序

2020-02-17 来源:51hei

15W系列是目前51单片机里面可用资源较多的处理器。一般的设计都可以用,本次分享下利用单片机自带的AD转换座一个数字电压表。显示用的LCD1602


单片机源程序如下:

#include<15w.H>

#include

#include

#include

#include

#define uchar unsigned char

#define uint unsigned int


typedef unsigned int WORD;


#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个时钟

unsigned char ch = 0;                        //ADC通道号


int time;

int time1;

int time2;

float p;


sbit RS = P5^5;   //定义端口 

sbit RW = P5^4;

sbit EN = P5^3;

sbit pwm=P2^7;

sbit key1 = P2^0;

sbit key2=P2^1;

sbit led=P5^1;

unsigned char ti[]={'0','1',0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};

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

uS延时函数,含有输入参数 unsigned char t,无返回值

unsigned char 是定义无符号字符变量,其值的范围是

0~255 这里使用晶振12M,精确延时请使用汇编,大致延时

长度如下 T=tx2+5 uS 

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

void DelayUs2x(unsigned char t)

{   

while(--t);

}

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

mS延时函数,含有输入参数 unsigned char t,无返回值

unsigned char 是定义无符号字符变量,其值的范围是

0~255 这里使用晶振12M,精确延时请使用汇编

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

void DelayMs(unsigned char t)

{

     

while(t--)

{

     //大致延时1mS

     DelayUs2x(245);

         DelayUs2x(245);

}

}

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

              判忙函数

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

bit LCD_Check_Busy(void) 

P4= 0xFF; 

RS=0; 

RW=1; 

EN=0; 

_nop_(); 

EN=1;

return (bit)(P4 & 0x80);

}

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

              写入命令函数

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

void LCD_Write_Com(unsigned char com) 

{  

while(LCD_Check_Busy()); //忙则等待

RS=0; 

RW=0; 

EN=1; 

P4= com; 

_nop_(); 

EN=0;

}

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

              写入数据函数

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

void LCD_Write_Data(unsigned char Data) 

while(LCD_Check_Busy()); //忙则等待

RS=1; 

RW=0; 

EN=1; 

P4= Data; 

_nop_();

EN=0;

}


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

                清屏函数

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

void LCD_Clear(void) 

LCD_Write_Com(0x01); 

DelayMs(5);

}

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

              写入字符串函数

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

void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) 

{     

if (y == 0) 

        {     

         LCD_Write_Com(0x80 + x);     //表示第一行

        }

else 

        {      

        LCD_Write_Com(0xC0 + x);      //表示第二行

        }        

while (*s) 

        {     

LCD_Write_Data( *s);     

s ++;     

        }

}

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

              写入字符函数

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

void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) 

{     

if (y == 0) 

        {     

        LCD_Write_Com(0x80 + x);     

        }    

else 

        {     

        LCD_Write_Com(0xC0 + x);     

        }        

LCD_Write_Data( Data);  

}

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

              初始化函数

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

void LCD_Init(void) 

{

   LCD_Write_Com(0x38);    /*显示模式设置*/ 

   DelayMs(5); 

   LCD_Write_Com(0x38); 

   DelayMs(5); 

   LCD_Write_Com(0x38); 

   DelayMs(5); 

   LCD_Write_Com(0x38);  

   LCD_Write_Com(0x08);    /*显示关闭*/ 

   LCD_Write_Com(0x01);    /*显示清屏*/ 

   LCD_Write_Com(0x06);    /*显示光标移动设置*/ 

   DelayMs(5); 

   LCD_Write_Com(0x0C);    /*显示开及光标设置*/

   }









void display(uint temp)                        //显示程序

{

   int A1,A2,A3;

   A1=temp/100;

   A2=temp%100/10;

   A3=temp%100%10/1;

   

            LCD_Write_Char(4,0,ti[A1]);

         LCD_Write_Char(5,0,ti[A2]);

         LCD_Write_Char(6,0,'.');

         LCD_Write_Char(7,0,ti[A3]);

         LCD_Write_Char(8,0,'V');



   }

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

软件延时

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

void Delay(WORD n)

{

    WORD x;


    while (n--)

    {

        x = 5000;

        while (x--);

    }

}

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

初始化ADC

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

void InitADC()

{

    P1ASF = 0x01;                   //设置P1口为AD口

    ADC_RES = 0;                    //清除结果寄存器

    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;

    Delay(2);                       //ADC上电并延时

}


void Timer0Init(void)                //200微秒@11.0592MHz

{

        AUXR |= 0x80;                //定时器时钟1T模式

        TMOD &= 0xF0;                //设置定时器模式

        TL0 = 0x5C;                //设置定时初值

        TH0 = 0xF7;                //设置定时初值

        TF0 = 0;                //清除TF0标志

        TR0 = 1;                //定时器0开始计时

        ET0=1;

        EA=1;


}



  


void main()                                        

{

        float i,j;

    P0M0 = 0x00;

    P0M1 = 0x00;

    P1M0 = 0x00;

    P1M1 = 0x00;

    P2M0 = 0x00;

    P2M1 = 0x00;

    P3M0 = 0x00;

    P3M1 = 0x00;

    P4M0 = 0x00;

    P4M1 = 0x00;

    P5M0 = 0x00;

    P5M1 = 0x00;


    LCD_Init(); 

    LCD_Clear();//清屏

    InitADC();                      //初始化ADC

    IE = 0xa0;                      //使能ADC中断

           Timer0Init();

        

        

         

  while(1){


           i=p*5;

         j=((i/256)*10);

    display(j);        

        DelayMs(500);  



  }



}

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

ADC中断服务程序

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

void adc_isr() interrupt 5 using 1

{

    ADC_CONTR &= !ADC_FLAG;         //清除ADC中断标志



     p=ADC_RES  ;       //读取高8位结果并发送到串口


//    SendData(ADC_LOW2);           //显示低2位结果

    

    ch = 0;           //切换到下一个通道

    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;

}



void tm0_isr() interrupt 1 

{


    time++;

        time1++;

        time2++;

        if(time1>100)

        time1=0;

        if(time1>50)

        pwm=1;

        else

        pwm=0;







        if(time>5000)

{        time=0;

        led=~led ;  }

}


推荐阅读

史海拾趣

AR RF/Microwave Instrumentation公司的发展小趣事

随着科技的不断发展,AR RF/Microwave Instrumentation意识到要想在激烈的市场竞争中保持领先地位,必须不断进行技术创新。公司投入大量资源进行研发,成功推出了一系列具有创新性的产品,如宽带高功率放大器、固态射频放大器等。这些产品不仅性能卓越,而且能够满足不同客户的需求,进一步巩固了公司在行业内的地位。

DBLECTRO公司的发展小趣事

近年来,随着物联网和大数据技术的快速发展,迪贝电子也积极探索将这些新技术应用于其产品中。公司推出了一系列智能气体检测和分析系统,这些系统可以通过物联网技术实现远程监控和数据传输,为用户提供更加便捷、高效的服务。同时,迪贝电子还利用大数据技术对用户的使用数据进行深度挖掘和分析,为产品的研发和优化提供了有力的支持。这些创新举措使得迪贝电子在气体检测及分析领域保持了领先地位,并为其未来的发展奠定了坚实的基础。

Excel-Display Corporation公司的发展小趣事

Excel-Display Corporation(以下简称EDC)成立于XX世纪初,由一群富有远见的电子工程师和企业家共同创立。他们看到了当时显示技术领域的巨大潜力,决定成立一家专注于研发和生产高质量显示器的公司。

EDC在创立初期就注重技术研发和产品质量,投入大量资金引进先进的生产设备和技术人才。经过几年的努力,EDC成功推出了一系列性能稳定、画质优良的显示器产品,逐渐在市场上崭露头角。

与此同时,EDC也积极开拓国际市场,与多家国际知名企业建立了合作关系。这些合作不仅为EDC带来了技术上的支持,也为其产品的国际化推广奠定了坚实的基础。

AXSEM公司的发展小趣事

随着全球环保意识的提高,EDC也积极响应号召,致力于绿色环保和可持续发展。公司投入大量资金研发节能、环保的显示器产品,并不断优化生产工艺以减少对环境的影响。

同时,EDC还积极参与各种环保公益活动,推动行业的绿色发展。这些举措不仅提升了公司的社会形象,也为公司的可持续发展奠定了坚实的基础。

EXXELIA Group公司的发展小趣事

EDC一直将产品质量视为企业的生命线。为了确保产品质量,公司建立了严格的质量管理体系,从原材料采购到生产过程中的每一个环节都进行严格的质量控制。

此外,EDC还注重售后服务,为客户提供全方位的技术支持和解决方案。这些举措让EDC赢得了客户的信赖和好评,也为公司赢得了更多的市场份额。

ENERGIZER公司的发展小趣事

ENERGIZER公司,作为全球领先的电池制造商,自1896年以来就以其技术革新引领着电池能源行业的发展。1896年,ENERGIZER发明了全球第一粒电池,这一创新性的产品为电子行业的发展奠定了基石。随着科技的不断进步,ENERGIZER的电池技术也在不断革新,以满足日益增长的电子设备需求。如今,ENERGIZER的电池已经广泛应用于各种电子设备中,从遥控器、手电筒到高端电子设备,其优良的品质和耐用的性能受到了全球消费者的广泛认可。

问答坊 | AI 解惑

基于嵌入式Web的电子交警系统

近年来智能交通系统发展迅速,它力图把先进的信息技术、通信技术、计算机技术、电子控制技术等高新技术有效地集成运用于整个交通运输管理体系,在大范围内建立起一种全方位的实时、准确、高教的交通运输综合管理系统。迄今为止,日本、美国、西欧、 ...…

查看全部问答>

开关电源原理分析

开关电源原理分析…

查看全部问答>

怎样看有没有使用ramdisk?

[code] u-boot> setenv bootargs root=/dev/mtdblock2 rw rootfstype=yaffs2 init=/linuxrc console=ttySAC0,115200 mem=64M u-boot>setenv bootcmd nand read 30000000 80000 300000\\;bootm 30000000 /code] 从上面的命令中可以看出来有没有 ...…

查看全部问答>

WinCE 保護 Registry

如何保護 wince的registry 不被registry editor修改??…

查看全部问答>

F13X系列信息区读写的问题?

   我在用F135的信息区(1000~10FF)保存系统参数时,按照魏小龙书上去做, 发现几个问题:   1)用例程可以解锁FALSH,并写入测试数据,并执行正常的加锁指令后,     用JTAG再次下载程序代码后,在程序 ...…

查看全部问答>

关于IAR写程序的问题?很奇怪,大家帮我看看!!

我用的是IAR Embedded Workbench IDE 3.42A 今天发现一个奇怪的小问题,程序如下: #include "msp430x16x.h" int main( void ) { int n,m,k,sum; n=2; m=3; sum=n+m; k=sum; } 调试的时候,发现k和sum在Watch窗口, ...…

查看全部问答>

关于MSP430与EEPROM通信之间的问题

关于MSP430与EEPROM通信之间的问题 小弟我刚刚接触MSP430, 准备以后就在这个方向学习下去, 还希望贵地的单片机大神们能给予点滴指导. 问题如下: 在与EEPROM进行IIC通信的时候, 向EEPROM写入字节的时候发现MSP430无法得到EEPROM的回应, 不知道问 ...…

查看全部问答>

大家谈谈DIY一个LED灯的经验,与大家分享

LED是照明 节能的方向,在不久的未来肯定会取代目前的许多照明系统,但是LED目前价格还是偏高的,国内国外生产LED的厂家很多,牌子各种各样,尤其国内搞LED生产的实在不少,DIY LED的时候大家首先要选取合适的LED,可以说LED的好坏关系到整个灯 ...…

查看全部问答>

MP3开发制作资料

MP3开发制作资料 [ 本帖最后由 用心思考 于 2012-9-4 14:09 编辑 ]…

查看全部问答>

FPGA程序在线调试与下载运行的区别

最近做一个新系统,仿真时序要求通过,最后通过AS下载到板子上拿到低温箱做低温试验时数据出现重写的问题,于是用JTAG在线调试想看看哪里数据有错误,但只要一接上JTAG,系统就完美运行,想请教一下这两者之间有啥区别吗,这个问题该如何解决呢?…

查看全部问答>