资讯详情

AVR单片机PCF8591AD-DA实验

未加入滤波函数所以数值有点晃动 //PCF8591 单片机程序 默认为输入模式下通道0开始通道0 光敏 ,通道1, ,通道2电位器,通道3外接电位器,如有标点符号丢失格式错乱的情况可从这里下载源码:http://www.ruidan.com/f/avr8591.rar #include #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; A=0xff; PORTB=0xff; DDRB=0xff; PORTC=0xff; DDRC=0xff; PORTD=0xff; DDRD=0x0f; } //---------------TWI宏定义------------- #define TWI 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_ A_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 A _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(); //输出模式 } } -电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。
锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台