单片机 通过串口控制DA变换器的输出程序

单片机 通过串口控制DA变换器的输出程序,第1张

DA,AD都在闷郑里面。。汪罩猛DA芯片是PCF8591ADDA

IIC协议 PCF8591ADDA转换

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

#include <intrins.h>//包含NOP空指令函数_nop_()

#define AddWr 0x90 //写数据地址

#define AddRd 0x91 //读数据地址

sbit Sda=P1^2 //定义总线连接端口

sbit Scl=P1^1

bit ADFlag //定义AD采样标志位

unsigned char code Datatab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}//7段数共阴码管段码表

data unsigned char Display[8]//定义临时存放数码管数值

/*------------------------------------------------

延时程序

------------------------------------------------*/

void mDelay(unsigned char j)

{

unsigned int i

for(j>0j--)

{

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

{}

}

}

/*------------------------------------------------

初始化定时器1

------------------------------------------------*/

void Init_Timer1(void)

{

TMOD |= 0x10

TH1=0xff /* Init value */

TL1=0x00

//PT1=1 /* 优先级*/

EA=1 /* interupt enable */

ET1=1/* enable timer1 interrupt */

TR1=1

}

/*------------------------------------------------

启动IIC总线

------------------------------------------------*/

void Start(void)

{

Sda=1

_nop_()

Scl=1

_nop_()

Sda=0

_nop_()

Scl=0

}

/*------------------------------------------------

停止IIC总线

------------------------------------------------*/

void Stop(void)

{

Sda=0

_nop_()

Scl=1

_nop_()

Sda=1

_nop_()

Scl=0

}

/*------------------------------------------------

应答IIC总线

------------------------------------------------*/

void Ack(void)

{

Sda=0

_nop_()

Scl=1

_nop_()

Scl=0

_nop_()

}

/*------------------------------------------------

非应困桥答IIC总线

------------------------------------------------*/

void NoAck(void)

{

Sda=1

_nop_()

Scl=1

_nop_()

Scl=0

_nop_()

}

/*------------------------------------------------

发送一个字节

------------------------------------------------*/

void Send(unsigned char Data)

{

unsigned char BitCounter=8

unsigned char temp

do

{

temp=Data

Scl=0

_nop_()

if((temp&0x80)==0x80)

Sda=1

else

Sda=0

Scl=1

temp=Data<<1

Data=temp

BitCounter--

}

while(BitCounter)

Scl=0

}

/*------------------------------------------------

读入一个字节并返回

------------------------------------------------*/

unsigned char Read(void)

{

unsigned char temp=0

unsigned char temp1=0

unsigned char BitCounter=8

Sda=1

do

{

Scl=0

_nop_()

Scl=1

_nop_()

if(Sda)

temp=temp|0x01

else

temp=temp&0xfe

if(BitCounter-1)

{

temp1=temp<<1

temp=temp1

}

BitCounter--

}

while(BitCounter)

return(temp)

}

/*------------------------------------------------

写入DA数模转换值

------------------------------------------------*/

void DAC(unsigned char Data)

{

Start()

Send(AddWr)//写入芯片地址

Ack()

Send(0x40) //写入控制位,使能DAC输出

Ack()

Send(Data) //写数据

Ack()

Stop()

}

/*------------------------------------------------

读取AD模数转换的值,有返回值

------------------------------------------------*/

unsigned char ReadADC(unsigned char Chl)

{

unsigned char Data

Start() //写入芯片地址

Send(AddWr)

Ack()

Send(0x40|Chl)//写入选择的通道,本程序只用单端输入,差分部分需要自行添加

//Chl的值分别为0、1、2、3,分别代表1-4通道

Ack()

Start()

Send(AddRd) //读入地址

Ack()

Data=Read() //读数据

Scl=0

NoAck()

Stop()

return Data //返回值

}

/*------------------------------------------------

主程序

------------------------------------------------*/

void main()

{

unsigned char num //DA数模输出变量

unsigned char ADtemp //定义中间变量

Init_Timer1()

while(1)

{

DAC(num) //DA输出,可以用LED模拟电压变化

num++ //累加,到256后溢出变为0,往复循环。显示在LED上亮度逐渐变化

mDelay(20)//延时用于清晰看出变化

if(ADFlag) //定时采集输入模拟量

{

ADFlag=0

ADtemp=ReadADC(0)

Display[0]=Datatab[(ReadADC(0))/50]|0x80//处理0通道电压显示

Display[1]=Datatab[((ReadADC(0))%50)/10]

ADtemp=ReadADC(1)

Display[2]=Datatab[((ReadADC(1))/50)]|0x80//处理1通道电压显示 此通道暂时屏蔽,可以自行添加

Display[3]=Datatab[((ReadADC(1))%50)/10]

ADtemp=ReadADC(2)

Display[4]=Datatab[((ReadADC(2))/50)]|0x80//处理1通道电压显示 此通道暂时屏蔽,可以自行添加

Display[5]=Datatab[((ReadADC(2))%50)/10]

ADtemp=ReadADC(3)

Display[6]=Datatab[((ReadADC(3))/50)]|0x80//处理1通道电压显示 此通道暂时屏蔽,可以自行添加

Display[7]=Datatab[((ReadADC(3))%50)/10]

}

}

}

/*------------------------------------------------

定时器中断程序

------------------------------------------------*/

void Timer1_isr(void) interrupt 3 using 1//定时器1执行数码管动态扫描

{

static unsigned int count,j

TH1=0xfb //重新赋值

TL1=0x00

j++

if(j==300)

{j=0ADFlag=1} //定时置位AD采样标志位

P0=Display[count]//用于动态扫描数码管

P2=count

count++

if(count==8) //表示扫描8个数码管

count=0

}

DA输出通道的实现方式:

查询方式中断方式DAM方式。D/A转换器的技术指标:分辨率:D/A转换器输丛世入二进制数的位数。分辨率为n位,表示D/A转换器输入二进制数的最低有效位LSB与满量程输出的1/2n相对应。建立时间:输入数字信号的变化是满量程时,输出信号达到离终值士1/2LSB的所需时间。一线性误差:在满刻度范围内,偏离理渗洞肢想转换特性的最大误差。理想转换特性(量化特性)应该是线性的,但实际转换特征并非如此。在满量程输入范围内,偏离理想转换特性的最大误差定义为线性误差。线性误差常用LSB的分数表示,如颤耐(1/2)LSB或土1LSB。

//DAC通道1输出初始化

void Dac1_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure

DAC_InitTypeDef DAC_InitType

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE ) //使能PORTA通道时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE ) //使能DAC通道时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 // 端口配置

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN //模拟输入

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz

GPIO_Init(GPIOA, &GPIO_InitStructure)

GPIO_SetBits(GPIOA,GPIO_Pin_4) //PA.4 输出高

DAC_InitType.DAC_Trigger=DAC_Trigger_None //不使用触发功能 TEN1=0

DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None//不神梁汪使用波形发生

DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0//屏蔽、幅值设置

DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable //DAC1输出缓存关闭 BOFF1=1

DAC_Init(DAC_Channel_1,&DAC_InitType) //初始化DAC通道1

DAC_Cmd(DAC_Channel_1, ENABLE) //使能DAC1

DAC_SetChannel1Data(DAC_Align_12b_R, 0) //12位右对齐数据格式设置DAC值

}

//设置通道1输出电压

//vol:0~3300,代表0~3.3V

void Dac1_Set_Vol(u16 vol)

{

float temp=vol

temp/=1000

temp=temp*4096/3.3

DAC_SetChannel1Data(DAC_Align_12b_R,temp)//12位右对齐数游仔据格式设渣誉置DAC值

}


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

原文地址:https://54852.com/yw/12245145.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存