[示例代码] T0定时器中断模式实验

[复制链接]
1378|19
 楼主| 家有两宝呀 发表于 2020-11-29 14:54 | 显示全部楼层 |阅读模式
程序声明 KF8F系列单片机开发板演示程序
标 题: T0定时器中断模式实验
项 目 名: 04-T0_Timer_Interrupt_TEST
开发环境:ChipON IDE
作 者:上海芯旺微电子有限公司
功能简述: T0定时中断模式的使用,使得数码管从0~9999计数,1秒增加1,当加到 9999时,又从0开始计数。

 楼主| 家有两宝呀 发表于 2020-11-29 14:54 | 显示全部楼层
4.2 硬件说明
本实验运用到两个模块,一个是单片机内部功能模块,定时器0(T0),另
一个是数码管显示模块。数码管具体特性在此之前已经讲解过,在此不作敷述,
T0属于内部模块,不需进行接线操作。
 楼主| 家有两宝呀 发表于 2020-11-29 14:55 | 显示全部楼层
4.3 程序设计说明
T0是一个8位的定时/计数器,当T0寄存器值加到255时,再加1,则会产生溢
出,T0寄存器的值返回到0开始重新计数。
 楼主| 家有两宝呀 发表于 2020-11-29 14:56 | 显示全部楼层
使用T0定时器,只需配置OPTR一个寄存器,其各个位如图4.1所示。在此重
点讲解定时器0的分频器使用,例如我们采用8M频率,T0工作在定时模式下为每
个机器周期加1,则定时器每次加1的时间是(1/8M)*4=0.5us。如果此时将预分
频器分频比设置成64分频,那么定时器每次加1的时间就是0.5us*64=32us。如果
我们需要一个5MS的定时,那么我们需要156个这样的计数。此时我们即可将T0
寄存器初始值设为100,当T0数值加到256时正好是156个计数,这样便会产生一
个5MS的定时。200个5MS这样的定时就是1S的时间。当T0用于定时中断功能时,
关于OPTR寄存器的说明如下:
 楼主| 家有两宝呀 发表于 2020-11-29 14:57 | 显示全部楼层
1、 配置T0CS = 0,使其工作于定时模式。
2、 PS<2:0>位用来设置T0预分频器分频比,如需要进行64分频,则PS0 = 1,
PS1 = 0,PS2 = 1。
其它位按照上电默认配置即可。
948475fc34630dd5db.png
 楼主| 家有两宝呀 发表于 2020-11-29 14:57 | 显示全部楼层
C程序代码
  1. #include<KF8F312.h>
  2. /*********************宏定义****************************/
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. /*********************宏定义结束****************************/
  6. /**********************全局变量*****************************/
  7. uchar const Arr_num[] = {0X3F,
  8. 0X06,
  9. 0X5B,
  10. 0X4F,
  11. 0X66,
  12. 0X6D,
  13. 0X7D,
  14. 0X07,
  15. 0X7F,
  16. 0X6F
  17. }; //共阴接法,数码管显示笔形码
  18. uchar Unit, Decade, Hundred, Thousand; //定义个十百千位
  19. uchar time_1s; //定时计数器
  20. /**********************全局变量结束*************************/
  21. /************************
  22. * 函数名 :Delay_200us
  23. * 函数功能:短时间延时
  24. * 入口参数:无
  25. * 返回 :无
  26. ************************/
  27. void Delay_200us()
  28. {
  29. uchar i = 60;
  30. while(--i);
  31. }
  32. /************************
  33. * 函数名 :Init_fun
  34. * 函数功能:初始化函数
  35. * 入口参数:无
  36. * 返回 :无
  37. ************************/
  38. void Init_fun(void)
  39. {
  40. OSCCTL = 0x60; // 设置为8M
  41. /*****端口初始化********/
  42. TR0 = 0x08; //设置P03端口为输入
  43. TR1 = 0x00; //设置P1端口为输出
  44. TR2 = 0x00; //设置P2端口为输出
  45. P0 = 0;
  46. P1 = 0;
  47. P2 = 0;
  48. /****初始化定时器0*****/
  49. OPTR = 0x05; //定时器0,分频为1:64,现在晶振为8M,一条指令为
  50. 0.5us(1/(8M/4)=0.5us ),则经过32us,计数1
  51. T0 = 0x64; //设定定时5MS, 0X64=100D 即计数156后为256溢
  52. 出产生中断,而156*32=4992 约为5000us=5ms
  53. INTCTL = 0XA0; //使能总中断AIE、使能T0中断T0IE、清T0中断标志
  54. 位T0IF
  55. }
  56. void main()
  57. {
  58. uchar i;
  59. Unit = 0;
  60. Decade = 0;
  61. Hundred = 0;
  62. Thousand = 0;
  63. time_1s = 0;
  64. Init_fun(); //初始化
  65. while(1)
  66. {
  67. for(i = 0; i < 100; i++)
  68. {
  69. P2 = 0XE0; //打开数码管的 个位
  70. P1 = Arr_num[Unit];
  71. Delay_200us();
  72. P1 = 0;
  73. P2 = 0XF0; //消影
  74. P2 = 0XD0; //打开数码管的 十位
  75. P1 = Arr_num[Decade];
  76. Delay_200us();
  77. P1 = 0;
  78. P2 = 0XF0; //消影
  79. P2 = 0XB0; //打开数码管的 百位
  80. P1 = Arr_num[Hundred];
  81. Delay_200us();
  82. P1 = 0;
  83. P2 = 0XF0; //消影
  84. P2 = 0X70; //打开数码管的 千位
  85. P1 = Arr_num[Thousand];
  86. Delay_200us();
  87. P1 = 0;
  88. P2 = 0XF0; //消影
  89. }
  90. }
  91. }
  92. //中断函数
  93. void int_fun() __interrupt
  94. {
  95. if(T0IF)
  96. {
  97. T0IF = 0; //清零中断标志
  98. T0 = 0x64; //T0重新赋值
  99. if(time_1s++ >= 200) //判断是否达到1s记时 5ms*200
  100. = 1s
  101. {
  102. time_1s = 0; //清零计数器
  103. Unit++; //个位相加
  104. if(Unit == 10)
  105. {
  106. Unit = 0;
  107. Decade++; //十位相加
  108. if(Decade == 10)
  109. {
  110. Decade = 0;
  111. Hundred++; //百位相加
  112. if(Hundred == 10)
  113. {
  114. Hundred = 0;
  115. Thousand++; //千位相加
  116. if(Thousand == 10)
  117. {
  118. Thousand = 0;
  119. }
  120. }
  121. }
  122. }
  123. }
  124. }
  125. }
 楼主| 家有两宝呀 发表于 2020-11-29 14:58 | 显示全部楼层
汇编程序代码
 楼主| 家有两宝呀 发表于 2020-11-29 14:58 | 显示全部楼层
  1. .INCLUDE "KF8F312.INC"
  2. ;;;;;;;;;;;;;;;;通用寄存器;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. DELAY_NUM1    .EQU 0X81    ;延时用的临时变量
  4. DELAY_NUM2    .EQU 0X82    ;延时用的临时变量
  5. PSW_TEMP    .EQU 0X83    ;PSW的临时保存变量
  6. PCH_TEMP    .EQU 0X84    ;PCH的临时保存变量
  7. UNIT     .EQU 0X85    ;数码管个位
  8. DECADE     .EQU 0X86    ;数码管十位
  9. HUNDRED     .EQU 0X87    ;数码管百位
  10. THOUSAND    .EQU 0X88    ;数码管千位
  11. TIME_1S     .EQU 0X89    ;累计计数1s
  12. FLAG_1S     .EQU 0X8A    ;计数1s的标志位
  13. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  14. .ORG 0X0000
  15.    NOP
  16.    JMP MAIN                   ;入口
  17. .ORG 0X0004
  18. JMP INTERRUPT
  19. ;*************************************************************
  20. *****************
  21. ;* 函 数 名: DIG_DATA
  22. ;* 函数功能: 数码管显示数据编码
  23. ;* 入口参数: 无
  24. ;* 返    回: R0,数码管显示的编码值
  25. ;* 注  意 : 查表函数需在程序开头定义,避免编译后表中元素存在Flash的不
  26. 同页造成查表出错
  27. ;*************************************************************
  28. *****************
 楼主| 家有两宝呀 发表于 2020-11-29 14:59 | 显示全部楼层
  1. DIG_DATA
  2. ADD PCL, R2
  3. RRET R0 ,#0X3F    ;0
  4. RRET R0 ,#0X06    ;1
  5. RRET R0 ,#0X5B    ;2
  6. RRET R0 ,#0X4F    ;3
  7. RRET R0 ,#0X66    ;4
  8. RRET R0 ,#0X6D    ;5
  9. RRET R0 ,#0X7D    ;6
  10. RRET R0 ,#0X07    ;7
  11. RRET R0 ,#0X7F    ;8
  12. RRET R0 ,#0X6F    ;9
  13. RRET R0 ,#0X77    ;A
  14. RRET R0 ,#0X7C    ;B
  15. RRET R0 ,#0X39    ;C
  16. RRET R0 ,#0X5E    ;D
  17. RRET R0 ,#0X79    ;E
  18. RRET R0 ,#0X71    ;F
  19. RRET R0 ,#0X00    ;空
  20. ;;;;;;;;;;;;;;;中断部
  21. 分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 楼主| 家有两宝呀 发表于 2020-11-29 14:59 | 显示全部楼层
  1. INTERRUPT
  2. ;;保护现场作用,根据实际情况进行保存,中断内部和外部都使用的资源需要保
  3. 护,常规需要保护的内容有PSW PCH R0 R1
  4. SWAPR R1 ,PSW
  5. MOVPSW_TEMP, R1
  6. MOVR1 , PCH
  7. MOVPCH_TEMP, R1
  8. ;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
  9. ;中断处理
  10. JB INTCTL,T0IF
  11. JMP INT_END
  12. CLR INTCTL,T0IF
  13. MOV R1 ,#0X64
  14. MOV T0, R1           ;设定定时5MS
  15. INC TIME_1S
  16. MOV R1 ,#0XC8         ;累计 计数200个5ms 即1S
  17. XOR R1 ,TIME_1S
  18. JB PSW,Z
  19. JMP INT_END
  20. CLR  TIME_1S
  21. MOV R1 ,#0X55
  22. MOV FLAG_1S, R1
  23. ;...
  24. ;...
  25. ;...
  26. ;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
  27. ;恢复现场作用
 楼主| 家有两宝呀 发表于 2020-11-29 15:00 | 显示全部楼层
  1. INT_END
  2. MOVR1 , PCH_TEMP
  3. MOVPCH, R1
  4. SWAPR R1 , PSW_TEMP
  5. MOV PSW, R1
  6. IRET
  7. ;;;;;;;;;;;;;;中断部分结
  8. 束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  9. ;;;;;;;;;;;;入口函数,主程
  10. 序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  11. MAIN
  12. CALL INIT_ALL       ;初始化寄存器
  13. CALL INIT_RAM               ;初始化RAM
  14. TIME_1S_LOOP
  15. CALL LED_DISPLAY    ;数码管显示当前数值
  16. MOV R0 ,#0X55
  17. XOR R0 ,FLAG_1S
  18. JB  PSW,Z
  19. JMP TIME_1S_LOOP
  20. ;; 时间增加操作
  21. CLR FLAG_1S
  22. INC UNIT         ;个位数字的递增
  23. MOV R0 ,UNIT
  24. XOR R0 ,#0X0A
  25. JB PSW ,Z
  26. JMP C_DIS
  27. CLR UNIT
  28. INC DECADE         ;十位数字的递增
  29. MOV R0 ,DECADE
  30. XOR R0 ,#0X0A
  31. JB PSW ,Z
  32. JMP C_DIS
  33. CLR DECADE
  34. INC HUNDRED         ;百位数字的递增
  35. MOV R0 ,HUNDRED
  36. XOR R0 ,#0X0A
  37. JB PSW ,Z
  38. JMP C_DIS
  39. CLR HUNDRED
  40. INC THOUSAND       ;千位数字的递增
  41. MOV R0 ,THOUSAND
  42. XOR R0 ,#0X0A
  43. JB PSW ,Z
  44. JMP C_DIS
  45. CLR THOUSAND
  46. C_DIS
  47. JMP TIME_1S_LOOP
  48. CRET
  49. ;;;;;;;;;;;;;主程序结
  50. 束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  51. ;*************************************************************
  52. *****************
  53. ;* 函 数 名: INIT_ALL
  54. ;* 函数功能: 初始化函数,对各种寄存器的初始化
  55. ;* 入口参数: 无
  56. ;* 返    回: 无
  57. ;*************************************************************
  58. *****************
 楼主| 家有两宝呀 发表于 2020-11-29 15:01 | 显示全部楼层
  1. INIT_ALL
  2. ;调入校准信息到控制寄存器
  3. CALL #0xFFF
  4. MOV OSCCAL0, R0    ;晶振校准0
  5. NOP
  6. NOP
  7. CALL #0xFFE
  8. MOV OSCCAL1, R0    ;晶振校准1
  9. NOP
  10. NOP
  11. ;选择工作频率
  12. MOV R0 ,#0x60   
  13. MOV OSCCTL, R0    ;设置为8M
  14. ;端口初始化
  15. MOV R0 ,#0xFF
  16. MOV TR0, R0     ;设置P0端口为输入
  17. MOV R0 ,#0x00
  18. MOV TR1, R0     ;设置P1端口为输出
  19. MOV R0 ,#0X0F
  20. MOV TR2, R0     ;设置P2端口的4,5,6,7为输出,0,1,2,3,为输入
  21. CLR P0
  22. CLR P1
  23. CLR P2
  24. ;初始化定时器0
  25. MOV R0 ,#0X84
  26. MOV OPTR, R0   ;定时器0,分频为1:32,现在晶振为4M,一条指令为1us
  27. (1/(4M/4)=1us ),则经过32us,计数1
  28. MOV R0 ,#0X64
  29. MOV T0, R0     ;设定定时5MS,  0X64=100D  即计数156后为256
  30. 溢出产生中断,而156*32=4992 约为5000us=5ms
  31. MOV R0,#0Xa0
  32. MOV INTCTL,R0       ;使能总中断AIE、使能T0中断T0IE、清T0中断标志
  33. 位T0IF
  34. CRET
  35. ;*************************************************************
  36. *****************
  37. ;* 函 数 名: LED_DISPLAY
  38. ;* 函数功能: 数码管显示函数,由4个8位LED灯显示
  39. ;* 入口参数: THOUSAND 千位 ,HUNDRED 百位 ,SMQ_S 十位, UNIT 个位  ,
  40. 每个数的范围 0~f
  41. ;* 返    回: 无
  42. ;*************************************************************
  43. *****************
 楼主| 家有两宝呀 发表于 2020-11-29 15:01 | 显示全部楼层
  1. LED_DISPLAY
  2. MOV R0 , #0XE0
  3. MOV P2 , R0        ;打开数码管的 个位
  4. MOV R2 , UNIT
  5. CALL DIG_DATA
  6. MOV P1 , R0
  7. CALL DELAY
  8. CLR P1     ;消抖
  9. MOV R0 ,#0XF0
  10. MOV P2 , R0
  11. MOV R0 ,#0XD0
  12. MOV P2 , R0        ;打开数码管的 十位
  13. MOV R2 , DECADE
  14. CALL DIG_DATA
  15. MOV P1 , R0
  16. CALL DELAY
  17. CLR P1     ;消抖
  18. MOV R0 ,#0XF0
  19. MOV P2 , R0
  20. MOV R0 , #0XB0
  21. MOV P2 , R0        ;打开数码管的 百位
  22. MOV R2 , HUNDRED
  23. CALL DIG_DATA
  24. MOV P1 , R0
  25. CALL DELAY
  26. CLR P1     ;消抖
  27. MOV R0 ,#0XF0
  28. MOV P2 , R0
  29. MOV R0 , #0X70
  30. MOV P2 , R0        ;打开数码管的 千位
  31. MOV R2 , THOUSAND
  32. CALL DIG_DATA
  33. MOV P1 , R0
  34. CALL DELAY
  35. CLR P1     ;消抖
  36. MOV R0 ,#0XF0
  37. MOV P2 , R0
  38. CRET
  39. ;*************************************************************
  40. *****************
  41. ;* 函 数 名: DELAY
  42. ;* 函数功能: 延时函数,时间为1ms
  43. ;* 入口参数: 无
  44. ;* 返    回: 无
  45. ;*************************************************************
  46. *****************
 楼主| 家有两宝呀 发表于 2020-11-29 15:02 | 显示全部楼层
  1. DELAY
  2. MOV R0,#0x12
  3. MOV DELAY_NUM1, R0
  4. LP0
  5. MOV R0,#0X12
  6. MOV DELAY_NUM2, R0
  7. LP1
  8. DECJZ DELAY_NUM2    ;DELAY_NUM2自减1,若为0,则跳过
  9. JMP LP1
  10. DECJZ DELAY_NUM1    ;DELAY_NUM1自减1,若为0,则跳过
  11. JMP LP0
  12. CRET         ;子程序返回
  13. ;/************************************************************
  14. ******************
  15. ;* 函 数 名: init_RAM
  16. ;* 函数功能: 初始化RAM
  17. ;* 入口参数: 无
  18. ;* 返    回: 无
  19. ;*************************************************************
  20. *****************/
 楼主| 家有两宝呀 发表于 2020-11-29 15:02 | 显示全部楼层
INIT_RAM     
CLR   R2       ;传递默认RAM值
; CLR RAM SET 0  BANK0
CLR   PSW ,RP0   
MOV   R0 ,#0X80   ;起始地址0x80
MOV   R1 ,#0X20   ;操作个数
CALL    INIT_RAM_0
; CLR RAM SET 0  BANK1
SET   PSW ,RP0   
MOV   R0 ,#0X80   ;起始地址0x80
MOV   R1 ,#0X01   ;操作个数
CALL    INIT_RAM_0
; 默认工作区域设定   BANK0
CLR   PSW ,RP0
; 其他变量的数值操作
   
   
   
CRET
;;;;;;;;;;;;;;;;;;执行默认数值装载到RAM区
INIT_RAM_0   
ST [R0],R2
INC R0
DECJZ R1
JMP  INIT_RAM_0
CRET  
   
.end
 楼主| 家有两宝呀 发表于 2020-11-29 15:03 | 显示全部楼层
通用寄存器
里面有晴雨 发表于 2020-12-11 18:01 | 显示全部楼层
感谢分享,这个**有有用处,我想是不是能够有打包文件发一下。
daichaodai 发表于 2020-12-12 14:28 来自手机 | 显示全部楼层
学习了,感谢楼主分享。
名字是啥样 发表于 2020-12-12 17:04 | 显示全部楼层
感谢楼主分享,感谢。
嵌入小菜菜 发表于 2020-12-22 14:10 | 显示全部楼层
感谢楼主耐心细致的分享,不错,不错的资料。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

62

主题

585

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部