一、項(xiàng)目背景介紹
隨著社會的不斷發(fā)展,人們對于汽車的安全性要求越來越高,而倒車?yán)走_(dá)系統(tǒng)就是為了增強(qiáng)汽車駕駛者的安全性而被廣泛使用。在這種情況下,我們開發(fā)了一個(gè)基于Linux設(shè)計(jì)的倒車?yán)走_(dá)系統(tǒng),該系統(tǒng)可以采用迅為4412主控板,運(yùn)行Linux3.5內(nèi)核,使用USB攝像頭、TFT真彩顯示屏、超聲波測距模塊和蜂鳴器等硬件。
二、創(chuàng)新點(diǎn)
本項(xiàng)目的創(chuàng)新點(diǎn)包括:
- 采用開源Linux系統(tǒng):采用Linux系統(tǒng),具有很好的可擴(kuò)展性和靈活性,可以實(shí)現(xiàn)更為豐富和復(fù)雜的功能。
- 多個(gè)模塊的協(xié)同工作:本項(xiàng)目涉及到了攝像頭模塊、超聲波測距模塊、處理模塊、告警模塊和顯示模塊等多個(gè)模塊,這些模塊需要協(xié)同工作才能實(shí)現(xiàn)完整的功能。
- 實(shí)現(xiàn)了告警功能:本項(xiàng)目采用了蜂鳴器來實(shí)現(xiàn)告警功能,根據(jù)距離調(diào)整PWM輸出給出不同級別的告警聲音,能夠提醒駕駛者注意障礙物。
三、使用技術(shù)介紹
- 迅為4412主控板:本項(xiàng)目采用了迅為4412主控板,該主控板具有較高的性能和穩(wěn)定性,能夠滿足系統(tǒng)的運(yùn)行要求。
- Linux操作系統(tǒng):本項(xiàng)目采用了開源的Linux操作系統(tǒng),具有很好的可擴(kuò)展性和靈活性,適合進(jìn)行自定義開發(fā)。
- V4L2協(xié)議:V4L2協(xié)議是Linux下的一個(gè)視頻設(shè)備驅(qū)動程序接口,可以方便地實(shí)現(xiàn)USB攝像頭的圖像采集。
- 超聲波測距模塊:通過GPIO口與主控板相連,使用定時(shí)器產(chǎn)生超聲波并計(jì)算與接收到回波之間的時(shí)間差,從而計(jì)算出與障礙物之間的距離。
- PWM輸出控制:根據(jù)距離調(diào)整PWM輸出給出不同級別的告警聲音。
- TFT真彩顯示屏:本項(xiàng)目采用了TFT真彩顯示屏,能夠?qū)崿F(xiàn)高清晰度的圖像顯示。
- 系統(tǒng)管理模塊:負(fù)責(zé)管理整個(gè)系統(tǒng)的啟動、配置和錯(cuò)誤處理等操作。例如,可以將系統(tǒng)的啟動腳本寫在/etc/rc.local中,通過調(diào)用shell腳本來實(shí)現(xiàn)系統(tǒng)的初始化和啟動。
四、系統(tǒng)架構(gòu)
整個(gè)系統(tǒng)由以下幾個(gè)模塊組成:
- 攝像頭模塊:負(fù)責(zé)采集車尾環(huán)境圖像,并傳輸給處理模塊。
- 超聲波測距模塊:負(fù)責(zé)與障礙物之間的距離測量,并將結(jié)果傳輸給處理模塊。
- 處理模塊:負(fù)責(zé)視頻顯示、距離信息的處理、告警功能的實(shí)現(xiàn)。
- 告警模塊:負(fù)責(zé)根據(jù)距離調(diào)整PWM輸出給出不同級別的告警聲音,并使用蜂鳴器輸出告警信息。
- 顯示模塊:負(fù)責(zé)將處理模塊生成的圖像顯示在TFT真彩顯示屏上。
- 系統(tǒng)管理模塊:負(fù)責(zé)管理整個(gè)系統(tǒng)的啟動、配置和錯(cuò)誤處理等操作。
五、功能設(shè)計(jì)
- 攝像頭模塊 由于Linux系統(tǒng)具有很好的驅(qū)動支持,因此可以直接使用V4L2協(xié)議來獲取USB攝像頭的圖像。獲取圖像后,需要通過DMA方式將數(shù)據(jù)傳輸給處理模塊進(jìn)行處理。
- 超聲波測距模塊 超聲波測距模塊可以通過GPIO口與主控板相連,使用定時(shí)器產(chǎn)生超聲波并計(jì)算與接收到回波之間的時(shí)間差,從而計(jì)算出與障礙物之間的距離。
- 處理模塊 處理模塊負(fù)責(zé)將攝像頭采集到的圖像和超聲波測距模塊測得的距離信息整合處理,并根據(jù)距離信息來控制告警模塊。
- 告警模塊 告警模塊根據(jù)處理模塊傳遞過來的距離信息來控制PWM輸出,并使用蜂鳴器輸出告警信息。
- 顯示模塊 顯示模塊負(fù)責(zé)將處理模塊生成的圖像顯示在TFT真彩顯示屏上,并實(shí)現(xiàn)顯示屏的刷新和管理操作。
- 系統(tǒng)管理模塊 系統(tǒng)管理模塊負(fù)責(zé)管理整個(gè)系統(tǒng)的啟動、配置和錯(cuò)誤處理等操作。例如,可以將系統(tǒng)的啟動腳本寫在/etc/rc.local中,通過調(diào)用shell腳本來實(shí)現(xiàn)系統(tǒng)的初始化和啟動。
六、攝像頭圖像顯示應(yīng)用代碼
#include
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
?
/* 圖片的象素?cái)?shù)據(jù) */
typedef struct PixelDatas {
int iWidth; /* 寬度: 一行有多少個(gè)象素 */
int iHeight; /* 高度: 一列有多少個(gè)象素 */
int iBpp; /* 一個(gè)象素用多少位來表示 */
int iLineBytes; /* 一行數(shù)據(jù)有多少字節(jié) */
int iTotalBytes; /* 所有字節(jié)數(shù) */
unsigned char *VideoBuf; //存放一幀攝像頭的數(shù)據(jù)
//指向了存放攝像頭數(shù)據(jù)的空間地址
}T_PixelDatas;
?
T_PixelDatas Pixedata; //存放實(shí)際的圖像數(shù)據(jù)
?
/*
USB攝像頭相關(guān)參數(shù)定義
*/
struct v4l2_buffer tV4l2Buf;
int iFd;
int ListNum;
unsigned char* pucVideBuf[4]; // 視頻BUFF空間地址
void camera_pthread(void);
?
//LCD屏相關(guān)的參數(shù)
unsigned char *lcd_mem=NULL; /*LCD的內(nèi)存地址*/
struct fb_fix_screeninfo finfo; /*固定形參*/
struct fb_var_screeninfo vinfo; /*可變形參*/
void LCD_Init(void);
void show_pixel(int x,int y,int color);
?
?
int main(int argc ,char *argv[])
{
if(argc!=2)
{
printf("./app /dev/videoX
");
return -1;
}
LCD_Init(); //LCD屏初始化
camera_init(argv[1]); //攝像頭設(shè)備初始化
//開始采集攝像頭數(shù)據(jù),并實(shí)時(shí)顯示在LCD屏幕上
camera_pthread();
return 0;
}
?
?
?
//LCD屏初始化
void LCD_Init(void)
{
/*1.打開設(shè)備文件*/
int fd=open("/dev/fb0",O_RDWR);
if(fd<0)
{
printf("/dev/fb0設(shè)備文件打開失敗!
");
return;
}
/*2. 讀取LCD屏的參數(shù)*/
ioctl(fd,FBIOGET_FSCREENINFO,&finfo);//固定參數(shù)
printf("映射的長度:%d
",finfo.smem_len);
ioctl(fd,FBIOGET_VSCREENINFO,&vinfo);//可變參數(shù),32位
printf("分辨率:%d*%d,%d
",vinfo.xres,vinfo.yres,vinfo.bits_per_pixel);
?
/*3. 映射LCD的地址到進(jìn)程空間*/
lcd_mem=mmap(NULL,finfo.smem_len,PROT_WRITE|PROT_READ,MAP_SHARED,fd,0);
if(lcd_mem==NULL)
{
printf("lcd_mem映射失敗!
");
return;
}
memset(lcd_mem,0xFFFFFFFF,finfo.smem_len);
}
?
/*畫點(diǎn)*/
void show_pixel(int x,int y,int color)
{
unsigned long *show32 = NULL;
/* 定位到 LCD 屏上的位置*/
show32 =(unsigned long *)(lcd_mem + y*vinfo.xres*vinfo.bits_per_pixel/8 + x*vinfo.bits_per_pixel/8);
*show32 =color; /*向指向的 LCD 地址賦數(shù)據(jù)*/
}
?
?
//顯示攝像頭的數(shù)據(jù)
void Show_VideoData(int w,int h,unsigned char *rgb)
{
int i,j;
int x0,x=0,y=0;
int color; //顏色 值
unsigned char r,g,b;
x0=x;
for(i=0;i
七、超聲波測距驅(qū)動代碼
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
?
#include
#include
#include
?
#include
?
static int chaoshengbo_irq=0;
?
#define GPB_CON 0x11400040
#define GPB_DAT 0x11400044
?
static u32 *gpb_con=NULL;
static u32 *gpb_dat=NULL;
?
/*
硬件連接:
輸出腳: GPX1_0 ---ECHO
輸入腳: GPB_7
*/
static void tiny4412_work_func(struct work_struct *work)
{
printk("GPB=%d
",*gpb_dat&1<<7);
?
ktime_t my_time1,my_time2;
unsigned int i,j;
unsigned int time_cnt=0;
?
my_time1=ktime_get(); //獲取當(dāng)前時(shí)間
i=ktime_to_us(my_time1); //轉(zhuǎn) us
?
while(gpio_get_value(EXYNOS4_GPX1(0))){} //高電平卡住
?
my_time2=ktime_get(); //獲取當(dāng)前時(shí)間
j=ktime_to_us(my_time2); //轉(zhuǎn) us
?
printk("us:%d
",j-i);
}
?
static DECLARE_WORK(caoshengbotiny4412_work,tiny4412_work_func);
?
/*
中斷處理函數(shù)
*/
irqreturn_t irq_handler_chaoshengbo(int irq, void *dev)
{
schedule_work(&caoshengbotiny4412_work); /*正常情況下: 是在中斷服務(wù)函數(shù)里面*/
return IRQ_HANDLED; /*表示中斷已經(jīng)處理過了*/
}
?
static void timer_function(unsigned long data);
static DEFINE_TIMER(timer_caoshengbo, timer_function,0,0);
?
static void timer_function(unsigned long data)
{
static u8 state;
state=!state;
if(state)*gpb_dat|=1<<7;
else *gpb_dat&=~(1<<7);
?
mod_timer(&timer_caoshengbo,jiffies+msecs_to_jiffies(500));
}
?
static int __init tiny4412_chaoshengbo_init(void)
{
int i,err;
/*獲取中斷號*/
chaoshengbo_irq=gpio_to_irq(EXYNOS4_GPX1(0));
printk("中斷號:%d
",chaoshengbo_irq);
/*外部中斷注冊*/
err=request_irq(chaoshengbo_irq,irq_handler_chaoshengbo,IRQ_TYPE_EDGE_RISING,"tiny4412_chaoshengbo",NULL);
if(err!=0)printk("中斷注冊失敗!
");
?
/*映射內(nèi)存*/
gpb_con=ioremap(GPB_CON,4);
gpb_dat=ioremap(GPB_DAT,4);
?
/*配置模式*/
*gpb_con&=~(0xF<<4*7); //輸出模式
*gpb_con|=0x1<<4*7;
mod_timer(&timer_caoshengbo,jiffies+msecs_to_jiffies(100));
return 0;
}
?
static void __exit tiny4412_chaoshengbo_exit(void)
{
free_irq(chaoshengbo_irq,NULL);
iounmap(gpb_con);
iounmap(gpb_dat);
del_timer(&timer_caoshengbo);
}
?
module_init(tiny4412_chaoshengbo_init); /*指定驅(qū)動的入口函數(shù)*/
module_exit(tiny4412_chaoshengbo_exit); /*指定驅(qū)動的出口函數(shù)*/
MODULE_LICENSE("GPL"); /*指定驅(qū)動許可證*/
?
?
-
嵌入式
+關(guān)注
關(guān)注
5149文章
19655瀏覽量
317285 -
物聯(lián)網(wǎng)
+關(guān)注
關(guān)注
2930文章
46210瀏覽量
392053 -
Linux
+關(guān)注
關(guān)注
87文章
11509瀏覽量
213675 -
倒車?yán)走_(dá)
+關(guān)注
關(guān)注
4文章
77瀏覽量
24217 -
雷達(dá)系統(tǒng)
+關(guān)注
關(guān)注
6文章
258瀏覽量
29116
發(fā)布評論請先 登錄
倒車雷達(dá)語音IC分享
倒車雷達(dá)應(yīng)用
怎么實(shí)現(xiàn)基于PSoC芯片的倒車雷達(dá)控制系統(tǒng)的設(shè)計(jì)?
請問怎樣去設(shè)計(jì)一種倒車雷達(dá)系統(tǒng)?
實(shí)現(xiàn)汽車倒車雷達(dá)系統(tǒng)的設(shè)計(jì)方法
何為倒車雷達(dá)
汽車倒車雷達(dá)系統(tǒng)的設(shè)計(jì)

基于Ameba的倒車雷達(dá)系統(tǒng)
汽車倒車雷達(dá)系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)(一)

評論