【IAR学习】学习笔记

发布者:mlgb999最新更新时间:2015-11-09 来源: eefocus关键字:IAR学习  学习笔记 手机看文章 扫描二维码
随时随地手机看文章
1、怎么生成.map文件:

【IAR学习】学习笔记(摘抄)
 

4、IAR编译器默认支持的指针变量最大为0xFFFF,如果超过0XFFFF,则需要再OPTION内进行设置。Project-->Option-->General-->Target-->Data model选择Large。

 

原文有图片,请到原文看:http://www.52solution.com/bbs/redirect.php?tid=1128&goto=lastpost
IAR学习笔记(摘抄)
IAR for AVR 学习笔记(1)--数据类型

数据类型(编译器支持 ISO/ANSI C 基本数据类型和一些附加数据类型)

1.1.        整型数据

 

bool 数据类型在C++语言里是默认支持的。如果你在C代码的头文件里包含stdbool.h, bool数据类型也可以使用在C语言里。也可以使用布尔值 false和 true。

1.2.浮点数据类型:

 

1.3.指针类型:指针有数据指针和函数指针。

1、数据指针:

数据指针的大小为8位,16位,24位。定义为:在整型数据类型后加”*”符号。
例如:char * p;
整型数据没有24位,具体定义指针见后面扩展关键字章节。

2、函数指针:函数指针的大小为16位,24位。
指针定义:在函数类型后加”*”符号

IAR for AVR 学习笔记(2)--扩展关键字

可以用来解决数据,函数的存放等。有了它我们就可以定义变量存放在EEPROM,FLASH空间。定义中断函数,指针等等。IAR关键字很多,这里只列举常用的。

2.1.扩展关键字:用于控制数据和指针。

__eeprom 用于EEPROM 存储空间, 控制数据存放,控制指针类型和存放
__tinyflash, __flash, __farflash, __hugeflash 用于flash 存储空间, 控制数据存放,控制指针类型和存放:
__ext_io, __io 用于I/O存储空间, 控制数据存放,控制指针类型和存放
__regvar 放置一个变量在工作寄存器中

2.2.函数扩展关键字:。

__nearfunc __farfunc 用于控制数据存放,这组关键字必须在函数声明和定义的时候指定:
__interrupt. 关键字控制函数的类型。这组关键字必须在函数声明和定义的时候指定
__root. 关键字仅仅控制有定义的函数:

2.3.其它特别的关键字:

@ 用于变量的绝对地址定位。也可以用#pragma location 命令
#pragma vector 提供中断函数的入口地址。
__root 保证没有使用的函数或者变量也能够包含在目标代码中
__no_init 禁止系统启动的时候初始化变量.
asm, __asm 插入汇编代码

IAR for AVR 学习笔记(3)--位操作

3.1.在c语言里对位的操作如一般如下:

PORTB|=(1<<2);//置PORTB的第2位=1
PORTB&=~(1<<2);//置PORTB的第2位=0
PORTB^|=(1<<2);//取反PORTB的第2位
While(PORTB&(1<<2));//判断1
While(!(PORTB&(1<<2)));//判断为0

3.2.IAR编译器对位的支持更强大,除了上面的方法外还有以下更简单的操作方法:

PORTB_ Bit2=1; //置PORTB的第2位=1
PORTB_ Bit2=0; //置PORTB的第2位=0
PORTB_ Bit2=~ PORTB_ Bit2;//取反PORTB的第2位
While(PORTB_ Bit2);或者while(PORTB_Bit2==1);//判断1
while(PORTB_ Bit2==0);//判断0
PORTC_Bit4=PORTB_Bit2;//把PORTB的第2位传送到PORTC的第4位

3.3.位变量定义:

由于iar使用了扩展语言,它对位域的支持变为最小为char类型,我们可以很方便地用来定义位变量。

采用结构体来定义位变量:

struct
{
unsigned char bit0:1;
unsigned char bit1:1;
unsigned char bit2:1;
unsigned char bit3:1;
unsigned char bit4:1;
unsigned char bit5:1;
unsigned char bit6:1;
unsigned char bit7:1;
}t;

然后就可以用以下位变量了。

t.bit0=1;
t.bit0=~t.bit0;

但是采用以上结构体做出来的位变量只可以访问t的位,不能够直接访问变量t,和标准的IAR位操作也不一样。采用联合体来定义效果更佳。

#i nclude
union
{
unsigned char t;
struct
{unsigned char t_bit0:1,
t_bit1:1,
t_bit2:1,
t_bit3:1,
t_bit4:1,
t_bit5:1,
t_bit6:1,
t_bit7:1;
};
};
void main(void)
{
t_bit0=1;//访问变量t的位
t_bit0=~t_bit0;
PORTB=t;//直接访问变量t
}

位变量也可以直接定义在工作寄存器里。

3.4 bool 数据类型在C++语言里是默认支持的。[page]

如果你在C代码的头文件里包含stdbool.h, bool数据类型也可以使用在C语言里。也可以使用布尔值 false和 true。不过是占用8位1个字节。

#i nclude
#i nclude
bool y=0;//定义位变量
void main(void)
{
y=!y;//取反位变量
PORTB_Bit3=y;//传递位变量
}

IAR for AVR 学习笔记(4)--Flash操作

FLASH常用类型的具体操作方法

4.1.FLASH 区域数据存储。

用关键字 __flash 控制来存放, __ flash 关键字写在数据类型前后效果一样
__flash unsigned char a;//定义一个变量存放在flash空间
unsigned char __flash a;//效果同上
__flash unsigned char p[];//定义一个数组存放在flash空间
对于flash空间的变量的读操作同SRAM数据空间的操作方法一样,编译器会自动用
LPM,ELPM 指令来操作。

例:

#i nclude
__flash unsigned char p[];
__flash unsigned char a;
void main(void)
{PORTB=p[1];// 读flash 数组变量的操作
PORTB=a;// 读flash 变量的操作
}

由于在正常的程序中,flash 空间是只读的,所以没有赋值的变量是没有意义的。定义常数在flash 空间,只要给变量赋与初值就可以了。由于常数在flash空间的地址是随机分配的,读取变量才可以读取到常数值。

10

IAR-AVR –C 编译器简要指南

__flash unsigned char a=9;//定义一个常数存放在EEPROM空间。
__flash unsigned char p[]={1,2,3,4,5,6,7,8};
//定义一个组常数存放在flash 空间。

例:

#i nclude
__flash unsigned char p[]={1,2,3,4,5,6,7,8};
__flash unsigned char a=9;
void main(void)
{
   PORTB=a;//读取flash 空间值9
   PORTC=p[0]; //读取flash 空间值
}

4.1.2flash 空间绝对地址定位:

__flash unsigned char a @ 0x8;//定义变量存放在flash 空间0X08单元__flash unsigned char p[] @ 0x22//定义数组存放在flash 空间,开始地址为0X22单元
__flash unsigned char a @ 0x08=9;//定义常数存放在flash 空间0X08单元
__flash unsigned char p[] @ 0x22={1,2,3,4,5,6,7,8};
//定义一个组常数存放在EEPROM空间开始地址为0X22单元

由于常数在flash 空间的地址是已经分配的,读取flash 空间值可以用变量和地址。

4.2.与 __flash 有关的指针操作。 __flash 关键字控制指针的存放和类型。

4.2.1指向flash 空间的指针flash 指针(控制类型属性)

unsigned char __flash * p;//定义指向flash 空间地址的指针,8位。
unsigned int __flash * p;//定义个指向flash 空间地址的指针,16位。
unsigned int __farflash * p;//定义指向flash 空间地址的指针,24位。
unsigned int __hugeflash * p;//定义指向flash 空间地址的指针,24位。
unsigned char __flash * p;//定义一个指向flash 空间地址的指针,指针本身存放在SARM中。P的值代表flash 空间的某一地址。*p表示flash 空间该地址单元存放的内容。例:假定p=10,表示flash空间地址10单元,而flash M空间10单元的内容就用*p来读取。

例:

#i nclude
char __flash t @ 0x10 ;
char __flash *p ;
void main(void)
{
PORTB=*p;//读取flash 空间10单元的值
PORTB=*(p+3);//读取flash 空间0x13单元的值
}

4.2.2.存储于flash 空间的指针数据指针

就象存储与flash 空间的数据一样控制存储属性

__flash unsigned char * p; //定义指向SARMM空间地址的指针,指针本身存放在flash 中。

4.3.控制数据和指针存放的__flash 定义必须是全局变量,控制类型属性(好像只有指针)可以是局部变量。

#i nclude
__flash unsigned char p;//控制存放
void main(void)
{
unsigned char __flash* t;//控制属性
PORTB=p;
PORTB=*t;
}

4.4. __root 关键字保证没有使用的函数或者变量也能够包含在目标代码中.

定义存放在__flash 空间的数据在程序编译时会自动生成代码嵌入到flash代码中,对于程序没有使用也要求编译的数据(比如可以在代码中嵌入你的版本号,时间等)必须加关键字__root 限制。

例:

#i nclude
__root __flash unsigned char p @ 0x10 =0x56;
void main(void)
{}

程序没有使用P变量,编译也会生成该代码。

:020000020000FC
:1000000016C018951895189518951895189518955F
:10001000569518951895189518951895189518953A
:10002000189518951895089500008895FECF0FE94A
:100030000DBF00E00EBFC0E8D0E003D0F4DFF4DF76
:06004000F3CF01E008957A
:0400000300000000F9
:00000001FF

4.5.flash 操作宏函数:在comp_a90.h intrinsics.h头文件里有详细说明。flash 空间具正常情况下有只读性能,对于读flash 数据编译器会自动编译对应的LPM,ELPM指令,但对于flash 空间的自编程写命令SPM就没有对应的C指令了,这里不讲解详细的自编程方法,只是讲解一下对flash 的读写函数。

直接在程序中读取flash 空间地址数据:要包含intrinsics.h头文件
__load_program_memory(const unsigned char __flash *);//64K空间
//从指定flash 空间地址读数据。该函数在intrinsics.h头文件里有详细说明。

在comp_a90.h文件有它的简化书写_LPM(ADDR)。注意汇编指令LPM Rd ,Z中的Z是一个指针。所以用(const unsigned char __flash *)来强制转换为指向flash空间地址指针。故该条宏函数的正确写法应该如下:

__load_program_memory((const unsigned char __flash *)ADDR);

例:

#i nclude
#i nclude
void main(void)
{PORTB=__load_program_memory((const unsigned char __flash *)0x12);
}

该条函数书写不方便,在comp_a90.h文件有简化:

#define _LPM(ADDR) __load_program_memory (ADDR)稍微方便一点。改为
#define _LPM(ADDR) __load_program_memory ((const unsigned char
__flash *)ADDR)就更方便了,直接使用数据就可以了。

例:

#i nclude
#i nclude
#i nclude
void main(void)
{
PORTB=__LPM(0x12);// 从指定flash 空间地址单元0x12中读数据
}
__extended_load_program_memory(const unsigned char __farflash *);
//128K空间_ELPM(ADDR); //128K空间

参照上面的理解修改可以书写更简单。

4.6.自编程函数:

_SPM_GET_LOCKBITS();//读取缩定位
_SPM_GET_FUSEBITS();//读取熔丝位
_SPM_ERASE(Addr);//16位页擦除
_SPM_FILLTEMP(Addr,Word);//16位页缓冲
_SPM_PAGEWRITE(Addr;)//16位页写入
_SPM_24_ERASE(Addr); //24位页擦除
_SPM_24_FILLTEMP(Addr,Data); //24位页缓冲
_SPM_24_PAGEWRITE(Addr) //24位页写入

IAR for AVR 学习笔记(5)--SRAM操作

SARM数据类型的具体操作方法

SARM空间是AVR单片机最重要的部分,所有的操作必须依赖该部分来完成。变量在SARM空间的存储模式有tiny ,small large 三种,也就是对应于__tiny, __near __far三中存储属性。一旦选择为哪种存储模式,对应的数据默认属性也就确定了,但可以采用__tiny, __near __far关键字来更改。

对于程序中的局部变量,编译器会自动处理的,我们也不可能加什么储存属性,但IAR提供了强大的外部变量定义。

5.1.定义变量在工作寄存器

IAR编译器内部使用了部分工作寄存器,留给用户的只有R4-R15供12个寄存器供用户使用,要使用工作寄存器必须在工程选项里打开锁定选项。

例:

定义两个变量使用工作寄存器R14,R15。

#i nclude
__regvar __no_init char g @ 15;
__regvar __no_init char P @ 14;
void main(void)
{
g++;
P++;
}

在工程选项里c/c++ complier>code里打开要使用的寄存器R14-R15。

 

编译结果就如下,看看是不是直接使用了寄存器做为数据应用

// 4 void main(void)
main:
CFI Block cfiBlock0 Using cfiCommon0
CFI Function main
// 5 { g++;
REQUIRE ?Register_R14_is_global_regvar
REQUIRE ?Register_R15_is_global_regvar
INC R15
// 6 P++; }
INC R14
RET

注意:定义在寄存器里变量不能带有初始值。最好不要使用超过9个寄存器变量,不然可能引起潜在的危险,因为建立库的时候没有锁定任何寄存器。

5.2.定义变量的绝对地址.没有特性的变量是随机分配的,要给变量分配地址必须加以特性修饰注意在定义地址的时候千万不要和片内寄存器地址重合了。[page]

5.2.1定义没有存储特性的绝对地址变量必须加__no_init 或者const对象特性

__no_init char t @ 0x65;//定义在I/O地址以外
const char t @ 0x65;//定义只读变量的地址

例:

#i nclude
__no_init char u @ 0x65 ;
void main(void)
{u++;}

对应汇编:

void main(void)
main:
{u++;}
00000000 E6E5 LDI R30, 101
00000002 E0F0 LDI R31, 0
00000004 8100 LD R16, Z
00000006 9503 INC R16
00000008 8300 ST Z, R16
0000000A 9508 RET

5.2.2带存储特性的关键字定义变量的绝对地址__io,__ext_io定义变量在i/o空间

#i nclude
__io char u @ 0x65 ;
void main(void)
{u++;}

对应汇编:

void main(void)
main:
{u++;}
00000000 91000065 LDS R16, 101
00000004 9503 INC R16
00000006 93000065 STS 101, R16
0000000A 9508 RET

从5.2.1和5.2.2对比,发现用5.2.2方法定义代码小多了。

5.3.关键字volatile保证从最原始的位置读取变量。在IAR编译器里,除了__no_init和__root定义的变量外,其他的类型的变量都包含有volatile和__no_init特性

IAR for AVR 学习笔记(6)--中断及相关函数操作

6.1.中断函数:

在IAR编译器里用关键字来__interrupt来定义一个中断函数。用#pragma vector来提供中断函数的入口地址

#pragma vector=0x12//定时器0溢出中断入口地址
__interrupt void time0(void)
{
;
}

上面的入口地址写成#pragma vector=TIMER0_OVF_vect更直观,每种中断的入口地址在头文件里有描述。函数名称time0可以为任意名称。中断函数会自动保护局部变量,但不会保护全局变量。

6.2.内在函数也可以称为本征函数

编译器自己编写的能够直接访问处理器底层特征的函数。在intrinsics.h中有描述完整类型在comp_a90.h里有进一步的简化书写方式

6.2.1延时函数,以周期为标准

__delay_cycles(unsigned long );

如果处理器频率为1M,延时100us,如下:

__delay_cycles(100 );

当然你也可以对该函数进行修改:

#define CPU_F 1000000
#define delay_us (unsigned long) __delay_cycles((unsigned long )*CPU_F)
#define delay_ms (unsigned long) __delay_cycles((unsigned long )*CPU_F/1000)

6.2.2中断指令

__disable_interrupt( );//插入CLI指令, 也可以用_CLI();也可以SREG_Bit7=0;
__enable_interrupt( );// 插入SEI指令,也可以用_SEI();也可以SREG_Bit7=1;

其实对于状态字的置位和清零只有BSET S 和BCLR S两条指令。像SEI不过是BSET 7;的另一个名字而已。AVR指令中还有很多类似的现象,如:ORI 和 SBR 指令完全一样,号称130多条指令的AVR其实没有那么多指令的。

6.2.3从FLASH空间指定地址读取数据

__extended_load_program_memory(unsigned char __farflash *);
__load_program_memory(unsigned char __flash *);

该条指令以及正确的使用方法在4.5.flash 操作宏函数里详细讲解,这里不再重复

6.2.4乘法函数

__fracdtional_multiply_signed(signed char, signed char);
__fractional_multiply_signed_with_unsigned(signed char, unsigned char);
__fractional_multiply_unsigned(unsigned char, unsigned char);
//以上为定点小数乘法
__multiply_signed(signed char, signed char);//有符号数乘法
__multiply_signed_with_unsigned(signed char, unsigned char);
//有符号数和无符号数乘法
__multiply_unsigned(unsigned char, unsigned char);//无符号数乘法

6.2.4 半字节交换指令

__swap_nibbles(unsigned char);

6.2.5 MCU控制指令

__no_operation();//空操作指令
_NOP();
__sleep();//休眠指令
_SLEEP();
__watchdog_reset();//看门狗清零
_WDR();

IAR for AVR 学习笔记(7)--头文件含义

avr_macros.h里面包含了读写16位寄存器的简化书写,和几个位操作函数

comp_a90.h对大量的内在函数做了简要书写

ina90.h包含"inavr.h" "comp_A90.h"文件

intrinsics.h内在函数提供最简单的操作处理器底层特征。休眠,看门狗,FLASH函数。

iomacro.H I/O寄存器定义文件样本。

iom8.h 包含I/O等寄存器定义

IAR for AVR 学习笔记(8)--汇编嵌入方式

嵌入汇编语言

在线汇编:使用asm或者__asm,推荐使用__asm。

#i nclude
void main()
{
   asm("NOP "
       "CLH "
       "OR R16,R17 ");
}

不过IAR提供了完全可以访问底层的函数,建议不要频繁使用汇编

关键字:IAR学习  学习笔记 引用地址:【IAR学习】学习笔记

上一篇:按键程序 PORT中断程序
下一篇:系统时钟初始化需要注意的问题

推荐阅读最新更新时间:2024-03-16 14:38

W801单片机学习笔记——SDK中一些难以理解的地方及修改意见
1.前言 W801单片机配套的SDK功能非常丰富,内置了FreeRTOS嵌入式实时操作系统,LWIP网络通讯协议栈以及HTTP、MQTT等等应用层的通讯协议,从宏观上来看,开发起来感觉得心应手。但是在使用中,确实有不少地方想吐槽一下,也想违抗纪律修改一下SDK中的部分文件,嗯,然后真这么做了,哈哈哈。 SDK下载连接如下(百度云): 链接:https://pan.baidu.com/s/1nN4M4OZhPb8Upxpmlyneqg 提取码:SYHT FreeRTOS和Fatfs修改均修改中间层的文件,具体修改参考MDK的CMSIS软件包和STM32的HAL固件包。 该篇文章会随着后期不断学习的深入而增加内容,此
[单片机]
W801单片机<font color='red'>学习</font><font color='red'>笔记</font>——SDK中一些难以理解的地方及修改意见
汇编入门学习笔记 (七)—— dp,div,dup
疯狂的暑假学习之 汇编入门学习笔记 (七) dp,div,dup 参考: 《汇编语言》 王爽 第8章 1. bx、si、di、和 bp 8086CPU只有4个寄存器可以用 中进行单元寻址。 bp:除了默认的段地址是ss,其他与bx一样。 它们所有正确的组合 mov ax, mov ax, mov ax, mov ax, mov ax, mov ax, mov ax, mov ax, mov ax, mov ax, mov ax, mov ax, 注意:bx与bp不可以同时使用,如 是错误的。 2. 指明要
[单片机]
STM32学习笔记一一ADC
1.STM32 ADC 简介 STM32 拥有 1~3 个 ADC(STM32F101/102 系列只有 1 个 ADC),这些 ADC 可以独立使用,也可以使用双重模式(提高采样率)。 STM32 的 ADC 是 12 位逐次逼近型的模拟数字转换器。它有 18 个通道,可测量 16 个外部和 2 个内部信号源。各通道的 A/D 转换可以单次、连续、扫描或间断模式执行。 ADC 的结果可以左对齐或右对齐方式(12位)存储在 16 位数据寄存器中。 模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。 STM32 的 ADC 最大的转换速率为 1Mhz,也就是转换时间为 1us(在 ADCCLK=14M,采样
[单片机]
STM32<font color='red'>学习</font><font color='red'>笔记</font>一一ADC
STM32NET学习笔记 UDP部分
1.前言 嵌入式以太网开发是一个很有挑战性的工作。通过几个月的学习,我个人觉得大致有两条途径。第一条途径,先通过高级语言熟悉socket编程,例如C#或C++,对bind,listen,connect,accept等函数熟悉之后,应用 lwIP。第二种途径,通过分析嵌入式以太网代码,结合TCPIP协议栈规范逐步实践代码。第一种途径效率高,开发周期短,编写出来的代码性能稳定,第二种途径花的时间长,开发出来的代码功能不完善,但是由于紧紧结合TCPIP规范,可以了解的内容较多,适合学习。本文通过分析和修改AVRNET源码,逐步实现TCPIP协议栈的各个子部分,包括ETHERNET部分,ARP部分,IP部分,ICMP部分,UDP部分
[单片机]
51单片机学习笔记:红外接收
正点原子的ALIENTEK遥控器 用户码00ff 16进制键值码表 45 46 47 44 40 43 07 15 09 16 19 0d 0c 18 5e 08 1c 5a 42 ☻ 4a 红外接收管 通用型即可 --------------------------------------------------------------------------- 下面是类似的波形图,这个是网上找的,图片较大,缩小后看上去有些模糊,不过没关系,数据手册上一般都有 遥控器在发射红外信号之前,我们的mcu已经开启了定时器 在定时器中断函数中的全局变量irTimeCounts++ 一
[单片机]
51单片机<font color='red'>学习</font><font color='red'>笔记</font>:红外接收
C51单片机学习笔记(二)——花样流水灯的实现
1.单片机引脚、晶振、复位的作用 复位电路:,复位是单片机的初始化操作。单片机启动时都需要先付薇,其作用是“清零”,也就是CPU和其他部件处于一个确定的初始状态,并从这个初始状态开始。 复位实质上是单片机的复位脚保持很短时间的高电平,按键复位就是通过按键接高电平(按一下的时间已经足够) 时钟电路(晶振):产生时间信号,使单片机按照一定的时间规律进行指令,晶振频率越高,时钟信号的周期就小,单片机运行也就越快。 32个I/O口 P1.0 ~ P1.7 对应1 ~ 8 号引脚 P2.0 ~ P2.7 对应21 ~ 28 号引脚 P3.0 ~ P3.7 对应10 ~ 17 号引脚 P0.0 ~ P0.7 对应39
[单片机]
C51单片机<font color='red'>学习</font><font color='red'>笔记</font>(二)——花样流水灯的实现
MSP430F5529 DriverLib 库函数学习笔记(五)定时器A
平台:Code Composer Studio 10.3.1 MSP430F5529 LaunchPad™ Development Kit (MSP‑EXP430F5529LP) 硬知识 定时器A具有如下特点:  4种运行模式的异步16位定时/计数器;  参考时钟源可选择配置;  高达7个可配置的捕获/比较寄存器;  可配置的PWM输出;  异步输入和输出锁存;  具有可对Timer_A中断快速响应的中断向量寄存器。 定时器A的结构框图如图所示。 定时器A 16位定时器原理 16位定时器的计数值寄存器TAR在每个时钟信号的上升沿进行增加/减少,可利用软件读取TAR寄存器的计数值。此外,当
[单片机]
MSP430F5529 DriverLib 库函数<font color='red'>学习</font><font color='red'>笔记</font>(五)定时器A
I.MX6Q(TQIMX6Q/TQE9)学习笔记——新版BSP之网卡驱动移植
由于对网卡这块不是很熟悉,误以为网卡驱动也可以简单的配置下DTS就可以正常工作了,实际移植中遇到了些问题。闲话少说,下面开始tqimx6q的网卡驱动移植。 DTS编写 首先在我们的DTS中添加网卡配置,参考sabrelite的DTS,我们可以如下编写: &fec { pinctrl-names = default ; pinctrl-0 = &pinctrl_enet_1 ; phy-mode = rgmii ; status = okay ; }; 开始以为添加以上内容后编译并烧写DTB就可以正常工作了,实则不然,还需要添加PHY相关的配置代码。 PHY配置 打开arch/arm/mach-imx
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved