如何获取CH384的如何获取输入数据

图片.png

目前可以控制2~9管脚(即 D0~D7)的输出,以及1、14、16、17管脚的输出,和10、11、12、13、15管脚的读取。

请问如何将根据CH384的手册2~9管脚是可以作为输入模式的,请问需要如何配置呢?


下面代码是(控制2~9管脚(即 D0~D7)的输出,以及1、14、16、17管脚的输出,和10、11、12、13、15管脚的读取。)

#include 
#include  
#include 
#include  
#include  
#include  
#include  
#include 

#if __LP64__ 
    #define strtoptr strtoull
#else
    #define strtoptr strtoul 
#endif

//#define PAGE_SIZE 16384



int main(int argc, char *argv[]) 
{ 

    size_t PAGE_SIZE;
    int width = 1;    
    void *virt_addr;
    off_t target, target_base;
    unsigned long read_result, writeval;
    int type_width;
    uint32_t value = 0,param=0,temp=0; 
    PAGE_SIZE = getpagesize(); 

    uintptr_t addr = strtoptr("0x0efdfc007400", 0, 16); //strtoptr(argv[1], 0, 16); //strtoptr("0x0efdfc007400", 0, 16); 
    uintptr_t endaddr = 0;  

    if (!endaddr) 
        endaddr = addr + width - 1; 

        //fprintf(stderr,"argv[1] %s addr %08x PAGE_SIZE %08x\n", argv[1],addr,PAGE_SIZE); 

    int fd = open("/dev/mem", O_RDWR | O_SYNC); 
    if(fd < 0) 
    { 
        fprintf(stderr,"cannot open /dev/mem\n"); 
        return -1; 
    } 
    off_t mmap_start = addr & ~(PAGE_SIZE - 1); 
    size_t mmap_size = endaddr - mmap_start + 1;
    mmap_size = (mmap_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); 
    void* page = mmap64(0, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mmap_start); 
    if(page == MAP_FAILED)
    { 
        fprintf(stderr,"cannot mmap region\n"); 
        return -1; 
    } 

  

    volatile uint8_t* PDR_reg= (volatile uint8_t*) (((uintptr_t) page) + (addr & (PAGE_SIZE -1 ))); 
    volatile uint8_t* PSR_reg = (volatile uint8_t*) (((uintptr_t) page) +( (addr+0x01) & (PAGE_SIZE -1 ))); 
    volatile uint8_t* PCR_reg = (volatile uint8_t*) (((uintptr_t) page) +( (addr+0x02) & (PAGE_SIZE -1 ))); 
    volatile uint8_t* PXR_reg = (volatile uint8_t*) (((uintptr_t) page)  +( (addr+0x03) & (PAGE_SIZE -1 ))); 
    
    PDR_reg=0XFF;//2~9管脚输出高电平
    PCR_reg=0x04;//1、14、16、17管脚的输出高电平
    fprintf(stderr," 10、11、12、13、15管脚的读取 PSR %02x \n",  (*PSR_reg)&0xF8);
    
    
    
}


您好,PSR为RO只读寄存器,是不用单独设定方向的。可以先测试下支持RW的PCR和PXR寄存器,先写入后读,看下是否可以正常访问。


如何读取PIR数据输入寄存器呢?

volatile uint8_t* PDR_reg= (volatile uint8_t*) (((uintptr_t) page) + (addr & (PAGE_SIZE -1 )));

volatile uint8_t* PIR_reg= (volatile uint8_t*) (((uintptr_t) page) + (addr & (PAGE_SIZE -1 )));


*PDR_reg=0XFF;//实际测试 2~9管脚可以输出高电平(3v)


下面那对PIR_reg进行读取是否有问题呢

 fprintf(stderr," 读取PIR %02x \n", *PIR_reg);


查看手册PIR和PDR的地址偏移地址相同。


图片.png


目前PSR寄存器可以读取的,PSR的对应管脚PIN_1(STROBE)、PIN_14(line feed)、PIN_16(RESET)、PIN_17(select printer)的电平信号可以正常识别的。

PDR数据输出寄存器可以正常对端口进行输入电平的,其对应并口针的顺序是9,8,7,6,5,4,3,2。

PXR设置默认值为0X00。

PCR状态寄存器的读写正常,并可以控制并口管脚1,10,12,13,15输出高低电平。


1、在EPP模式,读写D0~D7数据的时候需要通过PCR的DIRIN设置传输方向。

2、在ECP模式,读写D0~D7数据的时候需要通过PCR的DIRIN和PXR的ECPDIRIN设置传输方向。

另,EPP/ECP方式下读取的为已经锁存的输入缓冲区内数据。

SPP模式,若不能直接读取,可按照EPP操作那样试下,单独设定DIRIN后再读取。


分别测试


第一组设置 (SPP模式)

PDR=0x00

PXR=0X00(默认是spp模式)

PCR=0XC0

PIR读取的值为0x00。(使用万有表测试,在D0~D7输出0V,无外其接设备)。




PDR=0xff(修改)

PXR=0X00(默认是spp模式)

PCR=0XC0

PIR读取的值为0xff。(使用万有表测试,在D0~D7输出3.3V,无外其接设备)。


PDR=0xF0(修改)

PXR=0X00(默认是spp模式)

PCR=0XC0

PIR读取的值为0xf0。(使用万有表测试,在D4~D7输出3.3V,无外其接设备)。


该组的PIR读取的数据均为PDR的数值。读取失败。







第二组 (spp+PCR_DIRIN置1)

在第一组的情况的修改

PCR=0XE0;

测试的结果和第一组相同。


是否有现成的读取PIR的来获取D0~D7的例子代码吗。


下面的测试代码是否问题呢?

#include 
#include  
#include 
#include  
#include  
#include  
#include  
#include 
 
#if __LP64__ 
    #define strtoptr strtoull
#else
    #define strtoptr strtoul 
#endif
 
//#define PAGE_SIZE 16384
 
 
 
int main(int argc, char *argv[]) 
{ 
 
    size_t PAGE_SIZE;
    int width = 1;    
    void *virt_addr;
    off_t target, target_base;
    unsigned long read_result, writeval;
    int type_width;
    uint32_t value = 0,param=0,temp=0; 
    PAGE_SIZE = getpagesize(); 
 
    uintptr_t addr = strtoptr("0x0efdfc007400", 0, 16); //strtoptr(argv[1], 0, 16); //strtoptr("0x0efdfc007400", 0, 16); 
    uintptr_t endaddr = 0;  
 
    if (!endaddr) 
        endaddr = addr + width - 1; 
 
        //fprintf(stderr,"argv[1] %s addr %08x PAGE_SIZE %08x\n", argv[1],addr,PAGE_SIZE); 
 
    int fd = open("/dev/mem", O_RDWR | O_SYNC); 
    if(fd < 0) 
    { 
        fprintf(stderr,"cannot open /dev/mem\n"); 
        return -1; 
    } 
    off_t mmap_start = addr & ~(PAGE_SIZE - 1); 
    size_t mmap_size = endaddr - mmap_start + 1;
    mmap_size = (mmap_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); 
    void* page = mmap64(0, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mmap_start); 
    if(page == MAP_FAILED)
    { 
        fprintf(stderr,"cannot mmap region\n"); 
        return -1; 
    } 
 
   
 
    volatile uint8_t* PDR_reg= (volatile uint8_t*) (((uintptr_t) page) + (addr & (PAGE_SIZE -1 ))); 
    volatile  uint8_t* PIR_reg= (volatile uint8_t*) (((uintptr_t) page) + (addr & (PAGE_SIZE -1 )));
    volatile uint8_t* PSR_reg = (volatile uint8_t*) (((uintptr_t) page) +( (addr+0x01) & (PAGE_SIZE -1 ))); 
    volatile uint8_t* PCR_reg = (volatile uint8_t*) (((uintptr_t) page) +( (addr+0x02) & (PAGE_SIZE -1 ))); 
    volatile uint8_t* PXR_reg = (volatile uint8_t*) (((uintptr_t) page)  +( (addr+0x03) & (PAGE_SIZE -1 ))); 
     

    fprintf(stderr," PIR_reg%02x \n", *PIR_reg);//读取之前的PIR_reg
    
    
    PXR_reg=stroul(argv[1],0,16);//设置PXR的数值。 
    PCR_reg=stroul(argv[2],0,16);//设置PCR的数值。

    fprintf(stderr," PXR_reg%02x \n", *PXR_reg);//读取PXR_reg
    fprintf(stderr," PCR_reg%02x \n", *PCR_reg);//读取PCR_reg
    
    fprintf(stderr," PIR_reg%02x \n", *PIR_reg);//读取PIR_reg
     fprintf(stderr," PSR_reg %02x \n", *PSR_reg );//读取PSR_reg 
     
     PDR_reg=stroul(argv[3],0,16);//设置PDR_reg的数值。
    
     
     
}



您好,如上SPP流程测试无问题。另,测试EPP并口时,PXR的MODEEPP是否已经开启。在EPP和ECP方式,数据为锁存数据。如:EPP方式,数据在AFD或SIN引脚输出低电平才会锁存,因此不能直接测量。


只有登录才能回复,可以选择微信账号登录