- UID
- 1023166
- 性别
- 男
- 来自
- 燕山大学
|
SN 8 位单片机 SN8P2743 应用实践(2)
作者:bjxsdz
SN8P2743 是一较新的型号,内部含有放大器,比较器,AD 转换器并且有外部基准电压参考输入.....4K*16位 空间,感觉上比较"价廉物美!"
通常,我们使用SN单片机的 AD 功能时,如果选择外部基准电压,可以利用廉价的 TL431 提供 2.5V 左右的高稳定度电压,即使通着电的240℃高温电烙铁靠上去,TL431 的输出波动也仅仅 1~3mV ,此时,系统可以把 5V 基准时得到的 12BIT AD 变成 2.5V 基准得到了 12BIT AD,这是非常划算的举措! ---- 一方面,等同于使用了一只 2 倍放大的无偏移,无失调,无温飘的放大电路,另外一方面,让AD 的参考值具有高达 50ppm 的温度系数!
我就在最近使用 2743 的外部基准和 AD 功能时,遇见一个问题:
AD 读数远远相差期望值很远很远!仿真器的转接板上, AVREFH 测量到的基准电压不是 2.5V,而是 5.0V ,怎么回事呢?
检查仿真器上外部/内部基准 AVREFH 插头,已经拔开!(必须拔开!)
以为是需要外接基准电压,于是,把转接板上 AVREFH 的插针与外部基准 TL431 直接连接,看看是否正确? 结果,电压变成比 2.5V 稍大了 0.1~0.3V ,不稳定.由于事先有准备,不停摸一下 TL431,发现其温度上升,感觉此举错误,赶紧脱开 AVREFH 与 TL431 的连接.
转接板与目标板是具有引脚一对一关系的,外部基准实际已经到达芯片对应引脚,为什么转接板上 AVREFH 测量不到呢?
查看转接板上,原来这些接口是利用一种 NLAS4501DFT2G 通用单刀单掷模拟开关来切换的!为此,临时上网查阅该芯片的手册.费了不少劲!
小心测量 NLAS4501DFT2G 芯片的控制引脚,发现与"选择外部基准"的指令不同,怎么回事?
再重新阅读 2743 的数据手册,在 ADM 寄存器里,比通常的 SN 带 AD 单片机多了一个 FAVREFH 位,它 =1 则是选择外部基准! ---- 这里,通常不会出错!指令是正确的!
再看看它给出的示例:
ADC 操作举例
ADC:
; 复位ADC。
CLR ADM ; 清ADM 寄存器。
; 设置ADC 时钟Rate 和ADC 分辨率。
MOV A, #0nmn0000b ; nn:ADCKS[1:0]代表ADC 时钟Rate。
B0MOV ADR, A ; m 代表ADC 分辨率。
; 设置ADC 参考高电压。
B0BCLR FAVREFH ; 内部VDD。
or
B0BSET FAVREFH ; 外部参考源。
; 设置ADC 输入通道。
MOV A, #value1 ; 设置P4CON 选择ADC 输入通道。
B0MOV P4CON, A
MOV A, #value2 ; 设置ADC 输入通道为输入模式。
B0MOV P4M, A
MOV A, #value3 ; 禁止ADC 输入通道的内部上拉电阻。
B0MOV P4UR, A
; 使能ADC。
B0BSET FADCENB
; 执行ADC 100us 启动时间延迟循环。
CALL 100usDLY ; 100us 延迟循环。
; 选择ADC 输入通道。
MOV A, #value ; 设置ADCHS[2:0]选择ADC 输入通道。
OR ADM, A
; 使能ADC 输入通道。
B0BSET FGCHS
; 使能ADC 中断功能。
B0BCLR FADCIRQ ; 清ADC 中断请求。
B0BSET FADCIEN ; 使能ADC 中断功能。
; 开始AD 转换。
B0BSET FADS
好了!问题找到了! ----- 看看这一句: CLR ADM ; 清ADM 寄存器。---- 这里就把 BIT3 重新变成 0 了!
一个单片机系统,除了 AD 转换之外,大部分时间都在运行其它程序,FAVREFH (ADM.3)在程序指令下,会从 1 变成 0,又从 0 变成 1 ! 不停切换外部基准/内部基准,当然就会让外部基准不停变化了!
于是,删除这一句: " CLR ADM ; 清ADM 寄存器 " !
并且,在上电后最先的系统初始化时,就让 FAVREFH (ADM.3)=1 ! 以后,就必须牢记不能动这一位!选择AD通道时,可以使用 OR 指令或 AND 指令去改变 ADM ,当然,如果充分注意,仍然可以使用 MOV ADM,#value 去赋值!
例如:;B3:FAVREFH=1 外部参考源。
;选择ADC 输入通道:
MOV A,#098H ;=P40----FAVREFH (ADM.3)=1
;或
MOV A,#099H ;=P41----FAVREFH (ADM.3)=1
;或
MOV A,#09AH ;=P42----FAVREFH (ADM.3)=1
;或
MOV ADM,A
ZB1 FADS; 开始AD 转换。
;................
经过这样处理,测量转接板上 AVREFH 的插针上就是 2.5V ,稳定不动! AD 转换读数也变成正常了!
------ 当然了,P4M,P4UR,P4CON 这些相关寄存器仍然需要小心正确设置的!
此经历特别贴出,供朋友们使用 2743 时留意参考! ---- 随着应用深入,如果再发现有比较古怪的问题,再行贴出!
===========================================================
使用 2743 不能对 P0.N 位操作的问题
在使用 SN8P2743 时,代码里有:
BSET FP03
BCLR FP03
这样的指令,结果,编译器提示出错! "Only can use MOV command to change the Bit.."
查阅芯片手册,对 I/O 配置描述是:
IO 引脚配置
双向输入输出IO 口:P0、P1、P4
具有唤醒功能的IO 口:P0、P1 电平变换
具有上拉电阻的IO 口:P0、P1、P4
OP-amp/比较器引脚:P1、P4
ADC 输入引脚:P4.0~P4.7
这里,没有看见我为什么遇见的问题所在!
又查阅软件文件夹里的 SN8P2743.INC 文件,文件里对 P0 口的内容如下:
P0M EQU 0B8H
FP06M EQU P0M.6
FP05M EQU P0M.5
FP03M EQU P0M.3
FP02M EQU P0M.2
FP00M EQU P0M.0
P0 EQU 0D0H
FP06 EQU P0.6
FP05 EQU P0.5
FP04 EQU_R P0.4 ;只读
FP03 EQU P0.3
FP02 EQU P0.2
FP01 EQU_W P0.1 ;只写
FP00 EQU P0.0
留意到,P0 端口有一位只读,有一位只写! ----- 对一组端口里有只读位的,并不会影响其它位的位操作,是不是有只写位就不行了呢?
又再查阅芯片手册,在引脚说明里看见只写位 FP01 :
P0.1/PWM0 I/O P0.1:漏极开路的输出引脚。PWM0:PWM输出引脚和脉冲输出引脚。
再看看对端口 P0 的系统寄存器内容:
I/O 口模式
寄存器PnM 控制I/O 口的工作模式。
0B8H Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
P0M - P06M P05M - P03M P02M - P00M
读/写 - R/W R/W - R/W R/W - R/W
复位后 - 0 0 - 0 0 - 0
I/O 口数据寄存器 P0
0D0H Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
P0 - P06 P05 P04 P03 P02 P01 P00
读/写 - R/W R/W R R/W R/W W R/W
复位后 - 0 0 0 0 0 0 0
注:
1、当通过编译选项使能外部复位时,P04 保持为1。
2、若需要设置P0 寄存器的某位(P0.n)时,建议使用“MOV”或者“B0MOV”指令,而不要使用“read & modify write(读-改写)”型的指令(如,BSET、BCLR、B0BSET、B0BCLR…),否则执行这些指令后,P0 寄存器的只写位P0.1 会被更改。
原来问题是:
如果一组端口有某位为只写位,为了避免位操作指令的"读-改写"破坏只写位的状态,因此,对这组端口的其它位不能使用位操作指令!
这种情况很少遇见,芯片手册里 I/O 配置说明也不够具体和明确,
----- 为避免使用 2743 时出现类似麻烦,特贴出供大家参考!
=============================================================
注意 2743 的 P0 端口使用问题与解决方法:
最近使用 2743 做项目,其 P0 口的使用确实遇见一些麻烦事!
首先,它的 P0.1 是只能作为输出使用.属于开漏输出.(普通I/O模式时).不能输出高电平!
其次,这组端口不能使用位操作指令,非常的不方便!
如果使用它做数码管笔段驱动,低电平有效,如果包含小数点位置在内,是不能通过位操作指令快捷设置的!
先把端口状态读进来,到一个临时 RAM ,然后操作这个小数点,之后再送回到 P0 口!
此时,会出现错误, P0.1 这位状态会出错!
利用 AND 与 OR 等指令配合来操作,仍然会出现错误! --- 有点莫名其妙!
注意了: 偏偏在仿真器上没有这些错误,都是烧写芯片后才发现错误!
冷静下来,重新阅读芯片手册,终于幡然大悟! ---- P0.1 是只写位,不能读! 读进来就是错的!
凡是经过"读--改--写"过程的指令,操作它都会出错!
解决办法:
使用一个 P0 口的"影子"寄存器 EME,专门对付操作 P0 口的输出. 这样,不仅仅方便了,也与其它芯片做法一致了!所有对 P0 口的输出操作都变成对这个影子寄存器的操作,之后再及时" MOV_ P0,EME "去!
经过这样处理,较好地避免了对 P0 口操作出错的问题. ------ 输入模式下可以逐位读入,仅仅 P0.1 不能读!
=========================================================
SN8P2743 的比较器初试
SN8P2743 芯片内部带有 3 个比较器,今天,终于抽空对其进行了一些测试.
3 个比较器汇编叫做比较器 0 ,比较器 1 ,比较器 2 .
3 个比较器都是轨到轨输出的,就是在 5V 供电下,高/低电平输出幅度几乎达到 5V 和 GND 电平!
(芯片内部还有一个放大器,放大器的测试已经发布过帖子了!)
3 个比较器都可以作为普通比较器使用或特殊比较器器使用. 所谓特殊就是可以触发或停止 TC0 定时器的 PWM 输出脉冲.
与常规集成电路比较器更多选择的是,可以选择比较器翻转方向和进入中断! 可以选择是否使用比较器输出的引脚(与普通 I/O 口共享). 如果不用硬件引脚,就仅仅是软件内部处理结果或数据,则可以节省 3 个 I/O 口. 这是一大特色!
而比较器 1 和比较器 2 更有意思,可以软件选择内部参考到同相输入作为参考电压,此时,也可以不用硬件引脚,成为功能齐全而仅仅一个外接引脚的比较器! -------- 太棒了!
比较器是进行 2 个电压比较大小的重要元件,我对比较器 0 进行测试,方法是:
使用 2 个 1% 精度 3K 的电阻,串联后接到 5V 与 GND ,中间就是 5V/2 了,把这个 2.5V 接到比较器 0 的反相输入引脚,然后,利用微调定位器给比较器 0 的同相输入电压, 用数字万用表实时测量 2 个输入引脚的电压差, 并且让其比较输出低电平时或高电平时进入中断,结果都是 OK 的!
它还可以选择延时输出,但是我没有使用,一律不用延时输出.
而其比较的动作电压,一开始感觉有些大,高达上百 mV ! 查阅手册,分别给 2 个输入端口加上一只 1u 的滤波电容器, 结果,翻转电压差下降到仅仅 0.6~0.8mV 左右. ------ 就是在 5/2=2.5V 电压附近, +0.8V,输出=5V, -0.8V 输出=0 ! |
|