MSP430单片机深入学习笔记_第1页
MSP430单片机深入学习笔记_第2页
MSP430单片机深入学习笔记_第3页
MSP430单片机深入学习笔记_第4页
MSP430单片机深入学习笔记_第5页
免费预览已结束,剩余11页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、复位1. P0R信号只在两种情况下产生: ? 微处理器上电。? RST/NMI管脚被设置为复位功能,在此管脚上产生低电平时系统复位。2. PUC信号产生的条件为:?POR信号产生。?看门狗有效时,看门狗定时器溢出。?写看门狗定时器安全健值出现错误。?写FLASH存储器安全键值出现错误。PUC信号。而PUC信号不会引起POR信号的产3. P0R信号的出现会导致系统复位,并产生 生。系统复位后(POF之后)的状态为: ?RST/MIN管脚功能被设置为复位功能。? 所有I/O管脚被设置为输入。外围模块被初始化,其寄存器值为相关手册上注明的默认值。状态寄存器(SR复位。看门狗激活,进入工作模式。程序计

2、数器(PC载入OxFFFE ( OxFFFE为复位中断向量)处的地址,微处理器从此地 址开始执行程序。4. 典型的复位电路有以下3种:(a)rMSP430LOOkulRST/1NMw ijJir i ookQ nOJpFMSP430RsrrNMi(C)图Id典型复位电路(1) 由于MSP430具有上电复位功能,因此,上电后只要保持 RST/NMI(设置 为复位功能)为高电平即可。通常的做法为,在RST/NMI管脚接100k? 的上拉电阻,如图 1-5(a)所示。(2) 除了在 RST/NMI管脚接100k?的 上拉电阻外,还可以再接0.1卩F的电 容,电容的另一端接地,可以使复位更 加可靠。如

3、图1-5 (b)所示。由于MSP430具有极低的功耗,如 果系统断电后立即上电,则系统中电 容所存储的电荷来不及释放,此时系 统电压不会下降到最低复位电压以下, 因而MSP430不会产生上电复位, 同时 RST/NMI管脚上也没有足够低的电平 使MSP43C复位。这样,系统断电后立 即上电,MSP430并没有被复位。为了 解决这个问题,可增加一个二极管,这 样断电后储存在复位电容中的电荷就 可以通过二极管释放,从而加速电容 的放电。二极管的型号可取1N4008。如图1-5 (c)所示。系统时钟振荡器 :1. DC0数控RC振荡器,位于芯片内部。不用时可以关闭2. LFXT1 可以接低频振荡器,

4、典型的如 32.768kHz 的钟表振荡器,此时振荡器不需要接负 载电容。也可以接 450kHz8MHz的标准晶体振荡器,此时振荡器需要接负载电容。3. XT2接450kHz8MHz的标准晶体振荡器,此时振荡器要接负载电容,不用时可 以关闭。通常低频振荡器用来降低能量消耗, 例如使用电池的系统。 高频振荡器用来对事件作出 快速反应或者供 CPU进行大量运算。DCO勺振荡频率会受周围环境温度和MSP430工作电压的影响而产生变化,并且同一型号的芯片所产生的频率也不相同。DCO勺调节功能可以改善它的性能。DC0 的调节分为以下 3 步:(1) 选择BCSCTL1.RSEL)确定时钟的标称频率。(2

5、) 选择DCOCTL.DCO在标称频率基础上分段粗调。(3) 选择DCOCTL.MOD的值进行细调。MSP430定义了 3种时钟信号,分别为:(1) MCLK系统主时钟。除了 CPU运算使用此时钟信号外,外围模块也可以使用。MCLK可以选择任何一个振荡器产生的时钟信号并进行1、2、4、8分频作为其信号源。(2) SMCLK 系统子时钟。外围模块可以使用,并且在使用之前可以通过各模块的寄存器实现分频。SMCLK可以选择任何一个振荡器产生的时钟信号并进行1、2、4、8分频作为其信号源。(3) ACLK 辅助时钟。外围模块可以使用,并且在使用之前可以通过各模块的寄存器 实现分频。ACLK只能由LFX

6、T1进行1、2、4、8分频作为其信号源。PUC结束时,MCLK和SMCLK的信号源为DCO, DCO的振荡频率约为 800kHz (详见 相关手册)。ACLK的信号源为LFXT1。例 3.4 设置 MCLK 的时钟8 分频。下列 4条代码均可实现该功能。BCSCTL2 |= 0x30;BCSCTL2 |= BIT5+BIT4;BCSCTL2 |= DIVM1+DIVM0;/ 人肉记忆 +数脚趾头,原始社会才干的事!/需记忆DlVMx在BSCTL中的位置,不推荐!/ 由两项组成,看起来不直观,凑合!/ 简洁明了,力荐!BCSCTL2 |= DlVM_3;在使用按位或操作符“ |= ”配置寄存器时

7、,要注意宏定义之间的“叠加”效应。重新用 宏定义配置寄存器前,一定要先清零。 (此外,极少数寄存器上电复位后默认值不是 0,要 特别注意。) 例 3.5 先设定 MCLK 分频为 2,一段时间后改为 4 分频。错误的代码:BCSCTL2 |= DlVM_1; /这确实是 2 分频delay( );BCSCTL2 |= DlVM_2; /因为|=赋值的原因,这实际上是 8 分频,请自行面壁想清楚正确的代码:BCSCTL2 |= DIVM_1;/ 2 分频delay();BCSCTL2 &= ( DIVM_O+ DIVM_1+ DIVM_2+ DIVM_3); / 预先把全部相关控制位置

8、0BCSCTL2 |= DIVM_2;/此时再用|=设置才不出错相关控制位全置 0还可写成:BCSCTL2 &= DIVM_3 或 BCSCTL2 &=(DIVM0+DIVM1)低功耗模式上电和外部复位信号产生 POR信号,POR信号会引起PUC信号。看门狗激活时,定时器 溢出和安全键值错误也会引起PUC信号。PUC信号结束后,MSP430进入AM状态。在AM状态程序可以选择进入任何一种低功耗模式,然后在适当的时机,由外围模块的中断使 CPU退出低功耗模式。LPM0 (主力休眠,先头部队工作)和LPM3(主力和先头部队都休眠,仅留警戒哨兵)最常用,LPM4则当关机使用。洁动膜式

9、 CPU葫动CPUOf! =1SCO 匸 IKSL'NMl MM J有妆cpuoFr-iSCGO-GSCGI-I/ I PM3、CPU off, MCLKwffSMCLK DCOofT ACLKCPUofT* MCLK oil SM(DCQ otT_A-CLK 卞LPMD 宀、 cpu oiTt mclk otr SMCI.K - ACLK onkI.PMI J CPU olT, MCI K oH' SMCLK , ACLK orPORWDT(FOIWOT柄动RXT/1SIMI 蚁®冇敘k wnr 动 f 定时瞩时的到,溢出RSTMl为灵位功繼如皋【览o在活动模式中没

10、 自使用I则厲龙牛略天阳CPV0FF-I OSCOFF-1SCGO=1SCC I-1K'遂性器尺闭WD JPG-If.in=i LPM 2CPU oR; MCLKofl SMCLK otl; Lxru oil .ACLKonertrorr-1 SCG0= IlSCCJI-0MO工作模式转换中断MSP430可以在没有事件发生时进入低功耗状态,事件发生时,通过中断唤醒CPU,事件处理完毕后,CPU再次进入低功耗状态。MSP430 的中断分为:系统复位、不可屏蔽中断、可屏蔽中断。系统复位前面已经作过介绍,其中断向量为OxFFFE不可屏蔽中断向量为 OxFFFC产生不可屏蔽中断的原因如下:(1

11、) RST/NMI管脚功能选择为 NMI时,RST/NMI管脚上产生一个上升沿或者下降沿(具 体是上升沿还是下降沿由寄存器WDTCTL中的NMIES位决定)。NMI中断可以用 WDTCTL中的NMIIE位屏蔽。需要注意的是,当RST/NMI管脚功能选择为 NMI时,不要让 RST/NMI管脚上的信号一直保持在低电平。原因是如果发生了PUC,则RST/NMI管脚的功能被初始化为复位功能,而此时它上面的信号一直保持低电平,使CPU 一直处于复位状态,不能正常工作。(2)振荡器失效中断允许时,振荡器失效。(3) FLASH存储器的非法访问中断允许时,对FLASH存储器进行了非法访问。 不可屏蔽中断可

12、由各自的中断允许位禁止或打开。当一个不可屏蔽中断请求被接受时,相应的中断允许位自动复位。 退出中断程序时, 如果希望中断继续有效, 则必须用软件将相 应中断允许位置位。中断使用的步骤:1)配置子模块中断相关的寄存器,比如外部中断的上升沿触发还是下降沿触发,定 时中断的计数方式和定时值。2)依模板写中断服务子函数框架,添加中断后要干什么的代码(事件处理函数)。3)使能子模块的中断,使能总中断。4)一旦中断发生, CPU 停下主函数的活, 并标记位置。 进入中断服务子函数里干活, 完事后回到主函数标记位置处继续干活。我们来看 MSP430 的中断子函数模板, 加粗斜体部分是允许用户 “创意” 的地

13、方, 其他 则是固定格式。其中,PORT1_VECTOF是中断向量表中的地址宏定义,直接决定了这个中断子函数是响应哪个中断源。PORT1_ISR是中断子函数名,这个最好按标准写法取名字,便于理解。中断向量表和标准的中断子函数名可见头文件<MSP430G2553.h>。在 MSP430 单片机中,中断资源是比较“宝贵的” ,很多中断都是共用一个“中断向量 入口”。比如上面写的是 P1 口的中断服务子函数, 当 P1 的 8 个 IO 口任何一个检测 到中断事件(上升沿或下降沿) ,就会进入中断子函数。我们需要在子函数里,查询中断标志 位#pragma vector = PORT1_V

14、ECTOR_interrupt voidPORT1_ISR(void)/中断后想干的事写这里 ;LaunchPad 口袋实验平台 MSP-EXP430G2 篇50(特殊功能寄存器),判断一下到底是哪个10 口 “出事”了。&按位与,1按位或,A按位异或AND (位与&) 0R (位或| ) XOR ( 位异或a )1 & 1 =11 11 1 =11 A 1 =01 & 0 =01 11 0 =11 A0 =10 & 1 =00 11 1 =10 A1 =10 & 0 =00 11 0 =00 A0 =0C语言提供的位运算符列表:运算符含义描述&

15、amp;按位与如果两个相应的二进制位都为1,则该位的结果值为1,否则为0|按位或两个相应的二进制位中只要有一个为1,该位的结果值为1A按位异或 若参加运算的两个二进制位值相同则为0,否则为1取反是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0<<左移用来将一个数的各二进制位全部左移N位,右补0>>右移 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0写位操作:在对某字节使用“=”进行写操作时,所有位的值都将被改变。 如果先将原字节读出来, 再使用“按位”操作符对原字节进行赋值,则可“等效”实现对单个位的写操作。将P1.0置1、P1

16、.1置0、P1.2取反,不影响其他位。P10UTF 0x01;P1OUT |= BIT0;/ “按位或”,相当于 置 1P1OUT&= 0x02; P1OUT &= BIT1/取反后再“按位与”,相当于 置0P1OUTA= 0x04; P1OUT a= BIT2/ “按位异或”,相当于 取反也可以用加号对多位同时操作。将P1.0、P1.1、P1.2均置1,不影响其他位。P1OUT |= BIT0+BIT1+BIT2;/可用加法进行批量设置读位操作:读位操作主要是通过if语句判断的方法得到的。同样,这种变通的办法不意味着MSP430单片机可以对位进行读取,这种方法同样需要对1个字

17、节的8位都操作。Eg:将P2.0的输出设置成与 P1.1输入相反,读取P1.0状态到变量 Tempoun sig ned char Temp=0;if(P1IN&BIT1)=0)P2OUT |= BIT0; / 读 P1.1 写 P2.0elseif(P1IN&BIT0)elseP2OUT &= BIT0;Temp=1;/ 读 P1.0 写 TempTemp=0;寄存器配置小结1)一般情况下,均使用宏定义去配置寄存器,这样做省事省力,可读性好。2) 深刻理解“ |=”对寄存器赋值的效果,先清0后赋值,避免误操作。3) 提前查阅头文件,尽量使用组合宏定义配置寄存器。4)

18、对于由变量决定的寄存器配置,应使用移位后的变量直接赋值。文件管理什么是文件管理?就是不要在 main.c 中写下所有的代码,而应该将大的程序划分为小的 c 文件。1) 1 个 main.c 写下全部代码是最容易导致“亲妈都认不出来”的情况。2) 我们从一个初学者开始,陆陆续续会调试各种片内和片外的设备,会积累各种各样 的代码。不管是敝帚自珍还是独孤求败,重复写同样的代码总是令人身心疲惫的事 情。3) 初学者最容易想到的是事后用复制粘贴的方法利用原代码,这是非常效率低下而且 容易出错的。4) 正确的做法是,当我们写代码的时候,先就考虑这段代码有没有可能在别的地方能 用到,然后分开独立写 c 文件

19、,这样就可以有效准确利用原有代码。 如何有效进行文件管理呢?1) 按功能模块划分 c 文件,比如片内的时钟、定时器、 UART 收发器、 Flash 控制器、 ADC 模数转换器、片外的 12864 液晶、矩阵键盘,可以分别设为System_clock.c、Timer_A.c 、 UART.c、 Flash.c、ADC10.c、 LCD.c、 Key.c。2) 将隶属于各模块的代码函数都放进各自的 c 文件中。3) 建立与 c 文件同名的 h 头文件,在 h 文件中声明可能被调用到的函数。4) 在 main.c 中包含 h 头文件,就可以使用外部 c 文件中的函数了。例 3.8 建一个 Mot

20、or.c 文件,在里面编写一个启动电机函数 Motor_ON( ) 和一个停止电 机 函数 Motor_OFF( ) ,并编写头文件。Motor.c 文件void Motor_ON( )P1OUT |=BIT0;void Motor_OFF ()P1OUT &=BIT0;Motor.h 文件extern Motor_ON( );extern Motor_OFF ( );有些编译器支持直接在 h 头文件中写程序代码。无论编译器是否支持,都不建议这样 做,分开写 c 文件和 h 头文件可以让复杂程序的代码更易读,我们后面会再谈这个问题。系统时钟void BCSplus_init(void)

21、BCSCTL2 = SELM_0 + DIVM_0 + DIVS_0; / 复位默认值,此行代码可省略if (CALBC1_1MHZ != 0xFF) DCOCTL = 0x00;BCSCTL1 = CALBC1_1MHZ; /* Set DCO to 1MHz */DCOCTL = CALDCO_1MHZ;BCSCTL1 |= XT2OFF + DIVA_0; / 复位默认值,此行代码可省略BCSCTL3 = XT2S_0 + LFXT1S_2 + XCAP_1/; 设为内部低频振荡器 直接配置 System Clock前面我们学习了如何用 Grace 配置时钟,其实对 MSPG2553 单

22、片机来说, MCLK 和SMCLK基本就是使用 DCO(没外部高频晶振可用)。有32.768kHz手表晶振,则 ACLK选 32.768Hz,没有就选12kHz的VLO。所以,直接代码配置时钟也很方便, 直接调用 DCO出 厂校验参数即可。例 4.1 将 MSP430G2553 的时钟设置为 MCLK 和 SMCLK 均为 8MHz, ACLK 设为 32.768kHz。DCOCTL = CALDCO_8MHZ;/ 调取出厂校准后存储在 Flash中的参数BCSCTL1 = CALBC1_8MH Z;/ BCSCTL3 参数默认不用设例 4.2 将 MSP430G2553 的时钟设置为 MCL

23、K 和 SMCLK 均为 16MHz, ACLK 设为内部低 频振荡器。DCOCTL = CALDCO_16MHZ; / 调取出厂校准后存储在Flash中的参数BCSCTL1 = CALBC1_16MHZ;BCSCTL3 |= LFXT1S1;/ 设为内部低频振荡器例 4.3 将 MSP430G2553 的时钟设置为 MCLK 和 SMCLK 均为 16MHz, ACLK 设为使用 32.768kHz 晶振且 4 分频。DCOCTL = CALDCO_16MHZ;II 调取出厂校准后存储在 Flash中的参数BCSCTL1 = CALBC1_16MHZ;BCSCTL1 |= DIVA_2;II

24、 补充修改 BCSCTL的 DIVAx 位,4 分频例 4.4 将 MSP430G2553 的时钟设置为 MCLK4MHz, SMCLK 为 2MHz, ACLK 设为使用 32.768kHz 晶振。DCOCTL = CALDCO_8MHZ;II 先设为 8MHzBCSCTL1 = CALBC1_8MHZ;BCSCTL2 |= DIVM_1+DIVS_2;II 再对 MCLK2 分频 , SMCLK4 分频中断服务函数P0RT1_ISR属于中断服务子函数,由“ vector = PORT1_VECTO”中断向量调用, 而与函数名“ PORT1_ISR”本身无关。虽然无论 取什么函数名称都行,但

25、是建议按照 MSP430G2553.h 头文件中定义的中断服务子函数名称来命名 , 可在头文件中, 查看 “Interrupt Vectors (offset from 0xFFE0) ”部分。程序进入中断服务子函数并不是万事大吉,一般需要考虑以下几件事情:1) 由于中断向量远比中断源少得多,所以大部分中断事件都是“共用”中断服务子函 数。往往具体中断事件还需查询中断标志位来进一步确认。2) 有些时候,不仅要查询标志位,而且还要复杂的运算和判断才能确认中断事件,这 就需要使用专门的“事件检测函数”来完成。3) 使用“事件检测函数”可以将代码“移出”中断服务子函数“集中放置”便于阅读 ,因为中断

26、服务子函数内编写大段代码是编程“大忌” ,非常容易造成“连亲妈都 认不出来”。 此外“事件检测函数”也增强了代码的可移植性,因为事件检测的判 据往往可以重复使用。4) 一旦中断事件被“确认” ,事件应对代码宜专门编写“事件处理函数” ,而不应在 中断子函数中直接写代码。 “事件处理函数”可以在“事件检测函数”中调用。5) 最后,弄清楚是否需要手动清除中断标志位。很多中断标志位必须手动清除,否则 程序将会出现各种“无名肿痛” 。*名 称: PORT1_ISR()* 功 能:响应 P1 口的外部中断服务* 入口参数:无* 出口参数:无* 说 明:P1.0P1.8共用了 P0RT1中断,所以在 P0

27、RT1_ISR(中必须查询标志位 P1IFG才 能知道具体是哪个10引发了外部中断。P1IFG必须手动清除,否则将持续引发 P0RT1中断。* 范 例:无*/#pragma vector = P0RT1_VECT0R_interrupt void P0RT1_ISR(void) / 启用 Port1 事件检测函数 P1_I0Dect();/ 检测通过,则会调用事件处理函数P1IFG=0;/退出中断前必须手动清除10 口中断标志事件检测函数P1_IODect()就是上文提到的“中断事件检测函数”,专门用于判断是P0RT1的哪个10发生了中断(按键被按下) 。这里我们同样先不去考虑具体代码原理是什

28、么,总之这个函数 正确实现了按键 I0 的判断,并且调用了相应按键的“事件处理函数” 。/* 名 称: P1_I0Dect()*功 能:判断具体引发中断的10,并调用相应10的中断事件处理函数* 入口参数:无* 出口参数:无*说明:该函数兼容所有8个10的检测,请根据实际输入10激活“检测代码”。* 本例中,仅有P1.3被用作输入10,所以其他7个10的“检测代码”没有被“激活”。* 范 例:无*/void P1_I0Dect()unsigned int Push_Key=0;/-排除输出10的干扰后,锁定唯一被触发的中断标志位-Push_Key=P1IFG&(P1DIR);/ 延时一

29、段时间,避开机械抖动区域 _delay_cycles(10000);/ 消抖延时/ 判断按键状态是否与延时前一致 -if(P1IN&Push_Key)=0)/如果该次按键确实有效/-判断具体哪个10被按下,调用该10的事件处理函数-switch(Push_Key) /case BIT0:P10_Onclick();break;/case BIT1:P11_Onclick();break;/case BIT2:P12_Onclick();break;case BIT3:P13_Onclick();break;/cas e BIT4:P14_Onclick();break;/case BI

30、T5:P15_Onclick();break;/case BIT6:P16_Onclick();break;/case BIT7:P17_Onclick();break;default:break;/ 任何情况下均加上 default事件处理函数“事件处理函数” 对于读懂程序代码非常重要, 这意味着我们知道了一旦发生了某某事 件,将要干什么。所有的“事件处理函数”加上 main()函数,基本上就能读出程序的意图和 思想了。 在程序移植中,“事件处理函数” 的内容往往是需要改变的。 例如, P1.3 按键的“事 件检测函数”可能无需改变,检测的判据方法是一样的。神奇的 GPIO内部电阻在 IO

31、处于输出状态是无法固定为上拉的 (输出高电平时为上拉, 输出低电平 时为下拉)。使用捕获模块的一般步骤:1) 把主定时器设为连续计数模式,这样就有最长的“刻度尺”可用。当“尺子”长度还不够的时候,可以设定尺子每溢出1次,中断服务给全局变量Cou nt+1,这样就能测量任意时间长度了。2) 把CCRx模块对应的寄存器 CAP设为1,捕获模式。3) 选择CCRx模块的捕获源寄存器 CCISx也就是具体单片机哪个管脚作为捕获输入口CCIx4) 设定CMx寄存器,决定是上升沿捕获还是下降沿,还是上升下降都捕获。5) 设定SCS寄存器,决定是同步捕获还是异步捕获。咋一看起来,异步捕获响应要快,但是捕获后

32、的有效数据是来自定时器的计数值,响应再快也超不过时钟的分辨率。所以一般均设为同步捕获,这样可以减小电路毛刺,避免竞争冒险。6) 标志位 COV为1代表上次 TACCRx的数据没被取走,而又新来数据覆盖了TACCRx的异常情况。前面提到的“爱什么时候读什么时候去读TACCRx说的有些夸张,不能等下次捕获来临还不读取上次的捕获数据。表62 Timer_A比较模块的8中输出模式OUTMODx镣出腹式描述000 (模式“电半输出TAx管脚由OUTx位决定高低电平001 f模式1、延迟置位当主计数器计TACCRx时.TM管脚置1010 (模式2取反/清零当主计数器计到TACCRX时.TA管脚取反 当主计

33、数器计到TACCRD时+ TAx管脚置0011 (模式3)置位/清零当主计数器计到TACCRx时.TAx管脚収1 当主计数器计到TACCRO时.TAx管脚置0100 (模式4)取反当主计数器计到TACCRx, 丁加管脚収反101 (模式5)延迟清零当主计数器计到TACCRx时.TAx管脚収0110 (模式G取反/置位当主计数器计到TACCRx时,丁加管脚収反 当主计数器计到TACCRD TAx管脚豐1111 (模式7)淸零/置位当主计数器计到TACCRx时.TAx管脚収0 当主计数器计到TACCRD时* TAx管脚置1模式 0:通过 CCRx 模块各自的 OUT 控制位控制 TAx 输出,像操作普通 IO 口那样。一般用于程序预设定 TAx 的电平。 模式 1 和模式 5:用于生成单稳态脉冲。模式3和模式 7:用于产生 PWM信号。PWM 的频率由 CCRO的TACCR0决定,PWM 的 占空比由 TACCRx与TACCR0的比值决定。模式 2 和模式 6:用于产生带死区时间控制的互补PWM。定时器 A 使用要点:1.时钟源及变化方式例TACTL = TASSEL_2 + MCJ其TASSE定义了时钟源 MC_x定义了 CCR计数器样变化(连续、循环等)注:仅此句会让定时器 A开始计

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论