(一)標識符
標識符是用來表示源程序中自定義對象名稱的符號。其中的自定義對象可以是常量、變量、數組、結構、語句標號以及函數等。
在C51語言中,標識符可以由字母(a~z,A~Z)、數字(0~9)和下劃線“_”組成,最多可支持32個字符。
C51標識符的定義不是隨意的,應遵循“簡潔”和“見名知意”的原則,并需要符合一定的規則:
? 標識符的第一個字符必須是字母或者下劃線,不能為數字。由于有些編譯系統專用的標識符以下劃線開頭,所以用戶在定義標識符時一般不要以下劃線開頭。
? C51的標識符區分大小寫,例如“ch1”和“Ch1”表示兩個不同的標識符。
? 用戶自定義的標識符不能與系統保留的關鍵字重復。
(二)關鍵字
關鍵字是C51編譯器保留的一些特殊標識符,具有特定的含義和用法。單片機C51程序語言繼承了ANSI C標準定義的32個關鍵字,如表3-1所示。
表3-1 C51的關鍵字
同時C51又結合單片機硬件的特點擴展了19個關鍵字:
_at_ idata sfr16 alien interrupt small bdata large _task_ code bit pdata using reentrant xdata compact sbit data sfr
表3-2列出了Keil uVision2 C51編譯器所支持的數據類型。
表3-2 C51編譯器所支持的數據類型
1. char字符類型
char類型的長度是一個字節,通常用于定義處理字符數據的變量或常量。char字符類型分為無符號字符類型(unsigned char)和有符號字符類型(signed char),默認值為signed char類型。
unsigned char類型用字節中所有的位來表示數值,可以表達的數值范圍是0~255;signed char類型中字節最高位表示數據的符號,“0”表示正數,“1”表示負數(負數用補碼表示),所能表示的數值范圍是-128~+127。
提示
unsigned char常用于處理ASCII字符或小于等于255的整型數。
正數的補碼與原碼相同,負二進制數的補碼等于它的絕對值按位取反后加1。
2. int整型
int整型長度為兩個字節,用于存放一個雙字節數據。分為有符號整型數signed int和無符號整型數unsigned int,默認值為signed int類型。
signed int表示的數值范圍是-32768~+32767,字節中最高位表示數據的符號,“0”表示正數,“1”表示負數;unsigned int表示的數值范圍是0~65535。
3. long長整型
long長整型長度為四個字節,用于存放一個四字節數據。分有符號長整型signed long和無符號長整型unsigned long,默認值為signed long類型。
signed int表示的數值范圍是-2147483648~+2147483647,字節中最高位表示數據的符號,“0”表示正數,“1”表示負數;unsigned long表示的數值范圍是0~4294967295。
4. float浮點型
float浮點型在十進制中具有7位有效數字,是符合IEEE-754標準的單精度浮點型數據,占用四個字節。浮點數的結構較復雜,單片機使用較少,這里不做詳細討論。
5. *指針型
指針型數據本身是一個變量,在這個變量中存放著指向另一個數據的地址。根據處理器的不同,指針型數據所占的內存單元也不盡相同,在C51中它的長度一般為1~3個字節。
6. bit位標量
bit 位標量是C51編譯器的一種擴充數據類型,利用它可定義一個位標量,但不能定義位指針,也不能定義位數組。它的值是一個二進制位,非0即1。
定義格式:bit 變量名=變量值。
7. sfr特殊功能寄存器
sfr是一種擴充數據類型,占用一個內存單元,地址范圍為0x80~0xFF。
定義格式為:sfr 變量名=變量地址。
利用它可以訪問51單片機內部的所有特殊功能寄存器。例如,用“sfr P1=0x90”這一句定P1為P1端口在片內的寄存器。
8. sfr16 16位特殊功能寄存器
sfr16是一種擴充數據類型,占用兩個內存單元,sfr16和sfr一樣用于操作特殊功能寄存器,所不同的是,此類型的變量可訪問16為特殊功能寄存器。
定義格式:sfr16 變量名=變量地址。
此處的變量地址為16位中的低8位地址,其地址范圍為0x80~0xFF。通過sfr16變量讀16位特殊功能寄存器時,先讀低字節,后讀高字節;寫特殊功能寄存器時先寫高字節,后寫低字節。
9. sbit可位尋址位
sbit是C51中的一種擴充數據類型,利用它可以訪問芯片內部的RAM中的可尋址位或特殊功能寄存器中的可尋址位。
定義格式:
sbit 變量名=位地址;sbit 變量名=SFR地址^位序號;sbit 變量名=sfr16變量^位序號。
因P1端口的寄存器是可位尋址的,所以我們可以定義P1_1為P1中的P1.1引腳,同樣我們可以用P1.1的地址去寫,這樣在以后的程序語句中就可以用P1_1來對P1.1引腳進行讀寫操作了。
例如:
sbit P1_1=P1^1;
sbit P1_1=0x91
(一)常量
常量是在程序運行過程中不能改變的量,如固定的數據表、字符等。常量的數據類型只有整型、浮點型、字符型、字符串型和位標量。
1. 整型常量
不同數據類型的整型常量表示方法不同,十進制如123,0,-89等;十六進制則以0x開頭如0x34,-0x3B等;長整型就在數字后面加字母L,如104L,034L,0xF340等。
2. 浮點型常量
浮點型常量可分為十進制和指數表示形式。
十進制浮點型常量由數字和小數點組成,整數或小數部分為0,可以省略但必須有小數點,如0.888,3345.345,0.0等。
指數浮點型常量表示形式為:[±]數字[.數字]e[±]數字
[]中的內容為可選項,如125e3,7e9,-3.0e-3等。
3. 字符型常量
字符型常量是單引號內的字符,如‘a’,‘d’等。表示不顯示的控制字符,可以在該字符前面加一個反斜杠“\”組成專用轉義字符,常用轉義字符如表3-3所示。
4. 字符串型常量
字符串型常量由雙引號內的字符組成,如“test”,“OK”等。當引號內沒有字符時,為空字符串。
在C中字符串常量是做為字符類型數組來處理的,在存儲字符串時系統會在字符串尾部加上“>在C中字符串常量是做為字符類型數組來處理的,在存儲字符串時系統會在字符串尾部加上“\0”轉義字符以作為該字符串的結束符。字符串常量“A”和字符常量‘A’是不同的,前者在存儲時多占用一個字節的空間。<”轉義字符以作為該字符串的結束符。字符串常量“A”和字符常量‘A’是不同的,前者在存儲時多占用一個字節的空間。
表3-3 常用轉義字符表
5. 位標量
位標量是C51編譯器的一種擴充數據類型,它的值是一個二進制位,不是0就是1。
下面我們來看一些常量定義的例子:
以上兩句它們的值都保存在程序存儲器中,而程序存儲器在運行中是不允許被修改的,所以如果在這兩句后面用了類似a=110,a++這樣的賦值語句,編譯時將會出錯。
(二)變量
變量是可以在程序運行過程中不斷變化的量,變量的定義可以使用所有C51編譯器支持的數據類型。要在程序中使用變量必須先用標識符作為變量名,并指出所用的數據類型和存儲模式,這樣編譯系統才能為變量分配相應的存儲空間。
1. 變量的定義和作用范圍
定義一個變量的格式如下:
[存儲類型] 數據類型 [存儲器類型] 變量名表
在定義格式中除了數據類型和變量名表是必要的,其它都是可選項。
(1)存儲類型
不同存儲類型的變量以及不同位置定義的變量具有不同的代碼有效范圍,也就是變量的作用域。在單片機程序中,按照變量的存儲類型,可以分為:自動變量、全局變量、靜態變量和寄存器變量。
① 自動變量
自動變量是以關鍵字auto標識的變量類型,其一般是在函數的內部或者復合語句中使用。
自動型變量的作用域范圍是函數或者復合語句的內部。在C51中,函數或復合語句內部定義自動變量時,關鍵字auto可以省略,即默認為自動型變量。
在程序執行過程中,自動變量是動態分配存儲空間的。當程序執行到該變量聲明語句時,根據變量類型自動為其分配存儲空間。當該函數或者復合語句執行完畢后,該變量的存儲空間將立刻自動取消,此時,該自動變量失效,在函數或者復合語句外部將不能夠使用該變量。
② 全局變量
全局變量是以關鍵字extern標識的變量類型,如果一個變量定義在所有函數的外部,即整個程序文件的最前面,那么這個變量便是全局變量。全局變量有時也稱為外部變量。
在編譯程序時,全局變量將被靜態地分配適當的存儲空間。該變量一旦分配空間,在整個程序運行過程中便不會消失。因此,全局變量對整個程序文件都有效,即全局變量可以被該程序文件中的任何函數使用。
③ 靜態變量
靜態變量以關鍵字static定義,從變量作用域來看,靜態變量和自動變量類似,作用域只是定義該變量的函數內部。如果靜態變量定義在函數外部,將具有全局的作用域。
而從內存占用的角度,靜態變量和全局變量類似,其始終占有內存空間。
④ 寄存器變量
單片機的CPU寄存器中也可以保存少量的變量,這種變量稱為寄存器變量。寄存器變量以關鍵字register聲明。
由于單片機對CPU寄存器的讀寫十分快,因此寄存器變量的操作速度要原高于其他類型的變量。寄存器變量常用于某一變量名頻繁使用的情況,這樣做可以提高系統的運算速度。
由于單片機資源有限,程序中只允許同時定義兩個寄存器變量。如果多于兩個,在編譯時會自動地將其他的寄存器變量當做非寄存器變量來處理。
(2)存儲器類型
存儲器類型的說明就是指定該變量在C51硬件系統中所使用的存儲區域,并在編譯時準確的定位。表3-4中是KEIL uVision2所能認別的存儲器類型。
表3-4 存儲器類型
提示
在AT89C51芯片中RAM只有低128位,位于80H到FFH的高128位則在52芯片中才有用,并和特殊寄存器地址重疊。
如果省略存儲器類型,系統則會按編譯模式small,compact或large所規定的默認存儲器類型去指定變量的存儲區域。
① small存儲模式
small存儲模式將函數參數和局部變量放在片內RAM(默認變量類型為DATA,最大128字節)。另外所有對象包括棧都優先放置在片內RAM,當片內RAM用滿,再向片外RAM放置。
② compact存儲模式
compact存儲模式中將參數和局部變量放在片外RAM(默認存儲類型是PDATA,最大256字節);通過R0、R1間接尋址。
③ large存儲模式
large存儲模式將參數和局部變量直接放入片外RAM(默認的存儲類型是XDATA,最大64KB);使用數據指針DPTR間接尋址,因此訪問效率較低。
(3)對變量進行絕對定位
C51擴展的關鍵字_at_專門用于對變量作絕對定位,_at_使用在變量的定義中,其格式為:
[存儲類型] 數據類型 [存儲區] 變量名1 _at_ 地址常數[,變量名2…]
例如:
① 對data區域中的 unsigned char變量aa作絕對定位:
unsigned char data aa _at_ 0x30;
② 對pdata區域中的 unsigned int數組cc作絕對定位:
unsigned int pdata cc[10] _at_ 0x34;
③ 對xdata區域中的 unsigned char變量printer_port作絕對定位:
unsigned char xdata printer_port _at_ 0x7fff;
對變量絕對定位的幾點說明:
① 絕對地址變量在定義時不能初始化,因此不能對code型常量絕對定位;
② 絕對地址變量只能夠是全局變量,不能在函數中對變量絕對定位;
③ 絕對地址變量多用于I/O端口,一般情況下不對變量作絕對定位;
④ 位變量不能使用_at_絕對定位。
2. 變量的初始化和賦值
(1)變量的初始化
變量的初始化是指變量在被說明的同時賦給一個初值。外部變量和靜態全程變量在程序開始處被初始化,局部變量包括靜態局部變量是在進入定義它們的函數或復合語句時才作初始化。所有全程變量在沒有明確的初始化時將被自動清零,而局部變量和寄存器變量在未賦值前其值是不確定的。
對于外部變量和靜態變量,初值必須是常數表達式,而自動變量和寄存器變量可以是任意的表達式,這個表達式可以包括常數和前面說明過的變量和函數。
例如:
(2)變量的賦值
變量賦值是給已說明的變量賦給一個特定值。
單個變量的賦值:
① 整型變量和浮點變量
賦值格式如下:
變量名=表達式;
例如:
說明:
C語言中允許給多個變量賦同一值時可用連等的方式。
例如:
② 字符型變量
字符型變量可以用三種方法賦值。
例如:
(一)數組
所謂數組就是指具有相同數據類型的變量集,并具有共同的名字。數組中的每個特定元素都使用下標來訪問。數組由一段連續的存儲地址構成,最低的地址對應于第一個數組元素,最高的地址對應最后一個數組元素。數組可以是一維的,也可以是多維的。
1. 數組基本形式
(1)一維數組
一維數組的格式是:類型 變量名[長度];
類型是指數據類型,即每一個數組元素的數據類型,包括整數型、浮點型、字符型、指針型以及結構和聯合。
例如:
int a[10];
unsigned long a[20];
char *s[5];
char *f[];
說明:數組都是以0作為第一個元素的下標,因此,當說明一個int a[16]的整型數組時,表明該數組有16個元素,a[0]~a[15],一個元素為一個整型變量。
大多數字符串用一維數組表示。數組元素的多少表示字符串長度,數組名表示字符串中第一個字符的地址,例如在語句char str[8]說明的數組中存入“hello”字符串后,str表示第一個字母“h”所在的內存單元地址。str[0]存放的是字母“h”的ASCII碼值,以此類推,str[4]存入的是字母“o”的ASCII碼值,str[5]則應存放字符串終止符‘>大多數字符串用一維數組表示。數組元素的多少表示字符串長度,數組名表示字符串中第一個字符的地址,例如在語句char str[8]說明的數組中存入“hello”字符串后,str表示第一個字母“h”所在的內存單元地址。str[0]存放的是字母“h”的ASCII碼值,以此類推,str[4]存入的是字母“o”的ASCII碼值,str[5]則應存放字符串終止符‘\0’。<’。
C語言的編譯器大多對數組不作邊界檢查。
例如用下面語句說明兩個數組
char str1[5],str2[6];
當賦給str1一個字符串“ABCDEFG”時,只有“ABCDE”被賦給,“E”將會自動的賦給str2,這點應特別注意。
(2)多維數組
多維數組的一般格式:
類型 數組名[第n維長度][第n-1維長度]……[第1維長度];
例如:
數組m[3][2]共有3*2=6 個元素,順序為:
m[0][0],m[0][1],m[1][0],m[1][1],m[2][0],m[2][1];
數組c[2][2][3]共有2*2*3=12個元素,順序為:
c[0][0][0],c[0][0][1],c[0][0][2],
c[0][1][0],c[0][1][1],c[0][1][2],
c[1][0][0],c[1][0][1],c[1][0][2],
c[1][1][0],c[1][1][1],c[1][1][2];
數組占用的內存空間(即字節數)的計算式為:
字節數=第1維長度*第2維長度*...*第n維長度*該數組數據類型占用的字節數。
2. 數組的初始化
數組變量的初始化如:
數組進行初始化有下述規則:
① 數組的每一行初始化賦值用“{}”并用“,”分開,總的再加一對“{}”括起來,最后以“;”表示結束。
② 多維數組的存儲是按最右維數的變量變化最快的原則。
③ 多維數組存儲是連續的,因此可以用一維數組初始化的辦法來初始化多維數組。
例如:
④ 對數組初始化時,如果初值表中的數據個數比數組元素少,則不足的數組元素用0來填補。
⑤ 對指針型變量數組可以不規定維數,在初始化賦值時,數組維數從0開始被連續賦值。
例如:
char *f[]={'a','b','c'};
初始化時將會給3個字符指針賦值,即:*f[0]='a',*f[1]='b',*f[2]='c'。
3. 數組變量的賦值
整型數組和浮點數組的賦值,例如:
字符串數組的賦值,例如:
上面程序在編譯時,遇到char s[30]這條語句時,編譯程序會在內存的某處留出連續30個字節的區域,并將第一個字節的地址賦給s。當遇到strcpy函數時,首先在目標文件的某處建立一個“Good News!>上面程序在編譯時,遇到char s[30]這條語句時,編譯程序會在內存的某處留出連續30個字節的區域,并將第一個字節的地址賦給s。當遇到strcpy函數時,首先在目標文件的某處建立一個“Good News!\0”的字符串。其中“\0”表示字符串終止,終止符是編譯時自動加上的,然后一個字符一個字符地復制到s所指的內存區域。因此定義字符串數組時,其元素個數至少應該比字符串的長度多1。<”的字符串。其中“>上面程序在編譯時,遇到char s[30]這條語句時,編譯程序會在內存的某處留出連續30個字節的區域,并將第一個字節的地址賦給s。當遇到strcpy函數時,首先在目標文件的某處建立一個“Good News!\0”的字符串。其中“\0”表示字符串終止,終止符是編譯時自動加上的,然后一個字符一個字符地復制到s所指的內存區域。因此定義字符串數組時,其元素個數至少應該比字符串的長度多1。<”表示字符串終止,終止符是編譯時自動加上的,然后一個字符一個字符地復制到s所指的內存區域。因此定義字符串數組時,其元素個數至少應該比字符串的長度多1。
提示
① 字符串數組不能用“=”直接賦值,即s=“Good News!”是不合法的。所以應分清字符串數組和字符串指針的不同賦值方法。
② 對于長字符串,Turbo C2.0允許使用下述方法:
例如:
(二)指針
1. 指針基本形式
指針定義的一般形式為:類型識別符 *指針變量名;
例如:
C51 支持一般指針(Generic Pointer)和存儲器指針(Memory_Specific Pointer)。
(1)一般指針
一般指針的聲明和使用均與標準C相同,不過同時還可以說明指針的存儲類型。
例如:
以上的long、char等指針指向的數據可存放于任何存儲器中。一般指針本身用3個字節存放,分別存儲存儲器類型、高位偏移和低位偏移量。
(2)存儲器指針
基于存儲器的指針說明時即指定了存貯類型,例如:
這種指針存放時,只需1或2個字節就夠了,因為只需存放偏移量。
2. 指針變量的初始化
例如:
3. 指針變量的賦值
例如:
main()
{
int *i;
char *str;
*i=100;
str="Good";
}
*i表示i是一個指向整型數的指針,即*i是一個整型變量,i是一個指向該整型變量的地址。
*str表示str是一個字符型指針,即保留某個字符地址。在初始化時,str沒有什么特殊的值,而在執行str=“Good”時,編譯器先在目標文件的某處保留一個空間存放“Good>*str表示str是一個字符型指針,即保留某個字符地址。在初始化時,str沒有什么特殊的值,而在執行str=“Good”時,編譯器先在目標文件的某處保留一個空間存放“Good\0”的字符串,然后把這個字符串的第一個字母“G”的地址賦給str,其中字符串結尾符“\0”是編譯程序自動加上的。<”的字符串,然后把這個字符串的第一個字母“G”的地址賦給str,其中字符串結尾符“>*str表示str是一個字符型指針,即保留某個字符地址。在初始化時,str沒有什么特殊的值,而在執行str=“Good”時,編譯器先在目標文件的某處保留一個空間存放“Good\0”的字符串,然后把這個字符串的第一個字母“G”的地址賦給str,其中字符串結尾符“\0”是編譯程序自動加上的。<”是編譯程序自動加上的。
對于指針變量的使用要特別注意。上例中兩個指針在說明前沒有初始化,因此這兩指針為隨機地址,在小存儲模式下使用將會有破壞機器的危險。正確的使用辦法如下:
例如:
main()
{
int *i;
char *str;
i=(int*)malloc(sizeof(int));
i=420;
str=(char*)malloc(20);
str="Good, Answer!";
}
上例中,函數(int*)malloc(sizeof(int))表示分配連續的sizeof(int)=2個字節的整型數存儲空間并返回其首地址。同樣(char*)malloc(20)表示分配連續20個字節的字符存儲空間并返回首地址(有關該函數以后再詳述)。由動態內存分配函數malloc()分配了內存空間后,這部分內存將專供指針變量使用。
如果要使i指向三個整型數,則用下述方法。
例如:
#include
main()
{
int *i;
i=(int*)malloc(3*sizeof(int));
*i=1234;
*(i+1)=4567;
*(i+2)=234;
}
*i=1234表示把1234存放到i指向的地址中去,但對于*(i+1)=4567,如果認為將4567存放到i指向的下一個字節中就錯了。有些C語言編譯器中只要說明i為整型指針,則(i+1)等價于 i+1*sizeof(int)同樣(i+2)等價于i+2*sizeof(int)。
(三)數組與指針的關系
數組與指針有密切的聯系。數組名本身就是該數組的指針,反過來,也可以把指針看成一個數組,數組名和指針實質上都是地址,但是指針是變量,可以作運算。而數組名是常量,不能進行運算。
由上例可以看出數組和指針有如下關系:
(p+i)=&(s[i]),*(p+i)=s[i];
因此,利用上述表達式可以對數組和指針進行互換。兩者的區別僅在于:數組s是程序自動為它分配了所需的存儲空間;而指針p則是利用動態分配函數為它分配存儲空間或賦給它一個已分配的空間地址。
前面介紹了C語言中的基本數據類型,在實際進行C語言程序設計時僅有這些基本類型的數據是不夠的,有時需要將一批各種類型的數據放在一起使用,從而引入了構造類型的數據——結構與聯合。
(一)結構
結構是-種構造類型的數據,它能將多個不同類型的數據變量組合在一起,是一種數據的集合體。組成該集合體的各個數據變量稱為結構成員,集合體使用單獨的結構變量名。結構中的各個變量之間通常具有一定的關聯性,如時間數據中的時、分、秒,日期數據中的星期、午、月、日等。結構是將一組相關聯的數據變作為一個整體來進行處理,在程序中使用結構有利于對一些復雜而又具有內在聯系的數踞進行處理。
1. 結構變量的定義
方法一:先定義結構類型再定義結構變量名。
定義結構類型的一般形式為:
struct 結構名
{結構元素表};
結構元素表為該結構中的各個成員(又稱為結構的域),由于結構可以由不同類型的數據組成,因此對結構中的各個成員都要進行類型說明。
例如定義一個日期結構類型date的格式如下:
定義好一個結構類型之后,就可用它來定義結構變量。一般格式為:
struct 結構名 結構變量名l,結構變量名2,…,結構變量名n;
例如:
struct date d1,d2;
方法二:在定義結構類型的同時定義結構變量名。
將方法一的兩個步驟舍在一起,一般格式為:
struct 結構名
{ 結構元素表} 結構變量名1,結構變量名2,…,結構變量名n;
例:
方法三:直接定義結構變量。這種方法可以省略掉結構名,又稱為無名結構,-般形式為:
strut
{ 結構元素表} 結構變量名1,結構變量名2,…,結構變量名n;
例如:
方法四:用typedef命名一個結構類型(這時結構名就不太重要了)。
例如:
提示
結構類型與結構變量是兩個不同的概念。定義一個結構類型時只是給出該結構的組織形式,并沒有給出具體的組織成員,結構名不占用任何存儲空間,不能對結構名進行賦值、存取和運算。而結構變量則是一個結構中的具體成員,編譯器會為具體的結構變量名分配確定的存儲空間,因此可以對結構變量名賦值、存取和運算。
將-個變量定義為基本類型與將其定義為結構類型的不同之處是:前者只是說明變量的類型,后者不僅說明該變量為結構類型,同時還要指出該變量所屬結構類型的名字。
一個結構中的結構元素可以是另外一個結構類型的變量,即可以形成結構的嵌套。
例如:
其中,結構類型mrec中的結構元素time又是另一個結構類型clock的結構變量,形成了結構的結構,即結構的嵌套,結構的嵌套可以是多層次的,但這種嵌套不能包含其自身,即結構不能自己定義自己。
結構中的結構元素可以與結構外其他變量同名。它們各自代表不同的對象,在使用中不會互相影響。
在定義結構變量時,還可以說明它的存儲種類,可以extern、auto和static三種形式。
2. 結構變量的引用
結構變量定義之后就要考慮對它的引用問題(賦值、存取、運算)。對結構變量的引用是通過所屬的結構元素的引用實現的。引用結構元素的一般格式為:
結構變量名.結構元素
其中“.”是存取結構元素的成員運算符。如d1.month表示結構變量d1中的成員month。如果-個結構變量中的結構元素又是另外一個結構變量.即出現結構的嵌套時,則需要采用若干個成員運算符一級一級地找到最低一級的結構元素,而且只能對這個最低級的結構元素進行訪問,例:m1.time.min。
對結構變量中的各個元素可以像普通變量一樣進行賦值、存取和運算。
例:
d1.year=2006;
sum=d1.day+d2.day;
d1.month++;
m1.time.hour=0x22;
成員運算符的優先級別最高。
對于結構變量和結構元素在程序可以直接引用它們的地址。
例:scanf(“%d”&d1.year);
結構變量的地址通常用作函數參數,用來傳遞結構的地址。
3. 結構變量的初值
當結構變量為外部全局變量或靜態變量時可以在定義結構類型時給它賦初值,但不能給自動存儲種類的動態局部結構變量賦初值。
例如:
自動結構變量不能在定義時賦初值,只能在程序執行中用賦值語句為各結構元素分別賦值。結構變量初值個數必須小于等于結構變量中元素的個數。初值不夠時,余下的結構變量元素以0為其初值,如果初值個數多于元素個數時則會導致編譯出錯。
4. 結構數組
在實際使用中,結構變量往往不止一個,通常是將多個相同的結構組成一個結構數組,結構數組的定義方法與結構變量完全一致。
例如:
例:結構數組賦初值
5. 結構型指針
(1)結構型指針的概念
一個指向結構類型變量的指針稱為結構型指針,該指針變量的值也是它所指向的結構變量的起始地址。結構型指針也用來指向結構數組或結構數組中的元素。
定義結構型指針的一般形式為:
struct 結構類型標識符 * 結構指針標識符
其中“結構指針標識符”就是所定義的結構型指針變量的名字,“結構類型標識”就是該指針所指向的結構變量的具體類型名稱。
例:struct mepoint * mp;
(2)用結構型指針引用結構元素
通過結構型指針引用結構元素的一般形式為:
結構指針→結構元素
例:mp→pressure等同于(* mp).pressure
6. 結構與函數
(1)結構作為函數的參數
一般來說,結構既可作為函數的參敏,也可作為函數的返回值。當結構被用作函數的參數時,其用法與普通變量作為實參是一樣的,其參數傳遞屬于“值傳遞”方式。
程序在進行函數調用時,將整個結構變量作為參數傳遞給被調函數。系統為形式參數的結構變量分配存儲空間,并從相應的實際參數中取得各個元素的值。函數對形參中各個結構無素值進行的修改不會對相應的實參結構變量產生任何影響。
(2)結構型指針作為函數的參數
當結構較大時,若將該結構作為函數的參數,由于參數傳遞采用值傳遞方式,需要較大的存儲空間(堆棧)來將所有的結構元素壓棧和出棧,尤其當函數參數是結構數組時,影響更大,此外還會影響程序的執行速度。實際上可以用結構型指針來作為函數的參數,此時參數的傳遞是按地址傳遞方式進行的。由于采用的是地址傳遞方式,只需要傳遞一個地址值,與前者相比,既可節省存儲空間,同時還可加快程序的執行速度。缺點是在調用函數時對結構指針所作的任何變動都會影響到原來的結構變量。
(二)聯合
聯合也是C語言中一種構造類型的數據結構。在一個聯合中可以包含多個不同類型的數據元素。各種類型的變量放在同-個地址開始的內存單元中,實現了多層數據覆蓋,一方面有效地提高內存的利用率,另一方面也方便了數據類型間的轉換。
1. 聯合的定義
定義聯合類型變量的一般形式:
union 聯合類型名
{ 成員表列 } 變量表列;
也可以將類型定義與變量定義分開。即先定義一個union data類型,再將a、b、c定義為union data類型的變量。
還可以直接定義聯合變量。
由此可見,聯合類型與結構類型的定義方法是很相似的,只是將關鍵字struct改成了union。但是在內存的分配上它們之間有著本質的區別。結構變量所占用的內存長度是其中各個元素所占用內存長度的總和;而聯合變量所占用的時存長度是其中最長的元素的長度。聯合變量中的元素分時占用相同的存儲空間。
2. 聯合變量的引用
與結構變量類似,對聯合變量的引用也是通過對聯合元素的引用來實現的,引用聯合元素的一般格式為:
聯合變量名.聯合元素
或
聯合變量名->聯臺元素
例:
a.i //引用聯合變量a中的float型元素
a.j //引用聯合變量a中的long型元素
b.k //引用聯合變量b中的int型元素
c.m //引用聯合變量c中的char型元素
在引用聯合元素時,要注意聯合變量用法的一致性。因為聯合類型中定義的各個不同類型的元素都可以分時地賦給變量,而所讀取變量的值是最近放入的某一元素的值,因此在表達式中對它進行處理時,必須注意其類型要與表達式所要求的類型保持一致,否則將導致程序運行出錯。
聯合變量不能整體引用,例如下面的寫法就是錯誤的:
printf(“%f”,a);
因為變量a可能是 float、long、int和char三種類型,分別占用不同長度的內存區域,若在引用時僅寫聯合變量名a,系統將難以確定究竟應該輸出哪一個聯合元素的值。
正確的寫法為:
printf(“%f”,a.i);
聯合類型的數據占用的內存空間在某一時刻只能存放一種類型的元素。
MCU國產廠商有哪些,本文進行了盤點,并詳細對比了國內外MCU廠商的競爭實力!
【獲取更多傳感器行業深度資訊、報告,了解傳感器技術、傳感器與測試技術、物聯網傳感器技術……等傳感器知識,請關注傳感器專家網公眾號,設為星標,查看往期內容。】
黃金窗口期下,我們認為“產品完備度”高的MCU廠商可憑借先發優勢快速跑馬圈地。本篇報告我們即從料號數量、中高低端產品覆蓋面、生態建設完善度、下游應用覆蓋面多個維度,深入對比了MCU廠商的“產品完備度”:1)產品料號數量及中高低端產品覆蓋面上,兆易創新優勢明顯,國民技術追趕較快。2)生態建設上(用于MCU客制化開發),各家差異不大,兆易創新第三方開發工具選擇更多、稍具優勢。3)下游應用上,大多從消費切入,其中兆易創新已由消費為重、向工業消費并舉切換,而車規產品上兆易創新、芯海科技、華大半導體、BYD半導體已有產品量產,中穎電子、國民技術擬推出車規產品。
1)32位MCU:高端布局&料號數量上海內外存在差距,兆易創新是大陸龍頭,國民技術發展迅速。
我們統計了海外/國內分別近7000/500+款32位產品:
(1)ARM Cortex M內核在海外均是主流。海外方面,除瑞薩以自研為主外(占78%),M系列內核產品占比高達81%,自研內核產品占16%。國內方面,自研內核較少,M系列占比超過90%,另有少量廠商推出基于RISC-V、Xtensa內核的產品。
(2)高端產品領域,海內外存在差距,兆易創新是大陸龍頭,國民技術發展迅速。ARM內核包括中高低端不同產品,使用M7/33/35P/55高端內核是廠商能力的直觀體現之一。目前海外大廠基本是高中低全面配齊,低/中/高端的料號數量分別占38%/52%/10%。而大陸廠商在高端領域的布局仍有較大進步空間,其中兆易創新最為領先,2020年10月正式推出基于ARM Cortex M33內核的高性能產品,此外國民技術研發基于M7的高性能產品,預計2022年推出。
(3)料號數量上,海內外存在10倍差距,大陸廠商發展。海外廠商中除微芯、德州儀器32位產品在300-500種以外,其他廠商均有上千顆料號。而大陸方面,目前領先廠商包括兆易創新(370+顆)、華大半導體(100+顆)、國民技術(80+顆)。
2)8位MCU:大陸廠商中中穎電子一騎絕塵。海內外廠商的8位產品料號數量普遍少于32位產品,這里我們統計了海外5家廠商1600余款、大陸4廠商的122款產品:
(1)海外自研架構為主,大陸8051架構為主。8位產品內核方面,總體可以分為自研內核、基于8051開源架構的內核兩類。海外因8位產品開發年代較早,大多數使用自研內核,占我們統計數據的81%。國內基本都采用8051架構,我們統計的廠商中僅芯海科技使用自研內核。
(2)料號數量看,海內外同樣存在差距,大陸廠商中中穎電子存在絕對優勢。海外大廠料號數量在100-600不等,而大陸方面除中穎電子推出80余款產品外,其他廠商料號數量均在30顆以內。
3)生態建設:硬件開發工具較完善,軟件配套仍有欠缺。因工程師需要在MCU的基礎上做定制化開發,良好的生態環境可使得開發過程更便捷。我們對大陸7家廠商以及海外(含中國臺灣地區)的5家廠商從以下三個維度進行對比:
(1)硬件:主要指開發板及其他輔助硬件,大陸各企業均有官方提供開發板,該環節海內外無明顯差距。
(2)軟件:目前大陸大多數公司直接采用第三方開發工具,包括Keil、IAR等,其中兆易創新支持的第三方工具較多。海外方面則選擇更為多樣,并且部分廠商提供自研開發工具。
(3)學習資料:相對海外廠商,國內廠商在中文學習資料更具優勢。同時也學習海外廠商,建立開發者社群、推出大學計劃等,建立本土優勢。
4)下游應用布局:大陸從消費電子切入,往工業及汽車拓展。海外廠商基本是消費、工業、汽車全面布局,但各家側重不同。其中微芯(重8位)、意法(重32位)重點布局消費、工業,恩智浦、瑞薩重點布局汽車。大陸方面,大多數廠商選擇首先切入性能要求較低的消費領域,然后向工業級切入,其中兆易已從消費為主逐步向消費、工業并重切換。而車規產品,因在產品性能、可靠性、壽命等方面要求更高,因此目前大陸廠商涉足較少,幾乎僅在與安全相關性較低的車身模塊有量產產品,包括兆易創新、中穎電子、芯海科技等,而動力域等高端模塊幾乎沒有涉足。
5)團隊結構:團隊背景各具特色。從團隊背景看,各有特色:兆易創新“清華+留美工作經驗”的技術出身管理層特色突出;中穎電子管理層與技術人才大量來自中國臺灣地區;國民技術以國內人才為主,2018年以后新任董事長帶領公司轉型;芯海科技管理層為ADC專家,團隊國內人才偏多;樂鑫科技管理層來自新加坡,技術人才來自全球各地。
6)財務指標:2020年大陸龍頭營收近10億,對標海外龍頭仍有20倍空間。從營收體量上看,海外廠商中恩智浦、瑞薩、微芯MCU業務2020年營收體量均超過200億人民幣,而大陸廠商中2020年僅幾家達到10億營收上下的水平,我們認為在“貿易摩擦+缺貨潮”的催化下,2022年將有數家廠商有望步入數十億營收的梯隊。
目錄
1 32位產品:從ARM核及料號數量看,大陸已具備實力
1.1 外購ARM內核,是海內外一致的大趨勢
1.2 從ARM內核+料號數量看,兆易創新第一梯隊、國民技術發展迅速
2 8位產品:大陸相對布局較少,少數玩家極具實力
3 生態建設:硬件開發工具較完善,軟件配套仍有欠缺
4 下游應用布局:大陸從消費電子切入往工業及汽車拓展
4.1 海外:大廠在汽車、工控、消費電子三大市場錯位競爭
4.2 大陸:消費切入、逐步開拓工業市場,部分細分領域已誕生龍頭
4.3 大陸:車規MCU要求嚴苛,大陸廠商從低端切入
5 員工結構:規模+薪資+創收三維度,兆易創新、中穎電子位居前二
6 財務指標:大陸龍頭營收近10億,對標海外仍有20倍空間
7 投資建議
8 風險提示
正文
01 32位產品:從ARM核及料號數量看,大陸已具備實力
1.1 外購ARM內核,是海內外一致的大趨勢
從自研內核轉向外購內核是大趨勢,目前ARM Cortex M系列占據主流地位。
從MCU的發展歷史看,最初MCU廠商多自研內核,之后隨著計算要求越來越復雜,內核廠商開始出現、分工進一步細化,MCU廠商開始使用外購內核并將主要精力投身其他部分的研發。
其中目前外購內核中占據主導地位的是ARM Cortex M系列,該系列由ARM開發,采取IP授權形式,相比于ARM公司的其他系列產品(注:Cortex處理器可以分為應用處理器(A系列)、實時處理器(R系列)和微控制器處理器(M系列)),Cortex-M系列具有短流水線、超低功耗的設計特點,專門面向MCU及深度嵌入系統市場。2004年ARM公司推出第一款Cortex-M系列處理器M3,ST公司抓住機遇,在短時間內向市場推出一系列基于該內核的32位MCU(STM32系列)。
此后Cortex-M系列處理器迅速發展,2009年,超低功耗處理器M0一經推出,就受到了廣泛的歡迎,在9個月內就有多達15家廠商與ARM簽約。目前海外廠商幾乎都從自研內核轉向了使用ARM內核。除此之外,近幾年RISC-V則成為了32位內核市場的后起之秀,該內核誕生于伯克利大學,特點是簡單且免費開源,國內部分廠商也推出了基于此架構的MCU產品,但整體數量偏少。
ARM內核包括中高低端不同產品,使用M7/33/35P/55高端內核是廠商能力的直觀體現之一。目前ARM共推出10款Cortex M系列處理器,其在尺寸、功耗、性能、安全性、是否適用于AI應用等指標上有著差異化定位,全面滿足低、中、高端需求。其中,M0/0+/1/23四顆為低端內核,M3/M4為中端產品,M7/M23/35P/55為中高端產品。
1.2 從 ARM 內核+料號數量看,兆易創新第一梯隊、國民技術發展迅速
主攻消費&工業的意法半導體系 32 位市場的后起之秀,也是大陸廠商的重要競爭對手。相較于 8 位與 16 位產品,32 位產品集中度更高,前七大廠商均有布局,TOP7 集中度接近 90%(注:賽普拉斯被英飛凌收購后變為六位廠商),其中瑞薩和恩智浦在32位市場市占率均接近20%。而32位市場最大的變量來自于意法半導體,其在2004年ARM推出針對于MCU的Cortex M內核后,通過外購ARM內核快速鋪開產品,并憑借良好的生態,市占率持續提升。因瑞薩和恩智浦主攻車載市場,因此大陸廠商在32位的最重要競爭對手是意法半導體。
除瑞薩以自研為主外,其他廠商基于 ARM Cortex M 的產品料號占比高達 81%,中高端產品全面配齊。根據我們統計的 6 家海外大廠近 7000款 32 位產品,(注:原七大廠商中賽普瑞斯被英飛凌收購,變為六家)。
其中(1)外購 ARM Cortex 內核:我們共統計了近 4500 款 ARM Cortex M 系列產品,占我們統計的 32 位 MCU 的 64%;若除去以自研為主的瑞薩,則 ARM M 系列料號數量占到了 81%。同時海外大廠基本是 ARM Cortex M 系列的高中低全面配齊,低端/中端/高端的料號數量分別占38%/52%/10%。
(2)其他外購:少數廠商選擇購買 ARM Cortex A 系列內核(通常是用于手機、電腦 CPU),用于高端產品,比如瑞薩共推出118 款多核產品,其中主核多采用 A 系列,輔核多采用 M 系列;而德州儀器則推出了 43 款基于 ARM Cortex R 系列(實時處理器,通常用于存儲芯片,適用于 IoT、AI 等場景)產品,定位中高端的汽車 ADAS 系統和工控領域。
(3)自研內核:海外 6 大廠商中,僅瑞薩則以自研內核為主(占 78%)、外購內核為輔。而其他海外大自研產品基本在 100-300款,根據我們統計的 5 家廠商數據(除去瑞薩),除去瑞薩外,自研內核的料號數量約占 16%。
注:海外廠商以 6 大 MCU 廠為統計范圍;統計產品為官網列示產品,截至 2022/2。
料號上,每家廠商總數上千、各系列多達幾十種。從內核數量上,除微芯側重 8 位產品、德州儀器側重模擬產品外,其他廠商僅 32 位產品料號數量就有上千種,并且每個系列通常都有幾十種型號,用來提供不同存儲容量、不同頻率、不同下游應用的針對性產品。
大陸廠商外購ARM內核占比超過90%,少數推出RISC-V內核產品。我們統計了大陸8家廠商500余款產品,其中使用ARM Cortex M系列產品的占比超過90%,我們認為該比例高于海外主要由于:(1)海外廠商的大量自研內核產品主要是歷史遺留,實際上不管是海外廠商還是大陸廠商,在新品開發時都傾向于直接使用ARM內核。(2)大陸廠商前期主攻消費市場,而32位消費市場的主導者是意法半導體,意法32位產品全部基于ARM內核,因此大陸廠商可以通過外購ARM核生產pin-to-pin兼容型產品,降低替換難度。此外,少數廠商推出基于RISC-V內核的產品,如兆易創新、樂鑫科技。另外樂鑫科技目前產品中更多的則是基于美國廠商tensilica(2013年被Cadence收購)的Xtensa系列內核。
注:大陸廠商選取標準為上市/擬上市MCU公司;統計產品為官網列示產品,截至2022/2。
從高端產品及料號數量看,兆易創新最為領先,國民技術快速追趕。(1)從技術看,與海外中高低端全面覆蓋相比,大陸廠商在高端領域的布局仍有較大進步空間,其中兆易創新最為領先,2020年10月正式推出基于ARM Cortex M33內核的高性能產品,此外國民技術研發基于M7的高性能產品,預計明年推出。(2)從料號數量看,大陸廠商與海外廠商仍存在10倍差距,目前大陸領先廠商包括兆易創新(370+顆)、華大半導體(100+顆)、國民技術(80+顆)。
02 8位產品:大陸相對布局較少,少數玩家極具實力
8位市場微芯份額超過30%,是大陸廠商的主要對標者。8位市場中,前7大廠商中5家布局了8位產品(英飛凌、TI無8位產品),CR5在70%上下,其中微芯一家獨大,超過30%;第二位恩智浦約占15%、三四名瑞薩/意法占分別10%。
自研內核占主流,但多家廠商都具備8051內核的產品。
我們這里統計了5家海外廠商近1600款8位產品,其中
(1)自研內核:近1300款自研內核產品,占我們統計數據的81%。我們認為8位產品自研比例高于32位產品,主要因為其年代較為久遠,當時很多廠商都采取了自研內核,如微芯的AVR(前Atmel產品)、PIC,恩智浦的RS08\M68HC,瑞薩的RL78\H8K0,意法的STM8。這些產品因價格低,并且在客戶上已有較深綁定,仍占據很大市場份額。
(2)8051開源內核:8051內核是intel于1980年開發的架構,在1998年失去專業保護后成為開源IP,再次展現強大的二次生命力,各家廠商在8051內核基礎上進行一定改動后推出各種差異化產品,這類產品基本都統稱為8051內核的MCU。經過40多年的發展,目前8051 MCU產品已具備完善的生態系統以及多個免費開源版本。根據我們統計的5家海外廠商中有2家推出了8051產品,料號數量約占我們統計數據的19%,其中賽普拉斯(已被英飛凌收購)8051產品多過其自研產品,微芯也有近50款8051產品。
注:海外廠商以6大MCU廠為統計范圍,其中德州儀器無8位產品;統計產品為官網列示產品,截至2022/2。
料號相對32位較少,各家料號數量100-600種。與32位相比,8位市場相對較小&應用較簡單,因此料號數量不及32位豐富,海外大廠料號數量在100-600不等,其中恩智浦最多,達570余款,全部為自研產品,賽普拉斯(被英飛凌收購)第二,有420余款,其他廠商在100-300不等。
大陸8位市場相對布局較少,采用8051架構的廠商偏多,中穎大陸龍頭地位顯著。與海外市場相比,大陸廠商8位產品布局較少,在我們統計的22家廠商中僅11家布局了8位產品,而這里我們僅列示了4家廠商的122款產品。此外相較海外,大陸廠商使用8051架構的廠商偏多,如中穎電子、宏晶科技均提供的是基于8051架構的產品,其中中穎電子是8位市場的大陸龍頭,目前推出82顆基于8051內核的產品(官網列示數據)。此外,芯海科技8位產品均采用自研內核。
注:大陸廠商選取標準為上市/擬上市MCU公司;統計產品為官網列示產品,截至2022/2。
03 生態建設:硬件開發工具較完善,軟件配套仍有欠缺
客戶須在通用MCU基礎上做定制化開發,友好的生態環境使得開發過程更便捷。大多數MCU為通用型產品,工程師需要在MCU的基礎上做定制化開發,因此除硬件性能外,良好的開發環境、可得的學習資料對于工程師來說也極為關鍵。簡單來說,生態系統主要由其自身及其合作伙伴共同建立,主要包括三大部分:硬件開發工具(包括開發板等)、軟件開發工具(從配置、開發、編程、監控的全開發過程)、學習資料(包括開發者交流論壇、工程師培訓課程、指導手冊等)。
意法借力生態持續提升市場份額,為大陸廠商切入市場提供正確思路。當年意法半導體市占率的快速提升與其良好的生態建設不無關系。2005年意法進入市場,不僅提供了免費的開發板,還提供了更易上手的開發軟件、易于閱讀的學習資料,這與傳統廠商“高冷”的做派極為不同。意法成功開創了MCU行業建立完善生態的先河,之后不管是MCU的傳統玩家還是新晉玩家,也都或多或少向更為注重生態的建設。時至今日,意法仍然是良好生態建設的代表性廠商,在EE Times組織的消費者偏好投票中,意法產品多年穩居32位MCU第一。我們認為,本輪貿易摩擦+缺貨潮為大陸廠商提供了窗口期,而擁有良好生態建設的廠商能夠讓工程師們更快速的完成替換。
我們這里從硬件、軟件、學習資料三大維度對大陸與海外龍頭做對比:
1)硬件:大陸廠商開發硬件工具較為完善,與海外龍頭無明顯差距。硬件主要指開發板及其他輔助硬件,其中開發板是用來進行嵌入式系統開發的電路板,國內各企業均有官方提供。而兆易創新、芯海科技、樂鑫科技、華大半導體除開發板外還提供了豐富的官方或三方調試器、仿真器。
2)軟件:大陸廠商采用第三方公司Keil、IAR開發工具,而海外廠商選擇更為多樣。目前大陸大多數公司均直接采用此第三方開發工具,包括Keil、IAR等。此外樂鑫科技建立了自己的物聯網開發框架,開發平臺針對本公司產品設計,且內容豐富、支持主流三方IDE。而與大陸廠商相比,海外廠商一是在第三方開放工具的選擇上更多樣,二是部分也提供了官方自研的、或是與第三方軟件供應商合作開發的軟件工具。
(注:SDK一般指軟件開發工具包,提供基礎開發平臺。集成開發環境(IDE)是用于提供程序開發環境的應用程序,通常IDE在SDK基礎上還包含了圖形用戶界面及其他插件,更便于開發者使用。)
3)學習資料:在文獻資料上,海外大廠資料多以英文為主,提供的中文參考資料較少。而大陸企業在中文資料和培訓上提供的便捷,是搶占本土市場的一大優勢。而在開發者社區和高校合作方面,部分大陸廠商則建立了自己的開發者社群,并通過大學計劃、大學生競賽等方式,宣傳品牌并培養有潛質的研發人員。
04 下游應用布局:大陸從消費電子切入往工業及汽車拓展
4.1 海外:大廠在汽車、工控、消費電子三大市場錯位競爭
大廠錯位布局,瑞薩&恩智浦汽車領先,微芯&意法消費工業領先。
(1)恩智浦、瑞薩定位高端汽車、工控市場:恩智浦與瑞薩定位較為相似。其中恩智浦前期在醫療、通訊市場均有所布局,在2015年通過收購飛思卡爾進軍汽車電子領域。瑞薩在汽車MCU市場具有領先地位,2014年起就已占據汽車半導體全球市場份額第一。
(2)微芯、意法定位中低端工控、消費電子:微芯2016年通過收購Atmel,在工業控制領域形成全面覆蓋的產品線。意法半導體在物聯網和消費電子領域全面布局,包括了工業網關、電信設備、家庭自動化等產品,但在高端的工控、車規領域仍有所局限。
(3)其他:英飛凌在汽車電子、工業控制、醫療等領域長期經營,定位高端,價格偏高,且在2020年完成對賽普拉斯的收購,完善汽車電子產品線的同時進入了消費電子領域。德州儀器主要深耕工業控制與通信領域,在低功耗產品上有絕對的技術優勢。
4.2 大陸:消費切入、逐步開拓工業市場,部分細分領域已誕生龍頭
消費級切入,站穩腳跟后開拓工業級市場。從指標的嚴苛程度來說,消費<工業<汽車,因此相比于海外廠商的全方位布局,大陸廠商在切入市場時幾乎都選擇了消費類市場,如兆易創新、華大半導體、國民技術、中穎電子、芯海科技。通過消費級市場積累后,再開始向工業級甚至車規級切入。
以小家電為代表的部分細分領域已有所突破。目前在8位領域做得較好的廠商包括中穎電子(專注小家電)、宏晶電子等。以小家電市場為例,國內各小家電廠商主要通過兩條路徑打開市場:①通過各種應用創新,試圖通過創新技術建立起行業壁壘,如集烤/煮/炒/蒸于一體的小廚電;②通過尋找市場空白,推出全新產品,如大力推廣的消毒刀架等。相較于MCU其他領域來說,小家電的MCU產品迭代稍快、需求差異化,而國內MCU廠商相對國外大廠,能夠提供及時的、更全面的本地服務。目前,大陸廠商中穎電子、臺系廠商盛群半導體、義隆電子、松瀚電子均已擁有較高市場份額,該四家廠商2017年合計市占率達78%。
4.3 大陸:車規MCU要求嚴苛,大陸廠商從低端切入
車規MCU需同時保障功能與安全性,評估指標遠遠嚴苛于消費類和工業級MCU。車規MCU的評估指標無論從工作環境、使用壽命還是交付良率等方面,都要嚴苛于消費類與工業級的MCU。比如汽車發動機艙MCU工作溫度區間為-40℃-150℃,車身控制部分為-40℃-125℃,而消費類產品只需要達到:0℃-70℃。其它環境要求諸如濕度、發霉、粉塵、水、EMC,以及有害氣體侵蝕等等也往往都高于消費電子產品要求。
大陸廠商從中低端車規MCU切入,并考慮研發高算力產品。車規級MCU由于認證周期長、可靠性要求高,是國產替代最難突破的陣地。近年來部分大陸廠商已從與安全性能相關性較低的中低端車規MCU切入,如雨刷、車窗、遙控器、環境光控制、動態流水燈等車身控制模塊,并逐步開始研發未來汽車智能化所需的高端MCU,如智能座艙、ADAS等。目前,兆易創新、芯海科技、華大半導體、BYD半導等廠商均有通過車規驗證的產品,國民技術從后裝市場切入(無需車規認證)并規劃車規級產品,中穎電子預計2022年上半年推出車規級產品。此外,芯海科技2021年12月發布公告,擬募資2.9億元/總投資3.9億,用于車規級MCU開發,預計未來銷售量可達2億顆以上,實現動力域、底盤域、車身域、信息娛樂系統、智能座艙的全面覆蓋。
05 員工結構:規模+薪資+創收三維度,兆易創新、中穎電子位居前二
從公司整體研究人員規模看,兆易研發實力凸顯。總體規模從200到上千人等,其中兆易創新體量達1000人以上且增長最快;其他公司研發人員規模基本在500人以內。(注:富滿電子、國民技術總人數在700人以上,但其中生產人員占比較大,研究人員在500人以內。其中國民技術2018年收購斯諾實業后,生產人員人數增加較多,生產人員占比增加到38%)
人均工資方面,中穎電子、兆易創新、樂鑫科技位居第一梯隊。兆易創新、中穎電子、樂鑫科技人均工資領先明顯,2020年在50萬上下,富滿電子、國民技術由于生產人員較多,平均工資較低(國民技術低于25萬元,富滿低于10萬元)。
人均創收方面,兆易創新、中穎電子分列一二。兆易創新最高,2020年人均營收近400萬元/人均利潤近80萬元;中穎電子次之,人均營收280萬元/人均利潤58萬元。其他公司人均營收200萬以下/人均利潤35萬元以下。
兆易創新:清華+留美工作經驗的技術出身管理層。管理團隊多來自清華等國內知名高校,核心技術人員海外背景顯著,市場品牌人員同樣具有一定的微電子專業背景,公司具有國內外研發中心,與廈門大學等高校共同發起了MCU聯合實驗室。
中穎電子:管理層與技術人才大量來自中國臺灣地區。中穎的管理人員多具有臺灣背景,曾在聯電、聯詠等半導體知名企業中任職,核心技術和人才則主要由內地自主培養,包括了復旦、清華等國內知名高校的電子技術背景人員。
國民技術:國內人才為主,2018年以后新任董事長帶領公司轉型。管理團隊擁有中國華大、中興通訊等央企背景,其建立了遍及國內外的研發中心,在國內擁有博士后工作站,內部人員具有多年的市場推廣及MCU產品經驗。
芯海科技:管理層技術出身,國內人才偏多。核心技術團隊成員較為穩定,具備多年的IC相關領域背景,先后在多家國內外頭部IC設計商任職。市場營銷團隊具有相關領域經驗,曾在晶晨半導體等集成電路企業任銷售職務。
樂鑫科技:管理層來自新加坡,技術人才來自全球各地。管理團隊出身于新加坡國立大學,核心技術團隊來源廣泛,包含近半數的印度、新加坡、美國等外籍人員,有IBM、Sun Microsystems等海外領先軟件企業背景。國內技術團隊畢業于浙大、西安交大等國內知名高校,多出自瀾起科技等領先集成電路公司。
06 財務指標:大陸龍頭營收近10億,對標海外仍有20倍空間
國內龍頭公司營收10億上下,與海外龍頭仍有20倍差距。海外大廠中,恩智浦、瑞薩、微芯MCU業務營收體量均超過200億人民幣,而目前大陸MCU廠商仍處于百花齊放階段,營收體量較小。其中兆易創新、中穎電子、華大半導體為國內MCU龍頭,樂鑫科技在WiFi/藍牙MCU細分市場領先,其中華大半導體MCU估計超過10億元,兆易創新、中穎電子、樂鑫科技均在8億左右。其他廠商如芯海科技、富滿電子等營收體量還較小。
“貿易摩擦+缺貨潮”窗口期大陸廠商快速成長2022年數家廠商有望步入幾十億營收梯隊。從歷年營收情況看,海外大廠已步入成熟期。由于MCU下游應用更迭較慢,客戶通常在新品推出時才有更換供應商的意愿,因此過去多年國內MCU市場發展較慢。近兩年“貿易摩擦+缺貨潮”窗口期,使得大陸以兆易創新、中穎電子、國民技術為代表的廠商收入快速增長, 2022年將有數家廠商有望進入數十億營收的梯隊。
大陸廠商MCU產品毛利率普遍在40%以上,海外廠商整體毛利率在35%-65%不等。兆易創新、樂鑫科技MCU毛利率基本保持在45%以上,中穎電子能夠維持在40%以上,而芯海科技MCU毛利率相對較低,約為30%。MCU毛利率的差距或與各公司產品定位有關,兆易創新推出了中高端MCU產品,而目前芯海科技32位MCU均是基于ARM Cortex M0內核。
來源:ittbank
聲明:本文內容系作者個人觀點,不代表傳感器專家網觀點或立場。更多觀點,歡迎大家留言評論。如有投稿爆料采訪需求,請發郵箱:sensorexpert@sensorexpert.com.cn。