专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

AVR单片机PCF8591AD-DA实验

作者:佚名   来源:本站原创   点击数:  更新时间:2013年10月26日   【字体:


未加入滤波函数所以数值有点晃动



 
//PCF8591  AVR单片机程序    默认为输入模式下通道0开始通道0 光敏电阻,通道1,热敏电阻,通道2电位器,通道3外接电位器,如有标点符号丢失格式错乱的情况可从这里下载源码:http://www.51hei.com/f/avr8591.rar
#include <iom16.h>
#include <intrinsics.h>
#define uchar unsigned char
#define uint unsigned int
#define k1 PIND_Bit4  //模拟量输出值按键
#define k2 PIND_Bit5   //模拟量输入通道设定
#define k3 PIND_Bit6   //输入状态键
#define k4 PIND_Bit7   //输出状态键
uchar output_val=0;    //输出值
uchar input_val;    //输入值
uchar channel=0;     //通道值
uchar mode=1;        //输入输出状态模式 1表示输入2表示输出           默认为输入状态
uchar st1[]="  Input mode    "; 
uchar st2[]="  output mode   ";

void delay(uint k)
{
 uint i,j;
for(i=0;i<k;i++)
for(j=0;j<1140;j++); 
}
#include "1602.h"
void port_init()     //I/O口初始化
{
PORTA=0xff;
DDRA=0xff;
PORTB=0xff;
DDRB=0xff;
PORTC=0xff;
DDRC=0xff;
PORTD=0xff;
DDRD=0x0f;
}
//---------------TWI宏定义-------------
#define TWINT 7  //TWI完成当前操作允许应用程序介入时,置位
#define TWSTA 5  //声明自己希望成为主机TWI硬件检测是否可用,若空闲则接口上产生START 信号,若繁忙则一直等待直到一个STOP状态
#define TWSTO 4  //置位该位产生STOP状态
#define TWEN 2   //TWI接口激活 置位后I/O引脚切换到TWI模式

//--------------TWI状态字定义------MT主方式传输,MR主方式接受----------
#define START 0x08  //start已经发送
#define RE_START 0x10  //重复Start已经发送
#define MT_SLA_ACK 0x18   //SLA+W已经发送接受到应答    进入MT模式
#define MT_SLA_NOACK 0x20  //SLA+W已经发送接受到非应答
#define MT_DATA_ACK 0x28    //数据已经发送接受到应答
#define MT_DATA_NOACK 0x30   //数据发送接受到非应答
#define MR_SLA_ACK 0x40      //SLA+R已经发送接受到应答
#define MR_SLA_NOACK 0x48    //SLA+R已经发送接受到非应答
#define MR_DATA_ACK 0x50     //接受到数据ACK已经返回
#define MR_DATA_NOACK 0x58   //接受到数据NOACK已经返回
//-------TWI常用操作(主模式写,主模式读)--------------
#define start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
#define stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
#define wait() {while(!(TWCR&(1<<TWINT)));}        //等待TWINT置位说明信号 发送成功
#define test_ack() (TWSR&0xf8)               //测试应答状态
#define set_ack() (TWCR|=(1<<TWEA))        // 使能应答
#define set_noack() (TWCR=~(1<<TWEA))          //发送非应答
#define twi() (TWCR=(1<<TWINT)|(1<<TWEN))         //激活TWI
#define write_byte(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}   //数据装入TWDR  清零TWINT 准备发送
//-----------------------------
uchar ADC_read(uchar chl)        //读取函数设置通道变量
{
 uchar temp;       //读取值
 start();
 wait();
if(test_ack()!=START) return 0;  //启动失败返回0
write_byte(0x90);               //发送写方向
wait();
if(test_ack()!=MT_SLA_ACK) return 0;
write_byte(0x40|chl);           //发送写命令和通道值
wait();
if(test_ack()!=MT_DATA_ACK) return 0;
start();                     //再次启动
wait();
if(test_ack()!=RE_START) return 0;
write_byte(0x91);             //发送读方向
wait();
if(test_ack()!=MR_SLA_ACK) return 0;
twi();
wait();
if(test_ack()!=MR_DATA_NOACK) return 0;
temp=TWDR;
stop();
return temp;
}
//------------------------------------------------
uchar ADC_write(uchar data)
{
 start();
 wait();
 if(test_ack()!=START) return 1;
write_byte(0x90);            //启动写方向
wait();
if(test_ack()!=MT_SLA_ACK) return 1;
write_byte(0x40);                     //模拟量输出设定
wait();
if(test_ack()!=MT_DATA_ACK) return 1;
write_byte(data);                        //模拟量输出值
wait();
if(test_ack()!=MT_DATA_ACK) return 1;
stop();
delay(10);      //延时10ms  等待发送好
return 0;
}

//-----------------------------------------------------------
void key1()            //模拟量输出按键
{
 static uchar i,j;
if(k1==0)
{
      if(i==0)
      {
       j++;
         if(j>3)
         {
          if(k1==0)
          {
          i=1;j=0;
          output_val=output_val+10;
          }
         }   
       }
}
else
{
 i=0;
j=0;  

}
//---------------------------------------------------
void key2()       //模拟量输出通道选择
{
 static uchar i,j;
if(k2==0)
{
      if(i==0)
      {
       j++;
         if(j>3)
         {
           if(k2==0)
           {
          i=1;j=0;
          channel++;
          if(channel>3)channel=0;  
           }
         }   
       }
}
else
{
 i=0;
j=0;  

}
//---------------------------------------
void key3()
{
 static uchar i,j;
if(k3==0)
{
      if(i==0)
      {
       j++;
         if(j>3)
         {
           if(k3==0)
           {
          i=1;j=0;
       mode=1;      //输入模式
           }
         }   
       }
}
else
{
 i=0;
j=0;  

}
//---------------------------------
void key4()
{
 static uchar i,j;
if(k4==0)
{
      if(i==0)
      {
       j++;
         if(j>3)
         {
           if(k4==0)
           {
          i=1;j=0;
        mode=2;   //输出模式
           }
         }   
       }
}
else
{
 i=0;
j=0;  

}
//-----------------------------------------------------
void show_in()
{
  displaychar(0,0,st1);     // 第一行显示输入状态字符串
  displayonechar(14,1,channel+48);    //通道号选择
}
//--------------------------------------------------
void show_out()
{
  displaychar(0,0,st2);    //第一行显示输出状态字符串
  displayonechar(14,1,' ');
}
//---------------------------------------------------
void show_value(uchar k)       //显示数值
{
   displayonechar(7,1,((k/100)+48));
  displayonechar(8,1,((k%100/10)+48));
  displayonechar(9,1,((k%10)+48)); 
}
//-----------------------------------
void main()
{
 uchar temp;  //显示模拟量值
 port_init();
 init1602();
 ADC_write(0);
delay(1000);
while(1)
{
 if(mode==1)
 {
  temp=ADC_read(channel);     //从通道channel读取模拟量值给变量temp
  delay(3);
  show_in();                //显示输入状态字符串
  show_value(temp);
  key2();   //模拟输入通道按键
  delay(3);
 }
if(mode==2)
{
ADC_write(output_val);        //模拟量输出值
show_out();                  //显示模拟量输出状态字符串
show_value(output_val);
key1();   //模拟输出值按键
delay(3);
}
key3();   //输入模式
key4();   //输出模式
}
}
关闭窗口

相关文章