
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值
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)