物联网智能控制与管理教材_第1页
物联网智能控制与管理教材_第2页
物联网智能控制与管理教材_第3页
物联网智能控制与管理教材_第4页
物联网智能控制与管理教材_第5页
已阅读5页,还剩83页未读 继续免费阅读

下载本文档

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

文档简介

第3章单片机集成的典型资源及应用本章节主要内容3.1中断系统及其应用3.2定时/计数器及其应用

3.3串行通信接口及其应用3.4模数转换器及其应用3.1中断系统及其应用3.1.1中断源及中断结构3.1.2中断的允许、禁止及优先级3.1.3中断的编程举例3.1.1中断源及中断结构外部中断0(INT0)定时器0中断外部中断1(INT1)定时器1中断串口1中断A/D转换中断低压检测(LVD)中断PCA/CCP中断串口2中断SPI中断外部中断2()外部中断3()定时器T2中断外部中断4()STC15F2K60S2单片机的中断系统

中断源及中断结构外部中断0(INT0)和外部中断1(INT1)可以设置为下降沿触发中断,也可以设置为上升沿和下降沿都可以触发中断;定时器0和1的中断请求标志位是TF0和TF1。当定时器溢出时,溢出标志位TFx被置位,定时器中断发生;A/D转换的中断请求标志是ADC_FLAG,该位需用软件清0;低压检测(LVD)中断请求表示是LVDF,该位也需用软件清0;外部中断2、外部中断3及外部中断4只能下降沿触发;定时器2的中断请求标志位对用户不可见。当相应的中断服务程序执行后或ET2=0时,该中断请求标志位会自动地被清0;除外部中断2、外部中断3、定时器T2中断及外部中断4固定是最低优先级中断外,其它的中断都具有2个中断优先级,可实现两级中断服务程序嵌套。中断源及中断结构中断请求信号分别锁存在特殊功能寄存器TCON、SCON、S2CON、CCON、SPSTAT和ADC_CONTR中。下面分别介绍这些寄存器的定义和功能:定时/计数器T0和T1的控制寄存器TCON:地址为88H,复位值为00HIT0:外部中断INT0触发方式控制位。可由软件置1或清“0”;0:上升沿和下降沿均可触发外部中断。当INT0引脚出现上升沿或者下降沿平时,置位IE0。1:下降沿触发方式。INT0引脚上电平由高到低的负跳变时,置位IE0IE0:外部中断INT0请求标志。无论采取哪一种触发方式,只要满足了触发外部中断的条件,都会硬件置位IE0,并以此来向CPU请求中断。当CPU响应中断转向中断服务程序时,由硬件自动清“0”中断标志;IT1:外部中断INT1触发方式控制位,与IT0类似;IE1:外部中断INT1请求标志,其意义和IE0相同;TR0:定时/计数器T0启动/停止控制位,该位由软件置位和清零。当GATE=0,TR0=1启动T0开始计数,TR0=0时停止T0计数。当GATE=1,TR0=1且INT0输入高电平时,才允许T0计数;TF0:定时/计数器T0溢出中断标志,T0启动计数后,T0从初值开始加1计数,最高位产生溢出时,TF0由硬件置1,并向CPU请求中断,当CPU响应中断时,由硬件清零。TF0也可以由程序查询或清零;TR1:定时/计数器T1启动/停止控制位,含义和功能与TR0相似;TF1:定时/计数器T1的中断标志,含义和功能与TF0相似。中断源及中断结构串行口1控制寄存器SCON:地址为98H,复位值为00HRI:串行口1接收中断标志。RI为1表示串行口1接收器已经接收到数据,该数据放在接收缓冲区,向CPU申请中断,以便将接收到的数据转移到预先安排好的数据区,接收缓冲区准备接受下一个数据。RI必须由用户在中断处理程序中用指令清“0”;TI:串行口1发送中断标志。TI=1表示串行口发送器已经发送完一个数据,向CPU申请中断,以便发送下一个数据。TI必须由用户在中断处理程序中用指令清“0”;其他各位,与串行通信的方式、数据格式等选项设置有关,详细内容请参考“数据通信”一节的内容。

中断源及中断结构串口2控制寄存器S2CON:地址为9AH,复位值为00H

用于确定串口2的操作方式和控制串口2的某些功能,并设有接收和发送中断标志(S2RI及S2TI)位;S2TI和S2RI是串口2的发送中断标志和接收中断标志,与寄存器SCON对应位的含义和功能类似。中断源及中断结构电源控制寄存器PCON:地址为87H,复位值为30H与中断有关的位是LVDF。LVDF是低电压检测标志位,同时也是低电压检测中断请求标志位。在正常工作和空闲工作状态时,如果内部工作电压Vcc低于低电压检测门槛电压,低电压中断请求标志位LVDF自动置1,与低电压检测中断是否被允许无关。如果允许产生低电压检测中断,则在内部工作电压Vcc低于低电压检测门槛电压后,产生低电压检测中断

中断源及中断结构PCA控制寄存器CCON:地址为D8H,复位值为00xxx000BCF:PCA计数器溢出标志位。当PCA计数器溢出时,CF由硬件置位。如果CMOD寄存器的ECF位置位,CF标志可用来产生中断。CF位可通过硬件或软件置位,但只能通过软件清“0”;CCF2/CCF1/CCF0:PCA各个模块的中断标志。其中,CCF0对应模块0,CCF1对应模块1,CCF2对应模块2。当发生匹配或比较时由硬件置位相应的标志位。这些标志只能通过软件清除。在中断服务程序中,通过判断各个标志确定是哪个模块产生了中断。

中断源及中断结构SPI状态寄存器SPSTAT:地址为CDH,复位值为00xxxxxxBSPIF是SPI传输完成标志。当一次传输完成时,SPIF被置位。此时,如果SPI中断被允许,将产生中断。当SPI处于主模式且SSIG=0时,如果为输入并被驱动为低电平,SPIF也将置位,表示“模式改变”。SPIF标志通过软件向其写入“1”而清“0”;WCOL位的作用以及SPI模块的详细介绍请参见“串行通信接口及其应用”一节的内容

中断源及中断结构ADC控制寄存器ADC_CONTR:地址为BCH,复位值为00H与中断相关的位是A/D转换结束标志位ADC_FLAG。A/D转换完成后,ADC_FLAG=1。此时,若允许A/D转换中断,则由该位申请产生中断。也可以由软件查询该标志位判断A/D转换是否结束。不管是A/D转换完成后由该位申请产生中断,还是由软件查询该标志位A/D转换是否结束,当A/D转换完成后,ADC_FLAG=1,一定要软件清“0”3.1中断系统及其应用3.1.1中断源及中断结构3.1.2中断的允许、禁止及优先级3.1.3中断的编程举例3.1.2中断的允许、禁止及优先级1、中断的允许和禁止中断允许寄存器IE:地址为A8H,复位值为00HEA:中断允许总控制位0:禁止中断系统,所有中断源的中断请求均被禁止,称为关中断1:允许中断系统,所有中断源的中断请求均可以被允许,称为开中断;某一个中断源的请求是否允许,还要由该中断源所对应的中断允许控制位决定ELVD:低电压检测中断允许控制位。1:允许低电压检测中断;0:禁止低电压检测中断EADC:ADC中断允许控制位。1:允许ADC中断;0:禁止ADC中断ES:串行口1中断允许控制位。1:允许串行口1中断;0:禁止串行口1中断ET1:定时器1中断允许控制位。1:允许定时器1中断;0:禁止定时器1中断EXl:外部中断INT1中断允许控制位。1:允许外部中断1中断;0:禁止外部中断1中断ET0:定时器0中断允许控制位。1:允许定时器0中断;0:禁止定时器0中断EX0:外部中断源INT0中断允许控制位。1:允许外部中断0中断;0:禁止外部中断0中断中断的允许、禁止及优先级1、中断的允许和禁止中断允许寄存器IE2:地址为AFH,复位值为xxxxx000B,不能进行位寻址ET2:定时器2的中断允许位。1:允许定时器2产生中断;0:禁止定时器2产生中断ESPI:SPI中断允许控制位。1:允许SPI中断;0:禁止SPI中断ES2:串行口2中断允许控制位。1:允许串行口2中断;0:禁止串行口2中断中断的允许、禁止及优先级1、中断的允许和禁止外部中断使能和时钟输出寄存器INT_CLKO:地址为8FH,复位值为X0000000B,不能进行位寻址其中,EX4、EX3和EX2用于设置是否允许外部中断4、外部中断3和外部中断2冲断EX4:外部中断4()中断允许位。1:允许外部中断4中断;0:禁止外部中断4中断。外部中断4只能下降沿触发EX3:外部中断3()中断允许位。1:允许外部中断3中断;0:禁止外部中断3中断。外部中断3只能下降沿触发EX2:外部中断2()中断允许位。1:允许外部中断2中断;0:禁止外部中断2中断。外部中断2只能下降沿触发中断的允许、禁止及优先级1、中断的允许和禁止PCA比较/捕获寄存器CCAPMn(n=0,1,2,下同:地址分别对应DAH、DBH和DCH,复位值均为x0000000B)ECCFn:使能CCFn中断。此时,寄存器CCON的比较/捕获标志CCFn用来产生中断PCA工作模式寄存器(CMOD):地址为D9H,复位值为0xxx0000BECF:PCA计数器溢出中断使能位。ECF=1时,允许寄存器CCON中CF位的中断。ECF=0时,禁止寄存器CCON中CF位的中断 STC15F2K60S2单片机复位后,各中断允许寄存器控制位均被清“0”,即禁止所有中断。如果需要允许某些中断,可在程序中将相应中断控制位置为1。禁止某个中断源申请中断,也称为屏蔽某个中断源。欲使某中断源允许中断,必须同时使EA=1,即同时使CPU允许中断。所以EA相当于中断允许的“总开关”。中断的允许、禁止及优先级2、中断的优先级中断优先级寄存器IP:地址为B8H,复位值为00HPPCA:PCA中断优先级控制位1:PCA中断为高优先级;0:PCA中断为低优先级PLVD:低电压检测中断优先级控制位1:低电压检测中断为高优先级;0:低电压检测中断为低优先级PADC:ADC中断优先级控制位1:ADC中断为高优先级;0:ADC中断为低优先级PS:串行口1中断优先级控制位1:串行口1中断为高优先级;0:串行口1中断为低优先级PT1:定时器T1中断优先级控制位。1:定时器T1中断为高优先级;0:定时器T1中断为低优先级。PX1:外部中断优先级控制位。1:外部中断1中断为高优先级;0:外部中断1中断为低优先级。PT0:定时器T0中断优先级控制位。1:定时器T0中断为高优先级;0:定时器T0中断为低优先级。PX0:外部中断优先级控制位。1:外部中断0中断为高优先级;0:外部中断0中断为低优先级。

中断的允许、禁止及优先级2、中断的优先级第二中断优先级寄存器IP2:地址为B5H,复位值为xxxxxx00BPSPI:SPI中断优先级控制位1:SPI中断为高优先级;0:SPI中断为低优先级。PS2:串口2中断优先级控制位1:串口2中断为高优先级;0:串口2中断为低优先级

中断的允许、禁止及优先级2、中断的优先级同一优先级的中断源同时申请中断时,按照默认的优先级查询顺序响应中断,STC15F2K60S2单片机各中断默认的优先级如下表所示。其中,默认中断优先级次序号也称为中断号,其值越小,优先级越高。

3.1中断系统及其应用3.1.1中断源及中断结构3.1.2中断的允许、禁止及优先级3.1.3中断的编程举例3.1.3中断的编程举例使用C语言编写单片机中断应用程序时,用中断号区分每一个中断voidX0_ISR(void)interrupt0{} //外部中断0中断函数voidT0_ISR(void)interrupt1{} //定时器T0中断函数voidX1_ISR(void)interrupt2{} //外部中断1中断函数voidT1_ISR(void)interrupt3{} //定时器T1中断函数voidUART1_ISR(void)interrupt4{} //串行口1中断函数voidADC_ISR(void)interrupt5{} //ADC中断函数voidLVD_ISR(void)interrupt6{} //低电压检测LVD中断函数voidPCA_ISR(void)interrupt7{} //PCA中断函数voidUART2_ISR(void)interrupt8{} //串行口2中断函数voidSPI_ISR(void)interrupt9{} //SPI通信中断函数voidX2_ISR(void)interrupt10{} //外部中断2中断函数voidX3_ISR(void)interrupt11{} //外部中断3中断函数voidT2_ISR(void)interrupt12{} //定时器T2中断函数voidX4_ISR(void)interrupt16{} //外部中断4中断函数中断的编程举例清除中断请求信号的方法定时器/计数器T0、T1中断请求的撤除当CPU响应T0或T1的中断请求后,由硬件自动清除相应的中断请求标志TF0或TF1外部中断请求的撤除CPU响应外部中断0和外部中断1后,由硬件自动清除中断请求标志IE0和IE11串行口中断请求的撤除CPU响应串行口中断后,通过软件将串行口中断标志清“0”ADC中断请求的撤除ADC中断请求标志位ADC_FLAG不能自动清除,需要在ADC中断服务程序中用软件将其清“0”SPI中断请求的撤除SPI中断请求标志位SPIF不能自动清除,需要在SPI中断服务程序中用软件清“0”PCA中断请求的撤除PCA中断请求标志位CF/CCF0/CCF1/CCF2不能自动清除,需要在PCA中断服务程序中用软件将相应的标志位清“0”低电压检测中断请求的撤除低电压检测中断请求标志位LVDF不能自动清除,需要在低电压检测中断服务程序中用软件清“0”中断的编程举例【例3-1】利用INT0引入单脉冲,每来一个负脉冲,将连接到P0口的发光二极管循环点亮。发光二极管的连接方法如右图所示。解:利用INT0的下降沿触发中断。#include"stc15.h"//包含寄存器定义头文件unsignedchari=0x01;voidmain(void){ P0=0; IT0=1; EX0=1; EA=1; while(1); //循环等待}voidX0_ISR(void)interrupt0{ i<<=1; if(i==0)i=1; //移位8次后,i将变为0,因此需要重新赋值

P0=~i;}其中,RP1是1KΩ的排电阻。R5和C12起滤波作用中断的编程举例【例3-2】利用上升沿和下降沿均可触发中断的外部中断,可以检测脉冲跳变的次数,也可以检测按键的按下与弹起操作。下面的例子可以统计从INT1引脚输入脉冲的跳变次数。解:#include“stc15.h” //包含寄存器定义头文件unsignedcharp_cnt=0; //统计脉冲跳变次数变量voidmain(void){ IT1=0; //外部中断1为上升沿和下降沿均可触发的方式

EX1=1; //允许外部中断1 EA=1; //允许总的中断

while(1); //等待中断}voidX1_ISR(void)interrupt2 //外部中断1函数{

p_cnt++; //统计脉冲跳变次数}中断的编程举例【例3-3】外部中断2的使用。外部中断2~4的使用方法与外部中断0和1的使用方法类似,区别在于外部中断2~4只能是下降沿触发,并且,应注意开放中断的方法。如果将例3-1中的INT0引入单脉冲修改为利用INT2引入单脉冲,则对应的C语言程序如下:#include“stc15.h” //包含寄存器定义头文件voidmain(void){ P0=0; INT_CLKO|=0x10; //允许外部中断2 EA=1; //允许总的中断

while(1); //等待中断}voidX2_ISR(void)interrupt10 //外部中断2函数{ i<<=1; if(i==0)i=1; //移位8次后,i将变为0,因此需要重新赋值

P0=~i;}3.2定时/计数器及其应用3.2.1定时/计数器的相关寄存器3.2.2定时/计数器的工作方式及结构3.2.3定时/计数器的应用3.2.1定时/计数器的相关寄存器1.定时器工作方式控制寄存器TMOD:地址为89H,复位值为00HM1和M0:方式选择控制位。定时器的方式选择如下表所示:C/

:功能选择位1:计数器功能(对T0或T1引脚的负跳变进行计数);0:定时器功能(对时钟周期进行计数)。GATE:门控位。GATE用于选通控制。1:INTx为高电平且TRx置位时,启动定时器工作。0:每当TRx置位时,就启动定时器工作。

定时/计数器的相关寄存器定时器控制寄存器TCON:地址为88H,复位值为00HTF1:T1溢出标志位。T1启动计数后,T1从初值开始加1计数,最高位产生溢出时,TF1由硬件置1,并向CPU请求中断,当CPU响应中断时,由硬件清零。TF1也可以由程序查询或清零TR1:T1的运行控制位。该位由软件置位和清零。当GATE=0,TR1=1启动T1开始计数,TR1=0时停止T1计数。当GATE=1,TR1=1且INT1输入高电平时,才允许T1计数TF0:定时器/计数器0溢出标志位。含义和功能与TF1相似。TR0:定时器T0的运行控制位。含义和功能与TR1相似。

定时/计数器的相关寄存器辅助寄存器AUXR:地址为8EH,复位值为00H辅助寄存器AUXR主要用来设置定时器0、定时器1和定时器2的速度以及串口UART的波特率控制等T0x12:定时器0速度控制位。0:定时器0的速度是传统8051单片机定时器的速度,即12分频。1:定时器0的速度是传统8051单片机定时器速度的12倍,即不分频。T1x12:定时器1速度控制位。0:定时器1的速度是传统8051单片机定时器的速度,即12分频。1:定时器1的速度是传统8051单片机定时器速度的12倍,即不分频。如果UART串口用T1作为波特率发生器,T1x12位决定UART串口是12T还是1T。T2R:定时器2运行控制位。0:不允许定时器2运行; 1:允许定时器2运行。T2_C/

:控制定时器2用作定时器或计数器。0:用作定时器(对内部系统时钟进行计数);1:用作计数器(对引脚T2/P3.1的外部脉冲进行计数)T2x12:定时器2速度控制位。0:定时器2的速度是传统8051单片机定时器的速度,即12分频。1:定时器2的速度是传统8051单片机定时器速度的12倍,即不分频。定时器2除了作为一般定时器使用外,主要用于串行口的波特率发生器。UART_M0x6、S2SMOD和S1ST2用于控制UART串口的速度EXTRAM用于设置是否允许使用内部1792字节的扩展RAM定时/计数器的相关寄存器定时器2高8位寄存器T2H定时器2高8位寄存器(地址为D6H,复位值为00H)用于保存重装时间常数高8位定时器2低8位寄存器T2L定时器2低8位寄存器(地址为D7H,复位值为00H)用于保存重装时间常数低8位

3.2定时/计数器及其应用3.2.1定时/计数器的相关寄存器3.2.2定时/计数器的工作方式及结构3.2.3定时/计数器的应用定时/计数器的工作方式及结构

定时/计数器0和1的工作方式及结构

定时/计数器0和1的工作方式0(16位自动重装方式)当GATE=0时,如TRx=1,则定时器计数。GATE=1时,允许由外部输入INTx控制定时器0,这样可实现脉宽测量。当C/=0时,多路开关连接到系统时钟的分频输出,T0对内部系统时钟计数,T0工作在定时方式。当C/=1时,多路开关连接到外部脉冲输入Tx,即Tx工作在计数方式。STC15F2K60S2单片机的定时器有两种计数速率:一种是12T模式,每12个时钟加1,与传统8051单片机相同;另一种是1T模式,每个时钟加1,速度是传统8051单片机的12倍。定时器0和定时器1分别有2个隐藏的寄存器RL_THx和RL_TLx

。当定时器工作在模式0时,[TLx,THx]的溢出不仅置位TFx,而且会自动将[RL_TLx,RL_THx]的内容重新装入[TLx,THx]当T0CLKO=1时,T1/P3.5引脚配置为定时器0的时钟输出CLKOUT0。当T1CLKO=1时,T0/P3.4引脚配置为定时器1的时钟输出CLKOUT1。定时/计数器的工作方式及结构定时/计数器0和1的工作方式及结构定时/计数器0和1的工作方式1(16位定时/计数器方式)

此模式下,定时器配置为16位的计数器,由TLx的8位和THx的8位构成。TLx的8位溢出向THx进位,THx计数溢出置位TCON中的溢出标志位TFx。定时/计数器的工作方式及结构定时/计数器0和1的工作方式及结构定时/计数器0和1的工作方式2(8位自动重装方式)

方式2是能自动重置初值的8位定时/计数器,计数溢出后具有自动恢复初值的功能。当TL0/TL1计数溢出时,不仅置位溢出标志TF0/TF1,还自动将TH0/TH1的内容送入TL0/TL1,使TL0/TL1从初值开始重新计数。用户可以通过程序把时间常数预置在TH0/TH1中,再装入后,TH0/TH1的内容保持不变。当T0CLKO=1时,T1/P3.5引脚配置为定时器0的时钟输出CLKOUT0。当T1CLKO=1时,T0/P3.4引脚配置为定时器1的时钟输出CLKOUT1。自动装载时间常数的工作方式,适合用作较精确的定时脉冲信号发生器,如波特率发生器等。特别是工作方式0(16位自动重装方式),实际工程中应用更加方便,因此,建议读者尽量使用工作方式0进行定时器的应用设计。定时/计数器的工作方式及结构定时/计数器2的工作方式及结构定时/计数器2只有一种工作方式—16位自动重装方式,且T2的工作方式和T0/T1的工作方式0类似,不再赘述3.2定时/计数器及其应用3.2.1定时/计数器的相关寄存器3.2.2定时/计数器的工作方式及结构3.2.3定时/计数器的应用3.2.3定时/计数器的应用编程时主要考虑两点:一是正确初始化;写入控制字时间常数的计算并装入启动或停止定时/计数器

二是中断服务程序的编写,在中断服务程序中编写实现需要定时完成的任务代码。定时/计数器的应用计数初值的计算方法

当工作于定时状态时,定时/计数器是对时钟周期进行计数,若对时钟进行12分频,则每12个时钟周期计数一次;若不对时钟进行12分频,则每个时钟周期计数一次,计数的单位时间为:进行12分频时,m=1;不进行12分频时,m=0。定时时间为:Tc=XTu。其中,Tu为单位时间,Tc为定时时间,X为所需计数次数。STC15F2K60S2单片机的定时/计数器是对脉冲不断加1进行计数的,是加1计数器。因此,不能直接将实际的计数值作为计数初值送入计数寄存器中,而必须将实际计数值以28、216为模求补,以补码作为计数初值。即应装入计数/定时器的初值为:其中,n=8或16。进行计算时,TC的单位为秒,晶振频率的单位使用Hz。定时/计数器的应用计数初值的计算方法例如:若晶振频率为11.0592MHz,要求定时TC=10ms,采用16位方式,12分频时,根据上面的计算公式可得

定时/计数器的应用定时/计数器初始化部分的一般步骤:设置工作方式,将控制字写入TMOD寄存器(对于T0和T1)或AUXR(对于T2)设置分频方式,将控制字写入AUXR寄存器。默认的情况(即不进行设置时)是12分频(兼容传统8051单片机)计算定时/计数初值,并将其装入TLX和THX寄存器(对于T0和T1)或T2L和T2H寄存器(对于T2)置位ETX和EA允许定时/计数器中断(如果需要)置位TRX(对于T0和T1)或T2R(对于T2)以启动定时/计数对于T0和T1工作在非自动装载方式时,在中断服务程序中,需要注意计数初值的重新装入问题定时/计数器的应用【例3-4】

设系统时钟频率为11.0592MHz,利用T0定时,每隔0.5s将P0.0的状态取反。解:由于所要求的定时时间1s超过了定时器的定时能力(根据计算可知,时钟频率为11.0592MHz,12分频时,16位定时器的最长定时时间约为71.11ms),所以无法采用定时器直接实现0.5s的定时。这时可以将定时器的定时时间设为10ms,在中断服务程序中对定时器溢出中断请求的次数进行计数,当计够50次时,将P0.0的状态取反,否则直接返回主程序,从而达到0.5s的定时。选择T0为16位定时器方式0。根据前面的计算,可得T0的计数初值为:N=56320=0DC00H【例3-4】C语言程序如下:

#include“stc15.h” //包含STC15F2K60S2的寄存器定义文件

sbitP00=P0^0; //声明P0.0的引脚位变量

unsignedchari; //声明计数变量。C语言程序中尽量不要使用ACC voidmain(void) { P00=1;TMOD=0x00; TL0=0x0; TH0=0xDC; i=50; //计数变量赋初值

ET0=1; //允许T0中断

EA=1; //开放总的中断

TR0=1; //启动T0计数

while(1); //等待中断

} voidT0_ISR(void)interrupt1//定时器T0中断函数

{ i--; //计数变量减1

if(i==0){ //若减到0,则将P2.0取反

P00=!P00; //将P2.0取反

i=50; //重新给计数变量赋值

} }若使用工作方式1,该如何进行初始化及程序的编写?请读者自行实验学习。

定时/计数器的应用【例3-5】设时钟频率为18.432MHz,使用定时器2定时,使P0.1口输出38.4KHZ的方波。解:对应的C语言代码如下:

#include“stc15.h” //包含STC15F2K60S2的寄存器定义文件

//定义常数 #defineFOSC18432000L #defineT38_4KHz(65536-18432000/2/38400)//38.4KHz sbitTEST_PIN=P0^1;//定义测试引脚 voidmain(void) { AUXR|=0x04; //定时器2为1T模式 T2L=0x10; //设置定时器2重装载时间常数 T2H=0xff; //设置定时器2重装载时间常数

AUXR|=0x10; //启动定时器2 IE2|=0x04; //允许定时器2中断

EA=1; //开放CPU中断

while(1); //循环等待中断

} //定时器2中断服务函数 voidt2_isr(void)interrupt12 { TEST_PIN=~TEST_PIN; }3.3串行通信接口及其应用3.3.1异步串行通信接口及其应用3.3.2SPI接口及其应用3.3.1异步串行通信接口及其应用采用UART工作方式的全双工串行通信接口串行口1串行接收缓冲器只能读出,不能写入串行发送缓冲器只能写入,不能读出采用UART工作方式的全双工串行通信接口串行口2串口2的接收缓冲器和发送缓冲器共用一个地址号(9BH),串行口2的结构、工作原理与串行口1类似STC15F2K60S2的串行口既可以用于串行异步通信,也可以构成同步移位寄存器。如果在串行口的输入/输出引脚上加上电平转换器,可以方便地构成标准的RS-232接口。串行口1与传统8051单片机的串行口完全兼容

接收缓冲器和发送缓冲器在物理上是独立的,既可以接收数据也可以发送数据,还可以同时发送和接收数据。串口1的接收缓冲器和发送缓冲器共用一个地址号(99H)异步串行通信接口及其应用1.串行口的寄存器串行口1控制寄存器SCON:地址为98H,复位值为00HSM0/FE:PCON寄存器中的SMOD0位为1时,该位用于帧错误检测,当检测到一个无效停止位时,通过UART接收器设置该位。它必须由软件清零。PCON寄存器中的SMOD0为0时,该位和SM1一起指定串行通信的工作方式,如下表所示(其中,SYSclk为系统工作时钟频率)串行口1控制寄存器SCONSM2:多机通信控制位。REN:允许接收控制位。1:允许串行口接收数据;0:禁止串行口接收数据。TB8:在方式2和方式3时,它是要发送的第9个数据位,按需要由软件进行置位或清零。该位可用作数据的奇偶校验位,或在多机通信中用作地址帧/数据帧的标志位(TB8=1/0)RB8:在方式2和方式3时,它是接收到的第9位数据,作为奇偶检验位或地址帧/数据帧标志位。在方式1时,若SM2=0,则RB8是接收到的停止位。在方式0时,不使用RB8TI:发送中断请求标志位。在方式0时,当串行发送数据字第8位结束时由内部硬件置位,向CPU申请发送中断。CPU响应中断后,必须用软件清零。在其他方式时,在停止位开始发送时由硬件置位。同样,必须用软件清零。RI:接收中断标志位。在方式0时,当串行接收到第8位结束时由内部硬件置位。在其他方式时,RI在接收到停止位的中间时刻由硬件置位(例外情况见SM2说明)。RI也必须用软件清零。

异步串行通信接口及其应用1.串行口的寄存器串行口2控制寄存器S2CON:地址为9AH,复位值为00H

寄存器S2CON的各个位与寄存器SCON的各个位含义和功能类似,不再赘述异步串行通信接口及其应用1.串行口的寄存器掉电控制寄存器PCON:地址为87H,复位值为30HSMOD:串行口波特率系数控制位。复位时,SMOD=0。1:使方式1、方式2和方式3的波特率加倍。0:各工作方式的波特率不加倍。SMOD0:帧错误检测有效控制。复位时,SMOD0=0。1:SCON寄存器中的SM0/FE位用于FE(帧错误检测)功能。0:SCON寄存器中的SM0/FE位用于SM0功能,和SM1一起指定串行通信的工作方式。

异步串行通信接口及其应用1.串行口的寄存器辅助寄存器AUXR:地址为8EH,复位值为00HT0x12、T1x12和T2x12用于设置定时器0、定时器1和定时器2的速度。T2R为定时器2运行控制位。EXTRAM用于设置是否允许使用内部扩展的1792字节扩展RAM。UART_M0x6:串行口模式0的通信速度设置位。0:UART串行口模式0的速度是传统8051单片机串行口的速度,即12分频。1:UART串行口模式0的速度是传统8051单片机串行口速度的6倍,即2分频。S1ST2:串行口1波特率发生器选择位。0:选择定时器1作为串行口1波特率发生器。1:选择定时器2作为串行口1的波特率发生器,此时定时器1得到释放,可以作为独立定时器使用。注意:对于具有串行口2的STC15F2K60S2单片机,串行口2只能使用定时器2作为波特率发生器,不能够选择定时器1作为波特率发生器;串行口1既可以选择定时器1作为波特率发生器,也可以选择定时器2作为波特率发生器。异步串行通信接口及其应用1.串行口的寄存器定时器2高8位寄存器T2H地址为D6H,复位值为00H,用于保存重装时间常数高8位。配合定时器2低8位寄存器T2L以及辅助寄存器AUXR中的T2R和T2x12位确定时间常数。定时器2低8寄存器位T2L地址为D7H,复位值为00H,用于保存重装时间常数低8位。数据缓冲器数据缓冲器用于保存要发送的数据或者从串行口接收到的数据。写数据缓冲器的操作完成待发送数据的加载,读数据缓冲器的操作可获得已接收到的数据。串行口1的数据缓冲器是SBUF,串行口2的数据缓冲器是S2BUF。发送数据时,首先根据不同的工作方式和要求,将作为奇偶检验位或地址帧/数据帧标志位的值设置到TB8或者S2TB8中,然后将串行数据写入数据缓冲器启动发送过程。接收数据时,所收到的数据保存于数据缓冲器中,而作为奇偶检验位或地址帧/数据帧标志位的值保存在RB8或者S2RB8中,用户可以进行判断和使用。异步串行通信接口及其应用2.串行口的工作方式串行口1的工作方式

方式0:移位寄存器方式

方式0为半双工方式,又称为同步移位寄存器输出方式。TXD引脚输出同步移位时钟,RXD用于发送和接收串行数据。串行口输出端可直接与移位寄存器相连,也可用作扩展I/O口或外接同步输入输出设备。该方式下的数据帧为8位,低位在先,高位在后,没有起始位和停止位。串行口1方式0功能结构异步串行通信接口及其应用2.串行口的工作方式串行口1的工作方式方式0:移位寄存器方式发送过程:当CPU将数据写入到发送缓冲区SBUF时,串行口即把8位二进制数以SYSclk/12或SYSclk/2(由UART_M0x6确定)的速率由RXD引脚输出(SYSclk为系统工作时钟),同时由TXD引脚输出同步移位脉冲。字符发送完毕,置中断标志TI为1。接收过程:控制字除方式0外,还应置允许接收控制位REN=1,并清除RI中断标志。启动接收过程后,RXD为数据输入端,TXD为同步信号输出端。接收器以SYSclk/12或SYSclk/2(由UART_M0x6确定)的频率采样RXD引脚输入的数据信息。接收完8位数据后重新置RI=1。当再次接收时,必须通过软件将RI清0。串行口1方式0时序示意图异步串行通信接口及其应用2.串行口的工作方式串行口1的工作方式串行口1的UART方式

方式1:8位可变波特率方式

方式1提供异步全双工通信,适合于点到点的通信。每个数据帧长度为10位:1个起始位(低电平)、8个数据位和1个停止位(高电平)。传输的数据位首先是起始位,然后是8位数据(低位在前),最后一位是停止位。起始位和停止位是在发送时自动插入的。接收时,停止位进入SCON的RB8位。方式1的发送过程:发送数据时,数据由串行发送端TxD输出。当单片机执行一条写SBUF的指令时,启动发送过程,写SBUF信号还把“1”装入发送移位寄存器的第9位,并通知TX控制器开始发送。完成一帧数据信息的发送后,置位中断请求位TI,向CPU请求中断处理。方式1的接收过程:当软件置位接收允许标志位REN,即REN=1时,接收器便以选定波特率的16分频的速率采样串行接收端口RxD,当检测到RxD端口从“1”→“0”的负跳变时就启动接收器接收数据。接收到有效数据后,数据装入SBUF,停止位进入RB8,置位RI,向CPU请求中断。CPU在响应中断后,必须由软件将RI清0。通常情况下,串行口工作于方式1时,SM2设置为“0”。方式1的波特率=异步串行通信接口及其应用2.串行口的工作方式串行口1的工作方式串行口1的UART方式

方式2:9位固定波特率方式

方式2提供异步全双工通信,适合于固定波特率的多机通信。每个数据字节长度为11位:1个起始位、8个数据位(低位在前)、1个可编程的第9位(TB8/RB8)和1个停止位。与方式1相比,每帧增加了一个第9位。发送时,第9位数据由TB8提供,可以置位也可以清零。TB8既可作为多机通信中的地址数据标志位,也可以作为奇偶校验位(将PSW寄存器中的奇偶校验位P的值装入TB8)。接收时,第9位进入RB8位。TxD/P3.1为发送端,RxD/P3.0为接收端。串行通信方式2波特率=SYSclk为系统工作时钟频率PCON寄存器中的SMOD为波特率加倍位,当SMOD=1时,波特率为SYSclk/32;当SMOD=0时,波特率为SYSclk/64。方式2和方式1相比,除波特率发生源略有不同,发送时由TB8提供给移位寄存器第9数据位不同外,功能结构、接收/发送操作过程及时序基本相同。异步串行通信接口及其应用2.串行口的工作方式串行口1的工作方式串行口1的UART方式

串行口方式3:9位可变波特率方式

该方式也适合于多机通信。方式3的每个数据字节长度为11位:1个起始位、8个数据位(低位在前)、1个可编程的第9位(TB8/RB8)和1个停止位。发送时,第9位数据由TB8确定,可以置位也可以清零。TB8既可作为多机通信中的地址数据标志位,又可作为数据的奇偶校验位(将PSW中的奇/偶校验位P值装入TB8)。接收时,第9位进入RB8位。TxD/P3.1为发送端,RxD/P3.0为接收端。发送过程:CPU执行数据写入发送缓冲区SBUF的指令即可启动发送(如MOVSBUF,A)。串行口自动将发送缓冲区中的内容送入发送移位寄存器。发送移位寄存器先发送一个起始位,接着按程序设定的字符代码,先低位后高位。数据字加上奇偶校验位或可控位(方式2、3中即为程序设定的TB8位的值),再发送停止位,从而完成一帧的发送。串行数据均由TXD端输出,发送完毕,将发送中断标志位TI置1,以供查询及向CPU申请中断之用。CPU的响应中断后必须在中断服务程序中使TI清零。接收过程:接收数据由RXD输入,串行口以所选定波特率的16倍速率采样RXD端状态。当RXD端电平由1到0跳变时,就启动接收器。串行口按程序规定的格式接收一帧代码,并把此码的数据位拼成并行码送入接收缓冲寄存器中(在方式1时,把停止位送入RB8;在方式2、3时,把程控的第9位数据送入RB8),等待CPU取走。为保证可靠无误,对每一数据位进行连续3次采样,取3次采样中至少两次相同的值。接收完毕,置接收中断标志RI=1。CPU的响应中断后必须在中断服务程序中使RI清零。方式3的波特率==异步串行通信接口及其应用异步串行通信接口及其应用2.串行口的工作方式串行口2的工作方式0

串行口2工作于方式0时,为8位UART,波特率可变。一帧数据包含一个起始位(0),8个数据位和一个停止位(1)。10位数据通过RxD2/P1.0(RxD2_2/P4.6)接收,通过TxD2/P1.1(TxD2_2/P4.7)发送。接收时,停止位进入特殊功能寄存器S2CON的S2RB8位。波特率由定时器T2的溢出率决定。串行口2的波特率=SYSclk/12/(65536-[RL_TH2,RL_TL2])/4其中,RL_TH2是T2H的重装载寄存器,RL_TL2是T2L的重装载寄存器。串行口2的工作方式1

串行口2工作于方式1时,为9位UART,波特率可变。一帧数据包含一个起始位(0),8个数据位,一个可编程的第9位和一个停止位(1)。11位数据通过TxD2/P1.1(TxD2_2/P4.7)发送,通过RxD2/P1.0(RxD2_2/P4.6)接收。发送时,第9位数据位来自特殊功能寄存器S2CON的S2TB8位。接收时,第9位进入特殊功能寄存器S2CON的S2RB8位。串行口2方式1和方式0一样,其波特率可通过软件对定时器2的设置进行波特率的选择,是可变的,计算方法相同。异步串行通信接口及其应用3.多处理机通信一台主机,多台从机,主机发送的信息可被各从机接收,而从机只能对主机发送信息,从机间互相不能直接通信从机由初始化程序将串行口置成工作方式2或3,SM2=1,REN=1,处于接收状态当主机和某一从机通信时,主机应先发出一帧包含某从机地址的信息给各从机(TB8=1)。当各从机接收到主机发出的地址帧信息后,自动将第9数据位状态“1”送到SCON控制寄存器的RB8位,并将中断标志RI置1,产生中断在中断服务程序中把主机送来的地址号与本从机的地址号相比较,若地址相等,则使本机的SM2置“0”,为接收主机接着发送来的数据帧(第9数据位为0)作准备主机在发送完呼叫地址帧后(TB8=1),接着发送一连串的数据帧(TB8=0)。当主机要和另一个从机通信时,则再发呼叫地址帧(TB8=1),呼叫其他从机,原先被寻址的从机经分析得知主机在呼叫其他从机时,恢复其SM2=1,对其后主机发送的数据帧不予理睬。

异步串行通信接口及其应用4.波特率的确定串行口1波特率的确定方式0的波特率当UART_M0x6=0时,波特率为SYSclk/12;当UART_M0x6=1时,波特率为SYSclk/2。方式2的波特率当SMOD=0时,波特率为SYSclk/64;当SMOD=1时,为SYSclk/32。方式1和3的波特率串行口1工作于方式1和3时,波特率是可变的,可以通过编程改变定时器1的溢出率或者定时器2的溢出率来确定波特率。使用T1作为波特率发生器,并且工作于方式2时,方式1和方式3时的串行口波特率由下式求得异步串行通信接口及其应用4.波特率的确定串行口2波特率的确定由于串行口2只能T2作为波特率发生器,因此,在使用串行口2时,应特别注意波特率的设置方法。如下表所示常用的串行口波特率、系统时钟以及重装时间常数之间的关系如下表所示。读者在设计系统时,可以直接从表中查得所需设置的时间常数。异步串行通信接口及其应用5.串行口通信应用举例串行口1的编程要点

设置串行口的工作模式设置SCON寄存器的SM0和SM1的内容。若需要串行口具有接收功能,需将其中的REN位置1。设置正确的波特率使用定时器1作为波特率发生器时,需要设置定时器1的工作方式和时间常数(设定TMOD和TH1、TL1寄存器的内容);启动定时器1(置位TR1)。使用定时器2作为波特率发生器时,需要设置定时器2相关的寄存器和位,包括:[T2H,T2L],T2_C/位,T2x12位,SMOD位。启动T2(置位T2R)。设置串行口的中断优先级(设置PS位的值,也可以不设置,取默认值),设置相应的中断控制位(ES和EA)。如要串行口1发送,将数据送入SBUF。编制串行中断服务程序,在中断服务程序中应注意清除中断标志(TI和RI)。异步串行通信接口及其应用5.串行口通信应用举例串行口2的编程要点

设置串行口2的工作模式设置S2CON寄存器中的S2SM0位。如需要串行口2具有接收功能,将S2REN置1。设置串行口2的波特率相应的寄存器和位,包括:[T2H,T2L],T2_C/位,T2x12位,S2SMOD位。启动T2(置位T2R)。设置串行口2的中断优先级(设置PS2位的值,也可以不设置,取默认值),设置打开相应的中断控制位(ES2和EA)。如要串行口2发送,将数据送入S2BUF。编制串行中断服务程序,在中断服务程序中应注意清除中断标志指令(S2RI和S2TI)。异步串行通信接口及其应用5.串行口通信应用举例【例3-6】计算机向单片机发送一个数据,单片机接收到数据后,将接收到的数据按位取反后回发给计算机。假设单片机的系统时钟为11.0592MHz,通信参数为“9600,n,8,1”(这是常见的通信参数表示方法,即波特率为9600bit/s,8个数据位,1个停止位,没有奇偶校验)。在计算机上显示从单片机发送过来的数据。在这种方式中,计算机通常称为上位机。在下面的单片机程序设计中,利用STC15F2K60S2单片机的串行口1和上位计算机通信,选择定时器1作为波特率发生器。对应的C语言程序如下:#include"stc15.h"//包含STC15F2K60S2单片机寄存器定义文件voidmain(void){ SCON=0x50; //设置串行口的工作方式(方式1,允许接收)

TMOD=0x20; //使用定时器1作为波特率发生器,设置波特率9600bps TH1=0xfd; TL1=0xfd; TR1=1; ES=1; //开放串口中断

EA=1; //开放CPU中断

for(;;); //等待中断}voidSerial_ISR(void)interrupt4{ unsignedcharmydata;

if(RI) //如果是接收中断

{ RI=0;

mydata=SBUF; //将接收缓冲区的数据保存到mydata变量中

SBUF=~mydata; //将接收到的数据按位取反后发回

} else //如果是发送中断,将TI清零

TI=0;}3.3串行通信接口及其应用3.3.1异步串行通信接口及其应用3.3.2SPI接口及其应用3.3.2SPI接口及其应用1.SPI接口简介SPI的核心是一个8位移位寄存器和数据缓冲器,数据可以同时发送和接收。在SPI数据的传输过程中,发送和接收的数据都存储在数据缓冲器中SPI接口及其应用2.SPI接口的数据通信SPI接口由:MISO(MasterInSlaveOut,主入从出,默认与P1.4复用)MOSI(MasterOutSlaveIn,主出从入,默认与P1.3复用)SCLK(SPIClock,串行时钟信号,默认与P1.5复用)(SlaveSelect,从机选择信号,默认与P1.2复用)4根信号线构成STC15F2K60S2单片机的SPI接口的数据通信方式有3种:单主机-单从机方式双器件方式(器件可互为主机和从机)单主机-多从机方式。SPI接口及其应用2.SPI接口的数据通信作为从机时,若CPHA=0,SSIG必须为0,引脚必须取反并且在每个连续的串行字节之间重新设置为高电平。当CPHA=1时,SSIG可以为1或0。如果SSIG=0,引脚可在连续传输之间保持有效(即一直为低电平)。当系统中只有一个SPI主机和一个SPI从机时,这是首选配置。在SPI通信中,数据传输总是由主机启动的。如果SPI使能(SPEN=1),主机对SPI数据寄存器的写操作将启动SPI时钟发生器和数据的传输。在数据写入SPDAT之后的半个到一个SPI位时间后,数据将出现在MOSI引脚。传输完一个字节后,SPI时钟发生器停止,传输完成标志(SPIF)置位并产生一个中断(如果SPI中断使能)。SPI接口及其应用3.SPI接口的应用举例SPI相关的特殊功能寄存器

SPI控制寄存器(SPCTL):地址为CEH,复位值为00000100B

引脚忽略控制位SPI使能位SPI主/从模式选择位SPI接口及其应用3.SPI接口的应用举例SPI相关的特殊功能寄存器

SPI控制寄存器(SPCTL):地址为CEH,复位值为00000100BDORD:设定数据发送和接收的位顺序。0:数据字的最高位(MSB)最先传送1:数据字的最低位(LSB)最先传送CPOL:SPI时钟极性。0:SPI空闲时SCK=0。SCK的前时钟沿为上升沿而后沿为下降沿。1:SPI空闲时SCK=1。SCK的前时钟沿为下降沿而后沿为上升沿。CPHA:SPI时钟相位选择控制。0:数据在为低(SSIG=0)时驱动到SPI口线,在SCK的后时钟沿被改变,并在前时钟沿被采样。(注:SSIG=1时的操作未定义)1:数据在SCK的前时钟沿驱动到SPI口线,SPI模块在后时钟沿采样。SPR1:与SPR0联合构成SPI时钟速率选择控制位。SPR0:与SPR1联合构成SPI时钟速率选择控制位。SPI时钟选择如下表所示。SPI接口及其应用3.SPI接口的应用举例SPI相关的特殊功能寄存器SPI状态寄存器(SPSTAT):地址为CDH,复位值为00XXXXXXBSPIF:SPI传输完成标志。当一次传输完成时,SPIF被置位。此时,如果SPI中断被打开(即ESPI(IE2.1)=1,EA(IE.7)=1),将产生中断。当SPI处于主模式且SSIG=0时,如果为输入并被驱动为低电平,SPIF也将置位,表示“模式改变”。SPIF标志通过软件向其写入1而清0。WCOL:SPI写冲突标志。当一个数据正在传输时,又向数据寄存器SPDAT写入数据,WCOL将置位。WCOL标志通过软件向其写入1而清0。SPI接口及其应用3.SPI接口的应用举例SPI相关的特殊功能寄存器SPI数据寄存器(SPDAT):地址为CFH,复位值为00H位7-位0:保存SPI通信数据字节。其中,MSB为最高位,LSB为最低位。SPI接口及其应用3.SPI接口的应用举例编程实例

SPI接口的初始化

通过SPI控制寄存器SPCTL设置:引脚的控制、SPI使能、数据传送的位顺序、设置为主机或从机、SPI时钟极性、SPI时钟相位、SPI时钟选择;清0寄存器SPSTAT中的标志位SPIF和WCOL(向这两个标志位写1即可清0);开放SPI中断(IE2中的ESPI=1,IE2寄存器不能位寻址,可以使用“或”指令或者直接赋值进行设置);开放总中断(IE中的EA=1).SPI接口及其应用3.SPI接口的应用举例编程实例【例3-7】

计算机向主单片机发送一串数据,主单片机的RS-232串口每收到一个字节就立刻将收到的字节通过SPI口发送到从单片机中,与此同时主单片机收到从单片机发回的一个字节,主单片机把收到的这个字节通过RS-232口发送到计算机。从单片机的SPI口收到数据后,把收到的数据放到自己的SPDAT寄存器中,当下一次主单片机发送一个字节时把数据发回到主单片机。硬件连接如下图所示。可以使用串口助手观察结果。假设晶振频率SYSclk=18.432MHz,计算机RS232串口波特率设置为57600bps。【例3-7】解:经计算,当SYSclk=18.432MHz,PCON.7=0(波特率不加倍),波特率为57600bps时的重装时间常数为F6H。在主机的主程序中,使用查询的方法查询UART口是否接收到数据。C语言程序如下:3.4模数转换器及其应用3.4.1模数转换器的结构3.4.2模数转换器的应用3.4.1模数转换器的结构STC15F2K60S2的ADC由多路选择开关、比较器、逐次比较寄存器、10位DAC、转换结果寄存器(ADC_RES和ADC_RESL)以及ADC控制寄存器ADC_CONTR构成。STC15F2K60S2的ADC是逐次比较型模数转换器。STC15F2K60S2单片机ADC模块的参考电压源是输入工作电压Vcc,一般不用外接参考电压源。3.4模数转换器及其应用3.4.1模数转换器的结构3.4.2模数转换器的应用3.4.2模数转换器的应用1、与ADC有关的特殊功能寄存器P1口模拟功能控制寄存器P1ASF:地址为9DH,复位值为00H如果要使用相应口的模拟功能,需将P1ASF特殊功能寄存器中的相应位置为1。如,若要使用P1.6的模拟量功能,则需要将P16ASF设置为1。注意,P1ASF寄存器不能位寻址,可以使用C语言中的“或”运算符或者赋值运算符进行设

温馨提示

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

评论

0/150

提交评论