迪文科技论坛

 找回密码
 立即注册
搜索
查看: 555|回复: 15

【提问】求助DGUS变量读取数据问题

[复制链接]

0

主题

8

回帖

43

积分

新手上路

Rank: 1

积分
43
发表于 2024-9-3 15:21:35 | 显示全部楼层 |阅读模式
代码来源参考此链接 http://inforum.dwin.com.cn:20080 ... ad&tid=328#lastpost        




//读写T5L片内256KW Flash,mod=0x5A 为读取,mod=0xA5为写入
        //addr=DGUS变量地址,必须是偶数;addr_flash=flash读取地址,必须是偶数;len=读取字长度,必须是偶数。
        void T5L_Flash(unsigned char mod,unsigned int addr,long addr_flash,unsigned int len)
{        ADR_H=0x00;
    ADR_M=0x00;
    ADR_L=0x04;//这里为什么不是0x08,按照asic开发文档这里地址应该是0x08?
    ADR_INC=0x01;
    RAMMODE=0x8F;                //启动读Flash
        while(APP_ACK==0);
        DATA3=mod;
        DATA2=(unsigned char)(addr_flash>>16);
        DATA1=(unsigned char)(addr_flash>>8);
        DATA0=(unsigned char)(addr_flash&0xFE);
        APP_EN=1;        
        DATA3=(unsigned char)(addr>>8);
        DATA2=(unsigned char)(addr&0xFE);
        DATA1=(unsigned char)(len>>8);
        DATA0=(unsigned char)(len&0xFE);
        APP_EN=1;
        RAMMODE=0x00;
        wait_ok(0x0004);}        //等待数据读取OK

        //读取DGUS变量数据 addr=DGUS变量地址  *buf=数据返回指针  len=读取数据字长度
        void read_dgusii_vp(unsigned int addr,unsigned char *buf,unsigned int len)//这个函数不能读32位数据,需要怎么优化才能读32位数据
{   unsigned char i;     
    i=(unsigned char)(addr&0x01);
    addr=addr/2;//这里为什么要把DGUS变量地址除以2?
    ADR_H=0x00;
    ADR_M=(unsigned char)(addr>>8);
    ADR_L=(unsigned char)(addr);
    ADR_INC=0x01;
    RAMMODE=0xAF;
        while(APP_ACK==0);
        while(len>0)
{   APP_EN=1;
    while(APP_EN==1);
    if((i==0)&&(len>0))   
    {   *buf++=DATA3;
        *buf++=DATA2;                     
        i=1;
                len--;        }
         if((i==1)&&(len>0))   
    {   *buf++=DATA1;
        *buf++=DATA0;                     
        i=0;
                len--;        }}
        RAMMODE=0x00;}

        //写DGUS变量数据 addr=DGUS变量地址  *buf=写入数据指针  len=写入数据字长度
        void write_dgusii_vp(unsigned int addr,unsigned char *buf,unsigned int len)//这个函数不能写32位数据,需要怎么优化才能写32位数据
{   unsigned char i;     
    i=(unsigned char)(addr&0x01);
    addr=addr/2;//这里为什么要把DGUS变量地址除以2?
    ADR_H=0x00;
    ADR_M=(unsigned char)(addr>>8);
    ADR_L=(unsigned char)(addr);   
        ADR_INC=0x01;
        RAMMODE=0x8F;
        while(APP_ACK==0);
        if(i && len>0)
        {        RAMMODE=0x83;        
                DATA1=*buf++;               
                DATA0=*buf++;        
                APP_EN=1;               
                len--;}
        RAMMODE=0x8F;
        while(len>=2)
        {        DATA3=*buf++;               
                DATA2=*buf++;
                DATA1=*buf++;               
                DATA0=*buf++;
                APP_EN=1;               
                len=len-2;}
        if(len)
        {        RAMMODE=0x8C;
                DATA3=*buf++;               
                DATA2=*buf++;
                APP_EN=1;}
        RAMMODE=0x00;}        


回复

使用道具 举报

0

主题

12

回帖

65

积分

注册会员

Rank: 2

积分
65
发表于 2024-9-3 15:46:49 | 显示全部楼层
ADR_L=0x04;//这里为什么不是0x08,按照asic开发文档这里地址应该是0x08?  答:开发文档的是字地址,这里是双字地址,所以除了2.
//这个函数不能读32位数据,需要怎么优化才能读32位数据   答:把ADR_H给利用起来,这个是双字地址的高字节
addr=addr/2;//这里为什么要把DGUS变量地址除以2?   答:这个就是将字地址转为双字地址的过程
回复

使用道具 举报

0

主题

8

回帖

43

积分

新手上路

Rank: 1

积分
43
 楼主| 发表于 2024-9-3 16:15:18 | 显示全部楼层
Rye4869cjxy 发表于 2024-9-3 15:46
ADR_L=0x04;//这里为什么不是0x08,按照asic开发文档这里地址应该是0x08?  答:开发文档的是字地址,这里 ...

十分感谢
代码参考这个链接 http://inforum.dwin.com.cn:20080 ... &extra=page%3D1
void caninit()
{
        P0MDOUT = 0x04;        //P0.2(CAN_TX)配置为输出
        P0 = 0xFF;                         //输出高电平
        ADR_H = 0xFF;
        ADR_M = 0x00;
        ADR_L = 0x60;
        ADR_INC = 1;
        RAMMODE = 0x8F;        //写操作
        while(!APP_ACK);
        DATA3 = 45;
        DATA2 = 0x87;
        DATA1 = 0x43;
        DATA0 = 0;                         //设置BRP=45,SJW=4,T0=7,T1=4,T2=3,波特率125K
        APP_EN = 1;
        while(APP_EN);
        DATA3 = 0;
        DATA2 = 0;
        DATA1 = 0;
        DATA0 = 0;                         //验收寄存器清零
        APP_EN = 1;          
        while(APP_EN);
        DATA3 = 0xFF;
        DATA2 = 0xFF;
        DATA1 = 0xFF;
        DATA0 = 0xFF;                 //验收屏蔽寄存器全部置1,不对接收进行验收
        APP_EN = 1;       
        while(APP_EN);
        RAMMODE = 0;
        CAN_CR = 0xA0;                //打开CAN接口,并配置FF0060-FF0062
        while(CAN_CR&0x20);        //执行配置FF0060-FF0062动作
        ECAN = 1;                        //打开CAN中断
        EA = 1;                                //打开总中断               
}
这个CAN初始化代码,怎么不用把字地址转换伟双字地址呢?你们系统对CAN进行了特殊处理?
回复

使用道具 举报

0

主题

12

回帖

65

积分

注册会员

Rank: 2

积分
65
发表于 2024-9-3 16:53:26 | 显示全部楼层
这个CAN初始化函数里并没有形参,直接是对ADR_H ,ADR_M ,ADR_L 寄存器进行操作,其实就是双字地址
回复

使用道具 举报

0

主题

12

回帖

65

积分

注册会员

Rank: 2

积分
65
发表于 2024-9-3 17:08:04 | 显示全部楼层
是的  CAN通信接口的地址固定在了0xFF:0060-0xFF:006B,这个在开发指南里有
回复

使用道具 举报

0

主题

8

回帖

43

积分

新手上路

Rank: 1

积分
43
 楼主| 发表于 2024-9-3 17:45:45 | 显示全部楼层
Rye4869cjxy 发表于 2024-9-3 16:53
这个CAN初始化函数里并没有形参,直接是对ADR_H ,ADR_M ,ADR_L 寄存器进行操作,其实就是双字地址 ...

那我是不是可以理解如果要读写dgus变量存储器地址(0x1000-0xFFFF)(就是屏界面上各种变量的地址)里面的值,我都需要将dgus变量存储器地址除以2,然后赋值给SFR寄存器,通过DATA3-0把dgus变量存储器的值给读出来,这个是你们系统给封装好的(CAN例外)。谢谢
回复

使用道具 举报

0

主题

694

回帖

4103

积分

论坛元老

Rank: 8Rank: 8

积分
4103
发表于 2024-9-3 19:28:21 | 显示全部楼层
精灵王 发表于 2024-9-3 17:45
那我是不是可以理解如果要读写dgus变量存储器地址(0x1000-0xFFFF)(就是屏界面上各种变量的地址)里面 ...

可以这样理解
回复

使用道具 举报

0

主题

12

回帖

65

积分

注册会员

Rank: 2

积分
65
发表于 2024-9-4 09:00:43 | 显示全部楼层
精灵王 发表于 2024-9-3 17:45
那我是不是可以理解如果要读写dgus变量存储器地址(0x1000-0xFFFF)(就是屏界面上各种变量的地址)里面 ...

是的,但是只有norflash读写才需要偶数字地址,DGUS读写函数可以是任何0x1000-0xFFFF字地址
回复

使用道具 举报

0

主题

8

回帖

43

积分

新手上路

Rank: 1

积分
43
 楼主| 发表于 2024-9-5 16:24:16 | 显示全部楼层
本帖最后由 精灵王 于 2024-9-5 16:34 编辑
Rye4869cjxy 发表于 2024-9-4 09:00
是的,但是只有norflash读写才需要偶数字地址,DGUS读写函数可以是任何0x1000-0xFFFF字地址 ...

按照图片中介绍写读写屏幕上32位数据变量,现在有个问题请教下,就是读写屏幕上32位数据搞不定了,现象就是假如我给0x2016写数据,那么0x2015和0x2017也会收到影响,请问有没有什么解决办法,我感觉你们系统封装的变量接口读写函数,不支持32位数据的读写。参考代码如下:

void Write_Dgus_u32(u16 Dgus_Addr,u32 Val)
{         
        ADR_H = 0x00;
        ADR_M = (u8)((Dgus_Addr/2)>>8);
        ADR_L = (u8)(Dgus_Addr/2);
        /*ADR_M = (u8)(Dgus_Addr>>8);
        ADR_L = (u8)(Dgus_Addr);  */
        ADR_INC = 1;
        RAMMODE = 0x8F;                //写操作
        while(!APP_ACK);
        if(Dgus_Addr%2==1){
                RAMMODE = 0x83;
                //DATA3 =0;       
                //DATA2 =0;
                DATA1 =(u8)(Val>>24);
                DATA0 =(u8)(Val>>16);
                //DATA3 =(u8)(Val>>8);       
                //DATA2 =(u8)(Val);
                APP_EN = 1;
                while(APP_EN);
                RAMMODE = 0x8C;       
                DATA3 =(u8)(Val>>8);       
                DATA2 =(u8)(Val);
                //DATA1 =0;
                //DATA0 =0;
        }else{
                RAMMODE = 0x8F;       
                DATA3 =(u8)(Val>>24);       
                DATA2 =(u8)(Val>>16);
                DATA1 =(u8)(Val>>8);
                DATA0 =(u8)(Val);
        }               
        APP_EN = 1;
        while(APP_EN);
        RAMMODE = 0;               
}


本帖子中包含更多资源

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

x
回复

使用道具 举报

0

主题

12

回帖

65

积分

注册会员

Rank: 2

积分
65
发表于 2024-9-6 08:57:48 | 显示全部楼层
您好,这个函数是您自己写的嘛,如果想写双字完全没必要新写一个函数,你定义一个双字变量也可以直接通过write_dgusii_vp这个函数写进去,比如
u32 temp;

write_dgusii_vp(0x2016,(u8*)&temp,2);

这样就可以写一个双字了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|迪文科技论坛 ( 京ICP备05033781号-1 )

GMT+8, 2024-11-22 02:49 , Processed in 0.108765 second(s), 32 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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