LGT内部的1.25V reg做参考的问题【已解决】
本帖最后由 xwkm 于 2013-1-2 23:08 编辑编写了一个小程序:#include "RaysRTOS.h"
#include <stdio.h>
#define ADC_CHANNEL 0
#define VREF_VCC 1
#define VREF_1V5 2
#define ADC_GND 26
#define ADC_1V5 25
#define BAUDRATE 9600 //9600bps
/* ADC转换 */
volatile INT16U ADC_Convert(INT8U vref,INT8U channel)
{
INT16U retval;
ADMUX = ((vref << 6) | channel);
ADCSRA |= (1 << ADEN); //使能 ADC
//RAYS_TimeDelay(1);
retval=0;
ADCSRA |= (1 << ADSC); //开始转换
while(!(ADCSRA & (1 << ADIF)));
ADCSRA |= (1 << ADIF); //清除ADC中断标志
for(retval=0;retval<1000;retval++);
retval = ADC;
return retval;
}
void ADC_Init()
{//启动ADC
DIDR0=0xFF;//启动端口的模拟功能
ADCSRA = 0x07; //32分频
}
void Serial_Init()
{//串口初始化,8MHz,9600bps
UCSR0A=0x00;
UBRR0H=0x00;
UBRR0L=0x33; //9600bps
UCSR0B = 0x18; //0b00011000 允许:发送、接收
UCSR0C = 0x0E; //0b00001110 数据帧格式:8,N,1
}
void _putchar(char c)
{
while((UCSR0A & (1 << UDRE0)) == 0);
UDR0 = c;
}
void putstr(unsigned char* buf)
{
while (*buf)
{
_putchar(*buf);
buf++;
}
}
/*
+---------------------------------------------------------------------------------------+
|函数名称: IdleTask |
|---------------------------------------------------------------------------------------|
|函数原型: void IdleTask(void) |
| |
|函数功能: 电源电压检测&充电管理 |
| |
|有关说明: 空闲任务必须永远处于就绪状态 |
+---------------------------------------------------------------------------------------+
*/
void Task1(void)
{
volatile unsigned int voltage,t1,t2;
char buff;
asm("nop");
ADC_Init();
Serial_Init();
sprintf(buff,"%s from Idle Process\n","Hello world!");
putstr((void *)buff);
while(1)
{//每隔1s检测一次电源电压
/*putstr((void *)buff);*/
t1=ADC_Convert(VREF_VCC,ADC_CHANNEL);
t2=0x00;
volatile t2=ADC_Convert(VREF_VCC,ADC_1V5);
//voltage=(1500/t2*t1)/10;
//voltage=(1250/t2*t1)/10;
sprintf(buff,"t1 %d,t2 %d,PA0 voltage:%d\n",t1,t2,voltage);
putstr((void *)buff);
RAYS_TimeDelay(100);
}
}
用了RaysOS。论坛网友的一个小操作系统。我开了ICE跟踪。ADC值没有传错。
测试结果如下,PA0直接接VCC。但是程序算出来PA0的电压却是3.06V,不知道怎么解释!万用表测得3.32V
---------------不好意思我搞错了,内置的应该是1.25V的…… 本帖最后由 xwkm 于 2013-1-2 23:43 编辑
刚才我发现貌似ADC和实际结果固定有一个20的差值……
后来发现其实最大的问题是我看错规格书了……
另外现在在linux下面也可以搞LGT了。给udev写这么一个rules:SUBSYSTEM!="usb_device", ACTION!="add", GOTO="avrisp_end"
# Atmel Corp. JTAG ICE mkII
ATTR{idVendor}=="03eb", SYSFS{idProduct}=="2103", MODE="660", GROUP="dialout"
# Atmel Corp. AVRISP mkII
ATTR{idVendor}=="03eb", SYSFS{idProduct}=="2104", MODE="660", GROUP="dialout"
# Atmel Corp. Dragon
ATTR{idVendor}=="03eb", SYSFS{idProduct}=="2107", MODE="660", GROUP="dialout"
LABEL="avrisp_end"加到/etc/udevd/rules.d/中
然后sudo restart udevd
就可以使用avrdude 了(前提是那个J2短路后要刷mkII的固件。别刷高,Studio4的即可
rgwan@rgwan-desktop:~$ avrdude -p m164p -c jtag2 -P usb
avrdude: jtagmkII_initialize(): warning: OCDEN fuse not programmed, single-byte EEPROM updates not possible
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e1e1e
avrdude: Expected signature for ATMEGA164P is 1E 94 0A
Double check chip, or use -F to override this check.
avrdude done.Thank you.
rgwan@rgwan-desktop:~$
自己给自己解决问题了,就是这样,把问题清清楚楚表述出来,你会发现问题已经解决一大半了,就怕不知怎么表达,但就是觉着怪,找不出根在哪里。 dingshidong214 发表于 2013-1-2 23:26 static/image/common/back.gif
自己给自己解决问题了,就是这样,把问题清清楚楚表述出来,你会发现问题已经解决一大半了,就怕不知怎么表 ...
其实很多时候我都这样了。后面一回头才发现哪里错误了…… LGT的AD值跳动有点大,进入AD噪声抑制模式有改观但还是有跳动。AVR就不存在这个问题。 HYLG 发表于 2013-1-3 00:12 static/image/common/back.gif
LGT的AD值跳动有点大,进入AD噪声抑制模式有改观但还是有跳动。AVR就不存在这个问题。 ...
不管了。反正只是电池电压检测而已。多测几次去掉最高最低就行了 本帖最后由 xwkm 于 2013-1-3 02:00 编辑
void Task1(void)
{
volatile unsigned int voltage,t1,t2;
char buff;
asm("nop");
ADC_Init();
Serial_Init();
sprintf(buff,"%s from batt Process\n","Hello world!");
putstr((void *)buff);
while(1)
{//每隔1s检测一次电源电压
/*putstr((void *)buff);*/
t1=ADC_Convert(VREF_VCC,ADC_CHANNEL);
t2=ADC_Convert(VREF_VCC,ADC_1V5);
voltage=((13000/t2)*t1)/10;//LGT内部1.5V基准有固定的差值
//voltage=voltage * 10;
sprintf(buff,"t1 %d,t2 %d,PA0 voltage:%d mV \n",t1,t2,voltage);
putstr((void *)buff);
sprintf(buff,"Battery voltage:%d mV\n",voltage *2);//(voltage * 2)/1000);
putstr((void *)buff);
RAYS_TimeDelay(100);
}
}
这个程序。我在上位机上看到的是:
确实有跳动。但是至少现在我还不太敏感。反正锂电池降到3650mV就直接PD的。
但是以后做充放电曲线的话这个东西可能还是需要外部基准。这个模拟板还在面包板上。可能跳动是因为干扰。明天整套系统完工应该就不会了 HYLG 发表于 2013-1-3 00:12 static/image/common/back.gif
LGT的AD值跳动有点大,进入AD噪声抑制模式有改观但还是有跳动。AVR就不存在这个问题。 ...
话说怎么进入AD噪声抑制模式,我来回翻看文档,也没看见这个寄存器。。。 手册-系统时钟与功耗管理-睡眠模式。 HYLG 发表于 2013-1-25 16:07 static/image/common/back.gif
手册-系统时钟与功耗管理-睡眠模式。
多谢。。。原来就在开头。。。 为什么转换完成标志置位后要delay才读出呢?
页:
[1]