#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
}
单片机与 TLC0832 通卖消过 4 根线进行通信,时钟 CLK,片选 CS,输入 DI,输出 DO。更完整的描述可以参考 TLC0832 数据手册,以下为如何驱动 TLC0832 。
, 时钟占空比
,建立时间,在 CLK 上升沿前,CS 低电平或则 TLC0832 数据有效的时间。
,数据中雀知保持时间,CLK 上升沿后,TLC0832 数据保持有效的最低时间。
将这些参数值配合上时序图理解,也就是
RT-Thread 环境下的驱动参考:
其中的 CS, CLK, DI, DO 使用的是 STM32 的位带 *** 作。
我在实际使用时,用逻辑分析仪测量过 rt_pin_write() 需要 3.25us 的时间, rt_pin_read() 需要 3.5us 的时间。而位带 *** 作的 write 需要 0.25us,read *** 作时间没测出来岁绝,但肯定很小,因此使用位带 *** 作能够更好的控制驱动。
位带 *** 作的驱动文件可以参考:
TLC0832是8位A/D转换器,要在数码管上显示,需要几个数码管,这要看显示几位数,即模余搭拟信号的最大电压是5V,转换成数字量是255。所以,要显示数芓量,要用3位数码管。要显模拟电压,显示一位整数,两位小数,即0.00~5.00,知碰也竖猛拿同样需要3位数码管。TLC0832的特性如下
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)