[范例教程] TCS3200颜色传感器51单片机例程

[复制链接]
1047|0
 楼主| vivilyly 发表于 2023-10-24 16:00 | 显示全部楼层 |阅读模式



  1. TCS3200颜色传感器51例程
  2. //==============LCD1602接口连接方法=====================
  3. /*-----------------------------------------------------
  4.        |DB0-----P0.0 | DB4-----P0.4 | RW-------P2.3    |
  5.        |DB1-----P0.1 | DB5-----P0.5 | RS-------P2.4    |
  6.        |DB2-----P0.2 | DB6-----P0.6 | E--------P2.2    |
  7.        |DB3-----P0.3 | DB7-----P0.7 |
  8.     ---------------------------------------------------*/
  9. //================================================*/              
  10. #define LCM_Data     P0    //LCD1602数据接口
  11. #define Busy         0x80   //用于检测LCM状态字中的Busy标识
  12. sbit    LCM_RW     = P2^3;  //读写控制输入端,LCD1602的第五脚
  13. sbit    LCM_RS     = P2^4;  //寄存器选择输入端,LCD1602的第四脚
  14. sbit    LCM_E      = P2^2;  //使能信号输入端,LCD1602的第6脚

  15. //=================颜色传感模块连接=====================
  16. /*-----------------------------------------------------
  17.        |EO-----GND
  18.        |S0-----VCC | S2-----P2.0 | OUT-------P3.5
  19.        |S1-----VCC | S3-----P2.1 |
  20.   ---------------------------------------------------*/
  21. sbit    tcs230_s2=P2^0;//TCS230 S2接单片机P2.0
  22. sbit    tcs230_s3=P2^1;//TCS230 S3接单片机P2.1
  23. sbit    tcs230_en=P3^0; //TCS230 EN(E0)接GND
  24. //**************函数声明***************************************
  25. void    WriteDataLCM                (uchar WDLCM);//LCD模块写数据
  26. void    WriteCommandLCM        (uchar WCLCM,BuysC); //LCD模块写指令
  27. uchar   ReadStatusLCM(void);//读LCD模块的忙标
  28. void    DisplayOneChar(uchar X,uchar Y,uchar ASCII);//在第X+1行的第Y+1位置显示一个字符
  29. void    LCMInit(void);//LCD初始
  30. void    DelayMs(uint Ms);//1MS基准延时程序
  31. void    baipingheng();//白平衡子程序
  32. void    celiang();//实际颜色程序
  33. uint    ryz,gyz,byz;//分别定义红色因子 绿色因子 蓝色因子
  34. uint    rb,gb,bb;//RGB值
  35. uchar   tab1[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  36. //***********************主程序******************************
  37. main()   
  38. {   
  39.    TMOD=0x51;//设定T0以工作方式1定时10毫秒
  40.    LCMInit();//LCD初始
  41.    baipingheng();//上电时先白平衡一次
  42.    while(1)
  43.    {
  44.        celiang();//颜色测试
  45.        DisplayOneChar(0, 0,'R');//以十进制显示RGB中红色的分值
  46.        DisplayOneChar(0, 1, rb/100+0x30); //显示百位数据
  47.        DisplayOneChar(0, 2, rb/10%10+0x30);//显示十位数据
  48.        DisplayOneChar(0, 3, rb%10+0x30);//显示个位数据
  49.        DisplayOneChar(0, 5,'G');//以十进制显示RGB中绿色的分值
  50.        DisplayOneChar(0, 6, gb/100+0x30); //显示百位数据
  51.        DisplayOneChar(0, 7, gb/10%10+0x30);
  52.        DisplayOneChar(0, 8, gb%10+0x30);
  53.        DisplayOneChar(0, 10,'B');//以十进制显示RGB中蓝色的分值
  54.        DisplayOneChar(0, 11, bb/100+0x30);
  55.        DisplayOneChar(0, 12, bb/10%10+0x30);
  56.        DisplayOneChar(0, 13, bb%10+0x30);
  57.        //*****在LCD1602的第二行以16进制显示RGB*******************
  58.        DisplayOneChar(1, 1, tab1[rb/16]);
  59.        DisplayOneChar(1, 2, tab1[rb%16]);
  60.        DisplayOneChar(1, 3, 'H');
  61.        DisplayOneChar(1, 6, tab1[gb/16]);
  62.        DisplayOneChar(1, 7, tab1[rb%16]);
  63.        DisplayOneChar(1, 8, 'H');
  64.        DisplayOneChar(1, 11,tab1[bb/16]);
  65.        DisplayOneChar(1, 12,tab1[bb%16]);
  66.        DisplayOneChar(1, 13,'H');
  67.        DelayMs(250);//每隔0.25秒测试一次颜色
  68.    }
  69. }
  70. //******************************************************
  71. //白平衡子程序
  72. void   celiang()
  73. {
  74.      //*********求R值************************************
  75.      TH0=(65536-10000)/256;
  76.            TL0=(65536-10000)%256;
  77.      TH1=0;
  78.      TL1=0;
  79.      tcs230_s2=0;
  80.      tcs230_s3=0;//选择红色滤光器
  81.      tcs230_en=0;
  82.      TR0=1;//10毫秒开始计时
  83.      TR1=1;//开始计数
  84.      while(TF0==0);//等待定时器溢出
  85.      TF0=0;//清楚定时器0溢出标志
  86.      TR0=0;//关闭定时0
  87.      TR1=0;
  88.      rb=(unsigned long)(TH1*256+TL1)*255/ryz;
  89.      if(rb>255)rb=255;//判断RGB值是否合法
  90.      //***********求B值**************************************
  91.      TH0=(65536-10000)/256;
  92.            TL0=(65536-10000)%256;
  93.      TH1=0;
  94.      TL1=0;
  95.      tcs230_s2=0;
  96.      tcs230_s3=1;//选择蓝色滤光器
  97.      TR0=1;//10毫秒开始计时
  98.      TR1=1;//开始计数
  99.      while(TF0==0);//等待定时器溢出
  100.      TF0=0;//清楚定时器0溢出标志
  101.      TR0=0;//关闭定时0
  102.      TR1=0;
  103.      bb=(unsigned long)(TH1*256+TL1)*255/byz;
  104.      if(bb>255)bb=255;//判断RGB值是否合法     
  105.      //***********求G值**************************************   
  106.      TH0=(65536-10000)/256;
  107.            TL0=(65536-10000)%256;
  108.      TH1=0;
  109.      TL1=0;
  110.      tcs230_s2=1;
  111.      tcs230_s3=1;//选择绿色滤光器
  112.      TR0=1;//10毫秒开始计时
  113.      TR1=1;//开始计数
  114.      while(TF0==0);//等待定时器溢出
  115.      TF0=0;//清楚定时器0溢出标志
  116.      TR0=0;//关闭定时0
  117.      TR1=0;
  118.      tcs230_en=1;
  119.      gb=(unsigned long)(TH1*256+TL1)*255/gyz;
  120.      if(gb>255)gb=255;//判断RGB值是否合法  
  121. }
  122. //******************************************************
  123. //白平衡子程序
  124. void    baipingheng()
  125. {
  126.      //**************求取红色因子***********************
  127.      TH0=(65536-10000)/256;
  128.            TL0=(65536-10000)%256;
  129.      TH1=0;
  130.      TL1=0;
  131.      tcs230_s2=0;
  132.      tcs230_s3=0;//选择红色滤光器
  133.      tcs230_en=0;
  134.      TR0=1;//10毫秒开始计时
  135.      TR1=1;//开始计数
  136.      while(TF0==0);//等待定时器溢出
  137.      TF0=0;//清楚定时器0溢出标志
  138.      TR0=0;//关闭定时0
  139.      TR1=0;
  140.      ryz=TH1*256+TL1;//其实这里的比例因子应该为255/(TH1*256+TL1)
  141.      //**************求取蓝色因子***********************
  142.      TH0=(65536-10000)/256;
  143.            TL0=(65536-10000)%256;
  144.      TH1=0;
  145.      TL1=0;
  146.      tcs230_s2=0;
  147.      tcs230_s3=1;//选择蓝色滤光器
  148.      TR0=1;//10毫秒开始计时
  149.      TR1=1;//开始计数
  150.      while(TF0==0);//等待定时器溢出
  151.      TF0=0;//清楚定时器0溢出标志
  152.      TR0=0;//关闭定时0
  153.      TR1=0;
  154.      byz=TH1*256+TL1;//其实这里的比例因子应该为255/(TH1*256+TL1)
  155.      //**************求绿红色因子***********************
  156.      TH0=(65536-10000)/256;
  157.            TL0=(65536-10000)%256;
  158.      TH1=0;
  159.      TL1=0;
  160.      tcs230_s2=1;
  161.      tcs230_s3=1;//选择绿色滤光器
  162.      TR0=1;//10毫秒开始计时
  163.      TR1=1;//开始计数
  164.      while(TF0==0);//等待定时器溢出
  165.      TF0=0;//清楚定时器0溢出标志
  166.      TR0=0;//关闭定时0
  167.      TR1=0;
  168.      tcs230_en=1;
  169.      gyz=TH1*256+TL1;//其实这里的比例因子应该为255/(TH1*256+TL1)
  170. }
  171. /*======================================================================
  172. LCM初始化
  173. ======================================================================*/
  174. void LCMInit(void)
  175. {
  176. LCM_Data = 0;
  177. WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
  178. DelayMs(5);
  179. WriteCommandLCM(0x38,0);
  180. DelayMs(5);
  181. WriteCommandLCM(0x38,0);
  182. DelayMs(5);
  183. WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
  184. WriteCommandLCM(0x08,1); //关闭显示
  185. WriteCommandLCM(0x01,1); //显示清屏
  186. WriteCommandLCM(0x06,1); // 显示光标移动设置
  187. WriteCommandLCM(0x0C,1); // 显示开及光标设置
  188. DelayMs(100);
  189. }
  190. //==============================LCD1602显示子程序================================================
  191. // 写数据函数: E =高脉冲 RS=1 RW=0
  192. //======================================================================*/
  193. void WriteDataLCM(uchar WDLCM)
  194. {
  195. ReadStatusLCM(); //检测忙
  196. LCM_Data = WDLCM;
  197. LCM_RS = 1;
  198. LCM_RW = 0;
  199. LCM_E = 0; //若晶振速度太高可以在这后加小的延时
  200. LCM_E = 0; //延时
  201. LCM_E = 1;
  202. }
  203. /*====================================================================
  204.   写指令函数: E=高脉冲 RS=0 RW=0
  205. ======================================================================*/
  206. void WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测
  207. {
  208. if (BuysC) ReadStatusLCM(); //根据需要检测忙
  209. LCM_Data = WCLCM;
  210. LCM_RS = 0;
  211. LCM_RW = 0;
  212. LCM_E = 0;
  213. LCM_E = 0;
  214. LCM_E = 1;
  215. }
  216. /*====================================================================
  217.   正常读写操作之前必须检测LCD控制器状态:E=1 RS=0 RW=1;
  218.   DB7: 0 LCD控制器空闲,1 LCD控制器忙。
  219.   读状态
  220. ======================================================================*/
  221. uchar ReadStatusLCM(void)
  222. {
  223. LCM_Data = 0xFF;
  224. LCM_RS = 0;
  225. LCM_RW = 1;
  226. LCM_E = 0;
  227. LCM_E = 0;
  228. LCM_E = 1;
  229. while (LCM_Data & Busy); //检测忙信号  
  230. return(LCM_Data);
  231. }
  232. /*======================================================================
  233. 功 能:     在1602 指定位置显示一个字符:第一行位置0~15,第二行16~31
  234. 说 明:     第 X 行,第 y 列  注意:字符串不能长于16个字符
  235. ======================================================================*/
  236. void DisplayOneChar( uchar X, uchar Y, uchar ASCII)
  237. {
  238.   X &= 0x1;
  239.   Y &= 0xF; //限制Y不能大于15,X不能大于1
  240.   if (X) Y |= 0x40; //当要显示第二行时地址码+0x40;
  241.   Y |= 0x80; // 算出指令码
  242.   WriteCommandLCM(Y, 0); //这里不检测忙信号,发送地址码
  243.   WriteDataLCM(ASCII);
  244. }
  245. /*====================================================================
  246.   设定延时时间:x*1ms
  247. ====================================================================*/
  248. void DelayMs(uint Ms)
  249. {
  250.   uint i,TempCyc;
  251.   for(i=0;i<Ms;i++)
  252.   {
  253.     TempCyc = 250;
  254.     while(TempCyc--);
  255.   }
  256. }


您需要登录后才可以回帖 登录 | 注册

本版积分规则

113

主题

2034

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部