国产精品久久久久影院,成人午夜福利视频,国产精品久久久久高潮,国产精品 欧美 亚洲 制服,国产精品白浆无码流出

【STM32調(diào)試(一)】串口發(fā)送像素,上位機(jī)解析顯示

發(fā)布者:SparklingStar最新更新時(shí)間:2024-12-31 來源: jianshu關(guān)鍵字:STM32  調(diào)試  串口  上位機(jī) 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

一、思路

STM32采集OV數(shù)據(jù),數(shù)據(jù)尺寸是QVGA(320*240),RGB565數(shù)據(jù)格式。采集的FIFO數(shù)據(jù)是一個(gè)像素,占兩個(gè)字節(jié)。每采集一個(gè)像素就向串口發(fā)送一個(gè)像素。上位機(jī)是一個(gè)串口助手,接收串口數(shù)據(jù),將一個(gè)RGB565格式像素解析為RGB55格式并顯示在上位機(jī)。

二、STM32采集數(shù)據(jù)發(fā)送

2.1、OV7725模組

我們使用正點(diǎn)原子的例程進(jìn)行修改,在接線時(shí)注意將數(shù)據(jù)線綁在一起,其它線綁在一起,以防發(fā)生數(shù)據(jù)干擾。

我們使用正點(diǎn)原子的例程進(jìn)行修改,在接線時(shí)注意將數(shù)據(jù)線綁在一起,其它線綁在一起,以防發(fā)生數(shù)據(jù)干擾。

我買的OV7725攝像頭是帶FIFO的,因?yàn)?OV7725 的像素時(shí)鐘(PCLK)最高可達(dá) 24Mhz,我們用STM32F103的IO口直接抓取,是非常困難的,也十分占耗 CPU,所以我們并不是采取直接抓取來自 OV7725 的數(shù)據(jù),而是通過 FIFO 讀取,ALIENTEK-OV7725 攝像頭模塊自帶了一個(gè) FIFO 芯片(AL422B),用于暫存圖像數(shù)據(jù),OV將圖像幀存儲(chǔ)在FIFO中,CPU就可以自己慢慢讀取FIFO中的數(shù)據(jù)幀,這樣就可以很方便的獲取圖像數(shù)據(jù)了,而不再需要單片機(jī)具有高速 IO,也不會(huì)耗費(fèi)多少 CPU,任意一款MCU都可控制該模塊和獲取圖像。

在這里插入圖片描述

1. 串行攝像頭控制總線(SCCB)

ATK-OV7725 攝像頭模塊的所有配置,都是通過 SCCB 總線來實(shí)現(xiàn)的。

它由兩條數(shù)據(jù)線組成:一個(gè)是用于傳輸時(shí)鐘信號(hào)的 SIO_C(即 OV_SCL),另一個(gè)適用于傳輸數(shù)據(jù)信號(hào)的 SIO_D(即 OV_SDA)。 SCCB 的傳輸協(xié)議與 IIC 協(xié)議極其相似,只不過 IIC 在每傳輸完一個(gè)字節(jié)后,接收數(shù)據(jù)的一方要發(fā)送一位的確認(rèn)數(shù)據(jù),而 SCCB 一次要傳輸 9 位數(shù)據(jù),前 8 位為有用數(shù)據(jù),而第 9 位數(shù)據(jù)在寫周期中是 don’t care 位(即不必關(guān)心位),在讀周期中是 NA 位。 SCCB 定義數(shù)據(jù)傳輸?shù)幕締卧獮橄啵?phase),即一個(gè)相傳輸一個(gè)字節(jié)數(shù)據(jù)。

2. 驅(qū)動(dòng)程序

中斷程序:

PA15位中斷輸入,接OV7725的VSYNC腳,負(fù)責(zé)幀同步。
ov_sta是OV的中斷標(biāo)記,狀態(tài)變量ov_sta初始為0,VSYNC中斷到來時(shí),OV開始輸出一幀圖像,復(fù)位FIFO寫指針,允許寫入FIFO,ov_sta自增至1。

//中斷服務(wù)函數(shù)

u8 ov_sta;

void EXTI15_10_IRQHandler(void)

{           


    if(EXTI_GetITStatus(EXTI_Line15)==SET)

    {     

        if(ov_sta<2)

        {

            if(ov_sta==0)

            {

                OV7670_WRST=0;      //復(fù)位寫指針              

                OV7670_WRST=1;  

                OV7670_WREN=1;      //允許寫入FIFO

            }else OV7670_WREN=0;    //禁止寫入FIFO   

            ov_sta++;

        }

    }

    EXTI_ClearITPendingBit(EXTI_Line15);    //清除LINE15上的中斷標(biāo)志位  

}

//外部中斷初始化程序

//初始化PA15為中斷輸入.

void EXTI15_Init(void)

{


    GPIO_InitTypeDef GPIO_InitStructure;

    EXTI_InitTypeDef EXTI_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA,ENABLE);//外部中斷,需要使能AFIO和GPIOA時(shí)鐘


    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //關(guān)閉JTAG,使能SWD


    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_15;//PA15

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //設(shè)置成上拉輸入

    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA15


    GPIO_SetBits(GPIOA,GPIO_Pin_15);


    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);


    EXTI_InitStructure.EXTI_Line=EXTI_Line15;

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿觸發(fā)

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_InitStructure);     //根據(jù)EXTI_InitStruct中指定的參數(shù)初始化外設(shè)EXTI寄存器


    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;            //使能按鍵所在的外部中斷通道

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //搶占優(yōu)先級(jí)2, 

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;                   //子優(yōu)先級(jí)1

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                             //使能外部中斷通道

    NVIC_Init(&NVIC_InitStructure); 


}


刷新顯示:

camera_refresh()負(fù)責(zé)讀取FIFI圖像數(shù)據(jù),并送至LCD顯示。在這里是連續(xù)讀取的,讀完一幀圖像就立即將ov_sta置0。若想只讀取一幀圖像,可以不把ov_sta置0,不進(jìn)行下一次FIFO讀取。這也是做攝像機(jī)和照相機(jī)的區(qū)別。

2.2、串口發(fā)送

有兩種發(fā)送方式:高低位單獨(dú)發(fā)送;合并一起發(fā)送。
發(fā)送內(nèi)容:黑白,二值,彩圖

選擇黑白發(fā)送或二值圖像發(fā)送就會(huì)簡單許多,而且數(shù)據(jù)量至少會(huì)小一半。但是為了后續(xù)上位機(jī)有更高質(zhì)量的圖片做處理,這里還是選擇發(fā)送彩色圖像,將采集的像素點(diǎn)直接發(fā)送給串口。

采集一個(gè)像素,發(fā)送一個(gè)像素:

for(i=0;i{

        for(j=0;j        {

                GPIOB->CRL=0X88888888;

                OV7725_RCK=0;

                color=OV7725_DATA;  //讀數(shù)據(jù)  --高8位


                OV7725_RCK=1; 

                color<<=8;  

                OV7725_RCK=0;

                color|=OV7725_DATA; //讀數(shù)  --低8位     (高低8+8位合并成一個(gè)u16發(fā)送)                              

                OV7725_RCK=1;

                GPIOB->CRL=0X33333333;


                /*串口發(fā)送數(shù)據(jù)*/

                Send_Pic_Div(color);     //color:u16

                LCD_WR_DATA(color);      //顯示一個(gè)像素點(diǎn)(RGB) 320*240中的一個(gè)             

        }

}


然后RGB565的一個(gè)像素是16位,兩字節(jié)。在測試過程中發(fā)現(xiàn),如果直接發(fā)送u16的color,那么圖像將會(huì)偏綠。調(diào)試發(fā)現(xiàn)讀取高字節(jié)R分量值為0。所以我還是選擇將u16拆成低8位和高8位分開發(fā)送。

但是其實(shí)真正的原因在于上位機(jī)解析方法錯(cuò)了,發(fā)送方式并無影響,這點(diǎn)我們在后文說。

串口發(fā)送函數(shù),先發(fā)高位,后發(fā)低位:

void Send_Pic_Div(u16 color)

{

        u8 temp;         

        temp = color&0x00ff;                        //低八位

        USART_SendData(USART1,temp);

        while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);


        temp = color>>8;                                //高八位

        USART_SendData(USART1,temp);

        while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);

}


或者直接發(fā)u16的color像素:

void Send_Pic_All(u16 color)

{

        USART_SendData(USART1,color);

        while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);

}




最后需要注意,把串口其它發(fā)送數(shù)據(jù)部分注釋掉,因?yàn)樯衔粰C(jī)把所有接受數(shù)據(jù)都認(rèn)為是圖像數(shù)據(jù)。我這里只注釋了LCD初始化和TIM3中斷里的兩個(gè)printf()。


至此,STM32這邊的程序就完成啦,接下來做上位機(jī)部分。


三、上位機(jī)接收,解析,顯示保存

2.1、接收解析

上位機(jī)還是基于串口助手修改的,我直接用我之前寫的串口助手修改了,基礎(chǔ)功能不多(正是想要的)。需要重點(diǎn)修改的就是串口接收部分。

我們采用采用16進(jìn)制接收數(shù)據(jù)。因?yàn)槎际亲止?jié)流,而且是不斷發(fā)送過來的。所以接收到數(shù)據(jù)包就要解析。

這里需要強(qiáng)調(diào)一下,一個(gè)像素是16位,2字節(jié),所以我們要拿到兩個(gè)byte,也就是像素的高位和低位,然后再進(jìn)行解析。我這樣來取兩字節(jié):


 colorL = received_buf[i * 2];
 colorH = received_buf[i * 2 + 1];

還有Invoke最好套在最外面,因?yàn)槔锩鏁?huì)頻繁的更新UI顯示。
整個(gè)C#接收代碼是這樣的:

private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)

{

   this.Invoke(new EventHandler(delegate

   {            

       //---------------------------//

       int num = sp.BytesToRead;      //獲取接收緩沖區(qū)中的字節(jié)數(shù)

       byte[] received_buf = new byte[num];    //聲明一個(gè)大小為num的字節(jié)數(shù)據(jù)用于存放讀出的byte型數(shù)據(jù)

       receive_count += num;             //接收字節(jié)計(jì)數(shù)變量增加nun

       sp.Read(received_buf, 0, num);    //讀取接收緩沖區(qū)中num個(gè)字節(jié)到byte數(shù)組中

       sb.Clear();                       //防止出錯(cuò),首先清空字符串構(gòu)造器

       if (isHex == true)

       {

           //u16 = 2bytes

           //這里是按byte讀取,換成Int16也不行,需要一次讀兩個(gè)byte出來

           for (int i = 0; i < received_buf.Length; i++)

           {

               sb.Append(received_buf[i].ToString('X2') + ' ');    //將byte型數(shù)據(jù)轉(zhuǎn)化為2位16進(jìn)制文本顯示,并用空格隔開

               if ((i+1) * 2 <= received_buf.Length)

               {

                   //讀取一個(gè)像素

                   colorL = received_buf[i * 2];

                   colorH = received_buf[i * 2 + 1];

                   //解析RGB565

                   Int32 r, g, b;                        //0-255 , color 511

                   r = (colorH & 0xf8) >> 3;

                   g = ((colorH & 0x07) << 2) | ((colorL & 0xe0) >> 6);

                   b = colorL & 0x1f;

                   //Console.WriteLine('Red: '+r.ToString()+ ' Green: ' + g.ToString()+ ' Blue: ' + b.ToString());

                   //合成并顯示像素,提高亮度

                   newColor = Color.FromArgb(r*5, g*5, b*5);

                   Int32 Row = (receive_count) / 320 / 2;    //計(jì)算列: 共240列,每列320個(gè)像素點(diǎn)

                   OvImage.SetPixel(Row, y++, newColor);

                   //換列顯示

                   if (y == 320) { y = 0; }

               }                        

           }           

[1] [2]
關(guān)鍵字:STM32  調(diào)試  串口  上位機(jī) 引用地址:【STM32調(diào)試(一)】串口發(fā)送像素,上位機(jī)解析顯示

上一篇:STM32(1):點(diǎn)亮LED(上)
下一篇:【STM32調(diào)試(三)】采集bmp圖像保存在SD卡

推薦閱讀最新更新時(shí)間:2025-07-02 18:25

STM32F103標(biāo)準(zhǔn)庫開發(fā)---Uart串口通信實(shí)驗(yàn)---安裝串口驅(qū)動(dòng)和串口調(diào)試
串口調(diào)試器 USB轉(zhuǎn)TTL實(shí)物圖: 接口介紹: 串口驅(qū)動(dòng)安裝 雙擊串口驅(qū)動(dòng)CH341SER.EXE安裝軟件 點(diǎn)擊安裝 安裝成功 將串口調(diào)試器插入電腦,然后選擇設(shè)備管理器,成功后的端口驅(qū)動(dòng)如下: 串口調(diào)試助手 串口調(diào)試助手:sscom5.13.1 界面如下: 串口通信調(diào)試 1. 打開串口調(diào)試助手 雙擊sscom5.13.1.exe文件 2. 選擇端口 設(shè)備管理器中是COM5 串口調(diào)試助手中選擇COM5 3. 設(shè)置參數(shù) 數(shù)據(jù)具體如下: 4. 打開串口 點(diǎn)擊打開串口 5. 調(diào)試現(xiàn)象 我單片機(jī)中程序的功能是:每100ms發(fā)送一次 工欲善其事,必先利其器。 具體現(xiàn)象如下:
[單片機(jī)]
STM32F103標(biāo)準(zhǔn)庫開發(fā)---Uart<font color='red'>串口</font>通信實(shí)驗(yàn)---安裝<font color='red'>串口</font>驅(qū)動(dòng)和<font color='red'>串口</font><font color='red'>調(diào)試</font>
stm32怎么用keil軟件進(jìn)行調(diào)試
在做開發(fā)的前幾年,基本上都沒用仿真,有bug就嘗試改程序,一邊改一邊調(diào)試。 甚至都還不知道硬件仿真存在的價(jià)值,因?yàn)橐恢倍紱]用過,而且很多芯片也不支持。 直到有一次在做行車記錄儀項(xiàng)目的時(shí)候,接觸到了GRAIN公司的一款單片機(jī)。 本來我打算是直接開干的,但是老大非要我把這個(gè)芯片的仿真環(huán)境搭好。 于是我就開始網(wǎng)上搜集資料,不得不說這塊的資料真少,那時(shí)又剛接觸仿真這塊的。 搞了將近半個(gè)月都搞不定,然后我鼓起勇氣跟老大說,仿真搞不出來,要不我就直接開始寫程序燒錄進(jìn)去調(diào)試算了。 但是老大的意思還是希望我把仿真的環(huán)境搭建出來,我又試了2個(gè)星期,還是不行,于是就不理他了,直接開始寫程序調(diào)試。 如果沒浪費(fèi)時(shí)間研究怎么搭建仿環(huán)境,估計(jì)我程序都完成40
[單片機(jī)]
STM32死機(jī) 調(diào)試時(shí)進(jìn)入HardFault_Handler定位錯(cuò)誤的方法
STM32在運(yùn)行不正常的時(shí)候我們一般會(huì)進(jìn)行調(diào)試看看問題出在了哪里。但是當(dāng)STM32卡死后進(jìn)行調(diào)試的時(shí)候會(huì)發(fā)現(xiàn)進(jìn)入到了一個(gè)HardFault_Handler函數(shù)里,這是一個(gè)硬件錯(cuò)誤處理函數(shù)。通過它和MDK配合可以定位程序最后卡死的原因。 STM32卡死的原因有以下幾種:數(shù)組越界操作;內(nèi)存溢出,訪問越界;堆棧過??;中斷處理錯(cuò)誤;電壓供電異常。 現(xiàn)在實(shí)驗(yàn)一個(gè)堆棧過小的錯(cuò)誤,讓MDK來檢測這個(gè)問題然后定位錯(cuò)誤。 這個(gè)程序基于UCOSII 系統(tǒng) #define TFTLCD_STK_PRIO 8 //任務(wù)的優(yōu)先級(jí) #define TFTLCD_STK_SIZE 2 //任務(wù)的堆棧大小 OS_STK TFTLCD_TASK_S
[單片機(jī)]
<font color='red'>STM32</font>死機(jī) <font color='red'>調(diào)試</font>時(shí)進(jìn)入HardFault_Handler定位錯(cuò)誤的方法
STM32入門編程總結(jié)4 (中斷+串口
系統(tǒng)異常中斷與外部中斷統(tǒng)稱為中斷,復(fù)位中斷的優(yōu)先級(jí)最高, NVIC(NestedVectored Interrupt Controller)嵌套向量中斷控制器,調(diào)整各個(gè)中斷的優(yōu)先級(jí),中斷優(yōu)先級(jí) =搶占優(yōu)先級(jí)(1-4bit)+子優(yōu)先級(jí)(0、1)如果兩個(gè)中斷的搶占優(yōu)先級(jí)與子優(yōu)先級(jí)參數(shù)一致,則按照中斷向量表里的順序區(qū)分優(yōu)先級(jí)。GPIO的中斷,EXTI(External interrupt/event controller)外部中斷/事件(event)控制器,外部中斷為用戶自定義中斷內(nèi)容(用戶編寫程序發(fā)生中斷后要干啥事兒),外部事件為具體對應(yīng)外設(shè)自動(dòng)執(zhí)行,EXTI 0-15總共16個(gè),GPIO A-G當(dāng)中的pin尾數(shù)與EXTI尾數(shù)對應(yīng)
[單片機(jī)]
<font color='red'>STM32</font>入門編程總結(jié)4 (中斷+<font color='red'>串口</font>)
stm32串口字節(jié)丟失怎么辦?
“STM32串口發(fā)送必須先檢測狀態(tài),否則第一個(gè)字節(jié)無法發(fā)出,發(fā)送完畢,必須檢測發(fā)送狀態(tài)是否完成,否則,發(fā)送不成功,使用stm32f10x調(diào)試串口通訊時(shí),發(fā)現(xiàn)一個(gè)出錯(cuò)的現(xiàn)象,硬件復(fù)位重啟之后,發(fā)送測試數(shù)據(jù)0x01 0x02 0x03 0x04..接收端收到的數(shù)據(jù)為:0x02 0x03 0x04,第一個(gè)數(shù)據(jù)丟失。換成發(fā)送別的數(shù)值的數(shù)據(jù),如0x06 0x0ff,則接收到0x0ff,0x06丟失。錯(cuò)誤依舊。 故障排除過程:1、剛開始懷疑是接收端的錯(cuò)誤,我是使用電腦串口,運(yùn)行串口輔助調(diào)試工具接收,換成其他軟件后,發(fā)現(xiàn)故障依舊,而且電腦軟件一直是開啟狀態(tài),不像和電腦軟件有關(guān)。2、使用單步調(diào)試,單步運(yùn)行各個(gè)發(fā)送指令,都正常。能收到0x01
[單片機(jī)]
<font color='red'>stm32</font><font color='red'>串口</font>字節(jié)丟失怎么辦?
stm32串口的學(xué)習(xí)
串口的基本配置 (使用固件庫) 根據(jù)這圖我們可以知道 stm32 至少會(huì)有3個(gè)串口 由于自己是使用串口一 所以配置的為usart1 1 時(shí)鐘使能(用到哪個(gè)串口`和GPIO要把相應(yīng)的時(shí)鐘開啟) 2 串口復(fù)位;(一般在系統(tǒng)剛開始配置外設(shè)的時(shí)候,都會(huì)先執(zhí)行復(fù)位該外設(shè)的操作。) 3 GPIO口配置; 4 串口參數(shù)配置; 5 根據(jù)需要開啟中斷 下面的代碼部分 一 時(shí)鐘使能 由于UART的TX和RX和AFIO都掛在APB2橋上,因此采用固件庫函數(shù)RCC_APB2PeriphClockCmd()進(jìn)行初始化。UARTx需要分情況討論,如果是UART1,則掛在APB2橋上,因此采用RCC_APB2PeriphClockCmd()進(jìn)行初始化,
[單片機(jī)]
<font color='red'>stm32</font><font color='red'>串口</font>的學(xué)習(xí)
STM32 USART 串口簡單使用
STM32 的庫實(shí)在強(qiáng)大~!函數(shù)長的像句子...... 好了開始了: 使用查詢方式的USART: 設(shè)置時(shí)鐘: RCC_APB2Periph_AFIO功能復(fù)用IO時(shí)鐘 RCC_APB2Periph_GPIOAGPIOA時(shí)鐘 RCC_APB2Periph_USART1 USART1時(shí)鐘 你可以用 //使能串口1,PA,AFIO總線RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_USART1,ENABLE); 或直接 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AL
[單片機(jī)]
<font color='red'>STM32</font> USART <font color='red'>串口</font>簡單使用
STM32串口中斷、DMA接收的幾點(diǎn)注意地方
1UART串口中斷接收 使能UART串口中斷之后,有接收到UART數(shù)據(jù),進(jìn)入中斷,此時(shí)要清除RXNE接收標(biāo)志位: 1.通過軟件向該RXNE標(biāo)志位寫入零來清零; 2.通過對 USART_DR 寄存器執(zhí)行讀入操作將該位清零。 這里可以查看對應(yīng)《參考手冊》,一般我們選擇第2種,通過讀取UART串口數(shù)據(jù)來清零。 1.中斷接收數(shù)據(jù)丟失 在UART串口中斷函數(shù)中,或者更高優(yōu)先級(jí)中斷函數(shù)中長時(shí)間執(zhí)行,導(dǎo)致接收丟失,所以,請勿在中斷函數(shù)中長時(shí)間執(zhí)行。 特別有些人,還在中斷函數(shù)添加延時(shí)函數(shù)。實(shí)際應(yīng)用中,只要不是特殊情況,比如測試某個(gè)功能可以添加延時(shí)函數(shù),都不建議在中斷函數(shù)添加延時(shí)函數(shù)。 2.ORE上溢錯(cuò)誤 ORE上溢錯(cuò)誤是什么意思呢? 可能很
[單片機(jī)]
小廣播
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved