小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

ESP32串口的正確打開(kāi)方式 | 電子創(chuàng)客營(yíng)

 iamlijin 2019-08-07

之前寫(xiě)過(guò)一篇關(guān)于esp32串口的文章:ESP32中斷方式操作串口,但是不夠詳細(xì),這篇進(jìn)行更加細(xì)節(jié)的描述。

因?yàn)槲疫@個(gè)代碼是基于micropython esp32進(jìn)行二次開(kāi)發(fā)的,需要改造原有micropython對(duì)串口的配置。當(dāng)然這些代碼直接用ESP32-IDF開(kāi)發(fā)也沒(méi)問(wèn)題。

先看下Micropython對(duì)ESP32uart0的串口配置:

對(duì)應(yīng)文件為:/micropython/ports/esp32/uart.c

該文件初始化打開(kāi)了串口接收中斷,但是沒(méi)有安裝串口驅(qū)動(dòng),所以不能在中斷服務(wù)函數(shù)中調(diào)用uart_write_bytes()。如果要要調(diào)用該發(fā)送函數(shù),必須在串口初始化的時(shí)候,執(zhí)行如下兩步:

 uart_driver_install(UART_NUM_0, 256,0, 0, NULL, 0);
uart_isr_free(UART_NUM_0);
//micropython對(duì)串口的初始化代碼如下
void uart_init(void) {
	uart_isr_handle_t handle;
	uart_isr_register(UART_NUM_0, uart_irq_handler, NULL, ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM, &handle);
	uart_enable_rx_intr(UART_NUM_0);
}

該函數(shù)主要執(zhí)行兩個(gè)步驟:

  • 串口中斷服務(wù)函數(shù)的注冊(cè)
  • 串口接收中斷的使能,接收中斷使能函數(shù)里面打開(kāi)了兩個(gè)中斷FIFO 接收滿和接收超時(shí)中斷

如上是我們解釋一下micropython對(duì)串口的配置,但不是重點(diǎn),重點(diǎn)還在于我們自己的初始化和中斷服務(wù)函數(shù)代碼:

完整的串口初始化配置

void uart_init(void) {
	uart_config_t uart_config = {
	.baud_rate = 115200,
	.data_bits = UART_DATA_8_BITS,
	.parity = UART_PARITY_DISABLE,
	.stop_bits = UART_STOP_BITS_1,
	.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
	};
	uart_param_config(UART_NUM_0, &uart_config);
	uart_set_pin(UART_NUM_0,UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
	uart_isr_handle_t handle;
	uart_driver_install(UART_NUM_0, 256,0, 0, NULL, 0); //安裝驅(qū)動(dòng)程序,使用idf自帶中斷服務(wù)函數(shù)
	uart_isr_free(UART_NUM_0); //釋放不使用idf自帶中斷服務(wù)函數(shù)
	uart_isr_register(UART_NUM_0, uart_irq_handler, NULL, ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM, &handle); //重新注冊(cè)中斷服務(wù)函數(shù)
	uart_enable_rx_intr(UART_NUM_0); //使能中斷接收
	uart_set_rx_timeout(UART_NUM_0,10); //配置接收超時(shí)中斷時(shí)間,單位為按照當(dāng)前波特率傳輸1個(gè)bytes的時(shí)間
}

該初始化主要執(zhí)行以下幾個(gè)步驟:

  • 串口參數(shù)的初始化配置
  • 串口引腳配置
  • 串口驅(qū)動(dòng)安裝,這個(gè)地方需要注意,執(zhí)行完uart_driver_install以后,默認(rèn)會(huì)使用ESP32-IDF自帶的串口中斷服務(wù)函數(shù),而這里我們不是用就需要下一步操作
  • 釋放idf自帶串口中斷服務(wù)函數(shù)
  • 重新注冊(cè)自定義串口中斷服務(wù)函數(shù)
  • 使能串口接收中斷uart_enable_rx_intr,該函數(shù)會(huì)打開(kāi)兩個(gè)中斷源:rxfifo接收滿中斷,rxfifo超時(shí)中斷(默認(rèn)超時(shí)時(shí)間為10個(gè)byte)
  • 最后一步設(shè)置接收超時(shí)中斷時(shí)間可以省略,因?yàn)樵谏弦徊揭呀?jīng)默認(rèn)打開(kāi),并且idf默認(rèn)值為10個(gè)bytes時(shí)間。如果想修改超時(shí)中斷時(shí)間的話就調(diào)用該函數(shù)

完整的串口中斷服務(wù)函數(shù)

STATIC void IRAM_ATTR uart_irq_handler(void *arg) {
	volatile uart_dev_t *uart = &UART0;
	uint8_t recSize=0;
	uart->int_clr.rxfifo_full = 1;
	uart->int_clr.frm_err = 1;
	if(uart->int_st.rxfifo_tout) //檢查是否產(chǎn)生超時(shí)中斷
	{
		uart->int_clr.rxfifo_tout = 1;
		recSize=uart->status.rxfifo_cnt;
		if(recSize!=0)
		{
			while(uart->status.rxfifo_cnt)
			{
				uart0RxBuf[uart0RxCount++]=uart->fifo.rw_byte; 
			}
			if(uart0RxCount==uart0RxBuf[0]) //接收一幀數(shù)據(jù)長(zhǎng)度等于第一個(gè)byte指示的長(zhǎng)度,接收正確
			{
				port_infoToRecQueue(PORT_UART,uart0RxCount,uart0RxBuf);
				uart0RxCount=0;
			} 
			else if(uart0RxCount>uart0RxBuf[0]) //接收數(shù)據(jù)長(zhǎng)度大于第一個(gè)byte指示的長(zhǎng)度,接收出錯(cuò)
			{
				uart0RxCount=0; 
			} 
		} 
	} 
}

初始化已經(jīng)打開(kāi)了串口中斷,針對(duì)接收有兩個(gè)中斷源:rxfifo滿中斷 rx接收超時(shí)中斷。默認(rèn)rxfifo的深度為128byte,所以只要不連續(xù)發(fā)超過(guò)128個(gè)byte都不會(huì)觸發(fā)fifo滿中斷。當(dāng)發(fā)送完一幀數(shù)據(jù),只要后面空閑的時(shí)間超過(guò)設(shè)定的超時(shí)時(shí)間就會(huì)產(chǎn)生超時(shí)中斷。所以這里要弄清楚并不是每接收到一個(gè)byte就會(huì)產(chǎn)生一次串口中斷。
在實(shí)際測(cè)試中,給ESP32發(fā)送一幀數(shù)據(jù)會(huì)讓他觸發(fā)兩次rx超時(shí)中斷,詳述如下

關(guān)于esp32 串口接收超時(shí)中斷

IDF中設(shè)置默認(rèn)超時(shí)時(shí)間為,10代表以當(dāng)前波特率傳輸10bytes的時(shí)間

UART_TOUT_THRESH_DEFAULT (10)

每接收一幀連續(xù)的數(shù)據(jù)包,會(huì)觸發(fā)兩次超時(shí)中斷。

  • 第一次觸發(fā)超時(shí)中斷,讀取rxfifo中已接收字節(jié)數(shù)和這一幀數(shù)據(jù)長(zhǎng)度相等。
  • 第二次觸發(fā)超時(shí)中斷,讀取rxfilo已接收字節(jié)數(shù)為0

所以只要每一幀數(shù)據(jù)之間都有時(shí)間空隙,并且空隙時(shí)間長(zhǎng)于設(shè)定值,那么第一次觸發(fā)超時(shí)中斷時(shí)rxfifo中的數(shù)據(jù)就是一幀的數(shù)據(jù)。讀取UART0.status.rxfifo_cnt該寄存器里面的值就是這一幀的數(shù)據(jù)包長(zhǎng)度值

ESP32串口的正確打開(kāi)方式

轉(zhuǎn)載請(qǐng)注明轉(zhuǎn)自電子創(chuàng)客營(yíng):ESP32串口的正確打開(kāi)方式! 了解我們點(diǎn)擊這里
喜歡 (2)or分享 (0)

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多