基于STM32F407ZGT6和TCS3200的颜色采集,使用MATLAB制作上位机,利用串口进行通信(标准库)

目录

一、引言

1、设计要求

2、软硬件的使用

二、Keil代码部分

1、定时器

2、TCS3200设置

3、串口设置

三、上位机部分

四、参考资料


一、引言

暑期实践的课题,题目和标题是一样的。

使用的是普中·天马F407板子,上位机使用MATLAB制作,都是在网上找的资料。

工程文件在主页里面有,不需要积分,可以直接下载。

工程文件在主页里面有,不需要积分,可以直接下载。

工程文件在主页里面有,不需要积分,可以直接下载。

1、设计要求

设计一套固体颜色自动检测以及显示的系统;

颜色算法可靠、识别速度不低于1s;

将颜色检测结果在上位机分类显示。

2、软硬件的使用

使用F407作为单片机,MATLAB作为上位机制作软件。

软件:

keil5 MDK和MATLAB 2023a.

硬件:

TCS3200颜色传感器,STM32407ZGT6,TFT3.5-ILI9488彩屏

二、Keil代码部分

1、定时器

使用的是定时器5,定时器用来记录每个滤波器发送过来的脉冲数,采用向上计数的方式。

//**********************************************//定时器(用来计数每个滤波器开启时发过来的脉冲数)
void TIM5_Init()                                 
{
	GPIO_InitTypeDef GPIO_InitStructure;//设置GPIO为TIM的时钟输入引脚
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//设置定时器参数
	NVIC_InitTypeDef NVIC_InitStructure;//设置中断优先级
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//打开PB端口时钟    
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;               
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;//gpio模式设置为复用模式
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;   
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//设置为推挽
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;//不上下拉
	GPIO_Init(GPIOA,&GPIO_InitStructure);                  
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5);//设置GPIO复用为中断定时器输入
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);//使能TIM时钟
    TIM_TimeBaseStructure.TIM_Period = 30000;//自动重装载值
    TIM_TimeBaseStructure.TIM_Prescaler =0; //定时器分频
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
    TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
    TIM_ClearITPendingBit(TIM5,TIM_IT_Update);//清除溢出中断标志位
    TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE );//使能定时器更新中断
	 
TIM_TIxExternalClockConfig(TIM5,TIM_TIxExternalCLK1Source_TI1,TIM_ICPolarity_Falling,15);
  TIM_SetCounter(TIM5,0);//计数器清零
  TIM_Cmd(TIM5, ENABLE);//使能TIMx外设
  NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);   				
}

2、TCS3200设置

通过对引脚输出不同的高低电平来达到开启不同的滤波器,滤波器开启的时间用延时来确定。

先开启不同的滤波器,通过控制Pin_2、Pin_3引脚的高低电平来控制,然后使用定时器来记录发送过来的方波数,检测200ms,后将定时器内数据存储到数组中,重置定时器。

//*************************************//TCS3200滤波过程(检测)开启不同的滤波器的过程
void TIM5_CAP(void)                             
{
	GPIO_ResetBits(GPIOA,s2_PIN);
	GPIO_ResetBits(GPIOA,s3_PIN);      //红色滤波
	TIM_SetCounter(TIM5,0);
	delay_ms(200);		
	count=TIM_GetCounter(TIM5); 
  cnt[0] = count;  		
  TIM_SetCounter(TIM5,0);
	
	GPIO_SetBits(GPIOA,s2_PIN);
	GPIO_SetBits(GPIOA,s3_PIN);       //绿色滤波
	TIM_SetCounter(TIM5,0);
	delay_ms(200);
	count=TIM_GetCounter(TIM5); 
	cnt[1] = count; 
  TIM_SetCounter(TIM5,0);	
	
	GPIO_ResetBits(GPIOA,s2_PIN);
	GPIO_SetBits(GPIOA,s3_PIN);        //蓝色滤波
	TIM_SetCounter(TIM5,0);
  delay_ms(200);	 
  count=TIM_GetCounter(TIM5);					
	cnt[2] = count; 		
  TIM_SetCounter(TIM5,0);			
											
}

3、串口设置

通过串口输出检测到的数据,屏幕上显示RGB的值,同时串口接收上位机传输来的数据,串口先输入数字2,开启白平衡,输入数字1,为开启颜色检测。

白平衡和检测过后,会通过串口输出有三个变量的数组。R,G,B.

//***************************//串口1中断服务程序;利用串口收发数据,在串口处输入2,为白平衡,输入1,为开始检测

void USART1_IRQHandler(void)                	
{
	unsigned char Res = 0;
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
	{
		Res = USART_ReceiveData(USART1);	        //读取接收到的数据

//**********************************************燕颜色检测过程
		
   if (Res=='1')
    {
			while(1)
			{
				TIM5_CAP();//开启滤波
				LCD_Clear(WHITE);//刷新屏幕
				LCD_ShowFontHZ(80,10,"颜色检测");
				LCD_ShowString(10,40,tftlcd_data.width,tftlcd_data.height,24,"R:");
				LCD_ShowString(10,70,tftlcd_data.width,tftlcd_data.height,24,"G:");	
				LCD_ShowString(10,100,tftlcd_data.width,tftlcd_data.height,24,"B:");
				LCD_ShowNum(120, 40,(int)(cnt[0]*RGB[0]),3,24);
				LCD_ShowNum(120, 70,(int)(cnt[1]*RGB[1]),3,24);
				LCD_ShowNum(120, 100,(int)(cnt[2]*RGB[2]),3,24);
				
				R = (int)(cnt[0]*RGB[0]);
			  G = (int)(cnt[1]*RGB[1]);
			  B = (int)(cnt[2]*RGB[2]);
			      if(R>255)
							R=255;
						if(G>255)
							G=255;
						if(B>255)
							B=255;
			
				printf("%d,%d,%d\r\n",R,G,B);

			}
		}
	//*************************************************//白平衡
		if (Res=='2')
		{
			TIM5_CAP();//开启滤波
			//通过白平衡测试,计算得到白色物体RGB值255与1s内三色光脉冲数的RGB比例因子 
			RGB[0] = 255.0/ cnt[0] ;   //红色光比例因子    
			RGB[1] = 255.0/ cnt[1] ;   //绿色光比例因子
			RGB[2] = 255.0/ cnt[2] ;   //蓝色光比例因子
				
			LCD_Clear(WHITE);//屏幕刷新
			LCD_ShowFontHZ(80,10,"颜色检测");
			LCD_ShowString(10,40,tftlcd_data.width,tftlcd_data.height,24,"R:");
			LCD_ShowString(10,70,tftlcd_data.width,tftlcd_data.height,24,"G:");	
			LCD_ShowString(10,100,tftlcd_data.width,tftlcd_data.height,24,"B:");
			LCD_ShowNum(100, 40, RGB[0],3,24);  
			LCD_ShowNum(100, 70,RGB[1],3,24);
			LCD_ShowNum(100, 100,RGB[2],3,24); 
      LCD_ShowString(80,160,tftlcd_data.width,tftlcd_data.height,24,"White Blance");//白平衡结束

			R = (int)(cnt[0]*RGB[0]);
			G = (int)(cnt[1]*RGB[1]);
			B = (int)(cnt[2]*RGB[2]);
						if(R>255)
							R=255;
						if(G>255)
							G=255;
						if(B>255)
							B=255;
			printf("%.2f,%.2f,%.2f\r\n",RGB[0],RGB[1],RGB[2]);

		}	
			
	}		
}

三、上位机部分

上位机采用MATLAB App Design功能进行设计,主要实现接收单片机通过串口传输过来的数据,和向单片机通过串口发送指令。在运行上位机之前要将串口插上,不然会报错。

使用的是MATLAB 2023a

上位机面板:

上位机在编辑过程中主要使用各个部分的回调函数。

首先点击App,选择设计App,选择空白面板即可。

左侧选择按钮,放置在面板上

右侧更改按钮内容:

 右键单击选择回调

搜索串口的回调部分内容:

  % Code that executes after component creation
        function startupFcn(app)
            [app.COMS app.port] = get_com_ports();
            app.DropDown.Items=app.COMS;
            app.port_use=app.port(1);
            app.s=serial(app.port_use,'BaudRate',115200,'Terminator','LF');
        end

其中的get_com_ports()是用.m文件编写的串口搜索程序,建在同一个文件夹即可。我们在App中直接调用就可以获取到串口号。

.m内容:

function [COMS port] = get_com_ports()%获取串口号函数
command = 'wmic path win32_pnpentity get caption /format:list | find "COM"';
[status, cmdout] = system (command);
cmdout = strread(cmdout,'%s','delimiter','='); %按分隔符拆分字符串数组
if numel(cmdout)>0
    j=1;
    for i = 1:numel(cmdout)  %numel 返回元素个数
        if strcmp(cmdout{i}(1:7),'Caption')
            COMS{j} = cmdout{i+1};
            j=j+1;
        end
    end
    COMS_split=cell2mat(COMS);
    COMS_split=split(COMS_split,'(');%通过左括号将字符串分割
    j=1;
    for i = 1:numel(COMS_split)  %numel 返回元素个数
        if strcmp(COMS_split{i}(1:3),'COM')
            port_temp{j} = COMS_split{i};
            j=j+1;
        end
    end
    port_temp=split(port_temp,')');%通过右括号将字符串分割
    j=1;
    for i = 1:(numel(port_temp)-1)  %numel 返回元素个数
        if strcmp(port_temp{i}(1:3),'COM')
            port{j} = port_temp{i};
            j=j+1;
        end
    end
elseif numel(cmdout)==0
    COMS="没有搜索到串口";
    port="null";
    errordlg('没有搜索到任何可用端口');
end
end 

串口选择是左侧下拉框器件。选择回调,在回调中输入检测电脑串口号的程序,让其能选择使用那个串口。

        % Value changed function: DropDown
        function DropDownValueChanged(app, event)
            value = app.DropDown.Value;
            for i=1:length(app.DropDown.Items)    %遍历
                if strcmp(value,app.DropDown.Items{i})
                     app.port_use=app.port(1);%获得端口
                     app.s=serial(app.port_use,'BaudRate',115200,'Terminator','LF');
                end
            end
        end

 打开串口按键,和前面的搜索串口按键一样设置,只是回调中内容不同。我这里的打开串口,并没有真正的打开,只是按下之后有一次反馈。如果在这里写入打开串口的程序,会出现,打开串口之后,LCD屏幕复位。真正的打开串口程序在后面会写到。

    % Button pushed function: Button_2
        function Button_2Pushed(app, event)

            if app.lamp_flag==1%判断是否打开
                    app.Lamp.Color='g';
                    app.Button_2.Text="关闭串口";
                    app.lamp_flag=0;
                
            else       
                    app.Lamp.Color='r';
                    app.Button_2.Text="打开串口";
                    app.lamp_flag=1;
            end
        end

输出结果按键也是在左侧选择按钮即可,这里点击后才是打开串口,进行一次数据传输。

serial()这个函数就是打开串口的,后面是设置工作方式,波特率等。

打开一次后要直接关闭他,fclose()。否则下次使用串口,会提示串口被占用。

fgetl()是提取传输过来的数据,用split()分割。三个数据赋值,后进行颜色识别。

        % Button pushed function: Button_4
        function Button_4Pushed(app, event)

            if app.lamp_flag==0;
                app.s=serial('com5');
                set(app.s,'BaudRate', 115200,'DataBits',8,'Parity','none');
                app.s.DataTerminalReady='off';
                fclose(instrfind);
                fopen(app.s);
                a=fgetl(app.s);
                fclose(app.s);
                a=a(1:length(a)-1)
                a=split(a,',')
                R=a(1,1)
                G=a(2,1)
                B=a(3,1)
                app.Label_2.Text=R;
                app.Label_3.Text=G;
                app.Label_4.Text=B;

白平衡和开始检测也是左侧按钮,选择回调,点击后,先将以前开启的串口关闭,后再次开启串口使用fprintf()将数据发送到串口,单片机接收数据,执行操作

   % Button pushed function: Button_5
        function Button_5Pushed(app, event)
            if app.lamp_flag==0;
                app.s=serial('com5');
                set(app.s,'BaudRate', 115200,'DataBits',8,'Parity','none');
                app.s.DataTerminalReady='off';
                fclose(instrfind);
                fopen(app.s);
                num=['2']
                fprintf(app.s,num);%将数据发送至串口
                value=app.s;
                disp(value)
                fclose(app.s);
            end
        end

        % Button pushed function: Button_6
        function Button_6Pushed(app, event)
            if app.lamp_flag==0;
                app.s=serial('com5');
                set(app.s,'BaudRate', 115200,'DataBits',8,'Parity','none');
                app.s.DataTerminalReady='off';
                fclose(instrfind);
                fopen(app.s);
                num=['1']
                fprintf(app.s,num);%将数据发送至串口
                value=app.s;
                disp(value)
                fclose(app.s);
            end  
        end
    end

至于R,G,B值的显示,使用到的是左侧的文本,想要更改显示内容,只需要在按钮回调中写入

app.Label_2.Text=R;

app.Label_3.Text=G;

app.Label_4.Text=B;

就可以让RGB的数值显示,

中间区域的图像绘制,使用到的是左侧坐标区,

他的显示也是写在按钮回调中,

set(rectangle(app.UIAxes),'Edgecolor',[0,0,0],'LineWidth',0.8,'Facecolor',yanse);

四、参考资料

1.基于stm32f103的颜色识别,写的很好,有原理什么的,我主要参考的这个博客:https://blog.csdn.net/weixin_50950634/article/details/114645247?

2.上位机的制作主要是参考B站UP主的教程,教的比较好,全部都跟着做就能做好:

Matlab串口通信之获取设备端口号[毕设如此简单之上位机篇(四)]_哔哩哔哩_bilibili

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 你好,关于代码生成TCS3200颜色传感器STM32的问题,我可以回答。 首先,为了使用TCS3200颜色传感器,需要连接到STM32单片机上,具体可以参考传感器和单片机的数据手册进行接线。然后,在STM32的开发环境中,使用对应的编程语言(如C语言)编写代码,通过STM32的GPIO口和定时器等模块来实现对传感器的读取和数据处理。 以下是一个使用STM32TCS3200颜色传感器的示例代码(仅供参考): ```c #include "stm32f10x.h" // 定义TCS3200传感器的引脚 #define S0_PIN GPIO_Pin_0 #define S1_PIN GPIO_Pin_1 #define S2_PIN GPIO_Pin_2 #define S3_PIN GPIO_Pin_3 #define OUT_PIN GPIO_Pin_4 #define TCS3200_PORT GPIOA // 定义读取颜色值的变量 uint16_t redValue, greenValue, blueValue; void TCS3200_Init(void) { // 配置TCS3200传感器的引脚为输出模式 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = S0_PIN | S1_PIN | S2_PIN | S3_PIN | OUT_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(TCS3200_PORT, &GPIO_InitStructure); // 设置TCS3200传感器的输出频率为20%(即默认红色输出) GPIO_ResetBits(TCS3200_PORT, S0_PIN); GPIO_SetBits(TCS3200_PORT, S1_PIN); } void TCS3200_ReadColor(void) { // 读取TCS3200传感器的颜色值 GPIO_ResetBits(TCS3200_PORT, S2_PIN); GPIO_SetBits(TCS3200_PORT, S3_PIN); Delay(10); redValue = TIM_GetCounter(TIM2); GPIO_ResetBits(TCS3200_PORT, S3_PIN); GPIO_SetBits(TCS3200_PORT, S2_PIN); Delay(10); greenValue = TIM_GetCounter(TIM2); GPIO_SetBits(TCS3200_PORT, S3_PIN); GPIO_SetBits(TCS3200_PORT, S2_PIN); Delay(10); blueValue = TIM_GetCounter(TIM2); } int main(void) { // 初始化TCS3200传感器 TCS3200_Init(); // 初始化定时器,用于计算颜色值 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // 启动定时器 TIM_Cmd(TIM2, ENABLE); while (1) { // 读取TCS3200传感器的颜色TCS3200_ReadColor(); // 处理 ### 回答2: 代码生成tcs3200颜色传感器stm32需要经过以下几步: 1. 引入相应的库文件:在stm32的开发环境中,需要引入相应的库文件以支持tcs3200颜色传感器的使用。可以通过包管理工具等方式下载并添加到工程中。 2. 初始化引脚:根据tcs3200颜色传感器的引脚连接情况,通过设置GPIO引脚的方式初始化传感器的引脚,包括S0、S1、S2和S3引脚,以及OUT引脚。 3. 设置S0、S1引脚:根据需要设置S0、S1引脚的电平状态,以选择采样频率。例如,设置为低电平可以选择2%的采样频率。 4. 设置S2、S3引脚:根据需要设置S2、S3引脚的电平状态,以选择输出频率。例如,设置为低电平可以选择非调制输出频率。 5. 读取颜色数据:通过读取OUT引脚的电平状态,可以获取到tcs3200传感器所感知到的颜色数据。根据不同的颜色,电平状态会有所不同。 6. 处理颜色数据:可以根据实际需求对颜色数据进行进一步的处理和判断。例如,可以根据电平状态判断出RGB值,或者通过查表的方式将电平状态映射为具体颜色。 7. 数据应用:根据实际需求,可以将获取到的颜色数据应用到不同的场景中。例如,可以用于颜色识别、颜色排序等应用中。 总结一下,代码生成tcs3200颜色传感器stm32的过程分为初始化引脚、设置S0、S1、S2、S3引脚状态、读取颜色数据、处理颜色数据以及数据应用等步骤。通过这些步骤可以实现对tcs3200颜色传感器的控制使用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值