////////////////////////////////////////////////////IIC.c/////////////////////////////////////////////
#include " msp430f1232.h"
#include "main.h"
#include "iic.h"
#include "uart.h"
//-------------------SCL--------------
#define Scl_OUT P1DIR |= BIT1
#define Scl_LOW P1OUT &=~ BIT1
#define Scl_HIGH P1OUT |= BIT1
//-------------------SDA--------------
#define Sda_OUT P2DIR |= BIT2
#define Sda_LOW P2OUT &=~ BIT2
#define Sda_HIGH P2OUT |= BIT2
#define Sda_IN P2DIR &=~ BIT2
//------------------------------时间延时------------------------------//
void delay(unsigned int count)
{
unsigned int i;
for(i=count; i>0; i--);
}
/-----***-IIC起始-***-----//
void IIC_START(void)
{
Sda_HIGH;
Scl_HIGH;
delay(3);
Sda_OUT;
Scl_OUT;
delay(3);
Sda_HIGH;
delay(3);
Sda_LOW;
delay(3);
Scl_LOW;
delay(3);
}
//-----***-IIC停止-***-----//
void IIC_STOP(void)
{
Scl_OUT;
Sda_OUT;
Scl_HIGH;
delay(3);
Sda_LOW;
delay(3);
Sda_HIGH;
delay(3);
}
//-----***-IIC应答-***-----//
void IIC_SEND_ACK (void)
{
Scl_OUT;
Sda_OUT;
delay(3);
Sda_LOW;
delay(3);
Scl_HIGH;
delay(3);
Scl_LOW;
delay(3);
Sda_HIGH;
delay(3);
}
//----------------------发送一个字节-------
void IIC_TX_DATA (unsigned char DATA)
{
unsigned char i ;
for (i=0;i<8;i++)
{
if((DATA&0x80)!= 0) //分别发送每一位二进制数据
Sda_HIGH;
else
Sda_LOW;
Scl_HIGH;
DATA<<=1; //移位传送下一位
delay(3);
Scl_LOW; //在SCL上升沿的时候加载一位的数据
delay(3);
}
Sda_HIGH; //8位数据位发送完释放数据总线,同时SDA拉高
}
//-----------------------------接收一个字节----------------
unsigned char IIC_RX_DATA (void)
{
unsigned char i ,data=0;
Sda_IN; //在接收模式下,设置SDA的方向为输入
for (i=0;i<8;i++)
{
Scl_LOW;
delay(3);
Scl_HIGH; //SCL下降沿期间有数据,当SCL为高时数据线上的数据才有效
data<<=1;
if((P2IN>>2) & 0x01)
{
data += 1;
}
delay(3);
}
Sda_OUT; //接收结束的时候还要吧SDA的方向切换过来
return data;
}
//-----------------------------无应答---返回1------------
//------------------------------应答----返回0------------
unsigned char wait_ack()
{
unsigned char CY = 1;
Sda_IN; //在接收模式下,设置SDA的方向为输入
Scl_HIGH; //拉高时钟线
delay(2); //延时
CY=((P2IN>>2) & 0x01); //读应答信号
Scl_LOW; //拉低时钟线
delay(3); //延时
Sda_OUT; //接收结束的时候还要吧SDA的方向切换过来
return CY;
}
//-----------------------测试器件地址和应答------------------
void test_ack()
{
IIC_START();
IIC_TX_DATA (TCS3414_WRITE);
if(wait_ack())
{
IIC_STOP();
test_ack();
}
else
{
IIC_STOP();
return;
}
}
//---------------------------------读取一个字节-------------------
unsigned char READ_BYTE (unsigned char ADDR)
{
unsigned char DATA_R;
test_ack();
IIC_START ();
IIC_TX_DATA (TCS3414_WRITE);
while(wait_ack());
IIC_TX_DATA (ADDR);
while(wait_ack());
IIC_START ();
IIC_TX_DATA (TCS3414_READ);
while(wait_ack());
DATA_R=IIC_RX_DATA();
IIC_SEND_ACK ();
IIC_STOP ();
return DATA_R;
}
//------------------------------写一个字节------------------
void WRITE_BYTE (unsigned char ADDR,unsigned char DATA_W)
{
test_ack();
IIC_START ();
IIC_TX_DATA (TCS3414_WRITE);
while(wait_ack());
IIC_TX_DATA (ADDR);
while(wait_ack());
IIC_TX_DATA (DATA_W);
while(wait_ack());
IIC_STOP ();
}
////////////////////////////////////////////////IIC.h///////////////////////////////////////
#ifndef _iic_h
#define _iic_h
#define TCS3414_WRITE 0x72
#define TCS3414_READ 0X73
#define REG_CTL 0x80
#define REG_TIMING 0x81
#define REG_INT 0x82
#define REG_INT_SOURCE 0x83
#define REG_ID 0x84
#define REG_GAIN 0x87
#define REG_LOW_THRESH_LOW_BYTE 0x88
#define REG_LOW_THRESH_HIGH_BYTE 0x89
#define REG_HIGH_THRESH_LOW_BYTE 0x8A
#define REG_HIGH_THRESH_HIGH_BYTE 0x8B
#define REG_BLOCK_READ 0xCF
#define REG_GREEN_LOW 0xD0
#define REG_GREEN_HIGH 0xD1
#define REG_RED_LOW 0xD2
#define REG_RED_HIGH 0xD3
#define REG_BLUE_LOW 0xD4
#define REG_BLUE_HIGH 0xD5
#define REG_CLEAR_LOW 0xD6
#define REG_CLEAR_HIGH 0xD7
#define CTL_DAT_INIITIATE 0x03
#define CLR_INT 0xE0
//Timing Register
#define SYNC_EDGE 0x40
#define INTEG_MODE_FREE 0x00
#define INTEG_MODE_MANUAL 0x10
#define INTEG_MODE_SYN_SINGLE 0x20
#define INTEG_MODE_SYN_MULTI 0x30
#define INTEG_PARAM_PULSE_COUNT1 0x00
#define INTEG_PARAM_PULSE_COUNT2 0x01
#define INTEG_PARAM_PULSE_COUNT4 0x02
#define INTEG_PARAM_PULSE_COUNT8 0x03
//Interrupt Control Register
#define INTR_STOP 40
#define INTR_DISABLE 0x00
#define INTR_LEVEL 0x10
#define INTR_PERSIST_EVERY 0x00
#define INTR_PERSIST_SINGLE 0x01
//Interrupt Souce Register
#define INT_SOURCE_GREEN 0x00
#define INT_SOURCE_RED 0x01
#define INT_SOURCE_BLUE 0x10
#define INT_SOURCE_CLEAR 0x03
//Gain Register
#define GAIN_1 0x00
#define GAIN_4 0x10
#define GAIN_16 0x20
#define GANI_64 0x30
#define PRESCALER_1 0x00
#define PRESCALER_2 0x01
#define PRESCALER_4 0x02
#define PRESCALER_8 0x03
#define PRESCALER_16 0x04
#define PRESCALER_32 0x05
#define PRESCALER_64 0x06
void delay(unsigned int count);
unsigned char READ_BYTE (unsigned char ADDR);
void WRITE_BYTE (unsigned char ADDR,unsigned char DATA_W);
void test_ack();
#endif
/////////////////////////////////////////////////////////main.c///////////////////////////////////////
#include " msp430f1232.h"
#include "main.h"
#include "iic.h"
#include "uart.h"
unsigned char TCS_4314_ID = 0;
unsigned int red = 0,blue = 0,green = 0,clear = 0;
unsigned char d4,d3,d2,d1;
float X1,Y1,Z1;
unsigned int xx,yy;
void RGB_read()
{
unsigned int data0 = 0,data1 = 0;
if((READ_BYTE(0x80) & 0x10) == 0x10)
{
//绿色通道
data0 = READ_BYTE(0x90);
data1 = READ_BYTE(0x91);
green = (data0 + (data1*256));
//green *= 0.03125;
//红色通道
data0 = READ_BYTE(0x92);
data1 = READ_BYTE(0x93);
red = (data0 + (data1*256));
//red *= 0.03125;
//蓝色通道
data0 = READ_BYTE(0x94);
data1 = READ_BYTE(0x95);
blue = (data0 + (data1*256));
//blue *= 0.03125;
//清晰通道
data0 = READ_BYTE(0x96);
data1 = READ_BYTE(0x97);
clear = (data0 + (data1*256));
//clear *= 0.03125;
WRITE_BYTE(0X80,0X03);//清除转换完成标志
}
}
void RGB_UART_SEND()
{
SendString("\r\n");
SendString("RED-----> ");
//送入的数据必须是四位的,三位整数加一位小数
d4 = (unsigned char)(red/1000);
d3 = (unsigned char)(red%1000/100);
d2 = (unsigned char)(red%100/10);
d1 = (unsigned char)(red%10);
if(d4 != 0) SendData(d4+0x30);
if((d4 == 0)&&(d3 == 0)) ;
else SendData(d3+0x30);
SendData(d2+0x30);
SendData(0x2E);//发送小数点
SendData(d1+0x30);
SendString("\r\n");
SendString("\r\n");
SendString("GREEN---> ");
//送入的数据必须是四位的,三位整数加一位小数
d4 = (unsigned char)(green/1000);
d3 = (unsigned char)(green%1000/100);
d2 = (unsigned char)(green%100/10);
d1 = (unsigned char)(green%10);
if(d4 != 0) SendData(d4+0x30);
if((d4 == 0)&&(d3 == 0)) ;
else SendData(d3+0x30);
SendData(d2+0x30);
SendData(0x2E);//发送小数点
SendData(d1+0x30);
SendString("\r\n");
SendString("\r\n");
SendString("BLUE----> ");
//送入的数据必须是四位的,三位整数加一位小数
d4 = (unsigned char)(blue/1000);
d3 = (unsigned char)(blue%1000/100);
d2 = (unsigned char)(blue%100/10);
d1 = (unsigned char)(blue%10);
if(d4 != 0) SendData(d4+0x30);
if((d4 == 0)&&(d3 == 0)) ;
else SendData(d3+0x30);
SendData(d2+0x30);
SendData(0x2E);//发送小数点
SendData(d1+0x30);
SendString("\r\n");
SendString("\r\n");
SendString("CLEAR---> ");
//送入的数据必须是四位的,三位整数加一位小数
d4 = (unsigned char)(clear/1000);
d3 = (unsigned char)(clear%1000/100);
d2 = (unsigned char)(clear%100/10);
d1 = (unsigned char)(clear%10);
if(d4 != 0) SendData(d4+0x30);
if((d4 == 0)&&(d3 == 0)) ;
else SendData(d3+0x30);
SendData(d2+0x30);
SendData(0x2E);//发送小数点
SendData(d1+0x30);
SendString("\r\n");
SendString("\r\n");
SendString("\r\n");
}
void calculateCoordinate()
{
X1=(-0.14282)*red+(1.54924)*green+(-0.95641)*blue;
Y1=(-0.32466)*red+(1.57837)*green+(-0.73191)*blue;
Z1=(-0.68202)*red+(0.77073)*green+(0.56332)*blue;
xx=(unsigned int)(X1/(X1+Y1+Z1)*1000);
yy=(unsigned int)(Y1/(X1+Y1+Z1)*1000);
if((X1>0)&&(Y1>0)&&(Z1>0))
{
SendString("X和Y的坐标是 (");
SendString("0.");
d3 = (unsigned char)(xx%1000/100);
d2 = (unsigned char)(xx%100/10);
d1 = (unsigned char)(xx%10);
SendData(d3+0x30);
SendData(d2+0x30);
SendData(d1+0x30);
SendString(" , ");
SendString("0.");
d3 = (unsigned char)(yy%1000/100);
d2 = (unsigned char)(yy%100/10);
d1 = (unsigned char)(yy%10);
SendData(d3+0x30);
SendData(d2+0x30);
SendData(d1+0x30);
SendString(")\r\n");
SendString("请查照色度表得到对应的颜色\r\n");
}
else
SendString("值溢出,错误\r\n");
}
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;// Stop WDT
__enable_interrupt(); //使能中断
init_uart();
delay(500);
SendString("欢迎使用\r\n");
SendString("请发送十六进制的aa以开始转换\r\n");
test_ack();
TCS_4314_ID = READ_BYTE (0X84);//读ID号
WRITE_BYTE(0X80,0X03);//打开ADC
WRITE_BYTE(0X87,0X30);//增益64倍
//WRITE_BYTE(0X87,0X06);//最敏感的部分设置增益00(1×)和预分频器110(除以64)时
while(1)
{
if(rx_data == 0xaa)
{
RGB_read();
RGB_UART_SEND();
calculateCoordinate();
}
LPM3;
}
}
/////////////////////////////////////////////////////uart.h///////////////////////////////////////
#include " msp430f1232.h"
#include "uart.h"
#include "main.h"
#include "iic.h"
unsigned char Tx_busy = 0;
unsigned char rx_data = 0;
void init_uart()
{
P3SEL |= 0x30; // P3.4,5 = USART0 TXD/RXD
ME2 |= UTXE0 + URXE0; // Enabled USART0 TXD/RXD
UCTL0 |= CHAR; // 8-bit character
UTCTL0 |= SSEL0; // UCLK = ACLK
UBR00 = 0x03;
UBR10 = 0;
UMCTL0 = 0x4A; // no modulation
UCTL0 &= ~SWRST; // Initalize USART state machine
IE2 |= URXIE0 + UTXIE0; // Enabled USART0 RX interrupt
IFG2 &= ~UTXIFG0;
}
//----------------------------发送串口数据---------
void SendData(unsigned char dat)
{
while(Tx_busy);
Tx_busy = 1;
TXBUF0 = dat;
}
//----------------------------发送字符串-----------
void SendString(char *s)
{
while (*s) //检测字符串结束标志
{
SendData(*s++); //发送当前字符
}
}
//----------------------------------发送中断-----------
#pragma vector=USART0TX_VECTOR
__interrupt void usart0_tx (void)
{
Tx_busy = 0;
}
//-----------------------------------接收中断----------
#pragma vector=USART0RX_VECTOR
__interrupt void usart0_rx (void)
{
rx_data = RXBUF0;
LPM3_EXIT;
//TXBUF0 = RXBUF0; // RXBUF0 to TXBUF0
}
|