历史上的今天
今天是:2024年10月15日(星期二)
2021年10月15日 | STM8与汇编语言(15)--AD转换
2021-10-15 来源:eefocus
现在大部分的单片机也都具备了A/D转换器,有8位的,也有10位的,当然性能好的具备了12位的A/D。在STM8单片机中,提供的是10位的A/D,通道数随芯片不同而不同,少的有4个通道,多的则有16个通道。
下面的实验程序首先对A/D输入进行采样,然后将采样结果的高8位(丢弃最低的2位),作为延时参数去调用延时子程序,然后再去驱动LED控制信号。因此不同的采样值,决定了LED的闪烁频率。当旋转ST三合一开发板上的电位器时,可以看到LED的闪烁频率发生变化。
同样还是利用ST的开发工具,生成一个汇编程序的框架,然后修改其中的main.asm,修改后的代码如下。
stm8/
#include "mapping.inc"
#include "STM8S207C_S.INC"
; 定义堆栈空间的起始位置和结束位置
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
; 初始化LED对应的IO端口
LD A,#08
LD PD_DDR,A ; 将PD3设置成输出
LD A,#08
LD PD_CR1,A ; 将PD3设置成推挽输出
LD A,#00
LD PD_CR2,A ;
; 初始化A/D模块
LD A,#$00
LD ADC_CR2,A ; A/D结果数据左对齐
LD A,#$00
LD ADC_CR1,A ; ADC时钟=主时钟/2=1MHZ
; ADC转换模式=单次
; 禁止ADC转换
LD A,#$03
LD ADC_CSR,A ; 选择通道3
LD A,#$20
LD ADC_TDRL,A
;
MAIN_LOOP.L
LD A,ADC_CR1
OR A,#$01
LD ADC_CR1,A ; CR1寄存器的最低位置1,使能ADC转换
LD A,#100
WAIT_ADC_ON.L
DEC A
JRNE WAIT_ADC_ON ; 延时一段时间,至少7uS,保证ADC模块的上电完成
LD A,ADC_CR1
OR A,#$01
LD ADC_CR1,A ; 再次将CR1寄存器的最低位置1
; 使能ADC转换
WAIT_ADC_EOC.L
LD A,ADC_CSR
AND A,#$80
JREQ WAIT_ADC_EOC ; 等待ADC结束
LD A,ADC_DRH ; 读出ADC结果的高8位
CALL DELAY_MS ; 延时一段时间
LD A,PD_ODR ; 读回PD口的数据
XOR A,#$08 ; 将PD3反相
LD PD_ODR,A ; 送回
JRA MAIN_LOOP ; 继续主循环
; 函数功能:延时
; 输入参数:寄存器A -- 要延时的毫秒数,这里假设CPU的主频为2MHZ
; 输出参数:无
; 返 回 值:无
; 备 注:无
DELAY_MS.L
PUSH A ; 将入口参数保存到堆栈中
LD A,#250 ; 寄存器A<-250,作为下面的循环数
DELAY_MS_1.L
NOP ; 用空操作指令进行延时4T
NOP
NOP
NOP
NOP
DEC A ; 寄存器A<-A-1,本条指令执行之间为1T
JRNE DELAY_MS_1 ; 若不等于0,则循环,
; 本条指令执行时间为2T(跳时)或1T(不跳时)
POP A ; 从堆栈中恢复入口参数
DEC A ; 将要延时的MS数-1
JRNE DELAY_MS ; 若不等于0,则循环
RET ; 函数返回
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
dc.l {$82000000+NonHandledInterrupt} ; irq9
dc.l {$82000000+NonHandledInterrupt} ; irq10
dc.l {$82000000+NonHandledInterrupt} ; irq11
dc.l {$82000000+NonHandledInterrupt} ; irq12
dc.l {$82000000+NonHandledInterrupt} ; irq13
dc.l {$82000000+NonHandledInterrupt} ; irq14
史海拾趣
|
在点击的好多链接时总是出现未能查找到,是我的浏览器设置问题还是什么地方? 反正挺麻烦的,每次只能在论坛的主页上点击各个帖子,那位兄台知道的就告诉兄弟一下吧… 查看全部问答> |
|
lsb_release -a 查看系统版本。 cat /etc/redhat-release 看这个配置文件也可以。不过管理员可以修改这里的内容 cat /proc/CPUinfo 查看cpu信息,processor 0 为一个U, 1为两个,flags超线程。 lspci 查看主板信息 fr ...… 查看全部问答> |
|
整机为交流供电,数字电源和电子负载都有独立的液晶显示部分,显示各自的状态信息。 数字电源开机初始状态为0V,可在0-20V范围内以0.1V步进电压调整(同时具有0.01v的微调按纽)。带有输出电压,输出电流,输出功率显示。 & ...… 查看全部问答> |
|
平台wince 5.0 + 三星2450 休眠是可以实现的,可是唤醒时有些驱动没有加载,如触摸屏,camera等。请问这是为什么,控制加载驱动的代码在哪? 多谢了!… 查看全部问答> |
|
开门见山,小弟疑问如下: 1.如何确定一款单片机I/O口,是否有3态,如何设置高阻态。 2.若没有3态,则如何设置在上点之后,初始状态为灭。 请教各位,如有解答,不胜感激… 查看全部问答> |
|
有 谁遇到过同样的问题的没有,我都搞了两天了 还是这个错误,软件都重装了几次,就差装系统了。不想装系统的原因是我的电脑装系统必须全盘格式化,郁闷… 查看全部问答> |




