×
嵌入式 > 技术百科 > 详情

基于PCF8591的I_2C总线A_D_D_A转换的资料

发布时间:2020-06-13 发布时间:
|
/*******************
程序功能:
通过DA转换把输出电压逐渐增大,
使加在上面的发光二级管慢慢变亮  
到最亮后再变暗,如此循环
*******************/  

 
/*******************
       D/A转换
*******************/
#include
#define uint unsigned int
#define uchar unsigned char
#define PCF8591 0x90//PCF8591的地址
sbit sda=P2^0;
sbit scl=P2^1;
void delay()//执行空语句,微秒级延时函数
{;;}
void delay1ms(uint z)//延时1ms
{
uint x,y;
for(x=z;x>0;x--)
{
for(y=0;y<=110;y++)
{
}
}
}
void init()//初始化状态下SCL和SDA都为高电平
{
scl=1;
delay();
sda=1;
delay();
}
void start()//在SCL为高电平时SDA由高电平到低电平
{
sda=1;
delay();
scl=1;
delay();
sda=0;
}
void respons()
/*
应答信号,SCL在高电平期间,SDA被从设备拉为低电平表示应答。
(sda==1)和i<255相与,表示若在一段时间内没有从器件的应答则主器件
默认从器件已经收到数据而不再等待应答信号
*/
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))
{
i++;
}
scl=0;
delay();
}
void stop()//SCL在高电平期间,SDA一个上升沿停止信号
{
sda=0;
delay();
scl=1;
delay();
sda=1;
}
void write_byte(uchar date)//写一个字节
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;//只有在SCL为0期间才允许SDA数据线上的状态才允许变化
delay();
sda=CY;//PSW的寄存器的CY进位标志位
delay();
scl=1; //SCL时钟信号为高电平期间数据线上的数据必须保持稳定 delay();
delay();
}
scl=0;
delay();
sda=1;//释放总线
delay();
}
uchar read_byte()
{
uchar i,k;
scl=0;
delay();
sda=1;//释放总线
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
//delay();here is a bug
return k;
}

 
void write_address(uchar address,uchar date)
{
start();
write_byte(0x90);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
uchar read_address(uchar address)
{
uchar date;
start();
write_byte(0x90); //10010000  前四位固定 接下来三位全部被接地了 所以都是0 最后一位是写 所以为低电平
respons();
write_byte(address);
respons();
start();
write_byte(0x91);
respons();
date=read_byte();
stop();
return date;
}
void main()
{
uint count;
init();
while(1)
{
write_address(0x40,count);
delay1ms(5);
count++;
if(count>250)
{
count=0;
}
}

 
}
 

 

 
/*******************
程序功能:
旋转A/D电位器,将模拟量变成数字量,并用数码管显示其结果。
*******************/

 
/*******************
       A/D转换
*******************/
#include
#define uint unsigned int
#define uchar unsigned char
#define PCF8591 0x90//PCF8591的地址
sbit sda=P2^0;
sbit scl=P2^1; 
sbit LS138A=P2^2;//138译码器的3位 控制数码管的   
sbit LS138B=P2^3; 
sbit LS138C=P2^4; 
uchar num,ge,shi,bai;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f};//段选  
void delay()//执行空语句,微秒级延时函数
{;;}
void delay1ms(uint z)//延时1ms
{
uint x,y;
for(x=z;x>0;x--)
{
for(y=0;y<=110;y++)
{
}
}
}
void init()//初始化状态下SCL和SDA都为高电平
{
scl=1;
delay();
sda=1;
delay();
}
void start()//在SCL为高电平时SDA由高电平到低电平
{
sda=1;
delay();
scl=1;
delay();
sda=0;
}[page]
void respons()
/*
应答信号,SCL在高电平期间,SDA被从设备拉为低电平表示应答。
(sda==1)和i<255相与,表示若在一段时间内没有从器件的应答则主器件
默认从器件已经收到数据而不再等待应答信号
*/
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))
{
i++;
}
scl=0;
delay();
}
void stop()//SCL在高电平期间,SDA一个上升沿停止信号
{
sda=0;
delay();
scl=1;
delay();
sda=1;
}
void write_byte(uchar date)//写一个字节
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;//只有在SCL为0期间才允许SDA数据线上的状态才允许变化
delay();
sda=CY;//PSW的寄存器的CY进位标志位
delay();
scl=1; //SCL时钟信号为高电平期间数据线上的数据必须保持稳定 delay();
delay();
}
scl=0;
delay();
sda=1;//释放总线
delay();
}
uchar read_byte()
{
uchar i,k;
scl=0;
delay();
sda=1;//释放总线
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
//delay();here is a bug
return k;
}

 
void write_address(uchar address,uchar date)
{
start();
write_byte(0x90);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
uchar read_address(uchar address)
{
uchar date;
start();
write_byte(0x90); //10010000  前四位固定 接下来三位全部被接地了 所以都是0 最后一位是写 所以为低电平
respons();
write_byte(address);
respons();
start();
write_byte(0x91);
respons();
date=read_byte();
stop();
return date;
}
void display(uchar ge,uchar shi,uchar bai) 
P0=0xff; 
    LS138A=1;   //第一位 
    LS138B=1; 
    LS138C=1; 
    P0=table[ge]; 
    delay1ms(1); 
P0=0xff; 

 
    LS138A=0;   //第二位 
    LS138B=1; 
    LS138C=1; 
  P0=table[shi]; 
    delay1ms(1); 
    P0=0xff; 

 
    LS138A=1;   //第三位 
    LS138B=0; 
    LS138C=1; 
    P0=table[bai]; 
    delay1ms(1);   
void main() 
{        
    init(); 
    while(1) 
{                  
        num=read_address(0x40);   
        bai=num/100; 
shi=num/10%10;
ge=num%10;
display(ge,shi,bai);



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
看业界大佬们如何看待未来趋势!智能制造?健康医疗?新流通?