打印

m​s​p​4​0​f​1​2​3​2​驱​动​T​C​S​4​3​1​4...

[复制链接]
1217|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dirtwillfly|  楼主 | 2015-5-11 20:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
////////////////////////////////////////////////////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
}

相关帖子

沙发
冰河w| | 2015-5-19 21:58 | 只看该作者
感谢楼主分享

使用特权

评论回复
板凳
dirtwillfly|  楼主 | 2015-5-19 22:01 | 只看该作者

不客气

使用特权

评论回复
地板
598330983| | 2015-5-31 08:26 | 只看该作者
过程很清楚,看过之后觉得是不是可以写的更合理更可读呢,我要试试

使用特权

评论回复
5
gaoyang9992006| | 2015-5-31 20:56 | 只看该作者
如果那些芯片厂商提供各种版本的驱动函数就爽歪歪了,那样也会增加销售量,就纳闷了,那些厂商不懂这种道理吗

使用特权

评论回复
6
mintspring| | 2015-5-31 21:20 | 只看该作者
头文件是自己写的吗?如果是自己写的,真是太厉害了。

使用特权

评论回复
7
dirtwillfly|  楼主 | 2015-6-1 08:25 | 只看该作者
gaoyang9992006 发表于 2015-5-31 20:56
如果那些芯片厂商提供各种版本的驱动函数就爽歪歪了,那样也会增加销售量,就纳闷了,那些厂商不懂这种道理 ...

估计是没人干这活,需要很多时间和人力的

使用特权

评论回复
8
FireRiver9| | 2015-6-7 15:28 | 只看该作者
这个整明白了,会对串口和I2c的学习有很大帮助

使用特权

评论回复
9
dirtwillfly|  楼主 | 2015-6-7 15:54 | 只看该作者
FireRiver9 发表于 2015-6-7 15:28
这个整明白了,会对串口和I2c的学习有很大帮助

呵呵,仅供参考。
每个人的应用不一样,程序会有一些差异

使用特权

评论回复
10
309030106| | 2015-6-12 20:59 | 只看该作者
谢谢版主了

使用特权

评论回复
11
dirtwillfly|  楼主 | 2015-6-12 22:38 | 只看该作者

不客气

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:欢迎进入TI MCU论坛      21ic TI技术交流1群:61549143(已满),  21ic TI技术交流2群:311421422 我的博客:http://blog.timcu.com/

1181

主题

34894

帖子

1117

粉丝