版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第八章
μc/OS-Ⅱ消息郵箱與隊列 8.1 μC/OS-Ⅱ消息郵箱 8.2 SGX12864點陣LCD顯示屏 8.3 字符漢字與圖形顯示技術 8.4 μC/OS-Ⅱ消息隊列
8.5 LPC824內部顯示緩存技術
本章介紹了消息郵箱與消息隊列的用法,消息郵箱與隊列是μC/OS-Ⅱ系統(tǒng)中非常重要的組件,主要用于任務間傳遞信息,也可用于任務間同步,或用于中斷服務程序向任務傳遞信息。本章將基于LPC824學習板,介紹幾個消息郵箱與隊列相關的實例,同時還介紹了LPC824學習板上128×64點陣LCD屏的驅動方法。8.1.1 消息郵箱同步實例 在項目ZLX11的基礎上新建項目ZLX12,保存在目錄D:\ZLXLPC824\ZLX12下,此時的項目ZLX12與ZLX11相同。在項目ZLX11中借助于信號量Sem03實現任務Task06同步中斷服務程序PIN_INT2_IRQHandler的執(zhí)行,如第七章圖7-12所示。在項目ZLX12中,將Sem03改為消息郵箱Mbox01,使消息郵箱Mbox01用于實現任務Task06同步中斷服務程序PIN_INT2_IRQHandler的執(zhí)行。 項目ZLX11轉化為ZLX12,編譯鏈接并運行項目ZLX12,其運行結果與項目ZLX11相同。消息郵箱Mbox01用于任務同步中斷服務程序的執(zhí)行,如圖8-1所示。圖8-1 項目ZLX12中消息郵箱Mbox01的作用
8.1 μC/OS-Ⅱ消息郵箱
項目ZLX12中,在任務Task01中創(chuàng)建了消息郵箱Mbox01,在圖81中,當LPC824學習板上S1~S16中的某個按鍵被按下時,中斷服務函數PIN_INT2_IRQHandler被觸發(fā)而執(zhí)行,在其中釋放消息郵箱Mbox01。用戶任務Task06始終請求消息郵箱Mbox01,請求不到則永遠等待,一旦請求成功則執(zhí)行Task06任務中后續(xù)的語句。 項目ZLX12中僅給出了消息郵箱用作任務同步中斷服務程序時的用法,如果消息郵箱用作任務B同步任務A的執(zhí)行,則只需要在任務A中添加釋放消息郵箱的語句,與中斷服務函數PIN_INT2_IRQHandler中釋放消息郵箱的語句相同,任務B中添加請求消息郵箱的語句,與任務Task06中請求消息郵箱的語句相同。
8.1 μC/OS-Ⅱ消息郵箱8.1.2 消息郵箱傳遞信息實例 在項目ZLX12中,消息發(fā)送方的任務或中斷服務程序使用了啞元消息,消息接收方的任務請求到該啞元消息后不保存消息,因為接收方知道消息的內容,消息中沒有信息。本小節(jié)將在項目ZLX12的基礎上,將按鍵值作為消息,由中斷服務函數PIN_INT2_IRQHandler將該消息釋放到消息郵箱Mbox01中,用戶任務Task06接收消息郵箱Mbox01中的消息,從而得到按鍵值,具體的做法如下所示: (1)在zlg7289b.c文件(見圖7-8)中,將第5行由原來的“Int08UkeyCode;”改為“Int08UkeyCode[1];”,表示創(chuàng)建一維整型數組keyCode,用于保存消息,特別需要注意的是,用于保存消息的數組必須定義為全局變量! (2)在zlg7289b.c文件中,修改中斷服務函數PIN_INT2_IRQHandler的代碼如下所示。
程序段8-1中斷服務函數PIN_INT2_IRQHandler 1 voidPIN_INT2_IRQHandler(void) 2 { 3 OSIntEnter();
4 NVIC_ClearPendingIRQ(PIN_INT2_IRQn);
5 if((LPC_PIN_INT->FALL&(1uL<<2))==(1uL<<2))
8.1 μC/OS-Ⅱ消息郵箱 6 { 7 LPC_PIN_INT->FALL=(1uL<<2);
8 keyCode[0]=ZLG7289Key();
9 OSMboxPost(Mbox01,(void*)&keyCode[0]);
10 } 11 OSIntExit();
12 }
第8行調用ZLG7289Key函數獲得按鍵碼,賦給數組的第一個元素keyCode[0];第9行調用系統(tǒng)函數OSMboxPost將數組作為消息釋放到消息郵箱Mbox01中。
(3)文件task06.c修改為如程序段8-2所示。
程序段8-2文件task06.c
1 //Filename:task06.c 2 3 #include"includes.h" 4 5 externOS_EVENT*Mbox01;
6 externOS_EVENT*Mutex01;
7 INT8UkeyNum;
8
8.1 μC/OS-Ⅱ消息郵箱
第5行聲明外部定義的消息郵箱Mbox01。 9 voidTask06(void*data) 10 { 11 INT8Uerr;
12 void*pmsg; 13
第12行定義void*類型的指針pmsg,用于指向從消息郵箱獲得的消息。 14 data=data;
15 16 while(1) 17 { 18 pmsg=OSMboxPend(Mbox01,0,&err);
19 第18行請求消息郵箱Mbox01,使pmsg指向請求到的消息。
20 OSMutexPend(Mutex01,0,&err);
21 keyNum=KeyNumber(((INT8U*)pmsg)[0]);
22 OSMutexPost(Mutex01); 23 } 24 }8.1 μC/OS-Ⅱ消息郵箱
第21行將讀到的消息,即按鍵值(用C語言((INT8U*)pmsg)[0]表示),作為Key-Number函數的參數賦給keyNum變量。 項目ZLX13的執(zhí)行情況與項目ZLX12和ZLX11相同。仔細比較這三個項目中按鍵碼由中斷服務函數傳遞到Task06的方式,可以發(fā)現消息郵箱的優(yōu)點。消息郵箱本質上是一種全局變量的訪問機制,但是比直接使用全部變量進行信息傳遞要安全可靠。在項目ZLX11中,使用信號量+全部變量(keyCode)的方法,在項目ZLX12中,使用啞元消息郵箱+全局變量(keyCode)的方法,使得中斷服務程序中的按鍵值傳遞到任務Task06中,在這兩個項目中,keyCode是作為文件zlg7289b.c和task06.c共用的全局變量,keyCode定義在zlg7289b.c中,在task06.c中必須再次聲明該變量。而在項目ZLX13中,使用了消息郵箱傳遞信息的方式,這里的數組變量keyCode雖然仍然是全局變量,但是僅用于保存消息值,定義在zlg7289b.c中,在task06.c文件中,無需再次聲明它(即keyCode變量在task06.c中不可見),那些要使用keyCode變量值(即按鍵值)的任務,必須請求到消息郵箱中的消息才能使用,否則無法使用。顯然,后者這種定義一個保存消息的全局變量+消息傳遞機制的方法,比起定義共同的全局變量+信號量同步控制(或啞元消息郵箱同步控制)的機制更加安全。8.1 μC/OS-Ⅱ消息郵箱 參考第三章圖3-2和圖3-14可知,SGX12864點陣LCD屏與LPC824通過4根線相連接,其中,LPC824的PIO0_14與SGX12864的串行數據總線SDA相連接,當SGX12864工作在串口模式下時,SDA只能作為輸入口,故PIO0_14配置為通用目的數字輸出口;PIO0_13與SGX12864的片選信號CS相連,PIO0_13被配置為數字輸出口;PIO0_15與SGX12864的命令/數據選通信號線C/D相連接,C/D線即A0線,PIO0_15被配置為數字輸出口;PIO0_17與SGX12864的時鐘輸入線SCK相連,PIO0_17被配置為數字輸出口。
SGX12864點陣LCD顯示屏驅動芯片為UC1701X,UC1701X可驅動65×132個像素點,具有并口和串口兩種工作方式,SGX12864將UC1701X配置為4線S8串行口模式,該模式下只能向UC1701X寫入命令和顯示數據,無法從UC1701X讀出數據。UC1701X常用的操作命令如表8-1所示。表8-1 UC1701X常用的命令
8.2 SGX12864點陣LCD顯示屏8.2 SGX12864點陣LCD顯示屏 UC1701X的顯示內存如圖8-2所示。圖8-2 UC1701X顯存格式8.2 SGX12864點陣LCD顯示屏 針對SGX12864而言,僅使用了圖8-2中第0~7頁第0~127列的顯存,UC1701X的顯存只能按頁訪問,不能按位訪問,例如,可以訪問第0頁第0列的整個字節(jié),但不能單獨訪問第0行第0列的位。由于SGX12864配置UC1701X工作在串行方式下,只能寫UC1701X的顯存,無法讀顯存,因此,操作UC1701X顯存的常用方法為:在LPC824內存中開辟一塊1024B大小的空間SM,對SM進行讀寫操作,再在優(yōu)先級較低的用于刷新顯示屏的任務中將SM寫到UC1701X的物理顯存中。在將要介紹的項目ZLX14中,為了節(jié)省LPC824的內存,采用了直接寫UC1701X緩存的方法;在第8.5節(jié)的項目ZLX15中,重新編寫了文件lcd12864.c和lcd12864.h,使用LPC824片上SRAM作為顯示緩存的方法在SGX12864上顯示信息。 在圖8-2中配置UC1701X的MY=0,則顯存的左上角對應著SGX12864的左下角,顯存圖像的垂直鏡像將顯示在SGX12864上。如果配置MY=1,則顯存與SGX12864對應。在項目ZLX14中,直接寫UC1701X顯存,故配置了MY=1;而在項目ZLX15中,使用了LPC824內部緩存,故配置了MY=0。按圖8-2的配置,第0頁第1、2列的字節(jié)依次為0b11100000和0b00110011。 下面,在項目ZLX13的基礎上,新建項目ZLX14,保存在目錄D:\ZLXLPC824\ZLX14中,此時的項目ZLX14與ZLX13相同,然后,進行如表8-2所示的改動。表8-2請看下頁8.2 SGX12864點陣LCD顯示屏表8-2 項目ZLX14在ZXL13基礎上所做的改動8.2 SGX12864點陣LCD顯示屏8.2 SGX12864點陣LCD顯示屏8.2 SGX12864點陣LCD顯示屏 SGX12864點陣LCD屏輸出字符、漢字和圖形的原理是相同的,都是以圖形方式輸出的,即將字符、漢字或圖形轉化為點陣字模,然后,將字模輸出到UC1701X顯存中,那些為1的位顯示出來,為0的位不顯示。程序段85介紹了輸出字符、漢字和圖形的程序設計方法,在項目ZLX14中,將UC1701X顯存劃分為8行×16列的格子陣列,每個格子可顯示8×8點陣,函數中row的取值為0~7,col的取值為0~15。
程序段8-5文件lcd12864.c的第183~231行的內容
183 184 voidLCDOutput16X8(Int08Urow,Int08Ucol,constInt08U*str,Int08Un) 185 {//row:0~7 186 Int08Ui,j;
187 Int32UX=0;
188 UC1701WrCmd(0x10+(8*col/16)); //CA:High4-bit 189 UC1701WrCmd(0x00+(8*col%16)); //CA:Low4-bit 190 for(j=0;j<n;j++) 191 { 192 UC1701WrCmd(0xb0+row); //Page:row 193 for(i=0;i<8;i++) 194 {8.3 字符、漢字與圖形顯示技術 195 UC1701WrDat(str[X++]);
196 } //After:Col=Col+8 197 UC1701WrCmd(0xb0+row+1); //Page:row+1 198 UC1701WrCmd(0x10+(8*col/16)); //Col 199 UC1701WrCmd(0x00+(8*col%16)); //After:Col=Col+8 200 for(i=0;i<8;i++) 201 { 202 UC1701WrDat(str[X++]);
203 } 204 col=col+1;
205 } 206 } 207
第184~206行為輸出16×8點陣圖形的函數LCDOutput16X8,每個16×8的圖形占有2行1列,共2個格子。第187行定義變量X做為輸出圖形的字節(jié)索引號;第188~189行選中UC1701X顯存中對應col列所在的格子的最左邊列位置;然后變量j從0循環(huán)到n-1(共n個16×8的圖形字符):對于第1個字符,選中行號為row(第192行),然后i從0循環(huán)到8,輸出row×col處的格子(第193~196行),接著,row加1(第197行),調整到col列處(第198~199行),再輸出(row+1)×col處的格子,這樣一個16×8的字符輸出來了。要輸出下一個字符,只需要在循環(huán)體內部,使col加1即可(第204行)。
8.3 字符、漢字與圖形顯示技術 208 voidLCDOutput16X16(Int08Urow,Int08Ucol,constInt08U*str,Int08Un) 209 { 210 Int08Ui,j;
211 Int32UX=0;
212 213 UC1701WrCmd(0x10+(8*col/16));
214 UC1701WrCmd(0x00+(8*col%16));
215 for(j=0;j<n;j++) 216 { 217 UC1701WrCmd(0xb0+row);
218 for(i=0;i<16;i++) 219 { 220 UC1701WrDat(str[X++]);
221 } 222 UC1701WrCmd(0xb0+row+1);
223 UC1701WrCmd(0x10+(8*col/16));
8.3 字符、漢字與圖形顯示技術 224 UC1701WrCmd(0x00+(8*col%16));
225 for(i=0;i<16;i++) 226 { 227 UC1701WrDat(str[X++]);
228 }229col=col+2;
230 } 231 }
第208~231行的函數LCDOutput16X16與上述的LCDOutput16X8工作原理相同,只是該函數中,每個row行要連續(xù)輸出2列(第218~221行,第225~228行),然后,下一個16×16的漢字輸出列位置為當前列col加2(第229行)。8.3 字符、漢字與圖形顯示技術 由表8-2可知,在文件task01.c中創(chuàng)建了消息隊列Q01,隊列長度為10。項目ZLX14中新添加的文件task08.c、task08.h、task09.c和task09.h如程序段8-6至程序段8-9所示。
程序段8-6文件task08.c 1 //Filename:task08.c 2 3 #include"includes.h" 4 5 externOS_EVENT*Q01;
6 INT8UCounter[60][1];
7
第5行聲明外部定義的消息隊列事件Q01。第6行定義全局變量Counter,用于存放需要發(fā)送出、去的消息,由表8-2可知,消息隊列Q01的長度為10,即最多能容納10個消息(實際上是包含10個節(jié)點指針,最多能同時指向10個消息),這里故意把Counter定義為能容納60個消息的二維數組,目的在于說明消息隊列的長度和用于保存消息的全局變量的大小間沒有必然的關系。 8 voidTask08(void*data) 9 { 10 INT8Ui=0;
8.4 μC/OS-Ⅱ消息隊列 11 12 data=data;
13 14 while(1) 15 { 16 Counter[i][0]=i;
17 OSQPost(Q01,(void*)&Counter[i]);
18 19 i++;
20 if(i>=60) 21 i=0;
22 23 OSTimeDlyHMSM(0,0,1,0);
24 } 25 }
在任務函數Task08(第8~25行)中,第14~24行為無限循環(huán)體每隔1秒執(zhí)行一次(第23行)。第16行將變量i的值作為消息,賦給變量Counter[i][0],第17行調用系統(tǒng)函數OSQPost將Counter[i]釋放到消息隊列Q01中(實際上使消息隊列Q01中的第一個空閑的節(jié)點指針指向Counter[i])。第19~21行使變量i累加1,如果i的值大于等于60,則i清零。8.4 μC/OS-Ⅱ消息隊列 程序段8-7文件task08.h 1 //Filename:task08.h 2 3 #ifndef_TASK08_H 4 #define_TASK08_H 5 6 #defineTask08StkSize 50 7 #defineTask08ID 8 8 #defineTask08Prio (Task08ID+3) 9 10 voidTask08(void*);
11 12 #endif
文件task08.h中宏定義了用戶任務Task08的堆棧大小為50字(即200字節(jié))、任務ID號為8、任務優(yōu)先級號為11(第6~8行)。第10行聲明了任務函數Task08的函數原型。8.4 μC/OS-Ⅱ消息隊列
程序段8-8文件task09.c 1 //Filename:task09.c 2 3 #include"includes.h" 4 5 externOS_EVENT*Q01;
6 externconstInt08UDig16X8[];
7 externconstInt08UHZ16X16[];
8
第5行聲明外部定義的事件Q01。第6~7行聲明外部定義的常量數組Dig16X8和HZ16X16。 9 voidTask09(void*data) 10 { 11 INT8Uerr;
12 INT8Usec10,sec01;
13 void*msg;
14
第12行定義兩個局部變量sec10和sec01,分別用于保存秒計數值的十位和個位上的數字。第14行定義void*類型的指針msg,用于從消息隊列Q01中接收消息。
8.4 μC/OS-Ⅱ消息隊列
15 data=data;
16 17 LCDOutput16X16(1,5,&HZ16X16[5*32],1);
第17行在LCD屏的第1行第5列顯示漢字“秒”。
18 while(1) 19 { 20 msg=OSQPend(Q01,0,&err);
21 sec10=((INT8U*)msg)[0]/10;
22 sec01=((INT8U*)msg)[0]%10;
23 24 if(sec10==0) 25 LCDOutput16X8(1,2,&Dig16X8[11*16],1);
26 else 27 LCDOutput16X8(1,2,&Dig16X8[sec10*16],1);
28 LCDOutput16X8(1,3,&Dig16X8[sec01*16],1);
29 } 30} 在任務Task09的無限循環(huán)體(第18~29行)內,第20行請求消息隊列Q01,請求到的消息賦給msg,第21~22行從消息中提取出來秒計數值的十位和個位上的數字。第24~28行將秒計數值顯示在LCD屏上。在任務Task09中,借助于消息隊列獲得任務Task08中的秒計數值,而不用直接訪問全局變量Counter。8.4 μC/OS-Ⅱ消息隊列 程序段8-9文件task09.h 1 //Filename:task09.h 2 3 #ifndef_TASK09_H 4 #define_TASK09_H 5 6 #defineTask09StkSize 50 7 #defineTask09ID 9 8 #defineTask09Prio (Task09ID+3) 9 10 voidTask09(void*);
11 12 #endif
文件task09.h中宏定義了用戶任務Task09的堆棧大小為50字(即200字節(jié))、任務ID號為9、任務優(yōu)先級號為12(第6~8行)。第10行聲明了任務函數Task09的函數原型。
8.4 μC/OS-Ⅱ消息隊列
在項目ZLX14中,task08.c、task08.h、task09.c和task09.h保存在目錄D:\ZLX-LPC824\ZLX14\User下,同時將task08.c和task09.c添加到工程的USER分組下;lcd12864.c和lcd12864.h文件保存在目錄D:\ZLXLPC824\ZLX14\BSP下,同時,將lcd12864.c添加到工程的BSP分組下,完成后的項目ZLX14的工程管理器如圖8-3所示。 項目ZLX14中任務Task08和Task09的執(zhí)行情況如圖8-4所示。圖8-3 項目ZLX14的工程管理器
圖8-4 任務Task08和Task09的執(zhí)行情況8.4 μC/OS-Ⅱ消息隊列
由圖8-4可知,借助于消息隊列Q01,用戶任務Task08可以向Task09傳遞信息,這里是秒計數值。由表5-4可知,只有一個消息隊列請求函數OSQPend,但有三個向消息隊列中釋放消息的函數,如果使用OSQPost函數向消息隊列中釋放消息,則請求消息時消息是先進先出的;如果使用OSQPostFront函數向消息隊列中釋放消息,則請求消息時消息是后進先出的。還可使用OSQPostOpt函數向消息隊列中釋放消息,OSQPostOpt函數有3個參數,前兩個參數與OSQPost和OSQPostFront相同,第三個參數為選項參數,如果取為OS_POST_OPT_NONE,則OSQPostOpt相當于OSQPost;如果取為OS_POST_OPT_FRONT,則OSQPostOpt相當于OSQPostFront;如果取為OS_POST_OPT_BROADCAST,表示向所有請求該消息隊列的任務廣播消息,使它們每個都能收到同一則消息;還可以取為OS_POST_OPT_NO_SCHED,該參數與前三個組合使用,表示釋放消息后不進行任務調度,可一次性向消息隊列中釋放多個消息,但最后一個消息向消息隊列中釋放時不使用該參數,則該消息釋放完后,進行任務調度。 由此可見,消息郵箱就是隊列長度為1的消息隊列,消息隊列可以替代消息郵箱,因此,在μC/OS-Ⅱ中不再有消息郵箱組件,而只保留了消息隊列組件。ZLX14執(zhí)行時LPC824學習板的顯示結果如圖8-5所示,串口調試助手的顯示結果如圖8-6所示。
8.4 μC/OS-Ⅱ消息隊列
由圖8-5可知,LCD屏顯示的秒計數值與四合一七段數碼管上顯示的秒計數值相同,當小于10秒時,LCD屏僅顯示秒計數值的個位數字。 圖8-6顯示工程ZLX14中有12個任務,包括9個用戶任務Task01~Task09和3個系統(tǒng)任務,每秒任務的切換次數為41次,CPU占用率為1%,優(yōu)先級號為4的用戶任務Task01的堆??臻e56個字節(jié)。圖8-5 LPC824學習板的顯示結果示例 圖8-6 串口調試助手的顯示結果8.4 μC/OS-Ⅱ消息隊列 項目ZLX14在LCD屏顯示操作方面有以下兩個缺點: (1)對于128×64點陣的LCD屏SGX12864,項目ZLX14中的函數僅能訪問8行16列的128個格子,無法按照點的坐標進行訪問,這是因為SGX12864的驅動芯片UC1701X的顯存只能寫入不能讀出,且只能按字節(jié)寫入。 (2)項目ZLX14中向LCD屏輸出信息時,是直接寫LCD屏的物理顯存,一般地,顯示較多信息時,顯示過程將占用較多的CPU時間,從而影響項目的實時性。 解決上述兩個缺點的方法是借助于LPC824片上的SRAM空間作為顯存,所有的向LCD屏輸出信息的操作均針對該顯存進行操作,而不是直接寫物理顯存,不但寫入速度大大提升,而且,可以讀出顯存內容進行修改。然后,編寫一個任務優(yōu)先級號較低的用戶任務,在該任務中按照一定的頻率將LPC824片上SRAM顯存寫入到LCD屏的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 聚酯增粘裝置操作工創(chuàng)新應用知識考核試卷含答案
- 釩鐵沉淀工安全強化評優(yōu)考核試卷含答案
- 鍋爐除灰、脫硫、脫硝設備檢修工風險識別強化考核試卷含答案
- 印刷設備裝配調試工5S執(zhí)行考核試卷含答案
- 我國上市公司并購中換股比例確定:方法、案例與優(yōu)化策略
- 畜禽屠宰無害化處理工安全宣貫評優(yōu)考核試卷含答案
- 拖拉機柴油發(fā)動機裝試工班組考核知識考核試卷含答案
- 建設工程質量檢測員崗前QC管理考核試卷含答案
- 工程地質調查員操作能力競賽考核試卷含答案
- 超硬磨料制造工QC管理知識考核試卷含答案
- 液冷系統(tǒng)防漏液和漏液檢測設計研究報告
- 2025-2026學年貴州省安順市多校高一(上)期末物理試卷(含答案)
- 呼吸機相關肺炎預防策略指南2026
- 妊娠期缺鐵性貧血中西醫(yī)結合診療指南-公示稿
- 北京市2025年七年級上學期期末考試數學試卷三套及答案
- 2025年工廠三級安全教育考試卷含答案
- 2026年上海理工大學單招職業(yè)適應性測試題庫附答案
- TCEC電力行業(yè)數據分類分級規(guī)范-2024
- 建設用地報批培訓課件
- 駱駝的養(yǎng)殖技術與常見病防治
- 基層醫(yī)療資源下沉的實踐困境與解決路徑實踐研究
評論
0/150
提交評論