430单片机驱动TLV5618

430单片机驱动TLV5618,第1张

/******TLV5618***********/

#define TDIRP3DIR //2.7-5.5V低功耗双12位,带掉电D/A转换器

#define CS_LP3OUT &=~BIT0

#define CS_HP3OUT |= BIT0

#define SCLK_H P3OUT |= BIT1

#define SCLK_L P3OUT &=~BIT1

#define DIN_H P3OUT |= BIT2

#define DIN_L P3OUT &=~BIT2

/*******TLV5618转换程序*********/

void func(uint temp,uint contr) //编程位 R1SPD PWR R0

{ //寄存器选择位R1 R0

uchar i // 0 0 写数据到DACB和BUFFER

uint aa // 0 1 写数据到BUFFER

aa=temp | contr // 1 0 写数据到DACA和用BUFFER内容更新DACB

SCLK_H

CS_L //SPD 速度控制位 SPD=1高速,SPD=0低速

//发送16位数据

for(i=0i<16i++) //喊悄简PWR 电源控制位 PWR=1掉电,PWR=0正常 *** 作

{ //上运轿电时SPD=0,PWR=0(低速模式、正常 *** 作)

if(aa &0x8000) DIN_H //contr=0x8000 选择A通道,contr=0x0000选择B通道

else DIN_L

aa=aa<<1

SCLK_L

_NOP()

SCLK_H

_NOP()

}

CS_H

return

}

func(Ampn<<1,0x8000)

我从程序直接复制过来的,参考参考吧!!!很清晰郑裤。

PID调节器主控部分包括以下几个部分:单锋斗片机部分、A/D转换部分、D/A转换部分、稳压部分、数字输入输出部分以及串口通信部分。

D1:内部设定点信号灯

S1:内部设定点和外部设定点转换开关

D2:手动信号灯

S2:手动自动转换开关

D3:实际值X显示信号灯

D4:设定值W显示信号灯

S3:参数修改以及实际值和设定值显示转换开关

D5:超过限定值信并贺号灯

D6:低于限定值信号灯

S4:设定值增加按钮

S5:设定值减少按钮

S6:修改手动变量按钮

S7:修改手动变量按钮

附录[1] 主程序—MAIN.C

#include"adconver.h"

#include"delay.h"

#include"dis7281.h"

#include"STC12C5410AD.H"

#include"main.H"

#include"subkey0.h"

#include"subkey1.h"

#include"subkey2.h"

#include"subkey3.h"

#include"subkey4.h"

#include"subkey5.h"

#include"subkey6.h"

bit insertsetframe=1//内部设定标志位

bit handframe=1//手动设定标志位

bit improvedisframe=0//实际值标志位

bit shineframe=0//判断是不是第一次开机停止4LED的闪烁

bit canshuframe=0x00//参数标志位

unsigned char circleframe=0x00//参数循环变量

unsigned char channelframe=0x00//通道标志位

unsigned char ledframe=0xfc//LED灯管状态

unsigned char times=0x00//记数位

unsigned char readkey

unsigned int setvalue=0x00//设定值

unsigned char outputvalue=0x00//输出值

unsigned int limup=0x270f//实际值上限

unsigned int limdown=0x00//实际值下限

unsigned int a1=0x270f//上限报警值

unsigned int a2=0x00//下限报警值

unsigned int cp=0x00//P参数

unsigned int ci=0x00//I参数

unsigned int cd=0x00//D参数

unsigned char led[6]//LED值公共

main()

{

unsigned int tmr

unsigned char keynumber

for (tmr=0tmr<0xfffftmr++)

write7281(0x12,0x80)

write7281(0x10,0xf0)

write7281(0x00,0xc8)

write7281(0x14,0x1b)

write7281(0x14,0x2e)

write7281(0x15,0x30)

write7281(0x15,0x40)

write7281(0x15,0x50)

write7281(0x06,0xfc)

while(1)

{

while(!key)

{

keynumber=read7281(0x13)

switch(keynumber)

{

case 0x00:

subkey0()break

case 0x01:

subkey1()break

case 0x02:

subkey2()break

case 0x03:

subkey3()break

case 0x04:

subkey4()break

case 0x05:

subkey5()break

case 0x06:

subkey6()break

default:

break

}

}

}

}

附录绝基派[2] S1模块的程序—SUBKEY0.C

#include"delay.h"

#include"dis7281.h"

#include"STC12C5410AD.H"

#include"main.H"

#include"subkey0.h"

void subkey0()

{

if(insertsetframe==1)

{

insertsetframe=0

ledframe|=0x01

write7281(0x06,ledframe)

}

else

{

insertsetframe=1

ledframe&=0xfe

write7281(0x06,ledframe)

}

}//更改内部设定和外部设定的状态,并将相应的状态位进行更改,并更改状态灯

附录[3] S2模块的程序—SUBKEY1.C

#include"delay.h"

#include"dis7281.h"

#include"STC12C5410AD.H"

#include"main.H"

#include"subkey1.h"

void subkey1()

{

if(handframe==1)

{

handframe=0

ledframe|=0x02

write7281(0x06,ledframe)

}

else

{

handframe=1

ledframe&=0xfd

write7281(0x06,ledframe)

}

} //更改手动自动状态,改变相应的状态位,更改相应的状态灯

附录[4] S3模块的程序—SUBKEY2.C

#include"delay.h"

#include"dis7281.h"

#include"STC12C5410AD.H"

#include"main.H"

#include"subkey2.h"

#include"adconver.h"

#include"subkey0.h"

#include"subkey1.h"

#include"hdconver.h"

#include"subkey3.h"

#include"subkey4.h"

#include"pid.h"

#include"daconver.h"

void subkey2()

{

if(shineframe==0)

{

write7281(0x10,0xff)

shineframe=1

}

else

{

skey2()

}

}

void skey2(void)

{ // canshuframe=1

write7281(0x18,0x17)

switch(circleframe)

{

case 0x00: ledframe|=0x0c

write7281(0x06,ledframe)

circleframe+=1

hdconver(limup)//4LED显示上限值

dis4led()

write7281(0x14,0x41)

write7281(0x14,0x5C)//写入2LEDHI

break

case 0x01: circleframe+=1

hdconver(limdown)//4LED显示下限值

dis4led()

write7281(0x14,0x40)

write7281(0x14,0x5d)//写入2LEDLO

break

case 0x02: circleframe+=1

hdconver(a1)//4LED显示上限报警

dis4led()

write7281(0x14,0x41)

write7281(0x15,0x5a)//写入2LEDA1

break

case 0x03: circleframe+=1

hdconver(a2)//4LED显示下限报警

dis4led()

write7281(0x14,0x42)

write7281(0x15,0x5a)//写入2LEDA2

break

case 0x04: circleframe+=1

hdconver(cp)//4LED显示P参数

dis4led()

write7281(0x14,0x4e)

write7281(0x14,0x5f)//写入2LEDP

break

case 0x05: circleframe+=1

hdconver(ci)//4LED显示I参数

dis4led()

write7281(0x14,0x41)

write7281(0x14,0x5f)//写入2LEDI

break

case 0x06: circleframe+=1

hdconver(cd)//4LED显示D参数

dis4led()

write7281(0x15,0x4d)

write7281(0x14,0x5f)//写入2LEDI

break

case 0x07: improvedisframe=0

ledframe=(ledframe|0x08)&0xfb

circleframe+=1

adconver()

write7281(0x14,0x40)

write7281(0x14,channelframe)

write7281(0x06,ledframe)

break

case 0x08: improvedisframe=1

ledframe=(ledframe|0x04)&0xf7

circleframe=0

pidcf()

daconver()

hdconver(setvalue)

dis4led()

write7281(0x06,ledframe)

break

default:

break

}

}//按相应的S3改变不同的参数

附录[5] S4模块的程序—SUBKEY3.C

#include"delay.h"

#include"dis7281.h"

#include"STC12C5410AD.H"

#include"main.H"

#include"subkey3.h"

#include"subkey2.h"

#include"hdconver.h"

void subkey3()

{

switch(circleframe)

{

case 0x01:limup=add1(limup)

break

case 0x02:limdown=add1(limdown)

break

case 0x03:a1=add1(a1)

break

case 0x04:a2=add1(a2)

break

case 0x05:cp=add1(cp)

break

case 0x06:ci=add1(ci)

break

case 0x07:cd=add1(cd)

break

case 0x00:setvalue=add1(setvalue)

break

default:

break

}

}

unsigned int add1(unsigned int value)

{

ledframe|=0x20//关掉下限报警

write7281(0x06,ledframe)

if(value==9999)

{

ledframe&=0xef//打开上限报警灯

write7281(0x06,ledframe)

write7281(0x06,ledframe)

}

else

{

value+=1

}

hdconver(value)

dis4led()

return(value)

}

附录[6] S5模块的程序—SUBKEY4.C

#include"delay.h"

#include"dis7281.h"

#include"STC12C5410AD.H"

#include"main.H"

#include"subkey4.h"

#include"subkey2.h"

#include"hdconver.h"

void subkey4()

{

switch(circleframe)

{

case 0x01:limup=sub1(limup)

break

case 0x02:limdown=sub1(limdown)

break

case 0x03:a1=sub1(a1)

break

case 0x04:a2=sub1(a2)

break

case 0x05:cp=sub1(cp)

break

case 0x06:ci=sub1(ci)

break

case 0x07:cd=sub1(cd)

break

case 0x00:setvalue=sub1(setvalue)

break

default:

break

}

}

unsigned int sub1(unsigned int value)

{

ledframe|=0x10//关掉上限报?

write7281(0x06,ledframe)

if(value==0)

{

ledframe&=0xdf//打开上限报警灯

write7281(0x06,ledframe)

}

else

{

value-=1

}

hdconver(value)

dis4led()

return(value)

}

附录[7] S6模块的程序—SUBKEY5.C

#include"delay.h"

#include"dis7281.h"

#include"STC12C5410AD.H"

#include"main.H"

#include"subkey5.h"

#include"hdconver.h"

void subkey5()

{

if(improvedisframe==0)

{

channelframe=0x00

write7281(0x15,0x40)

write7281(0x15,0x50)//若现在状态为实际值,则改变通道状态并显示现在状态为00

}

else

{

if(handframe==1)

{

ledframe|=0x10//关掉上限报警灯

write7281(0x06,ledframe)

if(outputvalue==0x00)

{

ledframe&=0xdf//打开下限报警灯

write7281(0x06,ledframe)

}

else

{

outputvalue-=1

hdconver2(outputvalue)

}

dis2led()

}

}

}

附录[7] S7模块的程序—SUBKEY6.C

#include"delay.h"

#include"dis7281.h"

#include"STC12C5410AD.H"

#include"main.H"

#include"subkey6.h"

#include"hdconver.h"

void subkey6()

{

if(improvedisframe==0)

{

channelframe=0x01

write7281(0x15,0x41)

write7281(0x15,0x50)//若现状态为实际值,则2LED显示为01

}

else

{

if(handframe==1)

{

ledframe|=0x20//关掉下限报警灯

write7281(0x06,ledframe)

if(outputvalue==99)

{

ledframe&=0xef//打开上限报警档?

write7281(0x06,ledframe)

}

else

{

outputvalue+=1

hdconver2(outputvalue)

}

}

dis2led()

}

}

附录[8] A/D转换模块的程序—ADCONVER.C

#include"STC12C5410AD.H"

#include"adconver.H"

#include"delay.h"

#include"main.h"

#include"dis7281.h"

#include"hdconver.h"

void adconver()

{ unsigned char adchanne=0xe0//设置P1的0.1位为AD输入通道

ADC_CONTR=(0x80|ADC_CONTR)+channelframe//开启AD模拟电源

delay(1000)

P1M0=0x03

P1M1=0x03//设置通道为开漏模式

ADC_CONTR=adchanne+channelframe//设置AD转换通道

delay(22)

ADC_DATA=0x00

ADC_LOW2=0x00//清除数据口

ADC_CONTR|=0x08//开启AD端口

while(!(ADC_CONTR&0x10)){}//等待AD转换完成

ADC_CONTR&=0xe7//停止AD转换

P1M0&=0xfd

P1M1&=0xfd//设置P1口为普通IO模式

addis()

}

void addis()

{

unsigned int addata

double liangch

liangch=(limup-limdown)/100

addata=ADC_DATA+(ADC_LOW2&0x03)*1024

liangch=liangch/1023*addata

addata=(unsigned int)liangch

if(addata>a1)

{

ledframe&=0xef//打开上限报警灯

write7281(0x06,ledframe)

}

if(addata<a2)

{

ledframe&=0xdf//打开上限报警灯

write7281(0x06,ledframe)

}

hdconver(addata)

dis4led()

}

附录[8] D/A转换模块的程序—DACONVER.C

#include"delay.h"

#include"STC12C5410AD.H"

#include"main.H"

#include"daconver.h"

sbit TLV5618_SCLK=P1^7

sbit TLV5618_DIN=P1^5

sbit TLV5618_CS=P1^4

void mDelay(unsigned int a)

{unsigned int f

for(f=0f<af++)

}

void TLV5618 (unsigned int da)

{

unsigned int i

unsigned int dat

dat= da|0xc000

TLV5618_CS=0

TLV5618_SCLK=0

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

{

TLV5618_DIN=(bit)(dat&0x8000)

dat=dat<<1

TLV5618_SCLK=1

mDelay(50)

TLV5618_SCLK=0

mDelay(50)

}

TLV5618_CS=1

}

void daconver(void)

{ float i=100

unsigned int da

i=outputvalue/100*4096

da=(unsigned int)i

TLV5618 (da)

}

附录[9]显示及键盘模块的程序—DIS7281.C

#include"delay.H"

#include"STC12C5410AD.H"

#include"dis7281.H"

#include"main.h"

void write7281(unsigned char regadd,unsigned char writedata)

{

sendbyte(regadd)

sendbyte(writedata)

}

void sendbyte(unsigned char sendbyte)

{

unsigned char bitcounter

clk=0

clk=1

do{

clk=0

clk=1

}while(dat)

clk=0

clk=1

while(!dat)

for(bitcounter=0bitcounter<8bitcounter++)

{

if ((sendbyte&0x80)==0)

{ dat=0}

else

{dat=1}

sendbyte=sendbyte*2

clk=0

clk=1

delay(1)

}

dat=1

delay(2)

}

unsigned char receivebyte(void)

{

unsigned char bit_counter

unsigned char in_byte

clk=0

clk=1 //只发送一个单元的脉冲

while(dat)//等待BC7281响应DAT底电平

clk=0

clk=1//受到响应,再发一脉冲等待接受数据

for (bit_counter=0bit_counter<8bit_counter++ ) //接受8个BIT

{

delay(1)

in_byte=in_byte*2 //in_byte左移一位

if(dat) //如果DAT为1

{

in_byte=in_byte|0x01//bit^0=1

}

clk=0

clk=1

}

delay(2)

clk=0

clk=1

return(in_byte)

}

unsigned char read7281(unsigned char reg_add)

{

sendbyte (0x80+reg_add) //发送读指令(BIT 7=1)

return (receivebyte()) //接受数据字节并返回

}

void dis4led()

{

unsigned char i

unsigned char id=0x00

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

{

write7281(0x14,id+led[i])

id+=0x10

}

}

void dis2led()

{

unsigned char i

unsigned char id=0x40

for(i=4i<6i++)

{

write7281(0x14,id+led[i])

id+=0x10

}

}

附录[10]PID算法模块的程序—PID.C

#include"adconver.h"

#include"STC12C5410AD.H"

#include"math.h"

#include"pid.h"

#include"hdconver.h"

#include"dis7281.h"

xdata struct _pid

{

int pv

int sp

float integral

float pgain

float igain

float dgain

int deadband

int last_error

}

xdata struct _pid warm,*pid

xdata int process_point,set_point,dead_band

xdata float p_gain,i_gain,d_gain,integral_val,new_integ

void pid_init(struct _pid *warm,int process_point,int set_point)

{

struct _pid *pid

pid=warm

pid->pv=process_point

pid->sp=set_point

}

void pid_tune(struct _pid *pid,float p_gain,float i_gain,float d_gain,int dead_band)

{

pid->pgain=p_gain

pid->igain=i_gain

pid->dgain=d_gain

pid->deadband=dead_band

pid->integral=integral_val

pid->last_error=0

}

void pid_setinteg(struct _pid *pid,float new_integ)

{

pid->integral=new_integ

pid->last_error=0

}

void pid_bumpless(struct _pid *pid)

{

pid->last_error=(pid->sp)-(pid->pv)

}

float pid_calc(struct _pid *pid)

{

int err

float pterm,dterm,result,ferror

err=(pid->sp)-(pid->pv)

if(abs(err)>pid->deadband)

{

ferror=(float)err

pterm=pid->pgain*ferror

if(pterm>100||pterm<-100)

{

pid->integral=0.0

}

else

{

pid->integral+=pid->igain*ferror

if(pid->integral>100.0)

{

pid->integral=100.0

}

else

{

if(pid->integral<0.0)

{

pid->integral=0.0

}

}

}

dterm=((float)(err-pid->last_error))*pid->dgain

result=pterm+pid->integral+dterm

}

else

{

result=pid->integral

}

pid->last_error=err

return(result)

}

void pidcf(void)

{

int count=0

float val=100

float p_gain=cp/val

float i_gain=ci/val

float d_gain=cd/val

// unsigned int dadata

pid=&warm

dead_band=2

integral_val=(float)(0.01)

while(count<=20)

{

process_point=(unsigned int)addata/val

set_point=(unsigned int)setvalue/val

pid_init(&warm,process_point,set_point)

pid_tune(&warm,p_gain,i_gain,d_gain,dead_band)

pid_setinteg(&warm,0.0)

pid_bumpless(&warm)

count++

}

outputvalue=(unsigned char)pid_calc(&warm)

hdconver2(outputvalue)

dis4led()

}


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存