历史上的今天
今天是:2024年10月11日(星期五)
2021年10月11日 | STM8与汇编语言(6)--8位定时器应用之一
2021-10-11 来源:eefocus
STM8单片机中的外设资源是比较丰富的,定时器有8位的也有16位的,下面的实验程序,就是利用8位定时器4来进行延时,然后驱动LED闪烁。
同样还是利用ST的开发工具,生成一个汇编程序的框架,然后修改其中的main.asm,修改后的代码如下。
编译通过后,下载到开发板,运行程序,可以看到LED在闪烁,或者用示波器可以在LED引脚上看到方波。
在这里要特别提醒的是,从ST给的手册上看,这个定时器中的计数器是一个加1计数器,但本人在实验过程中感觉不太对,经过反复的实验,我认为应该是一个减1计数器(也许是我拿的手册不对,或许是理解上有误)。例如,当给定时器中的自动装载寄存器装入255时,产生的方波频率最小,就象下面代码中计算的那样,产生的方波频率为30HZ左右。若初始化时给自动装载寄存器装入1,则产生的方波频率最大,大约为3.9K左右。也就是说实际的分频数为ARR寄存器的值+1。
stm8/
#include "mapping.inc"
; #include "STM8S207S8.INC"
; 涉及到的硬件资源
; 下面定义端口D的寄存器地址
PD_ODR EQU $500f
PD_IDR EQU $5010
PD_DDR EQU $5011
PD_CR1 EQU $5012
PD_CR2 EQU $5013
; 定时器4的寄存器定义
TIM4_CR1 EQU $5340
TIM4_IER EQU $5341
TIM4_SR EQU $5342
TIM4_EGR EQU $5343
TIM4_CNTR EQU $5344
TIM4_PSCR EQU $5345
TIM4_ARR EQU $5346
; 定义堆栈空间的起始位置和结束位置
stack_start.w EQU $stack_segment_start
stack_end.w EQU $stack_segment_end
segment 'rom' ; 下面开始定义一个段,该段位于ROM中
main.l ; 定义复位后的第一条指令的标号(即入口地址)
;
; 首先要初始化堆栈指针
LDW X,#stack_end
LDW SP,X
; 下面初始化IO端口
; PD3设置成推挽输出
; PD7设置成悬浮输入
LD A,#08
LD PD_DDR,A ; 将PD3设置成输出,PD7设置成输入
LD A,#08
LD PD_CR1,A ; 将PD3设置成推挽输出
LD A,#00
LD PD_CR2,A ;
;
; 下面初始化定时器4
LD A,#$00
LD TIM4_IER,A ; 禁止中断
LD A,#$01
LD TIM4_EGR,A ; 允许产生更新事件
LD A,#$07
LD TIM4_PSCR,A ; 计数器时钟=主时钟/128=2MHZ/128
; 相当于计数器周期为64uS
LD A,#255
LD TIM4_ARR,A ; 设定重装载时的寄存器值,255是最大值
LD A,#255
LD TIM4_CNTR,A ; 设定计数器的初值
; 定时周期=(ARR+1)*64=16384uS
; 产生方波频率=30.5HZ
;
LD A,#$01
; b0 = 1,允许计数器工作
; b1 = 0,允许更新
LD TIM4_CR1,A ; 设置控制器,启动定时器
MAIN_LOOP.L
LD A,TIM4_SR ; 读入定时器4的状态
AND A,#01 ; 判断是否产生更新标志
JREQ MAIN_LOOP ; 若没有,则等待
LD A,#0 ; 清除更新标志
LD TIM4_SR,A
LD A,PD_ODR ; 将LED驱动信号取反
XOR A,#$08
LD PD_ODR,A ; LED闪烁频率=2MHZ/128/255/2=30.63
JRA MAIN_LOOP ; 无限循环
interrupt NonHandledInterrupt
NonHandledInterrupt.l
iret
; 下面定义中断向量表
segment 'vectit'
dc.l {$82000000+main} ; reset
dc.l {$82000000+NonHandledInterrupt} ; trap
dc.l {$82000000+NonHandledInterrupt} ; irq0
dc.l {$82000000+NonHandledInterrupt} ; irq1
dc.l {$82000000+NonHandledInterrupt} ; irq2
dc.l {$82000000+NonHandledInterrupt} ; irq3
dc.l {$82000000+NonHandledInterrupt} ; irq4
dc.l {$82000000+NonHandledInterrupt} ; irq5
dc.l {$82000000+NonHandledInterrupt} ; irq6
dc.l {$82000000+NonHandledInterrupt} ; irq7
dc.l {$82000000+NonHandledInterrupt} ; irq8
上一篇:STM8与汇编语言(5)
史海拾趣
|
考虑一个数字信号处理的实例,比如有限冲击响应滤波器(FIR)。用数 学语言来说,FIR 滤波器是做一系列的点积。取一个输入量和一个序数向量, 在系数和输入样本的滑动窗口间作乘法,然后将所有的乘积加起来,形成一 个输出样本。类似的运算在数 ...… 查看全部问答> |
|
关于sources.cmn和sources的问题,请大家帮忙指点,谢谢! 大家好请问: 1.sources.cmn和sources有什么区别? 2.sources.cmn里面的这些环境变量代表的是什么??? 希望大家能给个注释!!!!! &nbs ...… 查看全部问答> |
|
现在想安装XP与Wince双系统,要求在开机后能出现选项选择是进入XP系统还是Wince系统,不知道该怎么办? 请问有没有人安装过?或者有什么好的建议,请指点指点,呵呵! 谢谢大家!… 查看全部问答> |
|
从QWSKEYBOARDHANDLE继承下来的自己的类,在加入到QTE45后,总是报我写得几个函数重复定义,我可是按照QTE下面的那个41XX_QWS.H(CPP)两个文件写的,是不是那个宏定义的原因. 就是if !defined(xxxxx),下面要不要定义一下#define xxxx,可是我看别的驱动 ...… 查看全部问答> |
|
驱动加载程序中,在StartService()后,通过GetLastError()返回3错误(〖3〗-系统找不到指定的路径。) 驱动加载程序中,在StartService()后,通过GetLastError()返回3(〖3〗-系统找不到指定的路径。) 在虚拟机运行的,一开始是好的,暂停第二次打开 ,无论如何加载时运行到StartService()后的GetLastError()返回都是 ...… 查看全部问答> |
|
也来秀一下DIY,160*80带触摸液晶模块做的多功能时钟~~~~~~ 哈哈,其实这个屏是去年电赛的时候买的,正好也用上了,不过用得比较简单,感觉有点可惜了就干脆做了一个完整的模块,估计有的朋友还记得之前小弟发的第一次做PCB的帖子吧,就是给这个做的,这个是当时的链接 https://bbs.eeworld.com.cn/thre ...… 查看全部问答> |




