AVR单片机TCS3200颜色传感器程序

//晶振8M,ATMEGA128
//作者:初学者飞飞飞
//邮箱:xuhongfeifeifei@https://www.360docs.net/doc/167360758.html,
#include
#include
#define uint unsigned int
#define uchar unsigned char
#define YANSE_DDR DDRC
#define YANSE_PORT PORTC
/********************************/
#define LCD_DATA PORTA
#define LCD_RS_1 PORTE|=0x20
#define LCD_RS_0 PORTE&=0xdf
#define LCD_WR_1 PORTE|=0X40
#define LCD_WR_0 PORTE&=0XbF
#define LCD_EN_1 PORTE|=0X80
#define LCD_EN_0 PORTE&=0X7F
#define LCD_DATA_OUT DDRA=0XFF
#define LCD_DATA_IN DDRA=0X00
#define LCD_DATA_A PORTA=0XFF
#define LCD_DDRE DDRE|=0XF0
#define LCD_PORTE PORTE|=0XF0
/***************************************************/
//PA口接液晶的数据口,PE5接RS,PE6接WR,PE7接EN
/*********************函数声明部分******************/
void LCD_WAIT();
void LCD_WR_COM(uchar com);//LCD1602写指令函数
void LCD_WR_DATA(uchar data);//LCD1602写数据函数
void PORT_INIT();//LCD1602端口初始化函数
void delaylcd(uint mas);//毫秒延时函数
void Delayuslcd(uint US);//微妙延时函数
void write_string(uchar *string);//写字符串函数
//void port_init();
void LCD_INIT();//LCD初始化函数
void display(uchar dyh,uchar drh,uint data);//专门用来显示超声波模块测试的距离函数
void lcd_write_0_1(uchar x,uchar temp);//专门用来显示,红外对管状态的液晶显示函数
void displayAXDL345(uchar dyh,uchar drh,float data);//专门写倾角传感器测试距离函数
void writeonechar(uchar x,uint z);
/********************************/
uint pulse,ryz,gyz,byz;//分别定义红色因子 绿色因子 蓝色因子
uint rb,gb,bb;//RGB值;
uint num;
void delayms(uint mas);
void INT2_INIT(void);

void timer3_init(void);
void fanbai(void);//反白平衡调节
void yanseceling(void);
uchar flag;//定时器计数器溢出标志
uchar table[]={"0123456789ABCDEF"};
void main()
{
DDRB=0XFF;
PORTB=0XFF;
DDRD|=0X04;//
PORTD|=0X04;//
LCD_INIT();
PORT_INIT();

YANSE_DDR=0XFF;
YANSE_PORT=0XFF;//初始化端口,设置为输出

INT2_INIT();
LCD_WR_COM(0x80+1); //
write_string("yanse"); //
timer3_init();//
fanbai();//反白平衡调节//
SREG|=0X80;//打开总中断

while(1)
{ //fanbai();
yanseceling();
writeonechar(0,rb);
writeonechar(5,bb);
writeonechar(10,gb);
delaylcd(1000);

}

}

void fanbai(void)//反白平衡调节
{
flag=0;
pulse=0;
TCNT3H=(65536-10000)/256;
TCNT3L=(65536-10000)%256;
//清零脉冲数
YANSE_PORT=0XE3;//打开红色透镜

TCCR3B=0X02; //开启定时器
//EIMSK|=0X04;
SREG|=0X80;//打开总中断
while(flag!=1);//等待定时器溢出
//EIMSK=0X00;
flag=0;//清除溢出标志
TCCR3B=0X00;//关闭定时器
ryz=pulse;//读取红色因子脉冲数

/**********************************/
pulse=0;//清零
TCNT3H=(65536-10000)/256;
TCNT3L=(65536-10000)%256;


YANSE_PORT=0XEB;//打开蓝色透镜

TCCR3B=0X02;//开启定时器
SREG|=0X80;//打开总中断
while(flag!=1);//等待定时器溢出
flag=0;//清除溢出标志
//EIMSK=0X00;
TCCR3B=0X00;//关闭定时器
byz=pulse;//读取红色因子脉冲数

/**********************************/
pulse=0;//清零
TCNT3H=(65536-10000)/256;
TCNT3L=(65536-10000)%256;
YANSE_PORT=0XEF;//打开绿色透镜

TCCR3B=0X02;//开启定时器
SREG|=0X80;//打开总中断
while(flag!=1);//等待定时器溢出
//EIMSK=0X00;
flag=0;//清除溢出标志
TCCR3B=0X00;//关闭定时器
byz=pulse;//读取红色因子脉冲数
//YANSE_PORT|=0X10;

//EIMSK=0X00;
YANSE_PORT|=0XF0;
}

void yanseceling(void)//颜色测量函数
{
YANSE_DDR=0XFF;
YANSE_PORT=0XFF;//初始化端口,设置为输出
flag=0;
//*********求R值************************************
TCNT3H=(65536-10000)/256;
TCNT3L=(65536-10000)%256;
pulse=0;
YANSE_PORT=0XE3;//打开红色透镜
TCCR3B=0X02;//开启定时器
SREG|=0X80;//打开总中断
while(flag!=1);//等待定时器溢出
//EIMSK=0X00;
flag=0;//清除溢出标志
TCCR3B=0X00;//关闭定时器

//ryz=pulse;//读取红色因子脉冲数/
rb=(unsigned long)pulse*255/ryz;
if(rb>255)rb=255;//判断RGB值是否合法
/**************求B值*****************/
TCNT3H=(65536-10000)/256;
TCNT3L=(65536-10000)%256;
pulse=0;//清零
YANSE_PORT=0XEB;//打开蓝色透镜

TCCR3B=0X02;//开启定时器
SREG|=0X80;//打开总中断
while(flag!=1);//等待定时器溢出
//EIMSK=0X00;
flag=0;//清除溢出标志
TCCR3B=0X00;//关闭定时器
bb=(unsigned long)pulse*255/byz;
if(bb>255)bb=255;//判断RGB值是否合法
/**********************************/
//***********求G值**************************************/
TCNT3H=(65536-10000)/256;
TCNT3L=(65536-10000)%256;
pulse=0;//清零
YANSE_PORT=0XEF;//打开蓝色透镜
TCCR3B=0X02;//开启定时器
SREG|=0X80;//打开总中断
while(flag!=1);//等待定时器溢出
//EIMSK=0X00;
flag=0;//清除溢出标志
TCCR3B=0X00;//关闭定时器
gb=(unsigned long)pulse*255/byz;
if(gb>255)gb=255;//判断RGB值是否合法

}

void delayms(uint mas)//毫秒延时函数
{
uint i,j;
for(i=mas;i>0;i--)

for(j=1141;j>0;j--);

}

void INT2_INIT(void)//外部中断初始化函数
{
DDRD|=0X0F;
PORTD|=0X0F;//IO口初始化
EIFR|=0X04;//清除中断标志 //

EICRA=0X20;//打开外部中断INT2

EIMSK=0X04;//解除INT2中断屏蔽//
//SREG|=0X80;//打开总中断

}
void timer3_init(void)//定时器计数器3初始化函数
{
TCCR3A=0X00;
//TCCR3B=0X02;//8分頩,记一个数的时间为1微妙
TCCR3C=0X00;//普通定时模式

ETIMSK=0x04;//使能定时器计数器3

溢出中断
TCNT3H=(65536-10000)/256;//装入定时初值
TCNT3L=(65536-10000)%256;
//TCCR3B=0X02;//开启定时器
TCCR3B=0X00;//关闭定时器
//SREG|=0X80;//打开总中断
}


/***********************************************/
void LCD_INIT()//LCD初始化函数
{

LCD_DATA_OUT; //设A为输出
LCD_DDRE;//B为输出

LCD_WR_COM(0x38);
//LCD_WR_COM(0x08); /*显示关闭*/
/*显示清屏*/
LCD_WR_COM(0x06); /*显示光标移动设置*/
delaylcd(2);
LCD_WR_COM(0x0C);
LCD_WR_COM(0x01); /*显示开及光标设置*/
}

void LCD_WR_COM(uchar com)
{
LCD_DATA_OUT;//设置A口为输出
LCD_DDRE;//PB口为输入
LCD_RS_0;
Delayuslcd(2);
LCD_WR_0;
LCD_EN_1;
Delayuslcd(10);
LCD_DATA=com;
delaylcd(2);
LCD_EN_0;
LCD_RS_1;
LCD_WR_1;
}
/*****************************************************/
void LCD_WR_DATA(uchar data)//写数据函数
{
LCD_DATA_OUT;//设置PA口为输出
LCD_DDRE;//PB口为输入
LCD_RS_1;
Delayuslcd(10);
LCD_WR_0;
LCD_EN_1;
Delayuslcd(10);
LCD_DATA=data;
delaylcd(5);
LCD_EN_0;
LCD_RS_0;
LCD_WR_1;
}
/****************************************************/
void PORT_INIT()//端口初始化函数
{
LCD_DATA_OUT;//设置PA口为输出
LCD_DDRE;//设置PE口为输出
LCD_DATA_A; //PORTA=0XFF;
LCD_PORTE;//PORTB|=0XE0
LCD_WR_1;
LCD_EN_0;
delaylcd(2);
}
/****************************************************/
void write_string(uchar *string)//写字符串函数
{
while(*string)
{//LCD_WAIT();
LCD_WR_DATA(*string);
delaylcd(2);
string++;
}

}

/****************************************************/

void display(uchar dyh,uchar drh,uint data)//专门写超声波测试距离函数
{
uint bai,shi,ge;

if(dyh!=0&&drh==0)
{
LCD_WR_COM(0x80+dyh);//从第一行第drh位置开始写数据

}
else if(dyh==0&&drh!=0)
{
LCD_WR_COM(0x80+0x40+drh);//从第二行第drh位置开始写数据

}
else if(dyh==0&&drh==0)
{
LCD_WR_COM(0x80+0);//从第-行第0位置开始写数据
}
else
{
LCD_INIT();//重新初始化液晶,清除显示
}

bai= data/100; //
shi=data/10%10;//
ge=data%10;
LCD_WR_DATA(table[bai]);//
LCD_WR_DATA(table[shi]);//
LCD_WR_DATA(table[ge]);
}

void lcd_write_0_1(uchar x,uchar temp)//专门写0,1函数
{ uchar tablex[6],i;
uchar table2[]={"010"};
tablex[0]=temp&0x01;
tablex[1]=temp&0x02;
tablex[2]=temp&0x04;
tablex[3]=temp&0x08;
tablex[4]=temp&0x10;
tablex[5]=temp&0x20;
tablex[6]=temp&0x40;
tablex[7]=temp&0x80;
LCD_WR_COM(0x80+0x40+4+x);
for(i=0;i<8;i++)
{ if(tablex[i]!=0)
LCD_WR_DATA(table2[1]);
else
LCD_WR_DATA(table2[0]);
delaylcd(2);
}

}
void displayAXDL345(uchar dyh,uchar drh,float data)//专门写倾角传感器测试距离函数
{
uint qian,bai,shi,ge;
u

char table[]={"0123456789"};
/*if(dyh!=0&&drh==0)
{
LCD_WR_COM(0x80+dyh+1);//从第一行第drh位置开始写数据

}
else if(dyh==0&&drh!=1)
{
LCD_WR_COM(0x80+0x40+drh+1);//从第二行第drh位置开始写数据

}*/


if(data<0&&dyh==0&&drh!=0)
{
data=-data;
LCD_WR_COM(0x80+0x40+drh);
write_string("-");

}
else if(data<0&&dyh!=0&&drh==0)
{
data=-data;
LCD_WR_COM(0x80+dyh);
write_string("-");

}
else if(data>0&&dyh==0&&drh!=0)
{
LCD_WR_COM(0x80+0x40+drh);
write_string("+");
}

else if(data>0&&dyh!=0&&drh==0)
{
LCD_WR_COM(0x80+dyh);
write_string("+");
}
/*if(dyh!=0&&drh==0)
{
LCD_WR_COM(0x80+dyh+1);//从第一行第drh位置开始写数据

}
else if(dyh==0&&drh!=1)
{
LCD_WR_COM(0x80+0x40+drh+1);//从第二行第drh位置开始写数据

}*/
qian=(uint)data/1000;
bai=(uint)data/100%10;
shi=(uint)data/10%10;
ge=(uint)data%10;
LCD_WR_DATA(table[qian]);
LCD_WR_DATA('.');
LCD_WR_DATA(table[bai]);
LCD_WR_DATA(table[shi]);
LCD_WR_DATA(table[ge]);
LCD_WR_DATA('g');
}
void writeonechar(uchar x,uint z)
{
uint bai,shi,ge;
uchar table[]={"0123456789"};
if(z<0)
{
z=-z;
LCD_WR_COM(0x80+x);
LCD_WR_DATA('-');

}
else
{
LCD_WR_COM(0x80+x);
LCD_WR_DATA('+');
}
bai=(z/100);
shi=(z/10%10);
ge=(z%10);
LCD_WR_COM(0x80+x);
LCD_WR_DATA(table[bai]);
LCD_WR_DATA(table[shi]);
LCD_WR_DATA(table[ge]);
}

/****************************************************/
void delaylcd(uint mas)//毫秒延时函数
{
uint M;
uint N;
for(N=mas;N>0;N--)

for(M=1141;M>0;M--);
}

/****************************************************/
void Delayuslcd(uint US)//微秒延时函数
{
uint D;
US=US*5/4;
for( D=0;D}

/***********************************************/
#pragma interrupt_handler INT2INIT:4
void INT2INIT(void)//当检测到上升沿时则进入中断函数,脉冲数加1
{ pulse++;
PORTB=~PORTB;//
//delaylcd(100);

if(pulse>255)//若超出255则停止计数
{
pulse=255;
}

}

#pragma interrupt_handler Timer3:30
void Timer3()//定时器计数器3溢出中断
{
TCNT3H=(65536-10000)/256;//重装初值
TCNT3L=(65536-10000)%256;
flag=1;
CLI();


}/**/



相关文档
最新文档