标题:
请教一下大佬们关于IAP15w4k58s4型号单片机比较器的问题
[打印本页]
作者:
小乌鸦
时间:
2019-12-25 15:54
标题:
请教一下大佬们关于IAP15w4k58s4型号单片机比较器的问题
求大佬帮帮忙,我使用的是IAP15w4k58s4单片机,进行掉电保存验证,结果测试比较器没起作用怎么回事,烧录哪里我已经设置了允许低压中断还有允许低压eeprom操作,不知道还有哪里出了问题,感激不尽
#include "STC15W4K.H"
#include "intrins.h"
#include "time_uart.h"
#include <stdio.h>
#define uint unsigned int
#define uchar unsigned char
#define CMD_IDLE 0 //空闲模式
#define CMD_READ 1 //IAP字节读命令
#define CMD_PROGRAM 2 //IAP字节编程命令
#define CMD_ERASE 3 //IAP扇区擦除命令
#define ENABLE_IAP 0x83 //ifSYSCLK<12MHZ
#define IAP_address 0x0400
//sfr CMPCR1 = 0xE6; //比较器控制寄存器1
#define CMPEN 0x80 //比较器模块使能
#define CMPIF 0x40 //比较器中断标志位
#define PIE 0x20 //比较器上升沿中断使能位
#define NIE 0x10 //比较器下降沿中断使能位
#define PIS 0x08 //比较器正极选择位
#define NIS 0x04 //比较器负极选择位
#define CMPOE 0x02 //比较器输出控制位
#define CMPRES 0x01 //比较器比较结果位
//sfr CMPCR2 =0xE7; //比较器控制寄存器2
#define INVCMPO 0x80 //比较器结果反向输出控制位
#define DISFLT 0x40 //比较器输出端滤波使能位
#define LCDTY 0x3F //比较器输出的区抖时间控制
void delayms(uint n);
void iap_idle();
uint iap_readbyte(uint addr);
void iap_writebyte(uint addr,uint dat);
void iap_erase_sector(uint addr);
uint num;
void cmp_iar() interrupt 21 using 1
{
CMPCR1&=~CMPIF; //掉电后触发下降沿中断,向flash写入数据
iap_erase_sector(0x400);
iap_writebyte(0x400,num);
}
void main()
{
P5M0=0;
P5M1=0;
P55=1;
num=9;
init_uart();
CMPCR1=0; //初始化比较器寄存器1和2
CMPCR2=0;
CMPCR1&=~PIS; //选择外部管脚P55 CMP+作为比较器正极输入源
CMPCR1&=~NIS; //选择内部BandGap电压作为比较器负极输入源
CMPCR1&=~CMPOE; //禁用比较器的比较结果输出
CMPCR2&=~INVCMPO; //比较器比较结果正常输出到P12
CMPCR2&=~DISFLT; //使能比较器输出端0.1us滤波电路
CMPCR2&=~LCDTY; //比较器结果不去抖动直接输出
//CMPCR1|=PIE; //使能比较器上升沿中断
CMPCR1|=NIE; //使能比较器下降沿中断
CMPCR1|=CMPEN; //使能比较器
EA=1;
// if(iap_readbyte(0x400)!=9)
// iap_erase_sector(0x400);
while(1)
{
if(iap_readbyte(0x400)==9)
{
// CMPCR1&=~CMPEN; //失能比较器
while(1)
{
delayms(1000);
SBUF='0';
while(!TI);
TI=0;
}
}
if(CMPCR1&CMPRES) //正常状态CMP也就是P55大于BandGap电压,没问题
{
delayms(1000);
SBUF='9';
while(!TI);
TI=0;
}
else //掉电后,我以为可能程序还会走一点,结果中断没进入这里也没进入
{
iap_erase_sector(0x400);
iap_writebyte(0x400,num);
}
}
}
void delayms(uint n)
{
uint j,k;
for(j=0;j<n;j++)
for(k=0;k<111;k++); //时钟频率11.0592MHZ
}
//关闭IAP
void iap_idle()
{
IAP_CONTR=0;
IAP_CMD=0;
IAP_TRIG=0;
IAP_ADDRH=0x80;
IAP_ADDRL=0;
}
//从ISP IAP EEPROM区域读取一个字节
uint iap_readbyte(uint addr)
{
uint dat;
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_READ;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0x5A;
IAP_TRIG=0xA5;
_nop_();
dat=IAP_DATA;
iap_idle();
return dat;
}
//写一字节数据到ISP IAP EEPROM区域
void iap_writebyte(uint addr,uint dat)
{
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_PROGRAM;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_DATA=dat;
IAP_TRIG=0x5A;
IAP_TRIG=0xA5;
_nop_();
iap_idle();
}
//扇区擦去
void iap_erase_sector(uint addr)
{
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_ERASE;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0x5A;
IAP_TRIG=0xA5;
_nop_();
iap_idle();
}
作者:
Y_G_G
时间:
2019-12-25 16:30
STC的电压比较器的使用方法太反人类了,要设定一大堆寄存器,而且,输出结果并不是单纯的+-两个端口的电压大小关系,太扯了
掉电保存的话,还是用外部中断吧,如果中断不够用,那就直接检测某个端口的电平状态吧,反正都比电压比较器好使
作者:
小乌鸦
时间:
2019-12-25 19:20
我直接通过杜邦线拉低P55能进入中段,说明比较器可以用,而现在问题是我验证用的单片机是最小系统的板子,是不是这个比较器需要外部电路才可实现,之前我是直接断电验证的,我以为本身芯片里面就会配置有啥的,这样就断电后还可以运行一小会这样
作者:
wulin
时间:
2019-12-25 21:11
掉电保存需要外部硬件支持。最简单的方法是供MCU的VCC有足够大的电容,当检测到外部掉电时,立即把相关数据保存在EEPROM中。一般维持1~2秒VCC无明显下降,足可以保存1000个字节。并不是楼主认为的利用低压检测功能来完成此项工作。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1