资讯详情

大一下暑假留校训练记录

7.24 第一天 周六

:开会(介绍活动) : 1.TC264开发环境是ads,严格按照ads操作说明书。下载程序到MCU不需要像STC那样用ISP,直接用ads里面有一个小黄点。 逐飞库TC264各量的分析 2.在用ads下载时下载成功显示的“Flashing was successfull” 在这里插入图片描述

: 1.写了一个我眼中的PID” 2.FTM模块是由多个FTM用于计数的寄存器组成,也可以说是一个神奇的模块(高级定时器模块), [跟我学OSKinetis]第8课-FTM的PWM、输入捕获,正交解码 3.数字舵机比模拟舵机内置更多MCU,但这并不意味着数字舵机比模拟舵机更容易使用 4.核心板和单片机,母版是测试单片机加很多扩展 5.驱动电路可以简单地理解一个升压电路 6.USB转TTL模块的作用是计算机供电是5V,但通信模块对应3.3V这个模块可以理解降压器的电压 7.NRF插入核心板发送蓝牙数据的模块 8.ADC:数字信号连续模拟信号转离散


7.25 第二天 周日

: 继续完善PID控制博客,看C语言 1.龙邱科技TC264 2.龙邱科技类似于逐飞科技,是学习智能车的好地方。两者的淘宝详细页面都有相应的学习资料 逐飞TC264淘宝详细页面 龙邱TC264淘宝详细页面 3.Debug模式与Release,可能出现Debug不报错,Release报错的情况 4.ads导入工程 5.校赛使用车模(C车模)

: 安装Qt5.9.4、Cmake3.20.5、Opencv4.53,Cmake和Qt搞定了,Opencv还没有弄好 : 1.继续安装opencv,MinGW 就是 GCC 的 Windows 版本 。 mingw安装包(官网打不开,这是直接找的安装包) 2.win10系统下的QT cmake opencv安装(小白,超详细教程) 最后一步mingw32-make的前提是要先安装mingw 3.排线母头是排座(插入),公头尖


7.26 第三天 周一

继续思考如何在这里Qt下使用opencv,在11点击暂时放弃,真的不能出来,以后再说 

1.Opencv安装路径不能包括中文 2.windows同一个盘子里不能有两个名字相同的文件。大小写的变化不能改变文件的属性。例如,它不能被称为QQ和qq,两者不共存,会导致你把它们放在同一个目录中,然后被吃进前一个目录

在徐学长和王学长的帮助下,台风天的工作终于解决了opencv这个问题太令人兴奋了继续看图像处理go文件了 

1.解决了头文件opencv2\opencv.hpp: No such file or directory的问题 2.有时候在Qt中编译出错可以尝试把它注释掉,在.pro和MATLAB特殊文件中的注释是#,其他一般是/// 3.文件目录在windows一般选择用/而不是 4.被注释的行会报错,但通过注释被强行忽略

5.#include <opencv2/imgproc/types_c.h>,这句话的添加是为了冲走opencv我理解不同版本造成的,但感觉不是。具体细节需要研究。

6.点“readData然后去找存储的图片,然后J读下一帧,K读前一阵,G一直播放,再次暂停。 模块结束 1.opencv只只是一个工具,只要工具掌握了它的使用 2.总钻风的差异和算法:这是用两个像素点的值计算的最简单的摄像头算法,abs(a-b)*100/(a b)),乘100是为了避免浮点数,加快运算速度 3.*CCD(英文全称:Charge-coupled Device,中文全称:电荷耦合元件)是一种可将光学信号转换为数字信号的光学器件 线性CCD简介 线性CCD & 摄像头搜线方案 By逐飞科技 这就是巡线

4.时序图:二维图按时间顺序纵向排列 5.VScode里面将UTF-8替换为GBK,处理中文乱码问题 6.#ifdef与#endif作用及用法 7.学习名称空间,using namespace std

继续学习图像处理 

1.与龙邱一起飞行TC264是根据英飞凌公司的样片制作的 2.基于TC264摄像头、编码器和舵机使用视频教程–逐飞科技 3.RGB(红绿蓝):常说的显示器RGB由这三种原色组成的色域。 4.学习成像原理


7.27 第四天 周二

继续学习图像处理 

1.获取灰度直方图:通过直方图能获取更好的边界阈值,实质为两个数组,一个用来记录像素点的灰度值,另一个记录此灰度值出现的个数,根据两个数组绘制直方图(初中学的); 类似这种 ↓ 这种 ↓

数字图像处理(15): 灰度直方图(matplotlib 和OpenCV 绘制直方图)

归一化直方图:指将纵坐标换为此灰度级出现的概率 2.大津算法(OTSU)又称为最大类间方差法,目的:寻找全局图像的阈值。也叫基于阈值的分割算法 OTSU算法(大津法—最大类间方差法)原理及实现

: 1.:包括泛洪法,扫描线法,区段法三种 种子生长算法 2.电磁及摄像头(总钻风)寻迹算法浅析–逐飞科技 3.阳光算法,即之前提到的OTSU大津算法

4.allmap是摄像头真正采集到的,basemap是由allmap进行搜边界得到的,leftmap由basemap搜而得到

上了学校的PCB网课,除此之外好像也没做什么了

1.色环电阻读数 这个例子中的27000Ω的举例是差一个颜色的,最后的银色表示误差率


7.28 第五天 周三

白天帮同学安软件

用AD画原理图(作业)

1.电阻,左为res1,右为res2

2.电感 3.线是Ctrl+W,请区别线与引脚,引脚具有电气特性,线没有;且在AD中,线是可以斜着,但引脚线都是横平竖直 4.Designator——序列号,Comment——名称 5.改元器件都是在元件库里面改的,而不是在原理图上

: 1.补一个qt的问题,这个错因是opencv的版本问题,解决方案是在mainwindows里加#include <opencv2/imgproc/types_c.h> 2.sch原理图里面的端口是时钟端口

1.白色是0,黑色是1,边缘赋值2(转换后) 2.insidemap一般在有终点线(出发线)时会有显示黑色 3.为什么是YX,而不是XY,是因为最初定义的是uint8_t allmap[YM][XM],YM与XM是图像的XY极限 4.与递归有关的四个if,是在最初找的那个点的四周的情况,所以我们才看到y不变,x加减1,;x不变,y加减1 5.因为basemap是通过allmap形成的,当allmap里面出现黑点,就是allmap[Y][X]=1时对应于basemap[Y][X]取2,即找到的边缘点,多个边缘点形成线

1.永远左上角为1,开始逆时针转 2.丝印层:PCB最外层,用于注解,白色 3.双列直插(DIP封装)、贴片(SOP封装) 4.AD里面的线不能放缩,不是图片;但在sch原理图里面的矩形可以拖拽

: 1.轮廓在人眼中有方向趋势,在机器看来是一堆点,全部边沿点拼成轮廓 2.白底,黑边界,找边界,对于灰度图,二维图像,两个点差值,临界时的黑白点差值大于固定值(阈值)就可以认定为边界。 3.白不是绝对白,黑不是绝对黑,一个灰度图,两个点的差值是不断变化的,每时每刻都需要去计算那一个阈值。 4.:是指一个周期内信号最高值和最低值之间差的值 :一阶矩就是期望值,换句话说就是平均数 5.:首先计算对象是每一行或者整张图片,计算它们像素点的平均值和峰峰值,通过判断一整行的平均值是否大于峰峰值的一半,大致就可以判断出黑白。在此基础上,又保证这两个点的像素值的差小于平均值的一半,这样就得到了一种颜色时的阈值。


7.29 第六天 周四

: 1.排针里面的1~12指管脚的名称,而不是序列号;左上角P3是序列号,下面的Header 12是名称 2.最开始创建一个新的一定要创建项目,不是直接创建原理图,不然一被意外关闭就没了 3.网络标签(P+N)、网络标号:有助于模块化,一个传送门 4.电源端口,右键可选择不同的 5.在原理图里面的线是有电气特性的,而元件库里面的线没有 6.电容叫cap 电容容值表示,105也是一种

7.Y键是取关于原点对称(翻转的一种) 8.DAC、ADC,数字模拟转换器,D→A和A→D,Digital(数字的)、analog(模拟的) 9.RESET:复位按键 10.:库当中的XTAL就是晶振 11:细红×,代表这个口不接(快捷键P+V+N) 12.:对于黄色框的多引脚直接绘制,E+Y,记住要点那个初始的第一个

: 1.:工具+标注+原理图标注+Reset All+接受变更(创建ECO)+执行变更 画好两个,剩下的按住Shift走,也可以实现数字规律排列

1.:获得赛道引导线(中线) 2.全局变量一般储存在内存中,局部变量存储的区域就是栈,因为图像处理所需容量大,所以需要进行简单的内存分配 3.流程 4. 一、看go文件里面的对于各个赛道元素的处理,直线、左右转等,它们分别对应一个函数;二、图像上位机里面,这些参数对应的图像处理得到的边界,它们只是代称,如果要转换为代码中的变量需要在mainwindow.cpp去找它们真实反映的是哪一个参量,真实的参量出现在代码中,如果在看代码时遇到它们记得按上述流程查找它们的含义。

: 1.搜图会反复用到这个函数,把leftmap、rightmap、basemap等都当做map代入

2.原本按照灰度值,黑色为0,经常这样转换后,黑色为1,白色为0了 3.经过search函数后(allmap到basemap),图像变成0和2,0为白色,2为边界

4.:状态机是有限状态自动机的简称,是现实事物运行规则抽象而成的一个数学模型。

5.:可用于识别直线、曲线或圆弧 6.:指工程的元器件选型表 7.AD打开封装管理器时报错no valid components to change:原因所有工程没有放在一个项目下 8.编译时报错“has only one pin”,直接添加一个No ERC标号就不报错了,其实这个错误的原因是网络标号只有一个,软件找不到它对应的另一个(即单端网络) 1.走线从直到竖夹角135度 2.AD里面单位有英制和国标两种,ml和ms


7.30 第七天 周五

: 1.PCB封装:是电子设计图纸与实物间的映射体 焊盘:用于焊接器件 1脚标识:用于区分正反 阻焊:作用是防止绿油(阻焊油俗称绿油)覆盖,包裹在焊盘外围 通孔:打通的小孔,Multi-Layer 表贴:在板子上面一层用焊锡连接器件,Top Layer 2.:因为AD里面会用到很多快捷键,所以建议把输入法换成美式键盘 3.:元器件的手册里面会有 例:二极管 4.:Ctrl+D,转向拖拽Shft+鼠标右键 5.:R+P 6.:画丝印在丝印层画,AD下方的Top overlay。画线:P+L 7.:M+通过x,y移动选中对象 8.在PCB图中按D,选第二个,去实现元器件的导入

: 1.:左为极性,右为普通 2.按住Shift加鼠标拖动,可以把元器件拖出来 3.因为封装不同的原因,建议全部都调用一个库里面的,或者说严格按照boom表来找封装 4.出现unknown pin Altium Designer 更新到PCB时出现unknown pin

: 前提:注册 1.来到嘉立创EDA(相当于一个在线的AD),而不是嘉立创官网或嘉立创商城 2.点左边的元件库,找到需要的,放置在图纸上,保存,找到导出即可得到工程文件

1.结构体里面的“.”表示访问结构体的元素 2.结构体:学长的代码很多由结构体组成,就像下面的例子,today这个结构体是由day、month、year三个元素组成,再进一步判断,这可以用判断赛道元素 3.两个结构变量是可以赋值的

1.数字电路的地:单片机的地;模拟电路的地,是外部的;用0欧电阻或0欧电感来数字电路和模拟电路的共地 2.覆铜:所谓覆铜,就是将PCB上闲置的空间作为基准面,然后用固体铜填充,这些铜区又称为灌铜。覆铜的意义在于,减小地线阻抗,提高抗干扰能力;降低压降,提高电源效率;还有,与地线相连,减小环路面积。


7.31 第八天 周六

: 1.: ★定义:是用变量名称来代替数字常量,大括号内的“名字”叫符号常量,只能是int,

★枚举可以相当于int、float,这样的变量类型,但不好

2. ★一个结构是复合的数据类型。如下,一个date就包含两个变量

★结构类型和结构变量的区别

★结构变量名称不是地址,用结构指针时要&+结构变量名称

★★★结构作为函数参数 结构变量作为函数参数,

★TC264用hex下载文件的教程

★leftmap和rightmap是由basemap删线形成的,用于转向用

★图像最上方[YM][XM],YM是60,XM是47

:休息了


8.1 第九天 周日

★我们使用的TC264DA,在新建文件时型号选TC26xDA

★P10 5是接单片机,MCU3V3不是用单片机供电的意思,只是一个正极取的名字,是个代称

补 ★Image2Lcd的安装,用于将图像变成.c文件

★PctoLCD2002:用于将汉字生成十六进制,我的应用场景是龙邱历程中显示屏的汉字显示


8.2 第十天 周一

昨天忘记保存了,今天要汲取教训

: ★DMA相当于CPU的小弟,帮忙进行一些数据传输

★大津法适用于灰度直方图如下图所示的情形,可以找到中间的值

★找边缘点分左右、上下、左上到右下、左下到右上。下面的例子是用正负判断

★物体或人的影子在赛道上也会被摄像头认定为边缘,需进一步做处理

★SCCB是改编版IIC,可以理解为IIC的作用

★TC264是从CPU0开始运行

★干簧管(继电器)停车时用

★CPU0中放执行时间较长的程序;CPU1中放控制算法

★CPU0和CPU1是不能同时执行某个函数的,如果要执行某个函数,比方说先让0执行,0执行完后进行标志位判断,0是否执行完了,if判断里面写CPU1需要干嘛

★采集的图像不是全部都要使用,采集完储存在一个数组内后,后面要实现什么功能,我们去调用完整图像的部分做处理

: ★allmap中白黑交界没有所谓的边缘线,而在basemap中红色充当了这一角色,作为白黑的分界线。

★图像中的YM和XM还是按照直角坐标系去理解,虽然一个图像对应的二维数组为[YM][XM],但左右移动变化的是X,上下移动变化的是Y

:无


8.3 第十一天 周二

★C语言中的math.h对应到C++中为cmath,不再有尾缀(拓展名)

★通过图像判断方向的原理是绘制一个一次函数图像,看斜率和截距

★这里面出现的管脚都是可以作为电平输出的

★模块:电机模块、舵机模块、摄像头模块

★总线:总线(Bus)是计算机各种功能部件之间传送信息的公共通信干线,它是由导线组成的传输线束, 按照计算机所传输的信息种类,计算机的总线可以划分为数据总线、地址总线和控制总线,分别用来传输数据、数据地址和控制信号。——百度

★总线频率:人们常常以MHz表示的速度来描述总线频率。与晶振频率相关

★电机频率一般在10K到20K

★编码器的英文是encoder,缩写为ENC

★PWM的管脚:我们选择不同的PWM脚作为脉冲输入与输出。

★左边为PWM,右边dir

★ads中很多管脚前置名

,摄像头会用到DMA传输数据,Camera_Flag是是否搬运完原图像的标志位,在DMA.h中被改变

★向量号是用哪个内核来管理,

★OLED屏是单色的,数据量比较小

★通过定时器计数数值来反应电机当前速度

★关闭总中断→获取总线频率→→开启总中断

★改进:1.targetspeed写在电机驱动的那一块2.舵机PID控制3.左右电机特性的原因可能targetspeed不同

自己弄的代码(第一版)

#include <include.h>//各个模块的头文件 //所有头文件还是要保留的,毕竟要调用它的历程
#include <IfxCpu.h>
#include <IfxScuCcu.h>
#include <IfxScuWdt.h>
#include <IfxStm.h>
#include <IfxStm_reg.h>
#include <LQ_CAMERA.h>
#include <LQ_CCU6.h>
#include <LQ_GPIO_KEY.h>
#include <LQ_GPIO_LED.h>
#include <LQ_MotorServo.h>
#include <LQ_SOFTI2C.h>
#include <LQ_TFT18.h>
#include <LQ_UART.h>
#include <LQ_Inductor.h>
#include <Main.h>
#include "LQ_ImageProcess.h"

App_Cpu0 g_AppCpu0; // brief CPU 0 global data
IfxCpu_mutexLock mutexCpu0InitIsOk = 1;   // CPU0 初始化完成标志位
volatile char mutexCpu0TFTIsOk=0;         // CPU1 0占用/1释放 TFT


float servo_duty = 舵机中值 ;

int core0_main (void)
{ 
          
/****************************系统自带的*******************************/
//char txt[16];

// 关闭CPU总中断
IfxCpu_disableInterrupts();         //一来先关闭一下,防止上一次开着

// 关闭看门狗,如果不设置看门狗喂狗需要关闭
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());

// 读取总线频率 //相当于keil中的borad_init
g_AppCpu0.info.pllFreq = IfxScuCcu_getPllFrequency();
g_AppCpu0.info.cpuFreq = IfxScuCcu_getCpuFrequency(IfxCpu_getCoreIndex());
g_AppCpu0.info.sysFreq = IfxScuCcu_getSpbFrequency();
g_AppCpu0.info.stmFreq = IfxStm_getFrequency(&MODULE_STM0);

/****************************系统自带的*******************************/
    
//需要初始化的模块电机、舵机、摄像头、屏幕 //采集和数据处理可以放中断里
ATOM_PWM_InitConfig(ATOMPWM0,0,100);               //左电机PWM脚P23.1,电机电机初始化占空比为0,频率为14000
ENC_InitConfig(ENC2_InPut_P33_7,ENC2_Dir_P33_6);        //初始化左编码器
ATOM_PWM_InitConfig(ATOMPWM1,0,100);               //右电机PWM脚P32.4
ENC_InitConfig(ENC6_InPut_P20_3,ENC6_Dir_P20_0);        //初始化右编码器
ATOM_PWM_InitConfig(ATOMSERVO1, 1500, 50);   //ATOMSERVO1用的P33.10口作为舵机PWM输出口,servo是伺服的意思,3010的最佳工作频率为50HZ,初始值为1.5ms中值
CAMERA_Init(50);          //P2是信号脚,摄像头初始化 //里面数字表示摄像头帧率fps
//OLED_Init(); //以OLED为例
//OLED_CLS(); //LCD清屏
    
// 开启CPU总中断
IfxCpu_enableInterrupts();
    
while (1)	//主循环
{ 
          
    /****************************摄像头的使用*************************************/
    if (Camera_Flag == 2)       //Camera_Flag是是否搬运完原图像的标志位
    { 
          
    CAMERA_Reprot();    //上报数据给上位机 串口速度比较慢 注意上位机图像宽高设置为120*188
    Get_Use_Image();    // 图像压缩,提取部分使用的数据
    Camera_Flag = 0;    // 清除摄像头采集完成标志位 如果不清除,则不会再次采集数据

    Get_Bin_Image(1);            // 二值化 //括号内数字表示模式的选择
    OLED_Road(LCDH, LCDW, (unsigned char *)Bin_Image);      // OLED动态显示摄像头图像
    }

    Seek_Road();
    /****************************摄像头的使用*************************************/

    //OFFSET0、1、2是Seek_Road算出来的结果,面积为负数,数值越大说明越偏左边;如果面积为正数,数值越大说明越偏右边
    if(OFFSET>0)
    { 
          
        crossforleft();
    }
    else if (OFFSET<0)
    { 
          
        crossforright();
    }
    else if (OFFSET==0)
    { 
          
        targetspeed = 700;
        realspeed = ENC_GetCounter(ENC2_InPut_P33_7);       //获取左电机编码器PWM脚P33.7的脉冲数值,为了让左右电机转速基本相同,传入PID用同一个偏差
        这还有一个计数器清空的过程

        if(左偏)
        { 
          
            servo_duty += 10;
        }
        if(右偏)
        { 
          
            servo_duty -= 10;
        }
        error = targetspeed - realspeed ;      //偏差= 理想速度 - 当前速度,偏差用于代入PID函数中,用计数器的值直接反应速度
        leftspeed_duty = PidLocCtrl(leftspeed_pid,error);     //电机位置式控制
        rightspeed_duty = PidLocCtrl(rightspeed_pid,error);

        ATOM_PWM_SetDuty(IfxGtm_ATOM0_6_TOUT42_P23_1_OUT,leftspeed_duty);   //用占空比控制左右电机的PWM
        ATOM_PWM_SetDuty(IfxGtm_ATOM0_5_TOUT40_P32_4_OUT,rightspeed_duty);      //上面输入的duty是否需要做处理?
        }

	}
}

8.4 第十二天 周三

昨天大致写了小车的代码,只去写了一个功能,今天进一步去完善它

: ★左右两个编码器计数值一正一负,因为是头对头排列的

★初始化时钟频率

★执行函数Seek_Road后得到的应该是error值,再代入舵机的PID控制中,完成转向

★Seek_Road将图像划分为为由近到远三个区域,信任度由近到远递减,将三者加权算误差

★将图像划分区域后,例如左右两个区域,分别记录两边的黑点个数,只不过两边分别记为正和负,用左右两边黑点正负相加后的正负来衡量左偏和右偏

★转弯电机差速转,辅助过弯,使其更加平滑

★两个电机机械特性不同,所以为了达到相同的转速所对应的占空比是不同的,正因为如此需要用两个计数器计数

★offset的值与绝对的中值0是存在偏差的,用这个偏差

★进环岛可以找到一个跳变点,可能代码实现比较困难

★十字:有线→丢线→有线(边缘)

★所有程序在while(1)中:无法实现程序嵌套、占用资源

★飞线有两种:一种是因为设计缺陷,人为在印刷电路板外面两个节点上直接连着的;还有一种是特殊的信号线

★起跑线:白点黑点交叉循环出现,例如循环出现10次就可以把它视为起跑线了

★出库:固定打角一定时间

★补线是辅助判断,补线的触发条件是识别到了特殊点

★PWM信号的频率是可以设定,我们所常说的10K到20K是电机PWM的频率,而实际工程中一般选用13K到17K,因为10K和20K都会影响到电感的采集,造成干扰。如果频率太低,电机就表现为一卡一卡的,一转一停。如果频率太高,电机转速太快,容易烧坏。

★因为TC264自身结构的特殊性,它的每个PWM通道可以输出不同频率的波,所以每个通道都需要设置频率

★占空比的最大值被设置了,逐飞和龙邱都是10000

★ads中对工程进行rename容易造成工程被替代,所以不要随意进行改名

★ads也是可以实现导入多个工程,之前说不行,今天我发现可以,在导入的时候选择更高一级的目录,它的projects会自动搜索此大目录下所有符合ads工程的文件,然后一件添加就可以了,下面那个是否加入工作区勾选与否都行。

:看视频学习,记录不在这


#include <include.h>//各个模块的头文件 //所有头文件还是要保留的,毕竟要调用它的历程
#include <IfxCpu.h>
#include <IfxScuCcu.h>
#include <IfxScuWdt.h>
#include <IfxStm.h>
#include <IfxStm_reg.h>
#include <LQ_CAMERA.h>
#include <LQ_CCU6.h>
#include <LQ_GPIO_KEY.h>
#include <LQ_GPIO_LED.h>
#include <LQ_MotorServo.h>
#include <LQ_SOFTI2C.h>
#include <LQ_TFT18.h>
#include <LQ_UART.h>
#include <LQ_Inductor.h>
#include <Main.h>
#include "LQ_ImageProcess.h"

App_Cpu0 g_AppCpu0; // brief CPU 0 global data
IfxCpu_mutexLock mutexCpu0InitIsOk = 1;   // CPU0 初始化完成标志位
volatile char mutexCpu0TFTIsOk=0;         // CPU1 0占用/1释放 TFT


/*左电机*/


/*右电机*/



/*舵机*/
float servo_duty = 舵机中值 ;
float Last_servo_error = 0;



int core0_main (void)
{ 
          
/****************************系统自带的*******************************/
//char txt[16];

// 关闭CPU总中断
IfxCpu_disableInterrupts();         //一来先关闭一下,防止上一次开着

// 关闭看门狗,如果不设置看门狗喂狗需要关闭
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());

// 读取总线频率 //相当于keil中的borad_init
g_AppCpu0.info.pllFreq = IfxScuCcu_getPllFrequency();
g_AppCpu0.info.cpuFreq = IfxScuCcu_getCpuFrequency(IfxCpu_getCoreIndex());
g_AppCpu0.info.sysFreq = IfxScuCcu_getSpbFrequency();
g_AppCpu0.info.stmFreq = IfxStm_getFrequency(&MODULE_STM0);

/****************************系统自带的*******************************/
//需要初始化的模块电机、舵机、摄像头、屏幕 //采集和数据处理可以放中断里
ATOM_PWM_InitConfig(ATOMPWM0,0,100);               //左电机PWM脚P23.1,电机电机初始化占空比为0,频率为14000
ENC_InitConfig(ENC2_InPut_P33_7,ENC2_Dir_P33_6);        //初始化左编码器
ATOM_PWM_InitConfig(ATOMPWM1,0,100);               //右电机PWM脚P32.4
ENC_InitConfig(ENC6_InPut_P20_3,ENC6_Dir_P20_0);        //初始化右编码器
ATOM_PWM_InitConfig(ATOMSERVO1, 1500, 50);   //ATOMSERVO1用的P33.10口作为舵机PWM输出口,servo是伺服的意思,3010的最佳工作频率为50HZ,初始值为1.5ms中值
CAMERA_Init(50);          //P2是信号脚,摄像头初始化 //里面数字表示摄像头帧率fps

// 开启CPU总中断
IfxCpu_enableInterrupts();
while (1)	//主循环
{ 
          
    /****************************摄像头的使用*************************************/
    if (Camera_Flag == 2)       //Camera_Flag是是否搬运完原图像的标志位
    { 
          
    CAMERA_Reprot();    //上报数据给上位机 串口速度比较慢 注意上位机图像宽高设置为120*188
    Get_Use_Image();    // 图像压缩,提取部分使用的数据
    Camera_Flag = 0;    // 清除摄像头采集完成标志位 如果不清除,则不会再次采集数据

    Get_Bin_Image(1);            // 二值化 //括号内数字表示模式的选择
    OLED_Road(LCDH, LCDW, (unsigned char *)Bin_Image);      // OLED动态显示摄像头图像
    }

    Seek_Road();        //获得的三个OFFSET是需要进一步处理转换为舵机error的

    error = 此时的OFFSET0 - 上一次的OFFSET0;
    /****************************摄像头的使用*************************************/

    //OFFSET0、1、2是Seek_Road算出来的结果,面积为负数,数值越大说明越偏左边;如果面积为正数,数值越大说明越偏右边
    /*if(OFFSET>0) 左转 { crossforleft(); } else if (OFFSET<0) 右转 //对于偏差的判断已经被内涵在图像处理算error那里了,error给舵机 { crossforright(); } else if (OFFSET==0) 直走 { */
    //OFFSET0是距离车子最远的一段,OFFSET2是最近的
        targetSpeed1 = targetspeed2 = 700;
        realSpeed1 = ENC_GetCounter(ENC2_InPut_P33_7);       //获取左电机编码器PWM脚P33.7的脉冲数值,为了让左右电机转速基本相同,传入PID用同一个偏差
        realSpeed2 = ENC_GetCounter(ENC6_InPut_P20_3);       //1表示左,2表示右
        //原本在计数器使用完后还有一个计数器清零的过程,但龙邱库里把它放到ENC_GetCounter里面去了,所以就不用了

        /****************************舵机转向*************************************/
        //通过舵机的转向就可以实现转向了,这里面是用到了摄像头的,因为OFFSET是通过摄像头算出的值

        /*方案一:首先试试OFFSET不用0和1,只用2做判断OFFSET作为当前的值*/
        servo_error = OFFSET2 - 0;     //在赛道正中间左右黑点正负应该抵消掉(第一次)因为中点为0,所以OFFSET其实就代表当前的误差*/
        servo_duty = constrain_float(servo_duty,-700,700);      //舵机限幅
        servo_duty = PidIncCtrl(servo_pid,servo_error);          //舵机控制,Inc表示增量式

        /*方案二:用上0、1、2三个OFFSET,三者加权算一个值*/    
       /****************************舵机转向*************************************/ 
        motor_error1 = targetSpeed1 - realSpeed1 ;      //偏差= 理想速度 - 当前速度,偏差用于代入PID函数中,用计数器的值直接反应速度
        motor_error2 = targetSpeed2 - realSpeed2 ;
        leftSpeed_duty = PidLocCtrl(leftSpeed_pid,motor_error1);     //电机控制,Loc表示位置式
        rightSpeed_duty = PidLocCtrl(rightSpeed_pid,motor_error2);

        /*********************************** ATOM_PWM_SetDuty(IfxGtm_ATOM0_6_TOUT42_P23_1_OUT,leftspeed_duty); //用占空比控制左右电机的PWM ATOM_PWM_SetDuty(IfxGtm_ATOM0_5_TOUT40_P32_4_OUT,rightspeed_duty); //上面输入的duty是否需要做处理? //需要,只不过是通过MotorCtrl函数 ***********************************/

        MotorCtrl(leftSpeed_duty,-rightSpeed_duty);         //因为电机的放置原因,这里是有正负之分的,这里面是没有限幅的,需要自己补上

        TOM_PWM_SetDuty(ATOMSERVO1,error,50);//管脚+占空比+频率 舵机控制 //3010的最佳工作频率为50HZ
    }

}
    

}

8.5 第十三天 周四

: ●ads可以直接导出工程文件的,指工程包含的文件夹

*** TFT屏幕***

●TFT彩屏采用的SPI串行接口通信

●龙邱和逐飞的TFT屏管脚名字不同不用太在意,每个管脚的作用是一样的,逐飞多一个BL脚,背光控制输入脚,背光控制是屏幕背光的PWM控制,不用太在意

●我们用的TFT的脚和龙邱的历程是不同的,使用前需要到龙邱的TFT.c里面改;因为我们也是有8个脚的,有BL脚,龙邱只有7个脚,

●在龙邱历程中,cs脚是默认拉低的,cs可以理解为SPI通信的许可位,拉低表示许可,好像这脚也叫使能脚

●在初始化TFT屏幕后紧接着是清屏的操作,清屏指的是全屏显示单色画面

: ●***镜像***:可以被理解为一个虚拟机的快照,里面包含了需要部署的应用程序和它所关联的库

●增量式PID对微分项限幅

●在剪排针的时候建议预留两个管脚,因为剪的时候容易破坏管脚

8.6 第十四天 周五

★因为每个模块被写为了一个.cpp文件,所以在跨文件使用已被定义的变量时,要用extern进行一次声明

:stm中断就是一个周期中断,可以设置出现中断的时间,而GPIO就是一个外部中断而已

★学长代码里面PID有一个数组,用于记录四次编码器的值,这个数组是用来滤波的,因为编码器也是一个器件,也存在噪声;在motor.c的这里,对三次进行取平均,如果有一次算出来的值太大,有异常就以上一次为准。

★二次函数变速是看的曲率,曲率大速度慢,曲率小速度快,曲率是LSMI.DK,在speed.c里面做判断

★并不是所有引脚都有既输入又输出,对于ADC输入引脚,功能比较固定,有仅输入的限制

★RAM是随机存取存储器,速度快


21.8.7 第十五天 周六

:当取值为一串数据的算术平均值(全部相加除以数量),此时取得偏差平方的最小值(因为是一个二次函数,所以存在极值)


21.8.8 第十六天 周日

我休息去了,什么都没干


8.9 第十七天 周一

容忍值可以理解为阈值

畸变系数

栅头栅尾、栅区

种子生长法的栈

●图像畸变,可以理解为图像变形

●yaw叫偏航

●图像压缩:去除不必要信息

●图像更新:指再一次拿新点给图像赋值

●leftmap和rightmap的初值都是0,全白

●if (II.bnum_all),只要不冲出赛道,一般都是会执行的


(试试截长图的形式,因为打字我这边是需要一张

标签: yl100l一2电机用多大电容xy贴片电阻边沿触发式继电器计数盘状贴片电阻电容ic的机器xy贴片二极管

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台