2543|1

23

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

求熟悉Silicon的c8051f系列单片机进来看看,解决XBYTE读取XRAM数据问题手机费酬谢 [复制链接]

求大神指导,解决了手机费100酬谢,使用c8051f505,datasheet链接贴出:https://www.silabs.com/documents/public/data-sheets/C8051F50x-51x.pdf,总体思路就是复用地址数据总线,在定时器1中读取FPGA地址过来的数据,程序初始化完成后就等着8位计数中断,中断函数读取地址中的数据,别人用汇编写好的程序能够正常运行,我翻译成c之后进入中断读取不XBYTE[0X2001];数据。源码贴出:汇编代码:

cseg            AT    00H
                        LJMP    MAIN
            ORG    000BH
        LJMP    A1CDF
        ORG    001BH
        LJMP    A1CC8
 MAIN:           
                    ANL  PCA0MD,    #0BFh
                MOV     SFRPAGE, #CONFIG_PAGE
                MOV     OSCICN, #0C5H
                MOV     P0SKIP,  #03H
                MOV     P1SKIP , #0E0H
                MOV     XBR0, #00H             ;交叉开关使能
                MOV     XBR1, #0C0H
                MOV     XBR2, #040H
               ;MOV     XBR3, #00H     
                MOV     P2MDIN,    #0FH   ;端口配置,P0开漏,p1,P4口为推挽输出
                MOV     P1MDOUT,   #0E7H
                MOV     P2MDOUT,   #0FH
                MOV     P3MDOUT,   #0FFH    ;P0-p4端口为数字输入,p2四位模拟输入端口     
                MOV     P4MDOUT,   #0FFH
                MOV  EMI0CF,    #09H
                MOV   EMI0TC,    #045H
                MOV     SFRPAGE,#ACTIVE_PAGE      
      LCALL    A1D30
    CLR      P1.4        ;开接收 
        SETB    EA        ;清中断屏蔽位,开CPU中断
A1875:        MOV    B,#00H

     SETB  P1.0
       CLR   P1.0 
         MOV    B,#00H    
A1885:                        ;等待T1中断接收数据,主函数,    
        NOP
      NOP   
      NOP
      NOP    
        JNB    B.3,A1885    ;通过BB3判断接收是否完成.
        MOV    A,COM_DATA
        JNZ    A1893        ;Is it command ?
        MOV    B,#00H
    LJMP    A1885        ;是数据,继续等待接收!        
A1CC8:        PUSH    DPL        ;接收中断服务子程(T1中断)
        PUSH    DPH
        PUSH    ACC
        MOV    DPTR,#2001H
        MOVX    A,@DPTR
        JB    B.0,A1D19
        MOV    RMSB,A
        MOV    COM_DATA,#00H
      ;SETB    P2.1
        JNB    P1.3,A1D1D
        MOV    COM_DATA,#0FFH
    A1D1D:    SETB    B.0
        SJMP    LP5
    A1D19:    MOV    RLSB,A
        SETB    B.3
    SJMP    LP5
 A1D30:         ;定义定时器子程
    SETB    TR1        
        SETB    ET1
        SETB    TR0
        SETB    ET0
        MOV    TMOD,#66H
        MOV    TH0,#0F8H
        MOV    TL0,#0F8H
        MOV    TH1,#0F8H
        MOV    TL1,#0F8H
        RET
    END

翻译后c代码:

#include <compiler_defs.h>
#include <C8051F500_defs.h>            // SFR declarations
#include <absacc.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
//#define XBYTE ((unsigned char volatile SEG_XDATA *) 1000)
uchar xdata *pchar;
uchar BB0,BB3,BB4,test;
sbit P10=P1^0;
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit P14=P1^4;
sbit P15=P1^5;
sbit P20=P2^0;
sbit P21=P2^1;
sbit P22=P2^2;
sbit P23=P2^3;
void Oscillator_Init(void);
void EMI_IN(void);
void Port_IO_Init(void);
void Timer_Init(void) ;
void CCAR_COMM(uchar m) ;
INTERRUPT_PROTO (TIMER1_ISR, INTERRUPT_TIMER1);
void main(void)
{
    SFRPAGE = ACTIVE_PAGE;              // Set SFR Page for PCA0MD   
    PCA0MD &= 0xBF;                    // Disable Watchdog timer 
    PCA0MD=0x00;  
    Oscillator_Init();
    Port_IO_Init();
    EMI_IN();
//    XBYTE[0X2001]=0X30;
//    P11=0;              
    BB0=0;
    BB3=0;
    BB4=0;
    Timer_Init() ;
    P10=1;
    P14=0;     //开接收
    EA=1;       //开中断                       
    while(1)
    {
        BB0=0;
        BB3=0;
        BB4=0;
        P10=1;
        Delay_us(20);           //A1DF0;
        P10=0;
        BB0=0;
        BB3=0;
        BB4=0;
        //RLSB=XBYTE[0X2001];
        while(!BB3);
        if(COM_DATA)                 //判断是数据还是命令
             CCAR_COMM(RMSB);
    }
}
void Oscillator_Init(void)
{
    //SFRPAGE_SAVE=SFRPAGE;
    SFRPAGE   = CONFIG_PAGE;
    OSCICN    = 0xC5;
    SFRPAGE = ACTIVE_PAGE;
}
//定时器初始化//A1D30
void EMI_IN(void)
{
    //SFRPAGE_SAVE = SFRPAGE;
    SFRPAG=CONFIG_PAGE;
    EMI0CF   = 0x09;                    //配置EMIF端口复用方式,带块选择的分片方式,<4k用内存,>4k用外存
    EMI0TC    = 0x45;                    //最小地址建立时间、最大保持时间。原值55H
    SFRPAGE=ACTIVE_PAGE ;
    //SFRPAGE = SFRPAGE_SAVE;
}
void Port_IO_Init(void)
{
    //SFRPAGE_SAVE = SFRPAGE;
    SFRPAGE   = CONFIG_PAGE;
    P0SKIP = 0x03;                    // Skip P0.0 and P0.1
    P1SKIP = 0xE0;  
    XBR0      = 0x00;
    XBR1      = 0xC0;                       //T2、T1、T0连接到端口引脚
    XBR2      = 0x40;                       //使能交叉开关
    P2MDIN    = 0x0F;                       //设置P2口没有模拟输入
    P1MDOUT   = 0xE7;                       //推挽输出带负载能力强
    P2MDOUT   = 0x0F;
    P3MDOUT   = 0xFF;
    P4MDOUT   = 0xFF;
    SFRPAGE=ACTIVE_PAGE ;
    //SFRPAGE = SFRPAGE_SAVE;
}
void Timer_Init(void)                       
{
//    SFRPAGE   = CONFIG_PAGE;
//    TCON=0x00; 
//    EA=1; 
    ET0=1;
    ET1=1;
    TR0=1;
    TR1=1;
    TMOD=0x66;
    TL0=0xF8;
    TH0=0xF8;
    TL1=0xF8;
    TH1=0xF8;
//    SFRPAGE=ACTIVE_PAGE ;
}

//命令判断
void CCAR_COMM(uchar m)        
{
    switch(m)//A1893
    { 
    case 0x20:                     //2000H命令(时间谱短节通讯检查)是双字命令              
            DOUBLE_REC();         //等待接收双命令字的第二个字,如果第二个是命令字则返回到最初的命令判断,如果是数据,则返回到原命令继续执行
            P14=1;                  //关接收
            SLSB=RLSB;                   //将接收数据放到发送数据存储地址。
            SMSB=RMSB;
        //    Delay_bms(2);
        //    P04=!P04;            
            S_GUIDE(SMSB);
            while(!BB4);
        //    Delay_us(600);
            P14=0;
            break;
        default:
            C_ERR=0x08;
            break;    
    }                    
}

//接收中断 //接收数据      (实际函数初始化完毕后就等T1中断接收数据)
INTERRUPT(Timer1_ISR, INTERRUPT_TIMER1)
//void Timer1_ISR(void)  interrupt 3 
{
pchar=2001+1000;
    if(BB0)
    {

        RLSB=XBYTE[0X2001];
        BB3=1;
    }

    else 
    {
        RMSB=XBYTE[0X2001];
    //    RMSB=*pchar;
        COM_DATA=0x00;
        if(P13==0)BB0=1;
        else 
        {
            COM_DATA=0xff;
            BB0=1;
        }
    }
}

此帖出自51单片机论坛

最新回复

是要读固定RAM的值吗?可试试 char *ptr; char Value; ptr = 0x2001; Value = *ptr; // (0x2001值)   详情 回复 发表于 2020-11-6 14:24
点赞 关注
 

回复
举报

256

帖子

0

TA的资源

一粒金砂(高级)

沙发
 

是要读固定RAM的值吗?可试试

char *ptr;
char Value;
ptr = 0x2001;
Value = *ptr; // (0x2001值)

此帖出自51单片机论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表