搜索
bottom↓
回复: 10

LGT内部的1.25V reg做参考的问题【已解决】

[复制链接]

出0入0汤圆

发表于 2013-1-2 22:55:43 | 显示全部楼层 |阅读模式
本帖最后由 xwkm 于 2013-1-2 23:08 编辑

编写了一个小程序:
  1. #include "RaysRTOS.h"

  2. #include <stdio.h>
  3. #define ADC_CHANNEL 0
  4. #define VREF_VCC        1
  5. #define VREF_1V5        2

  6. #define ADC_GND                26
  7. #define ADC_1V5                25

  8. #define BAUDRATE 9600 //9600bps
  9. /* ADC转换 */
  10. volatile INT16U ADC_Convert(INT8U vref,INT8U channel)
  11. {
  12.         INT16U retval;

  13.                 ADMUX = ((vref << 6) | channel);       

  14.                 ADCSRA |= (1 << ADEN);                //使能 ADC

  15.                 //RAYS_TimeDelay(1);
  16.                 retval=0;

  17.                 ADCSRA |= (1 << ADSC);                //开始转换
  18.        
  19.                 while(!(ADCSRA & (1 << ADIF)));
  20.                 ADCSRA |= (1 << ADIF);                //清除ADC中断标志
  21.                 for(retval=0;retval<1000;retval++);
  22.                 retval = ADC;
  23.                 return retval;
  24. }
  25. void ADC_Init()
  26. {//启动ADC
  27.         DIDR0=0xFF;//启动端口的模拟功能
  28.         ADCSRA = 0x07;                        //32分频
  29. }


  30. void Serial_Init()
  31. {//串口初始化,8MHz,9600bps
  32.         UCSR0A=0x00;
  33.         UBRR0H=0x00;
  34.         UBRR0L=0x33;   //9600bps
  35.         UCSR0B = 0x18; //0b00011000    允许:发送、接收
  36.         UCSR0C = 0x0E; //0b00001110    数据帧格式:8,N,1
  37. }

  38. void _putchar(char c)
  39. {
  40.         while((UCSR0A & (1 << UDRE0)) == 0);
  41.         UDR0 = c;

  42. }

  43. void putstr(unsigned char* buf)
  44. {
  45.         while (*buf)
  46.         {
  47.                 _putchar(*buf);
  48.                 buf++;
  49.         }
  50. }
  51. /*
  52. +---------------------------------------------------------------------------------------+
  53. |函数名称:        IdleTask                                                                                                                                        |
  54. |---------------------------------------------------------------------------------------|
  55. |函数原型:        void IdleTask(void)                                                                                                                        |
  56. |                                                                                                                                                                                |
  57. |函数功能:        电源电压检测&充电管理                                                                                                                                                   |
  58. |                                                                                                                                                                                |
  59. |有关说明:        空闲任务必须永远处于就绪状态                                                                                                        |
  60. +---------------------------------------------------------------------------------------+
  61. */
  62. void Task1(void)
  63. {       
  64.         volatile unsigned int voltage,t1,t2;
  65.         char buff[30];
  66.         asm("nop");
  67.         ADC_Init();
  68.         Serial_Init();
  69.         sprintf(buff,"%s from Idle Process\n","Hello world!");
  70.         putstr((void *)buff);
  71.         while(1)
  72.         {//每隔1s检测一次电源电压


  73.                         /*putstr((void *)buff);*/
  74.                        
  75.                         t1=ADC_Convert(VREF_VCC,ADC_CHANNEL);
  76.                         t2=0x00;
  77.                         volatile t2=ADC_Convert(VREF_VCC,ADC_1V5);
  78.                         //voltage=(1500/t2*t1)/10;
  79.                         //voltage=(1250/t2*t1)/10;
  80.                         sprintf(buff,"t1 %d,t2 %d,PA0 voltage:%d\n",t1,t2,voltage);
  81.                         putstr((void *)buff);
  82.                         RAYS_TimeDelay(100);
  83.         }
  84. }
复制代码
用了RaysOS。论坛网友的一个小操作系统。我开了ICE跟踪。ADC值没有传错。
测试结果如下,PA0直接接VCC。但是程序算出来PA0的电压却是3.06V,不知道怎么解释!万用表测得3.32V

---------------不好意思我搞错了,内置的应该是1.25V的……

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2013-1-2 23:00:05 | 显示全部楼层
本帖最后由 xwkm 于 2013-1-2 23:43 编辑

刚才我发现貌似ADC和实际结果固定有一个20的差值……
后来发现其实最大的问题是我看错规格书了……
另外现在在linux下面也可以搞LGT了。给udev写这么一个rules:
  1. SUBSYSTEM!="usb_device", ACTION!="add", GOTO="avrisp_end"

  2. # Atmel Corp. JTAG ICE mkII
  3. ATTR{idVendor}=="03eb", SYSFS{idProduct}=="2103", MODE="660", GROUP="dialout"
  4. # Atmel Corp. AVRISP mkII
  5. ATTR{idVendor}=="03eb", SYSFS{idProduct}=="2104", MODE="660", GROUP="dialout"
  6. # Atmel Corp. Dragon
  7. ATTR{idVendor}=="03eb", SYSFS{idProduct}=="2107", MODE="660", GROUP="dialout"

  8. 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:~$

出0入0汤圆

发表于 2013-1-2 23:26:59 来自手机 | 显示全部楼层
自己给自己解决问题了,就是这样,把问题清清楚楚表述出来,你会发现问题已经解决一大半了,就怕不知怎么表达,但就是觉着怪,找不出根在哪里。

出0入0汤圆

 楼主| 发表于 2013-1-2 23:43:30 | 显示全部楼层
dingshidong214 发表于 2013-1-2 23:26
自己给自己解决问题了,就是这样,把问题清清楚楚表述出来,你会发现问题已经解决一大半了,就怕不知怎么表 ...

其实很多时候我都这样了。后面一回头才发现哪里错误了……

出0入0汤圆

发表于 2013-1-3 00:12:29 | 显示全部楼层
LGT的AD值跳动有点大,进入AD噪声抑制模式有改观但还是有跳动。AVR就不存在这个问题。

出0入0汤圆

 楼主| 发表于 2013-1-3 01:51:30 | 显示全部楼层
HYLG 发表于 2013-1-3 00:12
LGT的AD值跳动有点大,进入AD噪声抑制模式有改观但还是有跳动。AVR就不存在这个问题。 ...

不管了。反正只是电池电压检测而已。多测几次去掉最高最低就行了

出0入0汤圆

 楼主| 发表于 2013-1-3 01:58:44 | 显示全部楼层
本帖最后由 xwkm 于 2013-1-3 02:00 编辑

void Task1(void)
{       
        volatile unsigned int voltage,t1,t2;
        char buff[30];
        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的。
但是以后做充放电曲线的话这个东西可能还是需要外部基准。这个模拟板还在面包板上。可能跳动是因为干扰。明天整套系统完工应该就不会了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-1-25 15:54:30 | 显示全部楼层
HYLG 发表于 2013-1-3 00:12
LGT的AD值跳动有点大,进入AD噪声抑制模式有改观但还是有跳动。AVR就不存在这个问题。 ...

话说怎么进入AD噪声抑制模式,我来回翻看文档,也没看见这个寄存器。。。

出0入0汤圆

发表于 2013-1-25 16:07:33 | 显示全部楼层
手册-系统时钟与功耗管理-睡眠模式。

出0入0汤圆

发表于 2013-1-25 20:58:22 | 显示全部楼层
HYLG 发表于 2013-1-25 16:07
手册-系统时钟与功耗管理-睡眠模式。

多谢。。。原来就在开头。。。

出0入0汤圆

发表于 2013-3-20 10:29:46 | 显示全部楼层
为什么转换完成标志置位后要delay才读出呢?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-12 15:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表