打印
[STC单片机]

STC15W401AS测量电源电压并串口输出问题

[复制链接]
4145|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tsyszmtzq|  楼主 | 2015-5-12 15:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请大家帮助
#include "reg51.h"
#include "intrins.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
//WORD idata Vbg_RAM _at_ 0xef;               //对于只有256字节RAM的MCU存放地址为0EFH
//WORD idata Vbg_RAM _at_ 0x6f;             //对于只有128字节RAM的MCU存放地址为06FH
//注意:需要在下载代码时选择"在ID号前添加重要测试参数"选项,才可在程序中获取此参数
WORD code Vbg_ROM _at_ 0x03f7;            //1K程序空间的MCU
//#define Vbg_ROM 0x03f7      //1K程序空间的MCU
//-----------------------------------------                                            
sfr ADC_CONTR   =   0xBC;                   //ADC控制寄存器
sfr ADC_RES     =   0xBD;                   //ADC高8位结果
sfr ADC_LOW2    =   0xBE;                   //ADC低2位结果
sfr P1ASF       =   0x9D;                   //P1口第2功能控制寄存器
sfr P1M1        =   0x91;
sfr P1M0        =   0x92;
sfr P5M1        =   0xC9;
sfr P5M0        =   0xCA;
sfr T2H         = 0xd6;               //定时器2高8位
sfr T2L         = 0xd7;               //定时器2低8位
sfr AUXR        =   0x8e;       //辅助寄存器                              
sfr WKTCL       = 0xaa;                   //掉电唤醒定时器计时低字节
sfr WKTCH       = 0xab;                   //掉电唤醒定时器计时高字节



#define ADC_POWER   0x80                    //ADC电源控制位
#define ADC_FLAG    0x10                    //ADC完成标志
#define ADC_START   0x08                    //ADC起始控制位
#define ADC_SPEEDLL 0x00                    //540个时钟
#define ADC_SPEEDL  0x20                    //360个时钟
#define ADC_SPEEDH  0x40                    //180个时钟
#define ADC_SPEEDHH 0x60                    //90个时钟


void UartInit();
void SendUart(BYTE dat);



/*----------------------------
初始化串口
----------------------------*/
void UartInit()                //9600bps@5.5296MHz
{
        SCON = 0x5a;                //8位数据,可变波特率
        AUXR |= 0x04;                //定时器2时钟为Fosc,即1T
        T2L = 0x70;                //设定定时初值
        T2H = 0xFF;                //设定定时初值
        AUXR |= 0x01;                //串口1选择定时器2为波特率发生器
        AUXR |= 0x10;                //启动定时器2
}
/*----------------------------
发送串口数据
----------------------------*/
void SendUart(BYTE dat)
{
    while (!TI);                //等待前面的数据发送完成
    TI = 0;                     //清除发送完成标志
    SBUF = dat;                 //发送串口数据
}
void Delay(WORD n)
{
    WORD x;

    while (n--)
    {
        x = 5000;
        while (x--);
    }
}
void main()
{
        BYTE ADCbg;


        BYTE code *pVbg_ROM;
        WORD  VCC;
        BYTE  *pVCC; //这2个指针的数据类型用哪个正确?BYTE WORD
    BYTE i;  
        UartInit();         

          while (1)
      {         
          pVbg_ROM = &Vbg_ROM;         //从程序区读取BandGap电压值(单位:毫伏mV)          
          for (i=0; i<2; i++)         //读2个字节(高字节在前)
       {
        SendUart(*pVbg_ROM++);          //串口发送ROM中的标准电压  出04 DD  1245毫伏mV
        }
       
        ADC_RES = 0;            //清除结果寄存器
    P1ASF = 0x00;           //不设置P1ASF,即可从ADC的第9通道读取内部Bandgap电压的ADC测量值   
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
    Delay(2);                               //ADC上电并延时
        ADC_CONTR = ADC_POWER | ADC_SPEEDLL | 0 | ADC_START;
    _nop_();                                //等待4个NOP
    _nop_();
    _nop_();
    _nop_();
       
    while (!(ADC_CONTR & ADC_FLAG));        //等待ADC转换完成
       ADC_CONTR &= ~ADC_FLAG;                                  //清除ADC标志
       ADCbg = ADC_RES;
       SendUart(ADCbg); //串口发送对标准电压的ADC值
          
           VCC = 256 * (Vbg_ROM/ADCbg);         //必须先相除 不然超过WORD的范围
         
           pVCC        = &VCC;
            for (i=0; i<2; i++)         //读2个字节
        {
        SendUart(*pVCC++);         //串口出来的电源电压为什么就不对了?0F 00换电源电压低位还是00          
         }                   
       }
}

相关帖子

沙发
tsyszmtzq|  楼主 | 2015-5-12 15:59 | 只看该作者
1:串口输出的ROM出厂保存电压正常,出04  DD计算为1245豪伏,和厂家提供的例程结果一致。不理解的是BYTE code   *pVbg_ROM;     必须用BYTE,用WORD输出就不对呢?用BYTE编译是出一个警告,用WORD就没有。这个可以理解因为前面Vbg_ROM就定义成WORD。
2:串口输出的ROM出厂保存电压的ADC值正常,出4F  4010MV 供电,根据公式计算是对的。
3:为什么串口输出不对呢?出0F 00  低位没有,BYTE  *pVCC; 把它换成WORD  *pVCC,输出00 00更不对了?

使用特权

评论回复
板凳
zk5| | 2015-5-12 20:47 | 只看该作者
本帖最后由 zk5 于 2015-5-12 20:49 编辑

有一个RESL的寄存器,也是ADC的值。和RES配合使用的。你再看看。

使用特权

评论回复
地板
qqxw123456| | 2017-8-17 15:38 | 只看该作者
为什么我连程序都烧不进去,401as的rom地址只有1k,无论我怎么编译hex文件都超过1k啊

使用特权

评论回复
5
12864| | 2017-8-19 13:57 | 只看该作者
qqxw123456 发表于 2017-8-17 15:38
为什么我连程序都烧不进去,401as的rom地址只有1k,无论我怎么编译hex文件都超过1k啊 ...

你你你。。。算了,你先加大优化等级,如果编译出来还是超出1k,那你只能选更大flash的芯片了,比如402AS、404AS。。。

使用特权

评论回复
6
changle11sdo5| | 2017-8-26 10:37 | 只看该作者
那玩意就这样,也就学校用,如果做产品还是用STM8

使用特权

评论回复
7
autopccopy| | 2017-8-26 22:20 | 只看该作者
ls得有多大偏见哦,呵呵。应用范围并太不相同,你可实测一下抗干扰能力

使用特权

评论回复
8
autopccopy| | 2017-8-26 22:20 | 只看该作者
ls得有多大偏见哦,呵呵。应用范围并太不相同,你可实测一下抗干扰能力

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

5

帖子

0

粉丝