1、第11章 STC15系列单片机PCA模块单片机原理及应用系统设计本章主要内容 PCA的结构PCA模块控制寄存器PCA模块的工作模式与应用11.1 PCA的结构的结构 IAP15W4K58S4单片机内部集成了单片机内部集成了2路可编程计数器阵路可编程计数器阵列(列(PCA)模块,可用于软件定时)模块,可用于软件定时(Compare)、外部脉、外部脉冲捕获冲捕获(Capture)、高速输出以及脉宽调制(、高速输出以及脉宽调制(PWM)输)输出等功能,常简称为出等功能,常简称为PCA模块的模块的CCP功能。功能。IAP15W4K58S4单片机的PCA模块含有一个特殊的16位定时器(CH和CL),有2
2、个16位的捕获/比较模块与之相连,PCA模块结构如图11-1所示。11.1 PCA的结构模块模块0连接到连接到P1.0/CCP1或或P3.6/CCP1_2或或P2.6/CCP1_3 模块模块1连接到连接到P1.1/CCP0或或P3.5/CCP0_2或或P2.5/CCP0_3 11.1 PCA的结构每个模块可编程工作在每个模块可编程工作在4种模式下:种模式下:1.1.上升上升/下降沿捕获下降沿捕获2.2.软件定时器软件定时器3.3.高速脉冲高速脉冲4.4.可调制脉冲输出可调制脉冲输出16位PCA定时器/计数器是2个模块的公共时间基准,其结构如下图11-2所示。寄存器CH和CL构成16位PCA的自
3、动递增计数器,CH是高8位,CL是低8位。PCA计数器的时钟源有以下几种:1/12系统时钟、系统时钟、1/8系统时钟、系统时钟、1/6系统时钟、系统时钟、1/4系统系统时钟、时钟、1/2系统时钟、定时器系统时钟、定时器T0溢出脉冲或溢出脉冲或ECI引脚的输入脉冲引脚的输入脉冲(ECI引脚为P1.2或通过设置为P2.4或P3.4)。定时器的计数源由CMOD特殊功能寄存器中的CPS2,CPS1和CPS0位来确定(见CMOD特殊功能寄存器说明)。PCA计数器主要由PCA工作模式寄存器CMOD和PCA控制寄存器CCON进行管理和控制。1.PCA工作模式寄存器工作模式寄存器CMOD寄存器寄存器CMOD用
4、于选择用于选择PCA计数器的脉冲源及计数溢出计数器的脉冲源及计数溢出中断管理。地址为中断管理。地址为D9H,复位值为,复位值为0 xxx 0000B,其各位定,其各位定义如表义如表11-1所示。所示。CIDL:空闲模式下是否停止:空闲模式下是否停止PCA计数的控制位计数的控制位 CIDL=0;空闲模式下PCA计数器继续计数;CIDL=1;空闲模式下PCA计数器停止计数。CPS2、CPS1、CPS0:PCA计数脉冲源选择控制位计数脉冲源选择控制位 PCA计数脉冲选择如表11-2所示。ECF:PCA计数溢出中断使能位计数溢出中断使能位 ECF=0:禁止寄存器CCON中CF位的中断;ECF=1:允许
5、寄存器CCON中CF位的中断。2.PCA控制寄存器控制寄存器CCON寄存器寄存器CCON用于控制用于控制PCA计数器的运行及记录各计数器的运行及记录各PCA模块模块的中断请求标志位。地址为的中断请求标志位。地址为D8H,复位值为,复位值为00 xx x000B。其各位。其各位定义如表定义如表11-3所示。所示。CFCF:PCAPCA计数器溢出标志位。计数器溢出标志位。当当PCAPCA计数器溢出时,计数器溢出时,CFCF由硬件置位。如果由硬件置位。如果CMODCMOD寄寄存器的存器的ECFECF位置位置1 1,则,则CFCF标志可用来作为计数器计满溢出标志可用来作为计数器计满溢出中断标志。中断标
6、志。CFCF位可通过硬件或软件置位,位可通过硬件或软件置位,但只可通过软但只可通过软件清零。件清零。CRCR:PCAPCA计数器运行控制位。计数器运行控制位。CR=0CR=0:启动:启动PCAPCA计数器计数器:计数。计数。CR=1CR=1:关闭:关闭PCAPCA计数器计数。计数器计数。当出现匹配或捕获时该位由硬件置位。该位必须通过软件清零。CCF0:PCA模块模块0中断标志。中断标志。当出现匹配或捕获时该位由硬件置位。该位必须通过软件清零。3.PCA3.PCA模块比较模块比较/捕获寄存器捕获寄存器CCAPMnCCAPMn(n=0,1)(n=0,1)比较比较/捕获寄存器捕获寄存器CCAPM0对
7、应对应PCA模块模块0,CCAPM1对应对应PCA模块模块1。地址为。地址为DBH,复位值均为,复位值均为0000 0000B。CCAPMn寄存器的各位定义如表寄存器的各位定义如表11-4所示。所示。ECOMnECOMn:比较器功能使能位。:比较器功能使能位。当ECOM01时,允许比较器功能。CAPPnCAPPn:正捕获控制位。正捕获控制位。当CAPP01时,允许上升沿捕获。CAPNnCAPNn:负捕获控制位。:负捕获控制位。当CAPN01时,允许下降沿捕获。MATnMATn:匹配控制位。匹配控制位。当MATn1时,PCA计数器(CH、CL)的计数值与模块n的比较/捕获寄存器(CCAPnH、C
8、CAPnL)的值匹配时,将置位CCON寄存器中的中断请求标志位CCFn.。TOGn:翻转控制位。翻转控制位。当TOGn1时,PCA模块工作在高速脉冲输出模式。即PCA计数器(CH、CL)的数值与模块n的比较/捕获存器(CCAPnH、CCAPnL)的值匹配时,PCA模块n引脚的输出状态翻转。PWMn:脉宽调制模式控制位。脉宽调制模式控制位。当PWMn1时,PCA模块工作在脉宽调制模式,PCA模块n引脚用于脉宽调制输出。ECCFn:PCA模块模块n中断使能控制位。中断使能控制位。ECCFn=1:允许PCA模块n的CCFn标志位被置1,产生中断。ECCFn=0:禁止中断。CCAPMn寄存器各位的不同
9、取值对应PCA模块n不同的工作模式,如表11-5所示。4.PCA的的16位计数器位计数器CH、CL寄存器CH是PCA计数器的高8位,其地址为F9H。寄存器CL是PCA计数器的低8位,其地址为E9H,复位值均为0000 0000B,用于保存PCA的装载值。5.PCA的捕捉的捕捉/比较寄存器比较寄存器CCAPnH、CCAPnL(n=0,1)当PCA模块工作在捕获或比较模式时,CCAPnH、CCAPnL寄存器用于存储16位捕获计数值;当PCA模块工作在PWM模式时,CCAPnH、CCAPnL寄存器用于控制输出的占空比。其复位值均为00H。它们对应的地址分别为:CCAP0L EAH、CCAP0H FA
10、H:模块0的捕捉/比较寄存器。CCAP1L EBH、CCAP1H FBH:模块1的捕捉/比较寄存器。6.PCA模块模块PWM寄存器寄存器PCA_PWMn(n=0,1)PCA模块PWM寄存器PCA_PWMn用于设置PCA模块工作在PWM模式时的功能选择。PCA_PWM0对应模块0,其地址为F2H,PCA_PWM1对应模块1,其地址为F3H,复位值均为00H,各位定义如表11-6所示。EBSn_1、EBSn_0:PCA模块模块n工作于工作于PWM模式时的功能选模式时的功能选择位。择位。位数选择如表11-7所示。EPCnH:在:在PWM模式下,与模式下,与CCAPnH组成组成9位数。位数。EPCnL
11、:在:在PWM模式下,与模式下,与CCAPnL组成组成9位数。位数。11.3.1 11.3.1 捕获模式捕获模式CCAPMn寄存器的CAPNn和CAPNn两位中至少一位为1时,PCA模块n工作在捕获模式,其结构如图11-3所示。PCA模块工作于捕获模式时,对模块的外部模块工作于捕获模式时,对模块的外部CCPn输入输入(CCP0/P11,CCP1/P10,CCP2/P37)的跳变进行采样。当采)的跳变进行采样。当采样到有效跳变时,样到有效跳变时,PCA硬件就将硬件就将PCA计数器阵列寄存器计数器阵列寄存器(CH和和CL)的值装载到模块的捕获寄存器中()的值装载到模块的捕获寄存器中(CCAPnL和
12、和CCAPnH)。)。如果如果CCON特殊功能寄存器中的位特殊功能寄存器中的位CCFn和和CCAPMn特殊功特殊功能寄存器中的位能寄存器中的位ECCFn位被置位,将产生中断。可在中断位被置位,将产生中断。可在中断服务程序中判断哪一个模块产生了中断,并注意中断标志位服务程序中判断哪一个模块产生了中断,并注意中断标志位的软件清零问题。的软件清零问题。11.3 PCA模块的工作模式与应用模块的工作模式与应用【例【例11.1】利用利用IAP15W4K58S4单片机单片机PCA模块的捕获模式功能,模块的捕获模式功能,对按键输入信号的下降沿进行捕获,控制流水灯的方向。电路原对按键输入信号的下降沿进行捕获,
13、控制流水灯的方向。电路原理如图理如图11-4所示。请编写程序。所示。请编写程序。解:解:C C语言源程序代码如下:语言源程序代码如下:#include stc15w4k32s4.h /包含单片机头文件包含单片机头文件bit LEDGoFlag=0;/定义标志,流水灯方向定义标志,流水灯方向bit HaveInt=0;/有中断产生标记有中断产生标记void IO_Init(void);/函数声明函数声明void PCA_Init(void);void LED_Go(void);void Delay_ms(unsigned int ms);void main(void)/主程序主程序 IO_Ini
14、t();/IO口初始化口初始化 PCA_Init();/PCA模块初始化模块初始化 while(1)LED_Go();/运行流水灯运行流水灯 if(HaveInt=1)/有中断产生有中断产生 LEDGoFlag=!LEDGoFlag;/流水灯反向流水灯反向 HaveInt=0;void Delay_ms(unsigned int ms)/延时函数延时函数 unsigned int i;while(ms-)!=0)for(i=0;i 580;i+);void LED_Go(void)/流水灯函数流水灯函数 unsigned char LEDCnt;if(LEDGoFlag=1)/如果标记有效如果
15、标记有效 for(LEDCnt=0;LEDCntLEDCnt);/将数据送到将数据送到P0口口 Delay_ms(100);/延时延时100ms else for(LEDCnt=0;LEDCnt4;LEDCnt+)/依次从依次从往往上上 /下下单个点亮单个点亮 P0=(0 x10LEDCnt);/将数据送到将数据送到P0口口 Delay_ms(100);/延时延时100ms 第第11章章 STC15系列单片机系列单片机PCA模块模块void PCA_Init(void)/PCA计数模块初始化函数,使用计数模块初始化函数,使用PCA模模 /块的输入捕捉功能块的输入捕捉功能 AUXR1|=0 x1
16、0;/CCP端口切换至端口切换至P3.4,P3.5,P3.6 AUXR1&=0 xdf;CCON=0;/初始化初始化PCA控制寄存器,停止控制寄存器,停止PCA计数计数器器 /清除清除CF标记,清除标记,清除PCA各个模块中断各个模块中断 CCAPM0=0 x11;/初始化初始化PCA的比较的比较/捕获寄存器捕获寄存器0,/允许下降沿,捕获使能允许下降沿,捕获使能CCF0中断中断 CL=0;/清除清除PCA计数器计数器 CH=0;CMOD=0 x82;/设置设置PCA计数器时钟源为计数器时钟源为Fosc/2 /PCA计数器空闲模式停止计数,禁止计数器空闲模式停止计数,禁止PCA /计数溢出中断
17、计数溢出中断 CR=1;/运行运行PCA计数器计数器 EA=1;/启用中断启用中断void PCA_ISR(void)interrupt 7 /PCA模块捕获中断处理函数模块捕获中断处理函数 if(CCF0=1)/捕获中断捕获中断 HaveInt=1;/有中断产生标记有中断产生标记 CCF0=0;/PCA模块模块0比较比较/捕获中断标记必须软件清零捕获中断标记必须软件清零 void IO_Init(void)/单片机单片机IO端口模式初始化端口模式初始化 P0M1=0 x00;P0M0=0 x00;P1M1&=(10)|(14);P1M0&=(10)|(14);11.3.2 1611.3.2
18、16位软件定时器模式位软件定时器模式16位软件定时器模式结构图如图11-5所示。通过置位通过置位CCAPMn寄存器的寄存器的ECOM和和MAT位,可使位,可使PCA模模块用作软件定时器(上图)。块用作软件定时器(上图)。PCA定时器的值与模块捕获寄存器的值相比较,当两者相等定时器的值与模块捕获寄存器的值相比较,当两者相等时,如果位时,如果位CCFn(在在CCON特殊功能寄存器中特殊功能寄存器中)和位和位ECCFn(在(在CCAPMn特殊功能寄存器中)都置位,将产生中断。特殊功能寄存器中)都置位,将产生中断。CH,CL每隔一定的时间自动加每隔一定的时间自动加1,时间间隔取决于选择的,时间间隔取决
19、于选择的时钟源。例如,当选择的时钟源为时钟源。例如,当选择的时钟源为SYSclk/12,每,每12个时钟个时钟周期周期CH,CL加加1。当。当CH,CL增加到等于增加到等于CCAPnH,CCAPnL 时,时,CCFn=1,产生中断请求。如果每次,产生中断请求。如果每次PCA模模块中断后,在中断服务程序中断给块中断后,在中断服务程序中断给CCAPnH,CCAPnL增加增加一个相同的数值,那么下次中断来临的间隔时间一个相同的数值,那么下次中断来临的间隔时间T也是相同也是相同的,从而实现了定时功能。定时时间的长短取决于时钟源的的,从而实现了定时功能。定时时间的长短取决于时钟源的选择以及选择以及PCA
20、计数器计数值的设置。下面举例说明计数器计数值的设置。下面举例说明PCA 计计数器计数值的计算方法。数器计数值的计算方法。假设,系统时钟频率假设,系统时钟频率SYSclk=18.432MHz,选择的时钟源为选择的时钟源为SYSclk/12,定时时间定时时间T为为5ms,则则PCA计数器计数值为:计数器计数值为:PCA计数器的计数值计数器的计数值=T/(1/SYSclk)12)=0.005/(1/18432000)12)=7680(10进制数进制数)=1E00H(16进制数进制数)也就是说,也就是说,PCA计数器计数计数器计数1E00H次,定时时间才是次,定时时间才是5ms,这也就是每次给这也就是
21、每次给CCAPnH,CCAPnL增加的数值增加的数值(步长步长)。【例【例11.211.2】利用利用IAP15W4K58S4IAP15W4K58S4单片机单片机PCAPCA模块的软件定时模块的软件定时功能,在功能,在P0.4P0.4引脚输出引脚输出1S1S的方波控制的方波控制LEDLED指示灯的亮灭。指示灯的亮灭。请编写程序。请编写程序。解:解:C语言源程序如下:语言源程序如下:#include stc15w4k32s4.h /包含单片机头文件unsigned char PCA_Cnt=0;/全局变量定义sbit LED=P04;/LED端口void PCA_Init(void);/函数声明v
22、oid main(void)/主程序 PCA_Init();/PCA模块初始化 while(1);/等待PCA模块定时中断 void PCA_Init(void)/PCA模块初始化函数模块初始化函数CCON=0 x80;/初始化初始化PCA控制寄存器,停止控制寄存器,停止PCA计数器,清除计数器,清除CF标记,清除标记,清除PCA各个模块中断标记各个模块中断标记 CCAPM0=0 x49;/初始化初始化PCA的比较的比较/捕获寄存器捕获寄存器0,允许比较功能,比较匹配时允许比较功能,比较匹配时CCF0中断中断 CL=0;/清除清除PCA计数器计数器CH=0;CCAP0L=0 x00;/定时初值
23、定时初值50ms 11.0592MHz CCAP0H=0 xb4;CMOD=0 x80;/设置PCA计数器时钟源为Fosc/12,PCA计数器空闲模式停止计数,禁止PCA计数溢出中断 CR=1;/运行PCA计数器EA=1;/启用中断void PCA_ISR(void)interrupt 7 /PCA(计数器阵列)中断处理函数 if(CCF0=1)/比较中断 CL=0;/清除PCA计数器CH=0;PCA_Cnt+;if(PCA_Cnt=10)/定时500msPCA_Cnt=0;LED=!LED;/LED灯状态改变CCF0=0;/PCA模块0比较/捕获中断标记必须软件清零 11.3.311.3.3
24、高速脉冲输出模式高速脉冲输出模式该模式中(下图),当PCA计数器的计数值与模块捕获寄存器的值相匹配时,PCA模块的CCPn输出将发生翻转。要激活高速脉冲输出模式,CCAPMn寄存器的TOGn,MATn和ECOMn位必须都置位。CCAPnL的值决定了PCA模块n的输出脉冲频率。当PCA时钟源是SYSclk/2时,输出脉冲的频率F为:f=SYSclk/(4CCAPnL)其中,SYSclk为系统时钟频率。由此,可以得到CCAPnL的值:CCAPnL=SYSclk/(4f)如果计算出的结果不是整数,则进行四舍五入取整,即 CCAPnL=INT(SYSclk/(4f)+0.5)其中,INT()为取整运算
25、,直接去掉小数。例如,假设SYSclk=20MHz,要求PCA高速脉冲输出125kHz的方波,则CCAPnL中的值应为:CCAPnL=INT(20000000/(4125000)+0.5)=INT(40+0.5)=40=28H 11.3.4 脉宽调节模式(PWM)脉宽调制(PWM,Pulse Width Modulation)是一种使用程序来控制波形占空比、周期、相位波形的技术,在三相电机驱动、D/A转换等场合有广泛的应用。STC15系列单片机的PCA模块可以通过设定各自的寄存器PCA_PWMn(n=0,1,2.下同)中的位EBSn_1/PCA_PWMn.7及EBSn_0/PCA_PWMn.6
26、,使其工作于8位PWM或7位PWM或6位PWM 模式。本节以8位脉宽调节模式(PWM)为例介绍PCA工作于PWM模式。当EBSn_1,EBSn_0=0,0或1,1时,PCA模块n工作于8位PWM模式,此时将0,CL7:0 与捕获寄存器EPCnL,CCAPnL7:0进行比较。PWM模式的结构如下图11-7所示。图11-7 PCA PWM mode/可调制脉冲宽度输出模式结构图(PCA模块工作于8位PWM模式)当PCA模块工作于8位PWM模式时,由于所有模块共用仅有的PCA定时器,所有它们的输出频率相同。各个模块的输出 占 空 比 是 独 立 变 化 的,与 使 用 的 捕 获 寄 存 器EPCn
27、L,CCAPnL7:0 有关。当0,CL7:0的值小于EPCnL,CCAPnL7:0时,输出为低;当0,CL7:0的值等于或大于EPCnL,CCAPnL7:0时,输出为高。当CL的值由FF变为0 0溢 出 时,E P C n H,C C A P n H 7:0 的 内 容 装 载 到EPCnL,CCAPnL7:0中。这样就可实现无干扰地更新PWM。要使能PWM模式,模块CCAPMn寄存器的PWMn和ECOMn位必须置位。当PWM是8位的时:PWM的频率=PCA时钟输入源频率/256。PCA时钟输入源可以从以下8种中选择一种:SYSclk,SYSclk/2,SYSclk/4,SYSclk/6,S
28、YSclk/8,SYSclk/12,定时器0的溢出,ECI/P1.2输入。举例:设PCA模块工作于8位PWM模式。要求PWM输出频率为38KHz,选SYSclk为PCA/PWM时钟输入源,求出SYSclk的值。由计算公式38000=SYSclk/256,得到外部时钟频率SYSclk=38000 x 256 x 1=9,728,000 如果要实现可调频率的PWM输出,可选择定时器0的溢出率或者ECI脚的输入作为PCA/PWM 的时钟输入源当EPCnL=0及CCAPnL=00H时,PWM固定输出高当EPCnL=1及CCAPnL=FFH时,PWM固定输出低 当某个I/O口作为PWM使用时,该口的状态
29、:如表11-8所示。表表11-8 I/O11-8 I/O端口作为端口作为PWMPWM使用时的状态使用时的状态【例【例11.311.3】利用利用IAP15W4K58S4单片机单片机PCA模块的模块的PWM功能,使用功能,使用PCA0从从P3.5输出输出8位的位的PWM做做DAC,输出的输出的PWM经过经过RC滤波成直流电压送滤波成直流电压送P1.5做做ADC并用数码管显并用数码管显示出来。(示出来。(该例程序来自试验箱该例程序来自试验箱STC-STUDY-BOARD4-SCH-C-ASM-VER2提供的例程文件)。提供的例程文件)。解:相关说明如下:串口1配置为115200bps,8,n,1,切
30、换到P3.0 P3.1,下载后就可以直接测试.主时钟为22.1184MHZ,通过串口1设置占空比,串口命令使用ASCII码的数字,比如:10,就是设置占空比为10/256,100:就是设置占空比为100/256,可以设置的值为0256,0为连续低电平,256为连续高电平。左边4位数码管显示PWM的占空比值,右边4位数码管显示ADC值。C语言源程序如下:语言源程序如下:#define MAIN_Fosc22118400L /定义主时钟定义主时钟#include STC15Fxxxx.H /包括头文件包括头文件#define LED_TYPE0 x00 /定义定义LED类型类型,0 x00-共阴共
31、阴,0 xff-共阳共阳#define Timer0_Reload (65536UL-(MAIN_Fosc/1000)/Timer 0 中断频率中断频率,1000次次/秒秒#define DIS_DOT0 x20#define DIS_BLACK0 x10#define DIS_0 x11/*本地常量声明本地常量声明*/u8 code t_display=/标准字库标准字库/0 1 2 3 4 5 6 7 8 9 A B C D E FbitB_Capture0,B_Capture1,B_Capture2;u8PCA0_mode,PCA1_mode,PCA2_mode;u16CCAP0_tmp
32、,PCA_Timer0;u16CCAP1_tmp,PCA_Timer1;u16CCAP2_tmp,PCA_Timer2;voidUART1_config(u8 brt);/选择波特率,2:使用Timer2做波特率,其它值:使用Timer1做波特率.voidPrintString1(u8*puts);voidUART1_TxByte(u8 dat);voidUpdatePwm(u16 pwm_value);u16adc;u16Get_ADC10bitResult(u8 channel);/channel=07/*主函数*/void main(void)u8i;u16j;P0M1=0;P0M0=0
33、;/设置为准双向口P1M1=0;P1M0=0;/设置为准双向口P2M1=0;P2M0=0;/设置为准双向口P3M1=0;P3M0=0;/设置为准双向口P4M1=0;P4M0=0;/设置为准双向口P5M1=0;P5M0=0;/设置为准双向口P6M1=0;P6M0=0;/设置为准双向口P7M1=0;P7M0=0;/设置为准双向口display_index=0;/*Timer0初始化*/AUXR=0 x8/定时器0设置为1T,16位定时器自动重装模式 TH0=(u8)(Timer0_Reload/256);TL0=(u8)(Timer0_Reload%256);ET0=1;/使能定时器0中断 TR0
34、=1;/运动定时器0 /*PCA0初始化*/AUXR1&=0 x30;AUXR1|=0 x10;/切换IO口,0 x00:P1.2 P1.1 P1.0 P3.7,0 x10:P3.4 P3.5 P3.6 P3.7,0 x20:P2.4 P2.5 P2.6 P2.7CCAPM0 =0 x42;/工作模式 PWMPCA_PWM0=(PCA_PWM0&0 xc0)|0 x00;/PWM宽度,0 x00:8bit,0 x40:7bit,0 x80:6bit CMOD =(CMOD&0 xe0)|0 x08;/选择时钟源,0 x00:/12T,0 x02:2T,0 x04:Timer0溢出,0 x06:
35、ECI,0 x08:1T,0 x0A:4T,/0 x0C:6T,0 x0E:8TCR=1;UpdatePwm(128);/ADC初始化P1ASF=(1 5);/P1.5做ADCADC_CONTR=0 xE0;/90T,ADC power onUART1_config(1)/选择波特率,2:使用Timer2做波特率 /值:使用Timer1做波特率.EA=1;/打开总中断for(i=0;i=200)/200ms读一次ADCcnt200ms=0;j=Get_ADC10bitResult(5);/参数07,查询方式做一次ADC,返回值就是结果,=1024 为错误if(j=1000)LED84=j/10
36、00;/显示按键ADC值else LED84=DIS_BLACK;LED85=(j%1000)/100;LED86=(j%100)/10;LED87=j%10;if(RX1_TimeOut 0)/超时计数if(-RX1_TimeOut=0)if(RX1_Cnt 0)&(RX1_Cnt=3)/限制为3位数字 F0=0;/错误标志 j=0;for(i=0;i=0)&(RX1_Bufferi 256)PrintString1(错误!输入占空比过大,请不要大于256!rn);else UpdatePwm(j);if(j=100)LED80=j/100,j%=100;/显示PWM默认值 else LED
37、80=DIS_BLACK;LED81=j%100/10;LED82=j%10;PrintString1(已更新占空比!rn);else PrintString1(错误!输入字符过多!输入占空比为0256!rn);RX1_Cnt=0;/*发送一个字节*/voidUART1_TxByte(u8 dat)SBUF=dat;B_TX1_Busy=1;while(B_TX1_Busy);/*串口1发送字符串函数*/void PrintString1(u8*puts)/发送一个字符 for(;*puts!=0;puts+)UART1_TxByte(*puts);/遇到停止符0结束 /*设置Timer2做波
38、特率发生器*/void SetTimer2Baudraye(u16 dat)/选择波特率,2:使用Timer2做波特率,其它值:使用Timer1做波特率.AUXR&=(14);/Timer stop AUXR&=(13);/Timer2 set As Timer AUXR|=(12);/Timer2 set as 1T mode TH2=dat/256;TL2=dat%256;IE2&=(12);/禁止中断 AUXR|=(14);/Timer run enable/*UART1初始化函数*/void UART1_config(u8 brt)/选择波特率,2:使用Timer2/做波特率,其它值:
39、使用Timer1做波特率.if(brt=2)/波特率使用定时器2 AUXR|=0 x01/S1 BRT Use Timer2;SetTimer2Baudraye(65536UL-(MAIN_Fosc/4)/Baudrate1);else /波特率使用定时器1 TR1=0;AUXR&=0 x01;/S1 BRT Use Timer AUXR|=(16);/Timer1 set as 1T mode TMOD&=(16);/Timer1 set As Timer TMOD&=0 x30;/Timer1_16bitAutoReload;TH1=(u8)(65536UL-(MAIN_Fosc/4)/B
40、audrate1)/256);TL1=(u8)(65536UL-(MAIN_Fosc/4)/Baudrate1)%256);ET1=0;/禁止中断 INT_CLKO&=0 x02;/不输出时钟 TR1 =1;SCON=(SCON&0 x3f)|0 x40;/UART1模式,0 x00:同步移位输出,0 x40:8位数据,可变波特率,0 x80:9位数据,固定波特率,0 xc0:9位数据,可变波特率 PS =1;/高优先级中断 ES =1;/允许中断 REN=1;/允许接收 P_SW1&=0 x3f;P_SW1|=0 x80;/UART1 switch to,0 x00:P3.0 P3.1,0
41、x40:P3.6 P3.7,0 x80:P1.6 P1.7(必须使用内部时钟)PCON2|=(1=UART1_BUF_LENGTH)RX1_Cnt=0;RX1_BufferRX1_Cnt=SBUF;RX1_Cnt+;RX1_TimeOut=5;if(TI)TI=0;B_TX1_Busy=0;/*向HC595发送一个字节函数*/void Send_595(u8 dat)u8 i;for(i=0;i8;i+)dat=8)display_index=0;/8位结束回0/*Timer0 1ms中断函数*/void timer0(void)interrupt TIMER0_VECTOR DisplayS
42、can();/1ms扫描显示一位 B_1ms=1;/1ms标志/*查询法读一次ADC结果*/u16 Get_ADC10bitResult(u8 channel)/channel=07 ADC_RES=0;ADC_RESL=0;ADC_CONTR=(ADC_CONTR&0 xe0)|0 x08|channel;/start the ADC NOP(4);while(ADC_CONTR&0 x10)=0);/wait for ADC finish ADC_CONTR&=0 x10;/清除清除ADC结束标志结束标志 return (u16)ADC_RES 2)|(ADC_RESL&3);/*更新更新PWM值值*/voidUpdatePwm(u16 pwm_value)if(pwm_value=0)PWM0_OUT_0();/输出连续低电平输出连续低电平 else CCAP0H=(u8)(256-pwm_value);PWM0_NORMAL();谢谢!让我们一起努力学好单片机!谢谢!让我们一起努力学好单片机!