智能车竞赛摄像头组代码
浙江赛区-摄像头组-杭州电子科技大学信息工程学院-杭电信工摄像头一队
第九届“飞思卡尔”杯全国大学生
智能汽车竞赛
技术报告
学校:杭州电子科技大学信息工程学院
队伍名称:杭电信工摄像头1队
参赛队员:赵勇
林玉彪
杨平贝
带队老师:李金新余皓珉
关于技术报告和研究论文使用授权的说明
本人完全了解第九届“飞思卡尔”杯全国大学生智能汽车竞赛关保留、使用技术报告和研究论文的规定,即:参赛作品著作权归参赛者本人,比赛组委会和飞思卡尔半导体公司可以在相关主页上收录并公开参赛作品的设计方案、技术报告以及参赛模型车的视频、图像资料,并将相关内容编纂收录在组委会出版论文集中。
参赛队员签名:赵勇、林玉彪、杨平贝
带队教师签名:李金新、余皓珉
日期:2014/08/10
摘要
本文介绍了杭州电子科技大学信息工程学院的队员们在准备此次比赛中的成果。本次比赛采用大赛组委会提供的1:16仿真车模,硬件平台采用带MK60DN512ZVLQ10单片机的K60环境,软件平台为Keil开发环境。
文中介绍了本次我们的智能车控制系统软硬件结构和开发流程,整个智能车涉及车模机械调整,传感器选择,信号处理电路设计,控制算法优化等许多方面。整辆车的工作原理是先将小车的控制周期中提取出相应的时间片,相应的时间片用来控制车体的平衡,留下的时间片用来控制速度和转向,由CCD摄像头采集赛道信息至主板的硬件二值化模块进行信号处理,并递送二值化视频信息到单片机,再由单片机对二值化视频信号进行计算分析,运用我们自己的软件程序对赛道信息进行提取并选择最佳路径,通过对电机的精确控制从而实现小车在赛道上精彩漂亮的飞驰!
为了进一步提高小车在运行时的稳定性和速度,我们组在软件方面使用了多套方案进行比较。更新了SD卡技术实时存储赛道信息。硬件上为了稳定的考虑,采用了以前比较稳定的方案,但是在电源部分做了调整,使得整车的电源裕度更大,硬件鲁棒性更强。为更好的分析调车数据,我们继承并且改进上届的上位机,用C#软件编写了新的上位机程序来进行车模调试,很大程度上提高了调车效率。在进行大量的实践之后,表明我们的系统设计方案完全是可行的。
第八届飞思卡尔智能车竞赛摄像头组浙工大银江逐梦队技术报告
第八届"飞思卡尔"杯全国大学生
智能汽车竞赛
技术报告
学校:浙江工业大学
队伍名称:浙工大银江逐梦队
参赛队员:孟泽民
章志诚
徐晋鸿
带队教师:陈朋、朱威
关于技术报告和研究论文使用授权的说明
本人完全了解第八届"飞思卡尔"杯全国大学生智能汽车竞赛关保留、使用技术报告和研究论文的规定,即:参赛作品著作权归参赛者本人,比赛组委会和飞思卡尔半导体公司可以在相关主页上收录并公开参赛作品的设计方案、技术报告以及参赛模型车的视频、图像资料,并将相关内容编纂收录在组委会出版论文集中。
参赛队员签名:孟泽民
章志诚
徐晋鸿
带队教师签名:陈朋
朱威
日期:2013.8.15
摘要
本文设计的智能车系统以MK60N512ZVLQ10微控制器为核心控制单元,通过Ov7620数字摄像头检测赛道信息,使用K60的DMA模块采集图像,采用动态阈值算法对图像进行二值化,提取黑色引导线,用于赛道识别;通过编码器检测模型车的实时速度,使用PID 控制算法调节驱动电机的转速和转向舵机的角度,实现了对模型车运动速度和运动方向的闭环控制。为了提高模型车的速度并让其更稳定,我们使用自主编写的Labview上位机、SD卡模块、无线模块等调试工具,进行了大量硬件与软件测试。实验结果表明,该系统设计方案可行。
关键词:MK60N512VMD100,Ov7620,DMA,PID,Labview,SD卡
Abstract
In this paper we will design a smart car system based on MK60N512ZVLQ10 as the micro-controller unit. We use a Ov7620 digital image camera to obtain lane image information. The MCU gets the image by its DMA module. Then convert the original image into the binary image by using dynamic threshold algorithm in order to extract black guide line for track identification. An inferred sensor is used to measure the car`s moving speed. We use PID control method to adjust the rotate speed of driving electromotor and direction of steering electromotor,to achieve the closed-loop control for the speed and direction. To increase the speed of the car and make it more reliable,a great number of the hardware and software tests are carried on and the advantages and disadvantages of the different schemes are compared by using the Labview simulation platform designed by ourselves,the SD card module and the wireless module. The results indicate that our design scheme of the smart car system is feasible.
ov7725数字摄像头编程基本知识笔记
PCLK
HREF
HSYNC 像素值ov7725数字摄像头编程基本知识笔记
这里以ov7725为例,对数字摄像头的时序进行分析。其他数字摄像头的时序也大同小异。
像素输出顺序
数字摄像头输出图像时,一般都是从左到右,有上到下逐个输出(部分芯片可配置输出顺序):
有些摄像头有奇偶场,是采用隔行扫描方法,把一帧图象分为奇数场和偶数场两场。(ov7725没有奇偶场之分)
行中断时序
0 第一个输出像素
最后一个输出像素 最后一个
像素 消隐区,如果不按照时序来采集,就有可能采集到消隐区,值为0,即黑色。
行与行之间,场与场之间都
一行图像数据 第一个 像素 PCLK 上升沿时,MCU 采集图像;
下降沿时,摄像头输出图像。
HREF 和HSYNC 都用于行中断信号,但时序有点区别。 HREF 上升沿就马上输出图像数据,而HSYNC 会等待一段时间再输出图像数据,如果行中断里需要处理事情再开始采集,则显然用HREF 的上升沿是很容易来不两个都是行中断信号,共用同一个管脚,由寄存器配置选择哪个信号输出。
场中断时序
采集图像思路
①使用for 循环延时采集
1. 需要采集图像时,开场中断
2. 场中断来了就开启行中断,关闭场中断
3. 行中断里用for 循环延时采集像素,可以在行中断里添加标志位,部分行不采集,
即可跨行采集。
4. 行中断次数等于图像行数时即可关闭行中断,标志图像采集完毕。
②使用场中断和行中断,DMA 传输
1. 需要采集图像时,开场中断
2. 场中断来了,开行中断和初始化DMA 传输
3. 行中断来了就设置DMA 地址,启动DMA 传输。如果先过滤部分行不采集,则设
飞卡知识竞赛题目
山东大学(威海)飞思卡尔知识竞赛初赛试题(样题)
姓名:年级:学号:手机号:
一填空题(每空2分,共22分)
(1)HCS12微控制的工作电压为()
(2)飞思卡尔智能车竞赛最初起源于哪个国家()
(3)摄像头组一般使用的摄像头是CCD和()
(4)第七届全国飞思卡尔智能车山东赛区在哪个学校举办()
(5)飞思卡尔智能车赛要求使用的传感器不能超过()个
(6)伺服电机不超过几个()
(7)PWM即()
(8)第八届全国飞思卡尔智能车赛中电磁组中如果选用陀螺仪,则必须选择()公司的()系列的陀螺仪。(两空可选答一空,如果两空均答对则得4分但本题最多不超过20分)
(9)AD转换中A表示的是()信号,D表示的是()信号。
(10)如果有一车模通过连续扫描赛道反射点的方式进行路径检测的属于()组车模。
二选择题(每题2分,共20分)(请勿在A、B、C、D上打勾否则不得分)
1、以下学校中哪所学校是第七届飞思卡尔智能车全国总决赛举办地()
A.南京师范大学B.北京科技大学C.常熟理工学院D.杭州电子科技大学
2、请问CCD摄像头的额定工作电压是()
A.3.3V
B.5V
C.7.2V
D.12V
3、程序的灵魂是()
A.算法
B.函数
C.数据结构
D.表达式
4、以下哪种软件是用来绘制PCB(电路板)的?()
A. Keil
B.Proteus
C.Visual C++
D.Altium Designer
5、请问二进制数100101011110011110是()
A.奇数
B.偶数
6、请把十六进制数5A1D转化为二进制()
A.1000100011000110
智能车程序代码(摄像头)
//---------------------------------------------------CCD
#define odd_even PTIT_PTIT3
#define ROW_START 30 // begin to sample from line start
#define ROW_END 240 // end flag of sampling
unsigned char frm,open_frm,flag1,finish=0;
#define ROW_MAX 12 //最大取12行
#define LINE_MAX 52
unsigned char image_data[ROW_MAX][LINE_MAX];
//unsigned char image_simple[10]; /////////装10个黑点,只处理10个
//char row,line;
char row;
unsigned int line;
unsigned char temp;
unsigned int rowcount;
unsigned char line_temp;
//-------------------------------------------CCD_PROCESS
#define RMV_ROW 2 //抛弃前2行0-4行
#define V ALVE 24 // valve to decide black track or white track
unsigned char black_x[ROW_MAX];
东6 华东赛区-摄像头组-江苏理工学院-火影2队 技术报告
飞思卡尔智能车比赛细则
2016
目录
第十一届竞赛规则导读说明.......................... 错误!未定义书签。
一、前言.......................................... 错误!未定义书签。
二、比赛器材...................................... 错误!未定义书签。
1、车模 ....................................... 错误!未定义书签。
(1)车模的种类............................ 错误!未定义书签。
(2)车模修改要求.......................... 错误!未定义书签。
2、电子元器件 ................................. 错误!未定义书签。
(1)微控制器.............................. 错误!未定义书签。
(2)传感器................................ 错误!未定义书签。
(3)伺服电机.............................. 错误!未定义书签。
3、电路板 ..................................... 错误!未定义书签。
4、编程语言及调试工具 ......................... 错误!未定义书签。
三、比赛环境...................................... 错误!未定义书签。
飞思卡尔杯全国大学生智能汽车竞赛技术报告_摄像头组
第十届"飞思卡尔"杯全国大学生智能汽车竞赛技术报告
第十届“飞思卡尔”杯全国大学生
智能汽车竞赛
技术报告
学校:电子科技大学
摘要
本文设计的智能车系统以MK60DN512ZVLQ10微控制器为核心控制单元,通过CMOS摄像头检测赛道信息,使用模拟比较器对图像进行硬件二值化,提取黑色引导线,用于赛道识别;通过编码器检测模型车的实时速度,使用PID控制算法调节驱动电机的转速和转向舵机的角度,实现了对模型车运动速度和运动方向的闭环控制。
关键字:MK60DN512ZVLQ10,CMOS,PID
Abstract
In this paper we will design a smart car system based on MK60DN512ZVLQ10as the micro-controller unit. We use a CMOS image sensor to obtain lane image information. Then convert the original image into the binary image by the analog comparator circuit in order to extract black guide line for track identification. An inferred sensor is used to measure the car`s moving speed. We use PID control method to adjust the rotate speed of driving electromotor and direction of steering electromotor, to achieve the closed-loop control for the speed and direction.
摄像头的代码
Code Warrior 4.6
Target : MC9S12DG128B
Crystal: 16.000Mhz
busclock: 8.000MHz
pllclock:16.000MHz
本程序主要包括以下功能:
1.设置锁相环和总线频率;
2.IO口使用;
3.IOC7口16位计数器。
LED计数,根据灯亮可以读取系统循环了多少次
******************************************************************************* **********/
#i nclude <hidef.h> /* common defines and macros */
#i nclude <mc9s12dg128.h> /* derivative information */
#i nclude "LQprintp.h"
#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"
//-----------------------------------------------------
void setbusclock(void)
{
CLKSEL=0X00; //disengage PLL to system
PLLCTL_PLLON=1; //turn on PLL
SYNR=1;
REFDV=1; //pllclock=2*osc*(1+SYNR)/(1+REFDV)=32MHz;
_asm(nop); //BUS CLOCK=16M
摄像头控制代码
偶是E
波特率9600,E,8,1
说明$代码16进制,其中“,$”是两种代码的间隔。
TELE,WIDE,UP,DOWN,LEFT,RIGHT的第一行是发送,第二代码是停止码。
TELE
$83,$45,$0C,$01
$82,$45,$0E
WIDE
$83,$45,$0D,$01
$82,$45,$0E
up
$83,$45,$03,$16
$82,$45,$05
down
$83,$45,$04,$16
$82,$45,$05
left
$83,$45,$01,$16
$82,$45,$02
right
$83,$45,$00,$16
$82,$45,$02
查询预设的位置
$82,$01,$50 当返回的代码后,去掉A0后,剩下就是调用预设的代码了。
调用预设1
$8A,$41,$50,$0A,$06,$6B,$01,$2A,$00,$40,$00
调用预设2
$8A,$41,$50,$0A,$05,$4A,$01,$2A,$00,$40,$00
调用预设3
$8A,$41,$50,$08,$04,$21,$01,$2A,$00,$40,$00
调用预设4
$8A,$41,$50,$08,$01,$2E,$01,$2A,$00,$40,$00
调用预设5
$8A,$41,$50,$08,$00,$00,$01,$2A,$00,$40,$00
摄像头组长春理工大学天狼五号
第九届“飞思卡尔”杯全国大学生
智能汽车竞赛
技术报告
基于摄像头检测的寻线智能车设计
学校:长春理工大学
队伍名称:天狼五号
参赛队员:饶杨海
郭阳阳
吴至成
带队教师:郝子强
王英志
关于技术报告和研究论文使用授权的说明
本人完全了解第九届“飞思卡尔”杯全国大学生智能汽车竞速赛有关保留、使用技术报告和研究论文的规定,即:参赛作品著作权归参赛者本人,比赛组委会和飞思卡尔半导体公司可以在相关主页上收录并公开参赛作品的设计方案、技术报告以及参赛模型车的视频、图像资料,并将相关内容编纂收录在组委会出版论文集中。
参赛队员签名:饶杨海
郭阳阳
吴至成
带队教师签名:郝子强
王英志
日期:2014年8月12日
目录
摘要
该智能寻迹小车以MK60DN512ZVLL10单片机最小系统为核心,辅以电源模块、图像采集模块、电机驱动模块和运行调试模块。小车通过美国omnivision 公司的摄像头OV7620采集赛道信息,经过不断改进机械结构并优化算法,小车可以完美地识别各种赛道信息。经过图像处理后,通过转向控制策略与PID算法驱动电机速度,实现路径的检测与识别。同时通过调整小车的重心、使小车的稳定性与行进速度达到最优。系统属于以能量转换为主,由直流电机输入能量与电机,通过小车不同的运动输出能量,是典型的机电一体化系统。
这份技术报告中,我们小组通过对整体方案、硬件电路、软件算法、机械结构、调试参数等方面进行介绍,详尽地阐述了我们的思想和创意,具体表现了我们在电路的创新设计,以及算法方面的独特想法。这份报告凝聚着我们的心血和智慧,是我们共同努力后的成果。
摄像头组 哈尔滨工程大学 极品飞车一号
第九届全国大学生“飞思卡尔”杯
智能汽车竞赛
技术报告
学校:哈尔滨工程大学
队伍名称:极品飞车一号
参赛队员:何超
叶超
曲友阳
带队教师:张爱筠
管凤旭
关于技术报告和研究论文使用授权的说明本人完全了解第九届“飞思卡尔”杯全国大学生智能汽车邀请赛关于保留、使用技术报告和研究论文的规定,即:参赛作品著作权归参赛者本人,比赛组委会和飞思卡尔半导体公司可以在相关主页上收录并公开参赛作品的设计方案、技术报告以及参赛模型车的视频、图像资料,并将相关内容编纂收录在组委会出版论文集中。
参赛队员签名:
带队教师签名:
日期:
目录 (3)
摘要 (4)
第一章引言 (5)
1.1设计思路及方案的总体说明 (5)
1.2章节安排 (5)
第二章机械设计 (6)
2.1车体参数要求 (6)
2.2车体参数调整 (6)
2.3传感器支架和摄像头安装 (7)
2.4其他机械结构的调整 (9)
第三章硬件系统 (10)
3.1摄像头信号处理方案 (10)
3.2智能车电源系统设计 (12)
3.3电机驱动电路 (15)
第四章智能汽车控制软件设计 (17)
4.1智能车软件系统总体工作流程 (17)
4.2赛道中线提取及优化处理 (17)
4.3智能车的转向控制 (18)
4.4智能车的速度测量 (18)
4.5PID控制算法及其改进形式的应用 (19)
第五章开发调试过程及主要参数 (22)
5.1开发工具 (22)
5.2调试过程 (22)
5.3智能汽车外形参数 (23)
第六章总结 (24)
参考文献 (25)
本文对2014年哈尔滨工程大学极品飞车一号进行了详细的介绍,本车以
全国大学生智能汽车竞赛技术报告
全国大学生智能汽车竞赛技
术报告
设计概览
2.1整车设计思路
智能车主要由三个部分组成:检测系统,控制决策系统,动力系统。其中检测系统采用CMOS数字摄像头ov7620,控制决策系统采用S128作为主控芯片,动力系统主要控制舵机的转角和直流电机的转速。整体的流程为,通过视觉传感器来检测前方的赛道信息,并将赛道信息发送给单片机。
同时,通过光电编码器构成的反馈渠道将车体的行驶速度信息传送给主控单片机。根据所取得的赛道信息和车体当前的速度信息,由主控单片机做出决策,并通过PWM信号控制直流电机和舵机进行相应动作,从而实现车体的转向控制和速度控制。
2.2车模整体造型
我们车模的整体设计简洁,轻便,可靠美观。如下图:
2.3智能车软件设计
系统硬件对于赛车来说是最基础的部分,软件算法则是赛车的核心部分。首先,赛车系统通过图像采样处理模块获取前方赛道的图像数据,同时通过速度传感器模块实时获取赛车的速度。然后S128利用边缘检测方法从图像数据中提取赛道黑线,求得赛车于黑线位置的偏差,接着采用PID 方法对舵机进行反馈控制,并在PID算法的基础上,整合加入模糊控制算法,有利于对小车系统的非线性特性因素的控制。
最终赛车根据检测到的速度,结合我们的速度控制策略,对赛车速度不断进行恰当的控制调整,使赛车在符合比赛规则情况下沿赛道快速前进。
第三章小车的机械设计
良好的机械结构将直接影响小车的结构稳定,和车模的高速时的性能。模型车的机械机构和组装形式是整个模型车身的基础,机械结构的好坏对智能车的运行速度有直接的影响。经过大量的实验经验可以看出,机械结构决定了智能车的上限速度,而软件算法的优化则是使车速不断接近这个上线速度,软件算法只有在精细的机械结构上才能够更好的提高智能车的整体性能。
智能小车循迹、避障、红外遥控C语言代码
//智能小车避障、循迹、红外遥控C语言代码
//实现功能有超声波避障,红外遥控智能小车,红外传感器实现小车自动循迹,1602显示小车的工作状态,另有三个独立按键分别控制三种状态的转换
//注:每个小车的引脚配置都不一样,要注意引脚的配置,但是我的代码注释比较多,看起来比较容易一点
#include <>
#include <>
#include""
#include <>
#define uchar unsigned char
#define uint unsigned int
uchar ENCHAR_PuZh1[8]=" run ";//1602显示数组
uchar ENCHAR_PuZh2[8]=" back ";
uchar ENCHAR_PuZh3[8]=" stop ";
uchar ENCHAR_PuZh4[8]=" left ";
uchar ENCHAR_PuZh5[8]=" right ";
uchar ENCHAR_PuZh6[8]=" xunji ";
uchar ENCHAR_PuZh7[8]=" bizhang";
uchar ENCHAR_PuZh8[8]=" yaokong";
#define HW P2 //红外传感器引脚配置P2k口
#define PWM P1 /* L298N管脚定义*/
/******************************
超声波引脚控制
******************************/
sbit ECHO=P3^2; //超声波接收引脚定义兼红外遥控按键state_total =2 sbit TRIG=P3^3; //超声波发送引脚定义
智能小车代码
智能小车代码
一、主程序
#include
#include
#include "pwm.h"
#include "delay.h"
#include "tracking.h"
#define uchar unsigned char
#define uint unsigned int
sbit front=P3^3; /*前边红外避障*/
sbit right1=P3^4; /*右前红外避障*/
sbit right2=P3^5; /*右后红外避障*/
sbit left1=P3^6; /*左前红外避障*/
sbit left2=P3^7; /*左后红外避障*/
sbit shine0=P1^0; /*前趋光*/
sbit shine1=P1^1; /*左趋光*/
sbit shine2=P1^2; /*右趋光*/
sbit beef=P1^3;
sbit led=P2^4; /*声光报警led灯*/
uchar flag=0;
void main(void)
{ uchar k;
int i;
beef=1;
pwm_init();
/*******从A到B******************************/ while(right1==0 || right2==0 )
{
if(left1==0 && left2==0)
go(15,1);
else if(left1==1 && left2==0)
go(3,15);
else if(left1==0 && left2==1)
go(15,3);
else
go(14,15);
}
/******转弯进入Ⅰ区***************/
第八届北京科技大学摄像头组一队技术报告
图中为理想状态下的车模向左转弯,其中α、β为转向轮的打角,γ为质心处侧偏角,转向半径为ρ。理想的转向模型(阿克曼转向模型),是指在轮胎不打滑时,忽略左右两侧轮胎由百度文库受力不均产生的变形,忽略轮胎受重力影响下的变形时车辆的转向建模。车轮满足转向原理,左右轮的轴线与前轮轴线这三条直线必然交于一点。在这种理想的模型下,车体的转向半径ρ可以计算得到。
根据智能车系统的基本要求,我们设计了系统结构图,如图1.1所示。在满足比赛要求的情况下,力求系统简单高效,因而在设计过程中尽量简化硬件结构,减少因硬件而出现的问题。
图1.1系统结构图
1.
今年模型车的整车布局本着轻量化设计,如图2.1.具有以下特点:
(1)架高舵机并直立安装,以提高舵机响应速度;
(2)主板低位放置,降低赛车重心;
参赛队员签名:
带队教师签名:
日期:
摘
本文设计的智能车系统以MK60N512VMD100微控制器为核心控制单元,通过CMOS摄像头检测赛道信息,使用模拟比较器对图像进行硬件二值化,提取黑色引导线,用于赛道识别;通过光电编码器检测模型车的实时速度,使用PID控制算法调节驱动电机的转速和转向舵机的角度,实现了对模型车运动速度和运动方向的闭环控制。为了提高模型车的速度和稳定性,使用C#、MFC上位机、SD卡模块、键盘模块等调试工具,进行了大量硬件与软件测试。实验结果表明,该系统设计方案确实可行。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#include <MC9S12XS128.h> /* derivative information */
#pragma MESSAGE DISABLE C2705 /* Disable warning C2705 "Possible loss of data" */
///////////////////坑爹板子插接////////////////////////
//Vcc、GND
//PS0-3
//PB0-7 i
//AD0-7
//PP4(HREF)、PP5(VSYN)
/*****************************************************/
////////////////////////常量定义///////////////////////
//////////////////自己加入的宏定义////////////////////
////////////////////////////////////////////////////
#define White 0
#define Black 1
int flag=0;
int flag1=0;
//////////////////////可调参数///////////////////////
/////////////////////////////////////////////////////
#define IMG_ROWS 30 //图像采集行数
#define IMG_COLS 118 //图像采集列数
#define car_center 59 //车模中心值
#define steer_center 3830 //舵机中心值
#define steer_left 3100 //舵机左拐最大值
#define steer_right 4450 //舵机右拐最大值 ;cd
/////////////////////摄像头控制////////////////////
///////////////////////////////////////////////////
//CCD_state//
#define GETVSYNC 0 //获取场中断
#define GETHREF 1 //获取行中断
#define WAITVSYNC 2 //等待场中断
#define WAITHREF 3 //等待行中断
#pragma CODE_SEG DEFAULT //后续代码置于默认区域内
//////////////////自己加入的变量////////////////////
////////////////////////////////////////////////////
/*int border[IMG_ROWS]={135,135,134,133,133,132,130,128,
125,125,125,125,125,124,121,120,
120,120,120,120,120,120,120,120,
119,119,119,118,118,118}; */
/*int border[IMG_ROWS]={140,140,140,140,139,139,139,139,
138,138,135,135,132,132,130,130,
128,128,127,127,126,126,125,125,
124,124,123,123,122,122}; */
int border[IMG_ROWS]={118,118,118,118,118,118,118,118,
118,118,118,118,118,118,118,118,
118,118,118,118,118,118,118,118,
118,118,118,118,118,118};
///////////////////////LED////////////////////////
//////////////////////////////////////////////////
unsigned char Led[] = {0xFB,0xF7,0xDF,0xBF}; //PE2.3.5.6口显示,0对应的LED灯亮
int i=0,j=0,k=0;
int t=0,f=0,s_f=0;
///////////////////////数码管/////////////////////
//////////////////////////////////////////////////
unsigned char LedCode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数码管显示二进制码
unsigned char LedData[
]={0,0,0,0};
unsigned char LedNum = 0;
int time1 = 0;
int time=0;
int pulse=0;
///////////////////摄像头图像采
集//////////////////
///////////////////////////////////////////////////
uchar ImageData0[IMG_ROWS][IMG_COLS]; //图像存储数组
uchar image_v_num=0; //已采集到的摄像头的当前行
uchar v_counter=0; //已读取的行数
unsigned char CCD_state; //摄像头的给的状态
unsigned int VSync=0; //总场数
int count=0;
int st_flag=0;
int jishu=0;
//////////////////////黑线提取////////////////////
//////////////////////////////////////////////////
unsigned char Lx[IMG_ROWS]; //左引导线中心点列号,没有找到的值为IMG_COLS
unsigned char Rx[IMG_ROWS]; //右引导线中心点列号,没有找到的值为0
int center[IMG_ROWS]; //中点坐标
//////////////////////舵机PD控制/////////////////////
/////////////////////////////////////////////////////
int steer_out=steer_center; //舵机控制输出量
int steer_out1= steer_center;
//int steer_out6=steer_center;
//float steer_p_near=5.0; //对P值赋初值
//float steer_p_mid=14.0 ;
//float steer_p_far=13;
//float steer_p_near=25.0; //对P值赋初值
//float steer_p_mid=13.5;
//float steer_p_far=10.2;
//int SteerKd=2.0; //对D值赋初值
float steer_p_near=6.3; //对P值赋初值
float steer_p_mid=8.3;
float steer_p_far=10.2;
int SteerKd=1;
int near_piancha; //近处中线与车模中心偏差
int mid_piancha; //中间中线与车模中心偏差
int far_piancha; //远处中线与车模中心偏差
int allpiancha; //中线与车模中心总偏差
int hw_flag=1;
int zhidao=450 ;
int wandao= 450 ;
int SteerE0=0;
int SteerE1=0;
int M_flag=1;
int P_flag=0;
/****************************************************/
////////////////全局&初始化程序段/////////////////////
//////////////////////初始化函数/////////////////////
/////////////////////////////////////////////////////
//通用IO口初始化//
void initGPIO(void)
{
DDRB = 0xFF; //B口数码管输出,PORTB
DDRS = 0xFF; //S口输出,共阳数码管选择,PTS
DDRA=0x00;
//PP1、PP3PP5、PP7作为PWM输出时不用定义IO方向
//The PWM forces the I/O state to be an output for an enabled channel.
//If the PWM shutdown feature is enabled this pin is forced to be an input.
//In this case the data direction bit will not change.
//摄像头行场中断输入口
DDRP_DDRP4=0;
DDRP_DDRP5=0;
DDRT_DDRT1=0;
DDRT_DDRT2=0;
DDRT_DDRT0=0;
DDRT_DDRT3=0;
}
//ATD作为通用
IO//
void ATD0_init(void)
{
DDR1AD0=0x00; //AD口摄像头灰度值输入
ATD0DIEN=0x00FF;
}
//行场中断初始化//
void PP_init(void)
{
PIEP_PIEP4=1; //行中断允许
PIEP_PIEP5=1; //场中断允许
PPSP=0xFF; //上升沿触发中断
}
//锁相环初始化,将总线频率调整到80M//
void initPLL80M(void)
{
CLKSEL=0x00; //禁止锁相环,时钟有外部晶振提供,总线频率=外部晶振/2
PLLCTL_CME=1; //允许时钟监控
PLLCTL_SCME=0; //外部晶振失效进入自给时钟
CRGINT_SCMIE=1; //允许时钟状态改变时中断
PLLCTL_PLLON=1; //打开锁相环
SYNR=0xc9; //SYNRDIV=9
REFDV=0x81; //REFDIV=1 Fvoc=2*Fosc*(SYNRDIV+1)/(REFDIV+1) 2*16*10/2=160M
POSTDIV = 0x00; //Fpll=Fvoc/2/POSTDIV
//If POSTDIV = $00 then fPLL is same as fVCO (divide by one).
_asm(nop); //BUS CLOCK=80M (f_bus=f_pll/2) 160M/2=80M;
_asm(nop);
while(!(CRGFLG_LOCK==1)); // 等待锁相环初始化完成
CLKSEL_PLLSEL =1; // 使用锁相环
}
//总线80M,PWM初始化//
void initPWM80M(void)
{
PWME=0x00; //关闭所有PWM通道
PWMPOL=0xFF; //PWM极性选择,选择一个周期开始时为高电平
//Polarity = 1 (PPOLx = 1)
//Duty Cycle = [PWMDTYx / PWMPERx] * 100%
PWMPRCLK=0x22; //CLOCK A,B时钟分频,均选择从总线四分频,80M/4=20M,
PWMSCLA=5; //Clock SA = Clock A / (2 * PWMSCLA),从CLOCK A 10分频,2M(可以选用小于等于10M的其他频率)
PWMSCLB=5; //CLOCK SB从CLOCK B 10分频 ,20M/10=2M;
PWMCTL=0xF0; //01级联,23级联,45级联,67级联(16Bit)
PWMCLK=0xFF; //PWM始终选择,选择CLOCK SA SB为PWM时钟
//For channels 0, 1, 4, and 5 the choices are clock A or clock SA.
//For channels 2, 3, 6, and 7 the choices are clock B or clock SB.
PWMPER01=5000; //电机0 PWM频率=2M/200=10KHz,200为计数值,计数完了进入下一个PWM,计数频率为2M
PWMDTY01=300; //电机0的占空比=PWMDTY01/PWMPER01
PWMPER23=5000; //电机1 PWM频率=2M/200=10KHz
PWMDTY23=0; //电机1的占空比=PWMDTY23/PWMPER23
//PWMx Frequency = Clock (A, B, SA, or SB) / PWMPERx
PWMPER67=40000; //PP7的PWM频率为50Hz,舵机的PWM频率
PWMDTY67=steer_center; //舵机占空比
PWME_PWME1=1;
PWME_PWME3=1;
PWME_PWME7=1; //PWM波开始输出
}
// 实时中断初始化
//
void InitRTI(void)
{
RTICTL =0xAF; //16M/(80*1000)=200Hz 20ms中断一次
CRGINT = 0x80; // 打开实时中断
}
void Moto_PID1(int think_speed)
{
volatile static int err=0,derr=0,dderr=0;
volatile static int last_err=0,last_derr=0 ;
volatile static int M_PWM=0;
err=think_speed-pulse;// err
derr=err-last_err;
dderr=derr-last_derr;
if(err<80&&err>-80)
;
// else{
// if(err<40&&err>-40)
M_PWM+=err*1.3+derr*3.0+ dderr*3.3;
// else M_PWM+=err*5+ ;
// }
if(M_PWM<0)
M_PWM=0;
if(M_PWM>=2500)
M_PWM=2500;
PWMDTY01=M_PWM ;
last_err=err; //记录上次偏差值
last_derr=derr;
}
void Moto_PID() {
if((steer_out>=4000||steer_out<=3600)&&(steer_out1>=4000||steer_out1<=3600))
Moto_PID1(wandao) ;
else Moto_PID1(zhidao) ;
}
/***************************************************/
///////////////////图像处理算法//////////////////////
//摄像头正方向安装
//car_center=59
//IMG_COLS=118
//////////////////中线的中值滤波/////////////////////
/////////////////////////////////////////////////////
int lvbo(unsigned int a,unsigned int b,unsigned int c)
{
//lvbo(center[i-1],center[i+1],center[i])
unsigned int max,min;
if(a==0 || a==IMG_COLS || b==0 || b==IMG_COLS) return c;
//ab排序
max=a;
min=b;
if(a<b)
{
min=a;
max=b;
}
//c在ab中间
if(c>min && c<max) return c;
//否则
else return (max+min)/2;
}
////////////////////////二值化/////////////////////////
///////////////////////////////////////////////////////
void Erzhihua()
{
for(i=0;i<IMG_ROWS;i++)
{
for(j=0;j<IMG_COLS;j++)
{
if(ImageData0[i][j]>border[i]) ImageData0[i][j]=White;
else ImageData0[i][j]=Black;
}
}
}
//////////////////中线的中值滤波///////////////////////
///////////////////////////////////////////////////////
void CenterFilter()
{
int temp=0;
//黑线的中值滤波程序
for(i=IMG_ROWS-2;i>=1;i--)
{
temp=lvbo(center[i-1],center[i+1],center[i]);
center[i]=temp;
}
}
/////////////////////计算中心值//////////////////////
/////////////////////////////////////////////////////
void GetCenter(int i)
{
if(Lx[i]==2 && Rx[i]==116) {center[i]=car_center;} //左右均未搜到,用车中心值代替
if(Lx[i]==2 && Rx[i]!=116) {
if(i>2&&i<8) center[i]=Rx[i]-42;
if(i>13&&i<19) center[i]=Rx[i] -60;
else center[i]=Rx[i]-55 ;
}
if(Lx[i]!=2 && Rx[i]==116) {
if(i>2&&i<8) center[i]=Lx[i]+42;
if(i>13&&i<19) center[i]=Lx[i] +60;
else center[i]=Lx[i]+55;
}
if (Lx[i]!=2 && Rx[i]!=116)center[i]=(Lx[i]+Rx[i])/2;
}
void ImagePro
cessing()
{
//小车前1/2图像部分的处理//
for(i=IMG_ROWS-1;i>=IMG_ROWS*1/2;i--)
{
//从中间往右搜索右线
for(j=car_center;j<=IMG_COLS-3;j++)
{
if( !ImageData0[i][j] && ImageData0[i][j+1] && ImageData0[i][j+2] && ImageData0[i][j+3] )
{
Rx[i]=(j+1);
break;
}
if(j==(IMG_COLS-4)) {
Rx[i]=IMG_COLS-2;
}//没有搜索到右线
}
//从中间往左搜索左线
for(j=car_center;j>=3;j
--)
{
if( !ImageData0[i][j] && ImageData0[i][j-1] && ImageData0[i][j-2] && ImageData0[i][j-3] )
{
Lx[i]=(j-1);
break;
}
if(j==3){
Lx[i]=2; //没有搜索到左线 ////////为什么等于2啊?不应该等于0吗?
}
}
//计算中心线
GetCenter(i);
}
//小车后1/2图像部分的处理//
for(i=IMG_ROWS*1/2-1;i>=0;i--)
{
//从上一行中心点往右搜索右线
for(j=center[i+1];j<=IMG_COLS-3;j++)
{
if( !ImageData0[i][j] && ImageData0[i][j+1] && ImageData0[i][j+2] )
{
Rx[i]=(j+1);
break;
}
if(j==(IMG_COLS-3)) {
Rx[i]=IMG_COLS-2; //没有搜索到右线 //////?
}
}
//从上一行中心点往左搜索左线
for(j=center[i+1];j>=3;j--)
{
if( !ImageData0[i][j] && ImageData0[i][j-1] && ImageData0[i][j-2] )
{
Lx[i]=(j-1);
break;
}
if(j==3) {
Lx[i]=2; //没有搜索到左线
}
}
//计算中心线
GetCenter(i);
}
}
/***************************************************/
////////////////舵机电机控制算法/////////////////////
//获取中间值//
int get_mid(unsigned int a,unsigned int b,unsigned int c)
{
unsigned int x=0;
if(a>b){x=b;b=a;a=x;}
if(b>c){x=c;c=b;b=x;}
if(a>b){x=b;b=a;a=x;}
return b ;
}
/////////////////舵机控制///////////////////////
////////////////////////////////////////////////
void steer_PD()
{
steer_out1=steer_out;
near_piancha= car_center-get_mid((int)center[25],(int)center[26],(int)center[27]);
//若不在跑道内,保持最后的偏差值
//若偏右,则中线靠左,偏差大于0
mid_piancha= car_center-get_mid((int)center[15],(int)center[16],(int)center[17]);
far_piancha= car_center-get_mid((int)center[4],(int)center[5],(int)center[6]);
allpiancha=steer_p_near*(float)(near_piancha)+steer_p_mid*(float)(mid_piancha)+steer_p_far*(float)(far_piancha);
SteerE0=allpiancha;
steer_out=steer_center-SteerE0-SteerKd*(SteerE0-SteerE1); //若偏右,则舵机向左打(正开),steer_out应减小
//加改为减,因逆向行驶改为正向
SteerE1=SteerE0;
if(steer_out>steer_right) steer_out=steer_right; //舵机输出限幅,否则会烧坏舵机
if(steer_o
ut<steer_left) steer_out=steer_left;
PWMDTY67=steer_out;
}
/***************************************************/
//////////////// ///最终控制函数//////////////////////
void final_control()
{
if(CCD_state==GETVSYNC &&VSync%2==0 ) //偶数场进行控制,奇数场采集
{
Erzhihua();
ImageProcessing();
CenterFilter();
steer_PD();
Moto_PID() ;
CCD_state=WAITVSYNC;//等待下一个场中断
}
}
/***************************************************/
///////////////////主函数程序段//////////////////////
void main()
{
/* put your own code here */
DisableInterrupts; //不能
进入中断函数
initPLL80M();
initPWM80M();
InitRTI();
initGPIO();
ATD0_init();
PP_init();
PWMDTY67=steer_center;
PACTL = 0x40;
PACNT = 0; //初始化计数器
CCD_state=WAITVSYNC; //初始化摄像头状态变量,等待场中断
EnableInterrupts; //可以进入中断函数
/
for(;;) {
final_control();
_FEED_COP(); /* feeds the dog */
}
} /* loop forever */
/* please ma、 sure that you never leave main */
/******************************************************/
//////////////////中断函数程序段////////////////////////
//(中断号从Includes/MC9S12XS128.h中查询)
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 7 RTI_INT()
{
time++;
if (time>10){
pulse=PACNT;
PACNT=0;
time=0;
}
if(PTT_PTT1==0){
zhidao=550;
wandao=500;
}
else if(PTT_PTT2==0){
zhidao=500;
wandao=475;
}
else if(PTT_PTT3==0) {
zhidao=475;
wandao=475;
}
CRGFLG = 0x80;
}
////////////////灰度值获取//////////////
////////////////////////////////////////
interrupt 56 void V_SYNC() //行场中断服务子函数
{
if(PIFP_PIFP5==1) //场中断
{
PIFP_PIFP5=1;
PIEP_PIEP4=0; //进入场中断,行中断禁止
image_v_num=0; //行数清零
v_counter=0; //采集行清零
VSync++; //记录是奇数场还是偶数场
VSync=VSync%2;
if(VSync%2==0) //偶数场停止采集图像,即禁止行中断,用于控制
PIEP_PIEP4=0;
else
PIEP_PIEP4=1; //奇数场允许行中断,采集图像
CCD_state=GETVSYNC; //获得场中断
}
else if(PIFP_PIFP4==1) //行中断
{
image_v_num++;
//采集图像
if(image_v_num>=30 && image_v_num<=300 && v_counter<IMG_ROWS && image_v_num%5==0)
{
for(i=0;i<IMG_COLS;i++) //采集图像
{
Ima
geData0[v_counter][i]=PT1AD0;
}
v_counter++; //准备下一行
}
PIFP_PIFP4=1;
}
}
#pragma CODE_SEG DEFAULT