打印
[牛人杂谈]

[新唐003]+1年多的使用感受

[复制链接]
楼主: yjgna
手机看帖
扫描二维码
随时随地手机跟帖
21
能否帮忙测试下, 标定到16.6MHz后, SPI操作是否正常。
我在程序开始加了下面的代码后,spi就无法操作了, 发送直接死机
void MODIFY_HIRC_16600(void)
{
        unsigned char hircmap0,hircmap1;
        unsigned int        trimvalue16bit;

        set_IAPEN;
        IAPAL = 0x30;
        IAPAH = 0x00;
        IAPCN = READ_UID;
        set_IAPGO;
        hircmap0 = IAPFD;
        IAPAL = 0x31;
        IAPAH = 0x00;
        set_IAPGO;
        hircmap1 = IAPFD;
        clr_IAPEN;
        hircmap1 = hircmap1 & 0x01;
        trimvalue16bit = ((hircmap0 << 1) + (hircmap1 & 0x01));
        trimvalue16bit = trimvalue16bit - 15;
        //trimvalue16bit = trimvalue16bit - 13;
        hircmap1 = trimvalue16bit & 0x01;
        hircmap0 = trimvalue16bit >> 1;
        set_SFRPAGE;
        TA = 0XAA;
        TA = 0X55;
        RCTRIM0 = hircmap0;
        TA = 0XAA;
        TA = 0X55;
        RCTRIM1 = hircmap1;
}

使用特权

评论回复
22
yjgna|  楼主 | 2018-6-27 16:56 | 只看该作者
jekey 发表于 2018-6-27 16:44
能否帮忙测试下, 标定到16.6MHz后, SPI操作是否正常。
我在程序开始加了下面的代码后,spi就无法操作了, ...

HIRC调整到16.6M这个函数里面的
set_SFRPAGE; 去掉试试。

一般在操作SFR页1的时候,操作之前set_SFRPAGE; 操作之后要恢复为页0,clr_SFRPAGE;

使用特权

评论回复
23
jekey| | 2018-6-27 17:10 | 只看该作者
yjgna 发表于 2018-6-27 16:56
HIRC调整到16.6M这个函数里面的
set_SFRPAGE; 去掉试试。

明天试试

使用特权

评论回复
24
liangbaixin| | 2018-6-27 18:05 | 只看该作者
yjgna 发表于 2018-6-27 16:22
你的代码配的BOD电压是2.7V 不是4.4V
4.4V的配置是
clr_BOV1;

太感谢楼主了

使用特权

评论回复
25
yjgna|  楼主 | 2018-6-27 18:14 | 只看该作者

客气,相互学习

使用特权

评论回复
26
jekey| | 2018-6-28 09:44 | 只看该作者
yjgna 发表于 2018-6-27 16:56
HIRC调整到16.6M这个函数里面的
set_SFRPAGE; 去掉试试。

确实是这个问题。
太过相信从官方下载的代码了。
加了官方的代码后, 串口,定时器都正常,只是spi不正常。也就没有怀疑这段代码。
还以为是频率高,导致spi硬件异常。

使用特权

评论回复
27
xiaoqizi| | 2018-6-28 11:27 | 只看该作者
请问楼主 这款芯片的稳定性如何

使用特权

评论回复
28
liangbaixin| | 2018-6-28 16:07 | 只看该作者
yjgna 发表于 2018-6-27 13:13
在掉电时 保存数据到Flash,是可以通过BOD中断实现的。
需要更新的数据 存放在XRAM中,页擦除操作事先做 ...

掉电存数据我是这样写的,但是没有成功,新手没看出哪里问题

u8         bod_buf[128]        _at_        0x3400;
u8    config_f[64] ;
u32                device_hour = 0;
u32                lamp_strike;

void DataInit(void)
{
        u8 i;
        for(i=0;i<64;i++)
                config_f=bod_buf;       
               
        read_device_hours();
}

//读取设备运行时间
void        read_device_hours(void)
{       
        lamp_strike |= bod_buf[0] << 24;
        lamp_strike |= bod_buf[1] << 16;
        lamp_strike |= bod_buf[2] << 8;
        lamp_strike |= bod_buf[3] +1;
               
        device_hour |=        bod_buf[4] << 24;
        device_hour |=        bod_buf[5] << 16;
        device_hour |=        bod_buf[6] << 8;
        device_hour |=        bod_buf[7] ;
       
        //擦除
        FLASH_EraseBlock_a((u16)bod_buf);
                                                               
}

void BOD_Init(void)
{               
        clr_BOF;
  clr_BORF;
  clr_BORST;
        clr_BOV1;       
  clr_BOV0;    //4.4v       
        set_EBOD;                //使能欠压检测
        set_EA;
  set_BODEN;
}

void BOD_ISR(void) interrupt 8
{
        //清中断标志
       
        clr_EA;

        //存放查询次数
        config_f[0] =lamp_strike >> 24 ;
        config_f[1]        =lamp_strike >> 16 ;
        config_f[2]        =lamp_strike >> 8 ;
        config_f[3]        =lamp_strike);
       
        config_f[4]        =device_hour >> 24;
        config_f[5]        =device_hour >> 16;
        config_f[6]        =device_hour >> 8 ;       
        config_f[7]        =device_hour) ;
       
        FLASH_ProgramData((u16)bod_buf, &config_f, 12, 0);
       
        clr_BOF;
        set_EA;
}

使用特权

评论回复
29
liangbaixin| | 2018-6-28 16:30 | 只看该作者
yjgna 发表于 2018-6-27 16:22
你的代码配的BOD电压是2.7V 不是4.4V
4.4V的配置是
clr_BOV1;

这样写掉电存不了,新手不太懂
u8         bod_buf[12]        _at_        0x3400;
u8    config_f[12] ;
u32                device_hour = 0;
u32                lamp_strike;

void        read_device_hours(void)
{       
        lamp_strike |= bod_buf[0] << 24;
        lamp_strike |= bod_buf[1] << 16;
        lamp_strike |= bod_buf[2] << 8;
        lamp_strike |= bod_buf[3] +1;
               
        device_hour |=        bod_buf[4] << 24;
        device_hour |=        bod_buf[5] << 16;
        device_hour |=        bod_buf[6] << 8;
        device_hour |=        bod_buf[7] ;
       
        //擦除
        FLASH_EraseBlock_a((u16)bod_buf);
                                                               
}

void BOD_Init(void)
{               
        clr_BOF;
  clr_BORF;
  clr_BORST;
        clr_BOV1;       
  clr_BOV0;    //4.4v       
        set_EBOD;                //使能欠压检测
        set_EA;
  set_BODEN;
}

void BOD_ISR(void) interrupt 8
{
        //清中断标志
       
        clr_EA;

        //存放查询次数
        config_f[0] =lamp_strike >> 24 ;
        config_f[1]        =lamp_strike >> 16 ;
        config_f[2]        =lamp_strike >> 8 ;
        config_f[3]        =lamp_strike);
       
        config_f[4]        =device_hour >> 24;
        config_f[5]        =device_hour >> 16;
        config_f[6]        =device_hour >> 8 ;       
        config_f[7]        =device_hour) ;
       
        FLASH_ProgramData((u16)bod_buf, &config_f, 12, 0);
       
        clr_BOF;
        set_EA;
}

使用特权

评论回复
30
yjgna|  楼主 | 2018-6-29 08:59 | 只看该作者
xiaoqizi 发表于 2018-6-28 11:27
请问楼主 这款芯片的稳定性如何

我用它做的多款产品已经大批量出货,稳定性不用担心

使用特权

评论回复
31
yjgna|  楼主 | 2018-6-29 09:07 | 只看该作者
liangbaixin 发表于 2018-6-28 16:30
这样写掉电存不了,新手不太懂
u8         bod_buf[12]        _at_        0x3400;
u8    config_f[12] ;

我假设你的板子在掉电时,已经进入了BOD中断函数。并且你的FLASH_ProgramData函数是正确的
由于不确定你的VDD外挂电容是多大的,建议在FLASH_ProgramData写入后,把一个IO口拉高,用示波器抓下这个IO波形,掉电时 有没有出现脉冲,也就是FLASH_ProgramData有没有执行完毕

使用特权

评论回复
32
liangbaixin| | 2018-6-29 09:38 | 只看该作者
yjgna 发表于 2018-6-29 09:07
我假设你的板子在掉电时,已经进入了BOD中断函数。并且你的FLASH_ProgramData函数是正确的
由于不确定你 ...

我是直接用可变电源直接降到4.4V下的,写入函数没问题(现成的),我试下抓IO

使用特权

评论回复
33
liangbaixin| | 2018-6-29 09:57 | 只看该作者
yjgna 发表于 2018-6-29 09:07
我假设你的板子在掉电时,已经进入了BOD中断函数。并且你的FLASH_ProgramData函数是正确的
由于不确定你 ...

我抓了下IO,我只写12字节,23.5x12 =282us,掉电时脉冲持续了340us,时间上肯定够写完的

使用特权

评论回复
34
xiaoqizi| | 2018-6-29 11:50 | 只看该作者
yjgna 发表于 2018-6-29 08:59
我用它做的多款产品已经大批量出货,稳定性不用担心

哦哦哦  感谢您啊

使用特权

评论回复
35
1324968| | 2018-6-29 12:08 | 只看该作者
请问下 我这边也是电池产品,这个内部参考电压 你怎么弄的

使用特权

评论回复
36
yjgna|  楼主 | 2018-6-29 13:11 | 只看该作者
1324968 发表于 2018-6-29 12:08
请问下 我这边也是电池产品,这个内部参考电压 你怎么弄的

U16 xdata VDD_Voltage;

void READ_BANDGAP(void)
{
        U8 BandgapHigh, BandgapLow;
        double Bandgap_Value;

        set_IAPEN;
        IAPAL = 0x0C;
  IAPAH = 0x00;
  IAPCN = READ_UID;
  set_IAPGO;
        BandgapHigh = IAPFD;
        IAPAL = 0x0d;
  IAPAH = 0x00;
  IAPCN = READ_UID;
  set_IAPGO;
        BandgapLow = IAPFD;
        BandgapLow = BandgapLow & 0x0F;
        clr_IAPEN;
        Bandgap_Value = (BandgapHigh<<4)+BandgapLow;
  Bandgap_Voltage = 3072/(0x0fff/Bandgap_Value);
       
        Bandgap_Voltage = Bandgap_Voltage - 34;
}

U16 BAT_read_vdd(void)
{
  U16 auRet = 0;
  double auADValue = 0;  
  Enable_ADC_BandGap;                       // Find in "Function_define.h" - "ADC INIT"       
  CKDIV = 2; // Clk is 4MHz       
  ADC_Bypass(3);                             // For Band-gap convert please bypass the first 3 times.

  auADValue = ADC_read_value();
       
  CKDIV = 0; // Clk is 16MHz       

  return (U16)((0xFFF/auADValue)*Bandgap_Voltage - 30);
}

使用特权

评论回复
评论
yjgna 2019-12-6 08:41 回复TA
@zhuozhenjie :每次MCU上电读一次就好了 
zhuozhenjie 2019-11-9 21:18 回复TA
READ_BANDGAP在哪调用的 
37
1324968| | 2018-6-29 13:37 | 只看该作者
[3]ADC采样时,参考电压为VDD,而这个VDD是通过采用内部Bandgap电压 反推出来的,稍微麻烦点。 还有一点,不同批次的芯片Bandgap的采样值会有点偏差。
内部带隙电压(band-gap voltage)为1.22V   通过这个电压,和采集这个口的AD值,反推出VDD 是这样操作吗,这样就不用再外部线路去采集VDD

使用特权

评论回复
38
Harvard| | 2018-6-30 10:59 | 只看该作者
座机呀 发表于 2018-3-27 19:02
nulink版本问题,要重新安装nulink驱动到keil根目录,我的就是这样解决的

已经统一了

使用特权

评论回复
39
lss1985| | 2018-7-7 09:54 | 只看该作者
本帖最后由 lss1985 于 2018-7-7 09:56 编辑

楼主大神问一下dataflash烧写大概需要多少时间啊,现在在存储按键值时会影响定时器里面的LED显示功能,就是在擦除dataflash时LED会闪一下
void DATA_FLASH_Write(uint32_t u32addr,uint32_t u32data)
{
        DisableInterrupts();                                       
        SYS_UnlockReg();                                                
        FMC_ENABLE_ISP();

        FMC_Erase(u32addr);
        FMC_Write(u32addr,u32data);
        
        FMC_DISABLE_ISP();
        
        SYS_LockReg();                    
        EnableInterrupts();               
}
FMC用的库函数
static __INLINE void FMC_Write(uint32_t u32addr, uint32_t u32data)
{
    FMC->ISPCMD = FMC_ISPCMD_PROGRAM;   /* Set ISP Command Code */
    FMC->ISPADR = u32addr;              /* Set Target ROM Address. The address must be word alignment. */
    FMC->ISPDAT = u32data;              /* Set Data to Program */
    FMC->ISPTRG = 0x1;                  /* Trigger to start ISP procedure */
    __ISB();                            /* To make sure ISP/CPU be Synchronized */
    while(FMC->ISPTRG);                 /* Waiting for ISP Done */
}


static __INLINE int32_t FMC_Erase(uint32_t u32addr)
{
    FMC->ISPCMD = FMC_ISPCMD_PAGE_ERASE; /* Set ISP Command Code */
    FMC->ISPADR = u32addr;               /* Set Target ROM Address. The address must be page alignment. */
    FMC->ISPTRG = 0x1;                   /* Trigger to start ISP procedure */
    __ISB();                             /* To make sure ISP/CPU be Synchronized */
    while(FMC->ISPTRG);                  /* Waiting for ISP Done */

    /* Check ISPFF flag to know whether erase OK or fail. */
    if(FMC->ISPCON & FMC_ISPCON_ISPFF_Msk)
    {
        FMC->ISPCON = FMC_ISPCON_ISPFF_Msk;
        return -1;
    }
    return 0;
}


感觉擦除里面的while会影响定时器中断,因为前面关闭了总中断,而定时器是1ms扫描一次按键值并做显示
不知道这个问题怎么解决@yjgna

使用特权

评论回复
40
lss1985| | 2018-7-7 17:08 | 只看该作者
顶一下子

使用特权

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

本版积分规则