AT89C51读取TLC0832的AD转换值的程序

AT89C51读取TLC0832的AD转换值的程序,第1张

#include<reg51.h>

#include<intrins.h>

#include <absacc.h>

#include <math.h>

#define uchar unsigned char

#define uint unsigned int

#define BUSY 0x80 // LCD

#define DATAPORT P0 // 参

sbit LCM_RS=P2^0// 数

sbit LCM_RW=P2^1// 配

sbit LCM_EN=P2^2// 置

sbit reset=P3^7

sbit bj=P3^0

sbit time_start=P3^2

sbit time_over=P3^3

sbit EOC=P2^3//OE=1,输出转换得到的数据;OE=0,输出数据线呈高阻状态。

sbit START=P2^4//START为转换启动信号。当START上跳沿时,所有内部寄存器清零;下跳沿时,开始进行A/D转换;在转换期间,ST应保持低电平。

sbit OE =P2^5//EOC为转换结束信号。当EOC为高电平时,表明转换结束;否则,表明正在进行A/D转换。

sbit AD_ALE=P2^6//ad 转换

sbit CLK=P2^7

unsigned long int getdata

void ADC0808()

uchar code str0[]={"Throb: "}

uchar code str1[]={"Time:" }

void delay(uint k)//延时

void lcd_wait()//LCM忙检测

void WriteCommandLCM(uchar WCLCM,uchar BusyC)//写指令到LCM子函数

void WriteDataLCM(uchar WDLCM)//写数据到LCM子函数

void DisplayOneChar(uchar X,uchar Y,uchar DData)//显示指定坐标的一个字符子函数

void DisplayListChar(uchar X,uchar Y,uchar code *DData)//显示指定坐标的一串字符子函数

void initLCM( void)//LCD初始化子程序

uchar m=0

uint counter=0,counter_0=0

uchar second_0=0

uint totle_1

float totle_0

void main()

{

uint i,j,k

TMOD=0x02

TL0=0xfe

TH0=0xfe//AD频率

TR0=1

ET0=1

TH1=0x60

TL1=0x78//定时5ms

ET1=1

PX1=1

EX0=1

IT0=1

EX1=1

IT1=1

EA=1

delay(100)//系统延时500ms启动

initLCM( )

WriteCommandLCM(0x01,1)//清显示屏

DisplayListChar(0,0,str0)

DisplayListChar(0,1,str1)

AD_ALE=0

START=0

OE=0

while(1)

{

ADC0808()

//v=getdata

if(getdata>=300&&getdata<400)

{

delay(60)

if(getdata>=300&&getdata<400)

{

counter++

if(m==1)

{

PT1=1

TR1=1

m=0

}

}

}

// DisplayOneChar(7,0,0x30+getdata/100)

// DisplayOneChar(8,0,0x30+getdata%10)

// DisplayOneChar(9,0,0x30+getdata/10%10)

if(counter<100)

{

DisplayOneChar(8,0,0x30+counter/10)

DisplayOneChar(9,0,0x30+counter%10)

}

if(counter>=100)

{

DisplayOneChar(7,0,0x30+counter/100)

DisplayOneChar(8,0,0x30+counter/10%10)

DisplayOneChar(9,0,0x30+counter%10)

}

if(second_0>59)

{ second_0=0}

DisplayOneChar(7,1,0x30+second_0%10)

DisplayOneChar(6,1,0x30+second_0/10)

if(reset==0)

{

counter=0

counter_0=0

second_0=0

totle_0=0

totle_1=0

bj=0

}

totle_1=(int)totle_0

DisplayOneChar(9,1,0x30+totle_1/100)

DisplayOneChar(10,1,0x30+totle_1/10%10)

DisplayOneChar(11,1,0x30+totle_1%10)

DisplayOneChar(12,1,'/')

DisplayOneChar(13,1,'m')

DisplayOneChar(14,1,'i')

DisplayOneChar(15,1,'n')

if(totle_1>120)

{

for(k=0k<100k++)

{

for(i=0i<25i++)

bj=0

for(j=0j<25j++)

bj=1

if(reset==0)

{

counter=0

counter_0=0

second_0=0

totle_0=0

totle_1=0

bj=0

}

}

}

if(totle_1<40&&totle_1>0)

{

for(k=0k<100k++)

{

for(i=0i<25i++)

bj=0

for(j=0j<25j++)

bj=1

if(reset==0)

{

counter=0

counter_0=0

second_0=0

totle_0=0

totle_1=0

bj=0

}

}

}

}

}

/****************外部中断0*******************/

void intr0_int() interrupt 0 using 3

{

m=1

}

/****************外部中断1*******************/

void intr1_int() interrupt 2 using 3

{

PT1=0

TR1=0

totle_0=(float)counter/second_0*60

}

/****************定时中断0*******************/

void timer0_int() interrupt 1 using 1

{

CLK=~CLK

}

/****************定时中断1*******************/

void timer1_int() interrupt 3 using 2

{

TH1=0x60

TL1=0x78

counter_0++

if(counter_0==190)

{

counter_0=0

second_0++

}

}

/*********延时K*1ms,12.000mhz**********/

void delay(uint k)

{

uint i,j

for(i=0i<ki++)

for(j=0j<100j++)

}

/***********lcm内部等待函数*************/ //从这里到AD前面都是 LCD的驱动程序

void lcd_wait(void)

{

DATAPORT=0xff//读LCD前若单片机输出低电平,而读出LCD为高电平,则冲突,Proteus仿真会有显示逻辑黄色

LCM_EN=1

LCM_RS=0

LCM_RW=0

LCM_RW=1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

while(DATAPORT&BUSY)

{ LCM_EN=0

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

LCM_EN=1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

}

LCM_EN=0

}

/**********写指令到LCM子函数************/

void WriteCommandLCM(uchar WCLCM,uchar BusyC)

{

if(BusyC)

lcd_wait()

DATAPORT=WCLCM

LCM_RS=0// 选中指令寄存器

LCM_RW=0

LCM_RW=0// 写模式

LCM_EN=1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

LCM_EN=0

}

/**********写数据到LCM子函数************/

void WriteDataLCM(uchar WDLCM)

{

lcd_wait( )//检测忙信号

DATAPORT=WDLCM

LCM_RS=1// 选中数据寄存器

LCM_RW=0// 写模式

LCM_EN=1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

LCM_EN=0

}

/****显示指定坐标的一个字符子函数****/

void DisplayOneChar(uchar X,uchar Y,uchar DData)

{

Y&=0x01

X&=0x0f

if(Y)

X|=0x40//若y为1(显示第二行),地址码+0X40

X|=0x80//指令码为地址码+0X80

WriteCommandLCM(X,1)

WriteDataLCM(DData)

}

/*******显示指定坐标的一串字符子函数*****/

void DisplayListChar(uchar X,uchar Y,uchar code *DData)

{

uchar ListLength=0

Y&=0x01

X&=0x0f

while(X<16)

{

DisplayOneChar(X,Y,DData[ListLength])

ListLength++

X++

}

}

/**********LCM初始化子函数***********/

void initLCM( )

{

LCM_EN=0

DATAPORT=0

delay(15)

WriteCommandLCM(0x38,0)//三次显示模式设置,不检测忙信号

delay(5)

WriteCommandLCM(0x38,0)

delay(5)

WriteCommandLCM(0x38,0)

delay(5)

WriteCommandLCM(0x38,1)//8bit数据传送,2行显示,5*7字型,检测忙信号

WriteCommandLCM(0x08,1)//关闭显示,检测忙信号

WriteCommandLCM(0x01,1)//清屏,检测忙信号

WriteCommandLCM(0x06,1)//显示光标右移设置,检测忙信号

WriteCommandLCM(0x0c,1)//显示屏打开,光标不显示,不闪烁,检测忙信号

}

/*****************读电压**********************/ //AD转换的驱动程序,就这一部分

void ADC0808()

{

AD_ALE=1//锁存输入通道

_nop_()_nop_()

START=0//驱动AD转换

START=1

AD_ALE=0

_nop_()_nop_()

START=0//保持低电平

while(EOC==0)//等待AD转换结束

// TR0=0//AD转换结束时先停止T0

P1=0xff

OE=1//转换结束,允许AD值输出

getdata=P1//读出AD值.

OE=0//禁止输出

getdata=(unsigned long int)((unsigned long int)(getdata*500)/255)//转换成电压

// TR0=1//重新启动T0

}

可以这样,DAC0832是根据输入的数字量,输出相应的模拟量,锯齿波是有规律的模拟量。

单片机内部程序可以通过算法(规律计算或数组),定时生成一个数字量发送到DAC0832,使其输出相应模拟量,即可。

例如锯齿波是从0~3V,将0~3V分为若干个点(分辨率),定时输出每个点的数字量。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7782825.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-09
下一篇 2023-04-09

发表评论

登录后才能评论

评论列表(0条)

保存