Presentation is loading. Please wait.

Presentation is loading. Please wait.

单片机 C 语言应用程序设计 主讲教师:廉哲 QQ:17434548 电话: 13840210518 办公室:综合楼 C318.

Similar presentations


Presentation on theme: "单片机 C 语言应用程序设计 主讲教师:廉哲 QQ:17434548 电话: 13840210518 办公室:综合楼 C318."— Presentation transcript:

1 单片机 C 语言应用程序设计 主讲教师:廉哲 QQ:17434548 电话: 13840210518 办公室:综合楼 C318

2 单片机 C 语言应用程序设计  51 单片机硬件结构  C51 基础知识及其基本程序设计  C51 函数、数组、指针定义及应用  单片机内部资源及其 C 语言编程  单片机资源扩展及其 C 语言编程  综合程序设计  考试

3 单片机 C 语言应用程序设计 四 C51 编程设计 4.1 MCS-51 内部资源使用的 C 语言编程 4.2 MCS-51 片外扩展的 C 语言编程 4.3 频率量测量的 C 语言编程

4 单片机 C 语言应用程序设计 4.1 MCS-51 内部资源使用的 C 语言编程 4.1.1 中断应用的 C 语言编程 C51 编译器支持在 C 源程序中直接开发中断程序。中断服务 程序是通过按规定语法格式定义的一个函数。 中断服务程序的函数定义的语法格式如下: 返回值 函数名 ([ 参数 ]) interrupt m[using n] { } …

5 单片机 C 语言应用程序设计 表 4.1 MCS-51 中断源编号 编 号中 断 源中 断 源入 口 地 址入 口 地 址 0 外部中断 0 0003H 1 定时器 / 计数器 0 000BH 2 外部中断 1 0013H 3 定时器 / 计数器 1 001BH 4 串行口中断 0023H

6 单片机 C 语言应用程序设计 using n 选项用于实现工作寄存器组的切换, n 是中断服务子 程序中选用的工作寄存器组号 (0 ~ 3) 。在许多情况下,响应中断 时需保护有关现场信息,以便中断返回后,能使中断前的源程序 从断点处继续正确地执行下去。这在 MCS-51 单片机中,能很方便 地利用工作寄存器组的切换来实现。即在进入中断服务程序前的 程序中使用一组工作寄存器,进入中断服务程序后,由 "using n" 切换到另一组寄存器,中断返回后又恢复到原寄存器组。这样互 相切换的两组寄存器中的内容彼此都没有被破坏。

7 单片机 C 语言应用程序设计 图 4.1 扩展多个中断源 例 1 图 7.5 所示是利用优先权解码芯片,在单片机 8031 的一 个外部中断 INT1 上扩展多个中断源的原理电路图。图中是以开 关闭合来模拟中断请求信号。当有任一中断源产生中断请求,能 给 8031 的 INT1 引脚送一个有效中断信号,由 P1 的低 3 位可得对应 中断源的中断号。

8 单片机 C 语言应用程序设计 在中断服务程序中仅设置标志,并保存 I/O 口输入状态。 Franklin C51 编译器提供定义特定 MCS-51 系列成员的寄存器头文 件。 MCS-51 头文件为 reg51.h 。 C51 程序如下: # include unsigned char status ; bit flag ; void service_int1( ) interrupt 2 using 2 /* INT1 中断服务程序,使用第 2 组工 作寄存器 */ { flag=1 ; /* 设置标志 */ status=p1 ; /* 存输入口状态 */ } void main(void) { IP=0x04 ; /* 置 INT1 为高优先级中断 */ IE=-0x84 ; /* INT1 开中断, CPU 开中断 */

9 单片机 C 语言应用程序设计 for( ; ; ) { if(flag) /* 有中断 */ { switch(status) /* 根据中断源分支 */ { case 0 : break ; /* 处理 IN0 */ case 1 : break ; /* 处理 IN1 */ case 2 : break ; /* 处理 IN2 */ case 3 : break ; /* 处理 IN3 */ default : ; } flag=0 ; /* 处理完成清标志 */ }

10 单片机 C 语言应用程序设计 4.1.2 定时器 / 计数器 (T/C) 应用的 C 语言编程 例 2 设单片机的 fosc=12 MHz 晶振,要求在 P1.0 脚上输出周期 为 2 ms 的方波。 周期为 2 ms 的方波要求定时时间隔 1 ms ,每次时间到 P1.0 取反。 机器周期 =12/fosc=1 μs 需计数次数 =1000/(12/fosc)=1000/1=1000 由于计数器是加 1 计数,为得到 1000 个计数之后的定时器溢 出,必须给定时器置初值为 -1000( 即 1000 的补数 ) 。

11 单片机 C 语言应用程序设计 (1) 用定时器 0 的方式 1 编程,采用查询方式,程序如下: # include sbit P1_0=P1^0 ; void main(void) { TMOD=0x01 ; /* 设置定时器 1 为非门控制方式 1*/ TR0=1 ; /* 启动 T/C0 */ for( ; ; ) { TH0= -(1000/256) ; /* 装载计数器初值 */ TL0= -(1000%256) ; do { } while (!TF0) ; /* 查询等待 TF0 置位 */ P1_0=!P1_0 ; /* 定时时间到 P1.0 反相 */ TF0=0 ; /* 软件清 TF0 */ }

12 单片机 C 语言应用程序设计 (2) 用定时器 0 的方式 1 编程,采用中断方式。程序如下: # include sbit P1_0=P1^0 ; void time (void) interrupt 1 using 1 /* T/C0 中断服务程序入口 */ { P1_0=!P1_0 ; /* P1.0 取反 */ TH0= -(1000/256) ; / * 重新装载计数初值 */ } void main( void ) { TMOD=0x01 ; /* T/C0 工作在定时器非门控制方式 1 */ P1_0=0 ; TH0= -(1000/256 ) ; /* 预置计数初值 */ TL0= -(1000%256) ; EA=1 ; /* CPU 中断开放 */ ET0= 1 ; /* T/C0 中断开放 */ TR0=1 ; /* 启动 T/C0 开始定时 */ do { } while(1) ; /* 等待中断 */ }

13 单片机 C 语言应用程序设计 例 3 采用 10 MHz 晶振,在 P1.0 脚上输出周期为 2.5 s ,占空 比 20% 的脉冲信号。 10 MHz 晶振,使用定时器最大定时几十毫秒。取 10 ms 定时, 周期 2.5 s 需 250 次中断,占空比 20% ,高电平应为 50 次中断。 10 ms 定时,晶振 fosc=10 MHz 。 需定时器计数次数 =10×103×10/12=8333 # include # define uchar unsigned char uchar period=250 ; uchar high=50 ;

14 单片机 C 语言应用程序设计 timer0( )interrupt 1 using 1 /* T/C0 中断服务程序 */ {TH0= - 8333/256 ; /* 重置计数值 */ TL0= - 8333%256 ; if(++time==high)P1=0 ; /* 高电平时间到变低 */ else if (time==period) /* 周期时间到变高 */ {time=0 ; P1=1 ; }

15 单片机 C 语言应用程序设计 main( ) { TMOD=0x01 ; /* 定时器 0 方式 1 */ TH0= - 8333/256 ; /* 预置计数初值 */ TL0= - 8333%256 ; EA=1 ; /* 开 CPU 中断 */ ET0=1 ; /* 开 T/C0 中断 */ TR0=1 ; /* 启动 T/C0 */ do { }while(1) ; }

16 单片机 C 语言应用程序设计 图 2.2 中断服务程序流程图

17 单片机 C 语言应用程序设计 产生一个占空比变化脉冲信号的程序,它产生的脉宽调制 信号用于电机变速控制。 # include # define uchar unsigned char # define uint unsigned int unchar time,status,percent,period ; bit one_round ; uint oldcount,target=500 ; void pulse (void) interrupt 1 using 1 /* T/C0 中断服务程序 */ { TH0= - 833/256 ; /* 1ms - -10 MHz */

18 单片机 C 语言应用程序设计 TL0= - 833%256 ; ET0=1 ; if (++time=percent) P1=0 ; else if (time= =100 ) { time=0 ; P1=1 ; } } void tachmeter ( void ) interrupt 2 using 2 /* 外中断 1 服务程序 */ { union { unit word ; struct { uchar hi ; uchar lo ; } byte ; }

19 单片机 C 语言应用程序设计 newcount ; newcount. byte. hi=TH1 ; newcount.byte.lo=TL1 ; period=newcount.word - oldcount ; /* 测得周期 */ oldcount=newcount.word ; one_round=1 ; /* 每转一圈,引起中断,设置标志 */ } void main ( void ) { IP=0x04 ; /* 置 INT1 为高位优先级 */ TMOD= 0x11 ; /* T0,T1 16 位方式 */ TCON=0x54 ; /* T0 , T1 运行, IT1 边沿触发 */

20 单片机 C 语言应用程序设计 TH1=0 ; TL1=0 ; /* 设置初始计数值 */ IE=0x86 ; /* 允许中断 EX1 , ET0 */ for ( ; ; ) { if (one_round ) /* 每转一圈,调整 */ { if ( period <target ) {if (percent <100 ) ++percent ; /* 占空比增 */ } else if ( percent >0 ) - -percent ; / * 占空比减 */ one_round=0 ; }

21 单片机 C 语言应用程序设计 4.1.3 串行口使用的 C 语言编程 例 4 单片机 fosc=11.0592 MHz ,波特率为 9600 ,各设置 32 字节 的队列缓冲区用于发送接收。设计单片机和终端或另一计算机通 信的程序。 单片机串行口初始化成 9600 波特,中断程序双向处理字符,程 序双向缓冲字符。背景程序可以 " 放入 " 和 " 提取 " 在缓冲区的字符串, 而实际传入和传出 SBUF 的动作由中断完成。 Loadmsg 函数加载缓冲数组,标志发送开始。缓冲区分发 (t) 和收 (r) 缓冲,缓冲区通过两种指示 ( 进 in 和出 out) 和一些标志 ( 满 full , 空 empty ,完成 done) 管理。队列缓冲区 32 字节接收缓冲 (r_buf) 区满, 不能再有字符插入。当 t_in=t_out ,发送缓冲区 (t_buf) 空,发送中 断清除,停止 UART 请求。具体程序如下:

22 单片机 C 语言应用程序设计 # include # define uchar unsigned char uchar xdata r_buf[32] ; /* item1 */ uchar xdata t_buf[32] ; uchar r_in, r_out, t_in, t_done ; /* 队列指针 */ bit r_full, t_empty, t_done ; /* item2 */ code uchar m[ ]={ " this is a test program \r\n "} ; serial ( ) interrupt 4 using 1 /* item3 */ {if( RI && ~ r_full ) {r_buf[r_in]=SBUF ; RI=0 ;

23 单片机 C 语言应用程序设计 r_in= ++r_in & ox1f ; if ( r_in= =r_out ) r_full=1 ; } else if (TI && ~t_empty ) {SBUF=t_buf [t_out] ; TI=0 ; t_out = ++ t_out & 0x1f ; i f ( t_out= =t_in ) t_empty=1 ; } else if (TI ) { TI=0 ; t_done=1 ; }

24 单片机 C 语言应用程序设计 void loadmsg (uchar code * msg ) /* item4 */ {while ((*msg !=0 )&& (((( t_in+1)^t_out ) & 0x1f ) !=0 )) / * 测试缓冲区满 */ { t_ buf [t_in]= * msg ; msg++ ; t_in = ++ t_in & 0x1f ; if ( t_done ) {TI = 1 ; t_empty =t_done =0 ; /* 完成重新开始 */ }

25 单片机 C 语言应用程序设计 void process (uchar ch ) { return ; } / * item5 */ /* 用户定义 */ void processmsg ( void ) /* item6 */ {while ((( r_out+1 ) ^ r_in) !=0 ) /* 接收非缓冲区 */ {process ( r_buf [r_out ] ) ; r_out= ++r_out & 0x1f ; }

26 单片机 C 语言应用程序设计 main ( ) /* item7 */ {TMOD=0x20 ; /* 定时器 1 方式 2 */ TH1=0xfd ; /* 9600 波特 11.0592 MHz */ TCON=0x40 ; /* 启动定时器 1 */ SCON=0x50 ; /* 允许接收 */ IE=0x90 ; /* 允许串行口中断 */ t_empty=t_done=1 ; r_full =0 ; r_out=t_in =0 ; r_ in=1 ; /* 接收缓冲和发送缓冲置空 */ for ( ; ; ) {loadmsg ( & m ) ; processmsg ( ) ; }

27 单片机 C 语言应用程序设计 item1 :背景程序 " 放入 " 和 " 提取 " 字符队列缓冲区。 item2 :缓冲区状态标志。 item3 :串行口中断服务程序,从 RI , TI 判别接收或发送中 断,由软件清除。判别缓冲区状态 ( 满 full ,空 empty) 和全部发送 完成 (done) 。 item4 :此函数把字符串放入发送缓冲区,准备发送。 item5 :接受字符的处理程序,实际应用自定义。 item6 :此函数逐一处理接收缓冲区的字符。 item7 :主程序即背景程序,进行串行口的初始化,载入字 符串,处理接收的字符串。

28 单片机 C 语言应用程序设计 4.2 MCS-51 片外扩展的 C 语言编程 4.2.1 8255 与 8031 接口 C 应用程序举例 例 5 8255 控制打印机。 图 7.7 是 8031 扩展 8255 与打印机接口的电路。 8255 的片选线为 P0.7 ,打印机与 8031 采用查询方式交换数据。打印机的状态信号 输入给 PC7 ,打印机忙时 BUSY=1 ,微型打印机的数据输入采用选 通控制,当 ---STB 上负跳变时数据被输入。 8255 采用方式 0 由 PC0 模拟产生 ---STB 信号。 按照接口电路,口 A 地址为 7CH ,口 C 地址为 7EH ,命令口地 址为 7FH , PC7~PC4 输入, PC3~PC0 输出。方式选择命令字为 8EH 。

29 单片机 C 语言应用程序设计 图 4.3 8031 扩展 8255 与打印机接口的电路

30 单片机 C 语言应用程序设计 向打印机输出字符串 "WELCOME" 的程序如下: # include # define uchar unsigned char # define COM8255 XBYTE[0x007f ] /* 命令口地址 */ # define PA8255 XBYTE[ 0x007c] /* 口 A 地址 */ # define PC8255 XBYTE[ 0x007e] /* 口 C 地址 */ void toprn ( uchar *p ) / * 打印字符串函数 */ { while ( * p!= '\0') {while (( 0x80 & PC8255 )! =0 ) ; /* 查询等待打印机的 BUSY 状态 */

31 单片机 C 语言应用程序设计 PA8255 = * p ; /* 输出字符 */ COM8255 = 0x00 ; /* 模拟 STB 脉冲 */ COM8255=0x01 ; p++ ; } void main ( void ) { uchar idata prn [ ]= "WELCOME" ; /* 设测试用字符串 */ COM8255=0x8e ; /* 输出方式选择命令 */ toprn ( prn ) ; /* 打印字符串 */ }

32 单片机 C 语言应用程序设计 例 6 EPROM 编程器。 由 8031 扩展 1 片 EPROM2716 、 2 片 SRAM6116 及 1 片 8255 构成 EPROM 编程器,编程对象是 EPROM2732 。扩展编程系统中 2716 用来存放固化用监控程序,用户的待固化程序放在 2 片 6116 中。 8255 的口 A 作编程器数据口,口 B 输出 2732 的低 8 位地址, PC3~PC0 输出 2732 高 4 位地址, PC7 作 2732 启动保持控制器与 PGM 连接。 译码地址为: 6116(1) : 0800H ; 6116(2) : 1000H~17FFH ; 8255 的口 A : 07FCH ;口 B : 07FDH ;口 C : 07FEH ;命令口: 07FFH 。

33 单片机 C 语言应用程序设计 8255 的口 A 、口 B 、口 C 均工作在方式 0 输出,方式选择命令字 为 80H ; 2732 的启动编程和停止编程,由 PC7 的复位 / 置位控制, 当 PC7=0 时启动编程, PC7=1 时,编程无效。 EPROM 编程如下所示,参数为 RAM 起始地址、 EPROM 起始 地址和编程字节数。 # include # define COM8255 XBYTE [0x07ff ] # define PA8255 XBYTE [0x07fc] # define PB8255 XBYTE [0x07fd ] # define PC8255 XBYTE [0x07fe ] # define uchar unsigned char # define uint unsigned int

34 单片机 C 语言应用程序设计 void d1_ms ( unit x ) ; void program (ram, eprom, con ) uchar xdata * ram ; /* RAM 起始地址 */ uint eprom, con ; /* EPROM 起始固化地址,固化长度 */ { int i ; COM8255=0x08 ; /* 送方式选择命令字 */ COM8255=0x0f ; /* PC7=1 */ for (i=0 ; i<con ; i++ ) { PA8255= * ram ; /* 固化内容口 A 锁存 */ PB8255=eprom % 256 ; /* 2732 地址低 8 位 */ PC8255=eprom /256 ; /* 2732 地址高 4 位 */

35 单片机 C 语言应用程序设计 eprom ++ ; ram ++ ; COM8255=0x0e ; /* PC7=0 */ d1_ms (50 ) ; COM8255=0x0f ; /* PC7=1 */ } main ( ) { program ( 0x1000,0x0000,0x0100 ) ; }

36 单片机 C 语言应用程序设计 4.2.2 MCS-51 数据采集的 C 语言编程 例 7 ADC0809 与 8031 接口的数据采集程序举例。

37 单片机 C 语言应用程序设计 程序如下: # include # define uchar unsigned char # define IN0 XBYTE [ 0x7ff8 ] /* 设置 AD0809 的通道 0 地址 */ sbit ad_busy =P3^3 ; /* 即 EOC 状态 */ void ad0809 ( uchar idata *x ) /* 采样结果放指针中的 A/D 采集函数 */ { uchar i ; uchar xdata *ad_adr ; ad_adr= & IN0 ; for ( i=0 ; i<8 ; i++ ) /* 处理 8 通道 */ { *ad_adr=0 ; /* 启动转换 */

38 单片机 C 语言应用程序设计 i=i ; /* 延时等待 EOC 变低 */ i=i ; while (ad_busy = =0 ) ; /* 查询等待转换结束 */ x[i ]= * ad_adr ; /* 存转换结果 */ ad_adr ++ ; /* 下一通道 */ } void main ( void ) { static uchar idata ad [ 10 ] ; ad0809 ( ad ) ; /* 采样 AD0809 通道的值 */ }

39 单片机 C 语言应用程序设计 例 8 AD574 与 8031 接口的数据采集程序举例。

40 单片机 C 语言应用程序设计 源程序如下: # include # inlucde # define uint unsigned int # define ADCOM XBYTE[ 0xff7c ] /* 使 A0=0 , R/C=0 , CS=0 */ # define ADLO XBYTE [ 0xff7f ] /* 使 R/C =1 , A0=1 , CS=0 */ # define ADHI XBYTE [ 0xff7d ] /* 使 R/C=1 , A0=0 , CS =0 */ sbit r = P3 ^ 7 ; sbit w = P3 ^ 6 ; sbit adbusy = P1 ^ 0 ;

41 单片机 C 语言应用程序设计 uint ad574 ( void ) /* AD574 转换器 */ { r = 0 ; /* 产生 CE=1 */ w = 0 ; ADCOM = 0 ; /* 启动转换 */ while ( adbusy = =1 ) ; /* 等待转换 */ return ( ( uint )(ADHI<<4 )+( ADLO &0x0f ) ) ; /* 返回 12 位采样值 */ } main ( ) { uint idata result ; result =ad574 ( ) ; /* 启动 AD574 进行一次转换,得转换结果 */ }

42 单片机 C 语言应用程序设计 2.2.3 MCS-51 输出控制的 C 语言编程 例 9 8031 与 DAC0832 双缓冲接口的数据转换程序举例 。

43 单片机 C 语言应用程序设计 将 data1 和 data2 数据同时转换为模拟量的 C51 程序如下: # include # define INPUTR1 XBYTE[ 0x8fff ] # define INPUTR2 XBYTE[ 0xa7ff] # define DACR XBYTE [0x2fff ] # define uchar unsigned char void dac2b (data1,data2 ) uchar data1, data2 ; { INPUTR1 = data1 ; /* 送数据到一片 0832 */ INPUTR2 = data2 ; /* 送数据到另一片 0832 */ DACR= 0 ; /* 启动两路 D/A 同时转换 * / }

44 单片机 C 语言应用程序设计 例 10 8031 与 DAC0832 单缓冲区接口的数据转换举例。 图 4.7 DAC0832 与 8031 的单缓冲接口

45 单片机 C 语言应用程序设计 按片选线确定 FFFEH 为 DAC0832 的端口地址。使运行输出端 输出一个锯齿波电压信号的 C51 程序如下: # include # define DA0832 XBYTE [0xfffe ] # define uchar unsigned char # define uint unsigned int void stair (void ) { uchar i ; while ( 1 ) {for ( i=0 ; i<=255 ; i=I++ ) /* 形成锯齿波输出值,最大值为 255 */ { DA0832 = i ; /* D/A 转换输出 */ }

46 单片机 C 语言应用程序设计 例 11 8031 与 AD7521 接口的数据转换程序举例。 图 4.8 AD7521 与 8031 的接口

47 单片机 C 语言应用程序设计 使 AD7521 输出梯形波的 C51 程序如下: # include # define DA7521L XBYTE[0x7fff ] # define DA7521H XBYTE[0xbfff ] # define UP 0x010 # define T 1000 # define uint unsigned int

48 单片机 C 语言应用程序设计 void dlms ( uint a ); void stair(void) { uint i ; for ( i=0 ; i<=4095 ; i=i+UP ) /* 以阶高增量增值,形成梯形波输出值, 最大 4095*/ { DA7521L= i % 256 ; /* 送低 8 位数据到第一级缓冲器 */ DA7521H= i /256 ; /* 送高 4 位数据到高 4 位缓冲器,同时送 低 8 位到第二级 /* 缓冲转换 */ dlms ( T ) ; /* 延时 */ }

49 单片机 C 语言应用程序设计 4.3 频率量测量的 C 语言编程 4.3.1 测量频率法 测量频率法的最简单的接口电路,可将频率脉冲直接连接到 MCS-51 的 T1 端,将 8031 的 T/C0 用作定时器, T/C1 用作计数器。 在 T/C0 定时时间里,对频率脉冲进行计数。 T/C1 的计数值便是 单位定时时间里的脉冲个数。

50 单片机 C 语言应用程序设计 定时 输入脉冲 < T 图 2.10 测量频率中的脉冲丢失

51 单片机 C 语言应用程序设计 例 12 带同步控制的频率测量。 图 4.11 带同步控制的频率测量法接口

52 单片机 C 语言应用程序设计 控制时,首先 P1.0 发一个清零负脉冲,使 U 1 、 U 2 两个 D 触发 器复位,其输出封锁与门 G 1 和 G 2 。接着由 P1.1 发一个启动正脉 冲,其有效上升沿使 U 1 =1 ,门 G 1 被开放。之后,被测脉冲上升 沿通过 G 2 送 T1 计数;同时 U 2 输出的高电平使 INT0 =1 ,定时器 0 的门控 GATE 有效,启动 T/C0 开始定时。直到定时结束时,从 P1.0 发一负脉冲,清零 U 2 ,封锁 G 2 ,停止 T/C1 计数,完成一次 频率采样过程。

53 单片机 C 语言应用程序设计 测量 T/C 定时时间为 500 ms ,这样长的时间定时,先由 T/C0 定时 100 ms ,之后软件 5 次中断后的时间即为 5×100 ms=500 ms 。 中断次数的计数值在 msn 中。 T/C0 定时 100 ms 的计数初值: 03B0H 。计数器 1 采用 16 位计 数。设 T/C0 为高优先级,允许计数中断过程定时中断,即定时 时间到就中止计数。 tf 为 500 ms 定时时间到标志。程序如下:

54 单片机 C 语言应用程序设计 #include #define uchar unsigned char #define uint unsigned int #define A 5 /*500 ms 的中断次数 */ sbit P1_0=P1^0; sbit P1_1=P1^1; uchar msn=A ; bit idata tf=0 ; /*500 ms 时间到标志 */

55 单片机 C 语言应用程序设计 uint count(void) { P1_0=0 ; P1_0=1 ; /* 产生清零用负脉冲 */ TMOD=0x59 ; TH1=0x00; TL1=0x00;/* T/C1 计数器 */ TH0=0x3c ; TL0=0xb0 ; /* T/C0 定时器 100 ms */ TR0=1 ; TR1=1 ; PT0=1 ; ET0=1 ; ET1=1 ; EA=1 ; /* 启动 T/C ,开中断 */ P1_1=0 ; P1_1=1 ; /* 产生启动正脉冲 */ while (tf!=1 ) ; /* 等待 500 ms 定时到 */ P1_0=0 ; P1_0=1 ; /* 产生负脉冲,封锁 G2 */ TR0=0 ; TR1=0 ; /* 关 T/C */ return (TH1*256+TL1) ; / 返回计数值 */ }

56 单片机 C 语言应用程序设计 void timer0( void ) interrupt 1 using 1 /* 100 ms 定时中断服务 */ { TH0=0x3c ; /* 重置初值 */ TL0=-0xb0 ; msn - - ; if ( msn = = 0) { msn=A ; tf=1 ; } /* 500 ms 定时时间到设标志 */ } void timer 1 (void ) interrupt 3 { } void main ( void ) { float rate ; rate=( 10/A )* count( ) ; /* 得每秒的计数率 */ }

57 单片机 C 语言应用程序设计 4.3.2 频率脉冲的测量周期法 图 4.15 周期测量接口

58 单片机 C 语言应用程序设计 图 4.12 频率与周期波

59 单片机 C 语言应用程序设计 例 13 测量周期的程序举例。 设 fosc = 6 MHz ,机器周期为 2 μs ,测周期的测量值为计数 值乘以 2 。用 C 语言编写的程序如下: #include #define uint unsigned int sbit P1_0=P1^0 ; uint count,period ; bit rflag=0 ; / * 周期标志 */ void control (void) {

60 单片机 C 语言应用程序设计 TMOD=0x09 ; /* 定时器 / 计数器 0 为方式 1*/ IT0=1 ; TR0=1 ; TH0=0 ; TL0=0 ; P1_0=0 ; P1_0=1 ; /* 触发器清零 */ TR0=1 ; ET0=1 ; EA=1 ; /* 启动 T/C0 开中断 */ } void int_0(void)interrupt 0 using 1 /* INT0 中断服务 */ { EA=0 ; TR0=0 ; count=TL0+TH0*256 ; /* 取计数值 */ rflag=1 ; /* 设标志 */ EA=1; }

61 单片机 C 语言应用程序设计 void main(void) { contro1( ) ; while(rflag==0) ; /* 等待一周期 */ period=count*2 ; /* fosc=6 MHz , 2 μs 计数增 1 ,周期值单位 μs */ }


Download ppt "单片机 C 语言应用程序设计 主讲教师:廉哲 QQ:17434548 电话: 13840210518 办公室:综合楼 C318."

Similar presentations


Ads by Google