用VHDL语言设计一个AD转换程序,AD转换芯片采用TLC549

用VHDL语言设计一个AD转换程序,AD转换芯片采用TLC549,第1张

这是个我一直用的代码,没问题。就是是VERILOG的,你自己改改吧

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

** 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.0

CLK0 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

}


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存