[示例代码] P0口电平变化中断实验

[复制链接]
1895|19
 楼主| 家有两宝呀 发表于 2020-11-29 12:43 | 显示全部楼层 |阅读模式
程序声明KF8F系列单片机开发板演示程序 标 题: P0口电平变化中断实验
项 目 名: 02-IO_Change_Interrupt_TEST
开发环境:ChipON IDE
作 者:上海芯旺微电子有限公司
功能简述: 配置P02口电平变化中断,在中断处理函数中改变LED的亮灭状态,使得LED闪烁。

 楼主| 家有两宝呀 发表于 2020-11-29 12:43 | 显示全部楼层
硬件说明
使用杜邦线将单片机的P04口连接到单片机的P02口,改变P04口的输出电平,
使得P02口的电平发生变化,从而产生中断,在中断处理程序中改变LED的亮灭状
态,从而使得LED闪烁,接线图如图2.1所示。
809475fc327064b931.png
 楼主| 家有两宝呀 发表于 2020-11-29 12:44 | 显示全部楼层
程序设计说明 P0口每个引脚都具有电平变化中断功能,当引脚的当前电平与上次读P0寄存
器时的电平不匹配时将产生电平变化中断。
 楼主| 家有两宝呀 发表于 2020-11-29 12:45 | 显示全部楼层
IOCL为电平变化中断控制寄存器,将
IOCL某位置1将开启对应引脚的电平变化中断功能,如果该引脚电平发生变化,
不管电平变化中断是否使能,电平变化中断标志位(P0IF)都会置1,如果全局中
断使能位(AIE)和电平变化中断使能位(P0IE)都已置1,则会响应中断进入中断服
务子程序。除此之外,还需注意一下两点:
 楼主| 家有两宝呀 发表于 2020-11-29 12:45 | 显示全部楼层
1、 使用P0口电平中断功能,首先将相应引脚设置为数字输入模式,如果将某引
脚设置为输出或者设置为模拟输入口时将会自动禁止该引脚的电平变化中断
功能。
 楼主| 家有两宝呀 发表于 2020-11-29 12:46 | 显示全部楼层
2、 P0口各引脚的电平变化中断共用一个中断使能位P0IE和一个中断响应标志
位P0IF,所以同一时间只能判断一个端口的电平变化中断功能。
 楼主| 家有两宝呀 发表于 2020-11-29 12:49 | 显示全部楼层
3、 使用电平变化中断功能,当中断产生并进入中断处理函数时,必须读取当前
P0口电平,如在中断处理函数中加上 MOV P0。
 楼主| 家有两宝呀 发表于 2020-11-29 12:50 | 显示全部楼层
4、 除电平变化中断功能外,P0口还带有内部上拉功能(除P03口外),可通过
上拉功能控制寄存器PUR和OPTR寄存器中的PUPH来配置上拉功能是否打开。
同时只有将引脚设置为数字输入口时才可开启上拉电阻功能。例如,使能P02
口的上拉功能需作如下配置
  1. ANS2 = 0; // 寄存器 ANSEL 配置为数字口
  2. TR02 = 1; // 寄存器TR0 配置为输入口
  3. PUPH = 0; // 寄存器OPTR 使能上拉功能总使能位
  4. PUR2 = 1; // 寄存器PUR 使能P02上拉功能
 楼主| 家有两宝呀 发表于 2020-11-29 12:50 | 显示全部楼层
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. /*********************全局变量结束************************/
  20. /******************函数声明*******************************/
  21. void Init_fun();
  22. void Display();
  23. void Delay_200us();
  24. /******************函数声明结束***************************/
  25. /************************
  26. * 函数名 :init_fun
  27. * 函数功能:初始化函数
  28. * 入口参数:无
  29. * 返回 :无
  30. ************************/
  31. void Init_fun()
  32. {
  33. OSCCTL = 0x60; //设置为8M
  34. /*********端口初始化***********/
  35. TR0 = 0x08; //设置P03端口为输入
  36. TR1 = 0x00; //设置P1端口为输出
  37. TR2 = 0x00; //设置P2端口为输出
  38. P0 = 0;
  39. P1 = 0;
  40. P2 = 0xF0; //关闭数码管位选端
  41. }
  42. /************************
  43. * 函数名 :display
  44. * 函数功能:数码管显示
  45. * 入口参数:显示数字
  46. * 返回 :无
  47. ************************/
  48. void Display()
  49. {
  50. uint i; // 控制显示时长,确定自增的速度
  51. for(i = 0; i < 500; i++)
  52. {
  53. P2 = 0XE0; //打开数码管的 个位
  54. P1 = Arr_num[Unit];
  55. Delay_200us();
  56. P1 = 0;
  57. P2 = 0XF0; //消影
  58. P2 = 0XD0; //打开数码管的 十位
  59. P1 = Arr_num[Decade];
  60. Delay_200us();
  61. P1 = 0;
  62. P2 = 0XF0; //消影
  63. P2 = 0XB0; //打开数码管的 百位
  64. P1 = Arr_num[Hundred];
  65. Delay_200us();
  66. P1 = 0;
  67. P2 = 0XF0; //消影
  68. P2 = 0X70; //打开数码管的 千位
  69. P1 = Arr_num[Thousand];
  70. Delay_200us();
  71. P1 = 0;
  72. P2 = 0XF0; //消影
  73. }
  74. }
  75. /************************
  76. * 函数名 :Delay_200us
  77. * 函数功能:短时间延时
  78. * 入口参数:无
  79. * 返回 :无
  80. ************************/
  81. void Delay_200us()
  82. {
  83. uchar i = 60;
  84. while(--i);
  85. }
  86. /************************
  87. * 函数名 :main
  88. * 函数功能:程序入口主函数
  89. * 入口参数:无
  90. * 返回 :无
  91. ************************/
  92. void main()
  93. {
  94. Unit = Decade = Hundred = Thousand = 0;
  95. Init_fun();
  96. while(1)
  97. {
  98. Unit++; //个位加1
  99. if(Unit == 10) //如果个位的值加到10,那么个位归零,
  100. 十位加1,以下以此类推
  101. {
  102. Unit = 0;
  103. Decade++;
  104. if(Decade == 10)
  105. {
  106. Decade = 0;
  107. Hundred++;
  108. if(Hundred == 10)
  109. {
  110. Hundred = 0;
  111. Thousand++;
  112. if(Thousand == 10)
  113. {
  114. Thousand = 0;
  115. }
  116. }
  117. }
  118. }
  119. Display(); //显示函数调用
  120. }
  121. }
  122. //中断函数
  123. void int_fun() __interrupt
  124. {
  125. }
 楼主| 家有两宝呀 发表于 2020-11-29 14:34 | 显示全部楼层
汇编程序代码
 楼主| 家有两宝呀 发表于 2020-11-29 14:35 | 显示全部楼层
  1. .INCLUDE "KF8F312.INC"
  2. ;;;;;;;;;;;;;;;;通用寄存器;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. DELAY_NUM1    .EQU 0X81    ;延时用的临时变量
  4. DELAY_NUM2    .EQU 0X82    ;延时用的临时变量
  5. PSW_TEMP    .EQU 0X85    ;PSW的临时保存变量
  6. PCH_TEMP    .EQU 0X86    ;PCH的临时保存变量
  7. UNIT     .EQU 0X88    ;数码管个位
  8. DECADE     .EQU 0X89    ;数码管十位
  9. HUNDRED     .EQU 0X8A    ;数码管百位
  10. THOUSAND    .EQU 0X8B    ;数码管千位
  11. DIS_DEL     .EQU 0X8C    ;DIS_DEL是用来延时数值的递增用的,
  12. 数值越大,那么递增的速度就越慢
  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:36 | 显示全部楼层
  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. ;;;;;;;;;;;;;;;中断部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 楼主| 家有两宝呀 发表于 2020-11-29 14:36 | 显示全部楼层
  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. ;...
  11. ;...
  12. ;...
  13. ;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
  14. ;恢复现场作用
  15. INT_END
  16. MOVR1 , PCH_TEMP
  17. MOVPCH, R1   
  18. SWAPR R1 , PSW_TEMP
  19. MOV PSW, R1
  20. IRET
  21. ;;;;;;;;;;;;;;中断部分结
  22. 束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  23.    
  24.    
  25.    
  26. ;;;;;;;;;;;;;;入口函数,主程
  27. 序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  28. MAIN
  29. CALL INIT_ALL     ;初始化寄存器
  30.     CALL INIT_RAM           ;初始化RAM
  31. LOOP   
  32. INC UNIT       ;个位数字的递增
  33. MOV R0 ,UNIT
  34. XOR R0 ,#0X0A
  35. JB PSW ,Z
  36. JMP C_DIS
  37. CLR UNIT
  38.    
  39. INC DECADE       ;十位数字的递增
  40. MOV R0 ,DECADE
  41. XOR R0 ,#0X0A
  42. JB PSW ,Z
  43. JMP C_DIS
  44. CLR DECADE
  45.    
  46. INC HUNDRED       ;百位数字的递增
  47. MOV R0 ,HUNDRED
  48. XOR R0 ,#0X0A
  49. JB PSW ,Z
  50. JMP C_DIS
  51. CLR HUNDRED
  52.    
  53. INC THOUSAND     ;千位数字的递增
  54. MOV R0 ,THOUSAND
  55. XOR R0 ,#0X0A
  56. JB PSW ,Z
  57. JMP C_DIS  
  58. CLR THOUSAND
  59.    
  60. C_DIS   
  61. MOV R0,#0x33
  62. MOV DIS_DEL,R0     ;DIS_DEL是用来延时数值的递增用的,数值越
  63. 大,那么递增的速度就越慢
  64. CALL LED_DISPLAY    ;数码管显示当前数值
  65. DECJZ DIS_DEL   
  66. JMP $‐2         ;调整地址以当前地址减2的位置
  67. JMP LOOP
  68.    
  69. CRET
  70. ;*************************************************************
  71. *****************
  72. ;* 函 数 名: INIT_ALL
  73. ;* 函数功能: 初始化函数,对各种寄存器的初始化
  74. ;* 入口参数: 无
  75. ;* 返    回: 无
  76. ;*************************************************************
  77. *****************
 楼主| 家有两宝呀 发表于 2020-11-29 14:37 | 显示全部楼层
  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. ;***端口初始化********
  16. MOV R0 ,#0x08
  17. MOV TR0, R0      ;设置P0端口为输入
  18. MOV R0 ,#0x00
  19. MOV TR1, R0      ;设置P1端口为输出
  20. MOV R0 ,#0X00
  21. MOV TR2, R0      ;设置P2端口为输出
  22.    
  23. CLR P0
  24. CLR P1
  25. MOV R0 ,#0XF0       ;关闭数码管位选端
  26. MOV P2, R0      
  27. CRET
  28. ;*************************************************************
  29. *****************
  30. ;* 函 数 名: LED_DISPLAY
  31. ;* 函数功能: 数码管显示函数,由4个8位LED灯显示
  32. ;* 入口参数: THOUSAND 千位 ,HUNDRED 百位 ,SMQ_S 十位, UNIT 个位  ,
  33. 每个数的范围 0~f
  34. ;* 返    回: 无
  35. ;*************************************************************
  36. *****************
 楼主| 家有两宝呀 发表于 2020-11-29 14:37 | 显示全部楼层
  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.    
  12. MOV R0 ,#0XD0
  13. MOV P2 , R0        ;打开数码管的 十位
  14. MOV R2 , DECADE
  15. CALL DIG_DATA
  16. MOV P1 , R0
  17. CALL DELAY
  18. CLR P1     ;消隐
  19. MOV R0 ,#0XF0
  20. MOV P2 , R0
  21. MOV R0 , #0XB0   
  22. MOV P2 , R0        ;打开数码管的 百位
  23. MOV R2 , HUNDRED
  24. CALL DIG_DATA
  25. MOV P1 , R0
  26. CALL DELAY
  27. CLR P1     ;消隐
  28. MOV R0 ,#0XF0
  29. MOV P2 , R0   
  30. MOV R0 , #0X70   
  31. MOV P2 , R0        ;打开数码管的 千位
  32. MOV R2 , THOUSAND
  33. CALL DIG_DATA
  34. MOV P1 , R0
  35. CALL DELAY
  36. CLR P1     ;消隐
  37. MOV R0 ,#0XF0
  38. MOV P2 , R0   
  39. CRET
  40. ;*************************************************************
  41. *****************
  42. ;* 函 数 名: DELAY
  43. ;* 函数功能: 延时函数,时间为1ms
  44. ;* 入口参数: 无
  45. ;* 返    回: 无
  46. ;*************************************************************
  47. *****************
 楼主| 家有两宝呀 发表于 2020-11-29 14:38 | 显示全部楼层
  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 14:38 | 显示全部楼层
  1. INIT_RAM     
  2. CLR   R2       ;传递默认RAM值
  3. ; CLR RAM SET 0  BANK0
  4. CLR   PSW ,RP0   
  5. MOV   R0 ,#0X80   ;起始地址0x80
  6. MOV   R1 ,#0X20   ;操作个数
  7. CALL    INIT_RAM_0
  8. ; CLR RAM SET 0  BANK1
  9. SET   PSW ,RP0   
  10. MOV   R0 ,#0X80   ;起始地址0x80
  11. MOV   R1 ,#0X01   ;操作个数
  12. CALL    INIT_RAM_0
  13. ; 默认工作区域设定   BANK0
  14. CLR   PSW ,RP0
  15. ; 其他变量的数值操作
  16.    
  17.    
  18.    
  19. CRET
  20. ;;;;;;;;;;;;;;;;;;执行默认数值装载到RAM区
  21. INIT_RAM_0   
  22. ST [R0],R2
  23. INC R0
  24. DECJZ R1
  25. JMP  INIT_RAM_0
  26. CRET  
  27.    
  28. .end
嵌入小菜菜 发表于 2020-12-8 21:58 | 显示全部楼层
代码写的很整齐,不错,不错。
里面有晴雨 发表于 2020-12-11 18:03 | 显示全部楼层
这里面很多汇编语言是怎么回事呢?

幸福小强 发表于 2021-1-12 22:38 | 显示全部楼层
学习代码。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

62

主题

585

帖子

0

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