作品地址:http://m.1cnz.cn/project/33798
作者:Mak_z
項(xiàng)目簡(jiǎn)介:
使用基于RT-thread操作系統(tǒng)的AB32VG1開(kāi)發(fā)板作為主控,對(duì)ov7670攝像頭進(jìn)行圖像采集,并使用串口發(fā)送圖片RGB565格式到PC供opencv進(jìn)行圖像識(shí)別。原項(xiàng)目設(shè)想在開(kāi)發(fā)板上進(jìn)行采集的同時(shí)并通過(guò)簡(jiǎn)單的二值算法和插值算法實(shí)現(xiàn)車(chē)牌號(hào)識(shí)別,但實(shí)踐中發(fā)現(xiàn)開(kāi)發(fā)板的ram并不夠保存采集回來(lái)的圖像信息,與數(shù)據(jù)手冊(cè)中介紹的192k有一定差距,實(shí)現(xiàn)用戶(hù)能使用的ram是70k;同時(shí)原設(shè)想是帶lcd屏幕的,但最后發(fā)覺(jué)io口數(shù)量不夠,只能通過(guò)串口調(diào)試顯示,但lcd屏幕的 spi代碼仍保留在原碼中,可供參考。目前開(kāi)發(fā)板通過(guò)攝像頭采集完整數(shù)據(jù)部分已經(jīng)完成,并且可以通過(guò)串口uart1發(fā)送到上位機(jī)進(jìn)行圖像顯示。識(shí)別號(hào)牌上位機(jī)需要另外再做。
硬件說(shuō)明:
1.攝像頭ov7670帶fifo:采用csi總線的普通30w攝像頭。考慮到用模擬讀取攝像頭,io的反轉(zhuǎn)速度可能不能滿足高速采集的需要,因此保險(xiǎn)起見(jiàn),直接使用帶fifo的攝像頭。sccb總線采用全模擬的方式,跳過(guò)了所有中間層,直接操作寄存器,提高了總線的時(shí)鐘。
2.串口工具PL2302(ttl轉(zhuǎn)RS232),一款與pc通訊的串口工具,免驅(qū)。
3.總接線圖
軟件說(shuō)明:
1.軟件流程圖
2.關(guān)鍵代碼
/* 攝像頭IO口采用直接操作寄存器的方式實(shí)現(xiàn),極大提升io速度 */
/* sccb總線的初始化并設(shè)置ov7670相應(yīng)寄存器 */
sccb_init();
if(sccb_write_reg(0x12, 0x80) == RT_FALSE){
return RT_FALSE;
}
rt_thread_delay(50);
id1 = sccb_read_reg(0x0b);
id2 = sccb_read_reg(0x0a);
rt_kprintf("id1 = 0x%02x, id2 = 0x%02x\n", id1, id2);
for(rt_uint16_t i = 0;i < sizeof(ov7670_init_reg_tbl) / sizeof(ov7670_init_reg_tbl[0]);i++){
sccb_write_reg(ov7670_init_reg_tbl[0], ov7670_init_reg_tbl[1]);
}
/* 開(kāi)啟攝像頭vsync掃描線程(沒(méi)有外部中斷因此改用輪詢(xún)的方式實(shí)現(xiàn)) */
rt_thread_t thread;
/* 查詢(xún)VSYNC線程 */
thread = rt_thread_create("ov7670_vsync", ov7670_vsync_thread_entry, RT_NULL, 1024, 5, 100);
if (thread == RT_NULL){
rt_kprintf("ov7670_vsync thread create fail!\n");
return RT_FALSE;
}
/* 啟動(dòng)線程 */
rt_thread_startup(thread);
/* 提取hal庫(kù)實(shí)現(xiàn)了uart的數(shù)據(jù)發(fā)送函數(shù) */
void uart1_send(rt_uint8_t *pbuf, rt_uint32_t len)
{
for(rt_uint32_t i = 0;i < len;i++){
hal_uart_clRFlag(UART1_BASE, UART_FLAG_TXPND);
hal_uart_write(UART1_BASE, pbuf);
while(hal_uart_getflag(UART1_BASE, UART_FLAG_TXPND) == 0);
}
}
/* LCD底層驅(qū)動(dòng)代碼,因?yàn)橐_不夠,所以無(wú)法演示,測(cè)試可用,另外程序里也配有寄存器版本的操作代碼 */
static rt_uint32_t spi_bit_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
struct rt_spi_bit_ops *ops = (struct rt_spi_bit_ops *)device->user_data;
rt_uint8_t tmp_buf[1024];
rt_memset(tmp_buf, 0, sizeof(tmp_buf));
if(message->send_buf == RT_NULL){
message->send_buf = tmp_buf;
}else if(message->recv_buf == RT_NULL){
message->recv_buf = tmp_buf;
}else{
return RT_FALSE;
}
if (message->cs_take){
ops->set_cs(ops->data, PIN_LOW);
}
message->length & SPI_DC ? ops->set_dc(ops->data, PIN_HIGH) : ops->set_dc(ops->data, PIN_LOW);
message->length &= ~SPI_DC; /* 復(fù)原消息長(zhǎng)度 */
// rt_kprintf("message->length = %d\n", message->length);
spi_rw_bytes(device, (rt_uint8_t *)message->send_buf, (rt_uint8_t *)message->recv_buf, message->length);
if (message->cs_release){
ops->set_cs(ops->data, PIN_HIGH);
}
}
static const struct rt_spi_ops spi_bit_bus_ops ={
RT_NULL,
spi_bit_xfer
};
優(yōu)化思路:
1. 由于ab32vg1沒(méi)有外部中斷可以使用,ov7670的幀同步信號(hào)vsync只有500us的高電平時(shí)間,因此為了捕捉到該信號(hào),vsync線程一直占用很多的資源;
2. 串口與上位通訊的速度目前最快只有115200bps,上位機(jī)可以接受256000bps的速度,但將驅(qū)動(dòng)改為256000bps后,接收會(huì)出現(xiàn)亂碼,因此串口使用的圖片數(shù)據(jù)非常緩慢。
項(xiàng)目演示
-
RT-Thread
+關(guān)注
關(guān)注
31文章
1304瀏覽量
40300
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論