//PCF8591 AVR單片機程序 默認為輸入模式下通道0開始通道0 光敏電阻,通道1,熱敏電阻,通道2電位器,通道3外接電位器,如有標點符號丟失格式錯亂的情況可從這里下載源碼:http://www.zg4o1577.cn/f/avr8591.rar
#include <iom16.h>
#include <intrinsics.h>
#include <intrinsics.h>
#define uchar unsigned char
#define uint unsigned int
#define uint unsigned int
#define k1 PIND_Bit4 //模擬量輸出值按鍵
#define k2 PIND_Bit5 //模擬量輸入通道設定
#define k3 PIND_Bit6 //輸入狀態(tài)鍵
#define k4 PIND_Bit7 //輸出狀態(tài)鍵
#define k2 PIND_Bit5 //模擬量輸入通道設定
#define k3 PIND_Bit6 //輸入狀態(tài)鍵
#define k4 PIND_Bit7 //輸出狀態(tài)鍵
uchar output_val=0; //輸出值
uchar input_val; //輸入值
uchar channel=0; //通道值
uchar mode=1; //輸入輸出狀態(tài)模式 1表示輸入2表示輸出 默認為輸入狀態(tài)
uchar input_val; //輸入值
uchar channel=0; //通道值
uchar mode=1; //輸入輸出狀態(tài)模式 1表示輸入2表示輸出 默認為輸入狀態(tài)
uchar st1[]=" Input mode ";
uchar st2[]=" output 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;
}
{
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狀態(tài)
#define TWSTO 4 //置位該位產生STOP狀態(tài)
#define TWEN 2 //TWI接口激活 置位后I/O引腳切換到TWI模式
#define TWINT 7 //TWI完成當前操作允許應用程序介入時,置位
#define TWSTA 5 //聲明自己希望成為主機TWI硬件檢測是否可用,若空閑則接口上產生START 信號,若繁忙則一直等待直到一個STOP狀態(tài)
#define TWSTO 4 //置位該位產生STOP狀態(tài)
#define TWEN 2 //TWI接口激活 置位后I/O引腳切換到TWI模式
//--------------TWI狀態(tài)字定義------MT主方式傳輸,MR主方式接受----------
#define START 0x08 //start已經發(fā)送
#define RE_START 0x10 //重復Start已經發(fā)送
#define MT_SLA_ACK 0x18 //SLA+W已經發(fā)送接受到應答 進入MT模式
#define MT_SLA_NOACK 0x20 //SLA+W已經發(fā)送接受到非應答
#define MT_DATA_ACK 0x28 //數(shù)據(jù)已經發(fā)送接受到應答
#define MT_DATA_NOACK 0x30 //數(shù)據(jù)發(fā)送接受到非應答
#define MR_SLA_ACK 0x40 //SLA+R已經發(fā)送接受到應答
#define MR_SLA_NOACK 0x48 //SLA+R已經發(fā)送接受到非應答
#define MR_DATA_ACK 0x50 //接受到數(shù)據(jù)ACK已經返回
#define MR_DATA_NOACK 0x58 //接受到數(shù)據(jù)NOACK已經返回
#define MR_SLA_NOACK 0x48 //SLA+R已經發(fā)送接受到非應答
#define MR_DATA_ACK 0x50 //接受到數(shù)據(jù)ACK已經返回
#define MR_DATA_NOACK 0x58 //接受到數(shù)據(jù)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置位說明信號 發(fā)送成功
#define test_ack() (TWSR&0xf8) //測試應答狀態(tài)
#define set_ack() (TWCR|=(1<<TWEA)) // 使能應答
#define set_noack() (TWCR=~(1<<TWEA)) //發(fā)送非應答
#define twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //激活TWI
#define write_byte(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //數(shù)據(jù)裝入TWDR 清零TWINT 準備發(fā)送
#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置位說明信號 發(fā)送成功
#define test_ack() (TWSR&0xf8) //測試應答狀態(tài)
#define set_ack() (TWCR|=(1<<TWEA)) // 使能應答
#define set_noack() (TWCR=~(1<<TWEA)) //發(fā)送非應答
#define twi() (TWCR=(1<<TWINT)|(1<<TWEN)) //激活TWI
#define write_byte(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} //數(shù)據(jù)裝入TWDR 清零TWINT 準備發(fā)送
//-----------------------------
uchar ADC_read(uchar chl) //讀取函數(shù)設置通道變量
{
uchar temp; //讀取值
start();
wait();
if(test_ack()!=START) return 0; //啟動失敗返回0
write_byte(0x90); //發(fā)送寫方向
wait();
if(test_ack()!=MT_SLA_ACK) return 0;
write_byte(0x40|chl); //發(fā)送寫命令和通道值
wait();
if(test_ack()!=MT_DATA_ACK) return 0;
start(); //再次啟動
wait();
if(test_ack()!=RE_START) return 0;
write_byte(0x91); //發(fā)送讀方向
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 等待發(fā)送好
return 0;
}
uchar ADC_read(uchar chl) //讀取函數(shù)設置通道變量
{
uchar temp; //讀取值
start();
wait();
if(test_ack()!=START) return 0; //啟動失敗返回0
write_byte(0x90); //發(fā)送寫方向
wait();
if(test_ack()!=MT_SLA_ACK) return 0;
write_byte(0x40|chl); //發(fā)送寫命令和通道值
wait();
if(test_ack()!=MT_DATA_ACK) return 0;
start(); //再次啟動
wait();
if(test_ack()!=RE_START) return 0;
write_byte(0x91); //發(fā)送讀方向
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 等待發(fā)送好
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 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); // 第一行顯示輸入狀態(tài)字符串
displayonechar(14,1,channel+48); //通道號選擇
}
//--------------------------------------------------
void show_out()
{
displaychar(0,0,st2); //第一行顯示輸出狀態(tài)字符串
displayonechar(14,1,' ');
}
//---------------------------------------------------
void show_value(uchar k) //顯示數(shù)值
{
displayonechar(7,1,((k/100)+48));
displayonechar(8,1,((k%100/10)+48));
displayonechar(9,1,((k%10)+48));
}
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); // 第一行顯示輸入狀態(tài)字符串
displayonechar(14,1,channel+48); //通道號選擇
}
//--------------------------------------------------
void show_out()
{
displaychar(0,0,st2); //第一行顯示輸出狀態(tài)字符串
displayonechar(14,1,' ');
}
//---------------------------------------------------
void show_value(uchar k) //顯示數(shù)值
{
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(); //顯示輸入狀態(tài)字符串
show_value(temp);
key2(); //模擬輸入通道按鍵
delay(3);
}
if(mode==2)
{
ADC_write(output_val); //模擬量輸出值
show_out(); //顯示模擬量輸出狀態(tài)字符串
show_value(output_val);
key1(); //模擬輸出值按鍵
delay(3);
}
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(); //顯示輸入狀態(tài)字符串
show_value(temp);
key2(); //模擬輸入通道按鍵
delay(3);
}
if(mode==2)
{
ADC_write(output_val); //模擬量輸出值
show_out(); //顯示模擬量輸出狀態(tài)字符串
show_value(output_val);
key1(); //模擬輸出值按鍵
delay(3);
}
key3(); //輸入模式
key4(); //輸出模式
}
key4(); //輸出模式
}
}