使用C8051F310开发板通过汇编语言Keil编写代码实现功能:1. 启动循环时 abcdef 全亮(显示 0),延时 2 秒后熄灭,然后蜂鸣器响 0.5 秒,再开始按设定模式和 频率显示。 2. 可通过按键设置字段循环频率(范围为 1 ~ 9 次/秒) 3. 可通过按键切换变化模式(顺时针/逆时针),此时扫描频率应不变。 4. 通过 KINT 键实现启动和暂停功能,暂停时 D9 灯亮。 5. 利用单片机内部定时器定时,KINT 键输入和定时器控制均要求采用中断方式
时间: 2024-03-17 20:40:26 浏览: 115
以下是C8051F310开发板汇编语言Keil代码的示例,实现上述功能:
```
ORG 0H ; 程序起始地址
LJMP Main ; 跳转到主程序
ORG 0BH ; 中断向量表,定时器0中断
LJMP Timer0_ISR
ORG 33H ; 中断向量表,外部中断0
LJMP KINT_ISR
ORG 3FH ; 中断向量表,外部中断1
LJMP KEYP_ISR
; 定义变量
COUNT DB 0 ; 计数器
MODE DB 0 ; 变化模式,0表示顺时针,1表示逆时针
FREQ DB 1 ; 循环频率,初始值为1
; 按键扫描函数,返回扫描结果
ScanKey:
MOV P1, #0FFH ; 将P1口设置为输入
ACALL Delay ; 延时一段时间,确保P1口稳定
MOV A, P1 ; 读取P1口数据
CPL A ; 取反,使按键按下时对应位为0
RET
; 延时函数,参数为时间(毫秒)
Delay:
MOV R0, #0FH ; 设置计数器初值,经过一次循环计数器减一
DelayLoop:
MOV R1, #250 ; 设置内层循环计数器初值,一次循环耗时1ms
InnerLoop:
DJNZ R1, InnerLoop; 内层循环
DJNZ R0, DelayLoop; 外层循环
RET
; 定时器0中断服务程序
Timer0_ISR:
; 计数器加一
INC COUNT
; 根据变化模式和循环频率显示对应的字母
MOV A, COUNT
DIV AB, #FREQ ; 将计数器除以循环频率
MOV R0, B ; 获取商
MOV A, MODE
CJNE A, #0, ReverseMode ; 如果变化模式为逆时针,则倒序显示
MOV P0, #0BFH ; abcdef全亮
MOV R1, #0
CJNE R0, #0, ShowNextLetter ; 如果商不为0,则显示下一个字母
MOV R0, #6 ; 如果商为0,则显示第一个字母
ShowNextLetter:
MOV A, R0
ADD A, #0BFH
MOV P0, A ; 显示对应的字母
ACALL Delay ; 延时
MOV P0, #0FFH ; 熄灭
ACALL Delay ; 延时
; 检测KINT键是否按下
ACALL ScanKey
MOV A, P1
ANL A, #01H
JZ Timer0_Resume ; 如果没有按下,则继续计时
; 暂停计时,等待再次按下KINT键
SETB P3.1
SJMP Timer0_ISR
Timer0_Resume:
CLR P3.1
; 检测KEYP键是否按下
ACALL ScanKey
MOV A, P1
ANL A, #02H
JZ Timer0_ISR ; 如果没有按下,则继续计时
; 切换变化模式
CPL MODE
MOV MODE, ACC
SJMP Timer0_ISR
; 外部中断0中断服务程序
KINT_ISR:
; 检测KINT键是否按下
ACALL ScanKey
MOV A, P1
ANL A, #01H
JZ KINT_Pause ; 如果按下,则暂停计时
; 如果没有按下,则继续计时
CLR P3.1
SJMP KINT_ISR
KINT_Pause:
SETB P3.1
SJMP KINT_ISR
; 外部中断1中断服务程序
KEYP_ISR:
; 检测KEYP键是否按下
ACALL ScanKey
MOV A, P1
ANL A, #02H
JZ KEYP_ISR ; 如果按下,则等待松开
; 如果没有按下,则设置循环频率
MOV A, COUNT
DIV AB, #100 ; 计算当前计数器的值,即每秒的循环次数
MOV A, B
ADD A, #1 ; 循环频率加1
CJNE A, #10, SetFreq ; 如果循环频率不大于9,则设置
MOV A, #1 ; 如果循环频率大于9,则循环频率重置为1
SetFreq:
MOV FREQ, A
SJMP KEYP_ISR
Main:
; 初始化端口
MOV P0, #0FFH ; 端口P0设置为输出
MOV P1, #0FFH ; 端口P1设置为输入
MOV P3, #0H ; 端口P3设置为输出
SETB P3.0 ; 蜂鸣器初始为关闭状态
SETB IE.1 ; 允许外部中断0
SETB IE.3 ; 允许外部中断1
MOV TMOD, #01H ; 定时器0设置为定时器模式
MOV TH0, #0FEH ; 定时器0初值,1ms
SETB TR0 ; 启动定时器0
SETB EA ; 允许中断
; 主循环
MainLoop:
ACALL Delay ; 延时
; 检测KINT键是否按下
ACALL ScanKey
MOV A, P1
ANL A, #01H
JZ MainLoop ; 如果按下,则等待松开
; 如果没有按下,则启动计时器
CLR P3.1
MOV COUNT, #0 ; 计数器清零
SJMP MainLoop
```
请注意,以上代码仅供参考,实际使用时需要根据具体情况进行修改和调整。同时,还需要根据具体的硬件连接情况进行相应的配置和调试。
阅读全文