/**************************************************************************************************
** TLC549 AD转换器 verilog代码
**************************************************************************************************/
moduleadc(
clk,
rst_n,
adc_clk,
adc_data,
adc_cs_n,
rAdc_data
)
inputclk // 50MHz输入时钟
inputrst_n // 复位信号,低有效
input adc_data // ADC芯片输出的数据
output adc_clk // ADC芯片输入时钟
output adc_cs_n // ADC芯片片选信号,低有效
output[7:0]rAdc_data
reg start_adc
/*************************************************************************************************/
reg[10:0] clk_cnt // clk计数器
wire cs_n_valid1
wire cs_high
wire cs_n_valid2
always @(posedge clk or negedge rst_n)
if (!rst_n)
begin clk_cnt <= 11'd0start_adc<=1end
else if (start_adc)
clk_cnt <= clk_cnt + 1'b1
/*
** 完成一次笑亏转换需要75+8*64+850+75+8*64=2024个时钟周期
** adc_cs_n建棚神立时间为75个时钟周期1.5us 转换时间保持高电平17us,即850个时钟周期
** adc_clk周期为系统时钟的链升亏64倍
*/
assign cs_n_valid1 = (clk_cnt >11'd74) &&(clk_cnt <= 11'd587)
assign cs_high= (clk_cnt >11'd587) &&(clk_cnt <= 11'd1437)
assign cs_n_valid2 = (clk_cnt >11'd1512) &&(clk_cnt <= 11'd2024)
//=================================================================================================
regrAdc_cs
always@(posedge clk or negedge rst_n)
if (!rst_n)
rAdc_cs <= 1'b1
else if (start_adc) begin
rAdc_cs <= 1'b0
if (cs_high)
rAdc_cs <= 1'b1
else
rAdc_cs <= 1'b0
end
assign adc_cs_n = rAdc_cs
//=================================================================================================
reg [5:0] div_cnt // 64分频计数器
reg rAdc_clk
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
div_cnt <= 6'd0
rAdc_clk <= 1'b0
end
else if ((cs_n_valid1) || (cs_n_valid2)) begin
div_cnt <= div_cnt + 1'b1
if (div_cnt <32)
rAdc_clk <= 1'b1
else
rAdc_clk <= 1'b0
end
assign adc_clk = rAdc_clk
//=================================================================================================
reg [7:0] rAdc_data
always @(posedge clk or negedge rst_n)
if (!rst_n)
rAdc_data <= 8'd0
else
case (clk_cnt)
11'd1513:rAdc_data[7] <= adc_data
11'd1577:rAdc_data[6] <= adc_data
11'd1641:rAdc_data[5] <= adc_data
11'd1705:rAdc_data[4] <= adc_data
11'd1769:rAdc_data[3] <= adc_data
11'd1833:rAdc_data[2] <= adc_data
11'd1897:rAdc_data[1] <= adc_data
11'd1961:rAdc_data[0] <= adc_data
default:rAdc_data[0] <= 1'b0
endcase
endmodule
DAT0 BIT P1.0CLK0 BIT P1.1
CS BIT P1.2
----------------------------------------------------------------------------
TLC549_ADC: 串物世行显示处理程序,结芦肢果存在A中罩哗肢
CLR A
CLR CLK0
CLR CS
MOV R6,#8
ADLOOP:
SETB CLK0
NOP
NOP
MOV C,DAT0
RLC A
CLR CLK0
NOP
DJNZ R6,ADLOOP
SETB CS
SETB CLK0
RET
#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
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)