精华内容
下载资源
问答
  • 电脑并口测试盒的制作方法及测试程序下载! 不知各位是否遇到像我这样的尴尬情况,辛辛苦苦花了大半天的工夫和一大把接口芯片银子把HP6L修好。(HP6L不联机)。客户把电脑搬来要求试打一下, 天啦,刚刚修好的机子又...
  • 并行接口,简称并口,也就是LPT接口,是采用并行通信协议的扩展接口。本文介绍是用并口控制液晶Lcd6963的测试程序
  • 12864并口显示程序

    2014-03-24 11:41:45
    绝对好用,不显示图片,并口驱动,已经烧写测试通过了哦
  • YM12864并口驱动程序

    2010-04-25 00:35:05
    51驱动YM12864R的并口显示历程,我已经测试过啦,程序不会有问题,如果不能正常显示,有可能是VO口的分压不够大造成的呢,我就遇到这个情况啦
  • 好吧,最近找完工作,时间也蛮多,于是想系统的学习一下Linux下的驱动程序设计。一是为了学习,二是为了实验室实际项目需要。所以我买了传说中的经典书籍LDD>,之前早已听闻这本书。  花了大概大半个

    一、前言

            一直想多学习一下Linux,总得找一个方向吧。书太多,也看过许许多多的Linux书,代码太多,看过比较多的代码,可是为啥一直在入门ing,从未进入过。。。。。。好吧,最近找完工作,时间也蛮多,于是想系统的学习一下Linux下的驱动程序设计。一是为了学习,二是为了实验室实际项目需要。所以我买了传说中的经典书籍LDD<<Linux设备驱动程序>>,之前早已听闻这本书。

            花了大概大半个月时间把这本书的前十二章看完了,于是想自己动手写写驱动程序,来实际验证究竟是不是像书上讲的那样写,就能在Linux下实现驱动程序控制设备的功能。于是找了书中的例子,拿并口驱动程序做实验。此文主要想记录我实验的详细过程和实验过程中遇到的问题和解决办法。

             以下是我的实验环境:

              1、一台带并口的PC机:研华工业计算机,酷睿CPU

              2、ubuntu11.04,安装盘原装内核2.6.38.8。

             

    二、实验过程

    1、确保并口是功能完好的。

           我刚开始没想到先验证并口是否可用,于是就先按照书上讲的方法先写了一个简单的驱动程序测试并口。结果当然是并口并不能受我的驱动程序控制,于是就很难定位问题出在哪里,很可能是驱动程序问题吧?因为我第一次写驱动,于是一遍一遍的查找是不是程序有问题。。。。。最后发现我找的第一台电脑的并口就是坏的,然后才找到研华工控机的并口是好的。

          检查方法我试过二种,第一种是在windows系统下,上网上找并口测试程序,然后用万用表去量并口电压是否受能按设定改变。第二种是在Ubuntu下用原装系统自带的并口驱动程序提供的接口写用户空间测试程序,照样是用万用表去量并口管脚,主要参照http://mockmoon-cybernetics.ch/computer/linux/programming/parport.html。以下是我亲自在我平台上测试通过的:

    //Access via raw IO (not recommended)在用户空间获得权限直接访问并口I/O端口,只在X86平台支持。
    #include <stdio.h>
    #include <sys/io.h>
    
    #define BASEADDR 0x378
    
    int main(int argc, char **argv)
    {
    	int i;
    
    	if(ioperm(BASEADDR, 4, 1) < 0) {
    		fprintf(stderr, "could not get i/o permission. are you root ?\n");
    		return 5;
    	}
    	for(i=0; i < 256; i++) {
    		outb(i, BASEADDR);
    	}
    	ioperm(BASEADDR, 4, 0);
    	return 0;
    }
    
     
    //这是利用UBUNTU自带的并口驱动ppdev和并口设备/dev/parport0(ubuntu已建好)进行并口测试。
    //lsmod可以看见lp,ppdev parport_pc parport等并口驱动,cat /dev/ioports能看见并口端口被占的情况
    #include<stdio.h>
    #include<fcntl.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<asm/ioctl.h>
    #include<linux/parport.h>
    #include<linux/ppdev.h>
    
    #define DEVICE "/dev/parport0"
    
    int main()
    {
    	struct ppdev_frob_struct frob;
    	int fd;
    	int mode;
    	char data = 0xFF;
    	fd = open(DEVICE, O_RDWR);
    	if(fd < 0)
    	{
    		printf("open error:\n");
    		return -1;
    	}
    	
    	if(ioctl(fd, PPCLAIM))        //这里也可以是其它一些测试代码,按照上面网站教程所说。
    	{
    		perror("PPCLAIM");
    		close(fd);
    		return -1;
    	}
    	
    	ioctl(fd, PPWDATA, &data );	
    	ioctl(fd, PPRELEASE);
    	close(fd);
    	return 0;
    }

    2、按照LDD书或者网上各种资料写自己的并口驱动程序,简单的主要完成控制并口电压,驱动程序通过ioctl或者write方法都行。
          主要的步骤是:
          在module_init(init_function)的初始化函数init_function()中注册一个字符设备cdev,动态静态注册都行。我是用register_chardev()静态注册。如果注册成功,再用request_region(0x378, 8, DEV_NAME)去申请独占并口端口。这个表示这一并口的I/O端口寄存器是从0x378-0x37F的8个连续地址,可以在BIOS设置基址。
           然后就是实现ioctl了或者write方法了,ioctl用copy_from_user()将用户空间数据拷贝到内核或者直接用arg参数都行。write()方法必须用copy_from_user()将需要写的数据从用户空间拷贝到内核。然后调用outb(value, 0x378),就能设置0x378地址的I/O端口了。以下是我参照网上一网友的程序:
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/fs.h>
    #include <linux/errno.h>
    #include <linux/types.h>
    #include <linux/fcntl.h>
    
    #include <asm/uaccess.h>
    #include <asm/io.h>
    
    #define DEV_NAME "phoenix_port"
    
    #define DEV_MAJOR 223
    #define PORT_WRITE_ADDR 0X378
    
    #define PORT_READ_ADDR 0X379
    
     
    
    int phoenix_open(struct inode *inode,struct file *filp)
    {
    	return 0;
    }
    
    int phoenix_release(struct inode *inode,struct file *filp)
    {
    	return 0;
    }
    
    ssize_t phoenix_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
    {
    	//this fun read one char,not the count you pass
    	unsigned char status;
    	//inb is a function that can read a byte form addr
    	status=inb(PORT_READ_ADDR);
    	//put the byte to usr buf
    	put_user(status, (char *)buf);
    	return 1;
    }
    
    ssize_t phoenix_write(struct file *filp, char *buf, size_t count, loff_t *fpos)
    {//write one char ,no matter how many you want to write;
    
    //get param from usr to kernel
    	unsigned char status;
    	get_user(status, (char*)buf);
    	outb(status, PORT_WRITE_ADDR);
    	printk(KERN_ALERT "write io value:%x",status);
    	return 1;
    }
    
     
    
    struct file_operations oper_struct=
    {
    	.owner=THIS_MODULE,
    	.open=phoenix_open,
    	.release=phoenix_release,
    	.read=phoenix_read,
    	.write=phoenix_write,
    };
    
    int phoenix_init(void)
    {
    	int tmp;
    	tmp=register_chrdev(DEV_MAJOR, DEV_NAME, &oper_struct);
    	if(tmp<0)
    	{
            printk(KERN_ALERT "module_init error !\n");
            return tmp;
    	}
    	if(request_region(0x378, 8, DEV_NAME))
    	{
    		printk(KERN_ALERT "get io port region");
    	}
    	else
    	{
    		printk(KERN_ALERT "can not get io port region");
    	}
    	return 0;
    }
    
    void phoenix_exit(void)
    {
    	release_region(0x378, 8);
    	unregister_chrdev(DEV_MAJOR,DEV_NAME);
    }
    
    module_init(phoenix_init);
    module_exit(phoenix_exit);
    MODULE_LICENSE("Dual BSD/GPL");
    
           这段程序是看不出有问题的,然后编译通过生成port.ko文件,用sudo insmod port.ko载入我们写的驱动模块。然后用命令sudo mknod /dev/myport c 223 0生成一个和并口驱动对应的设备文件,其中223必须和驱动一致,次设备号应该是0-255任一个都行,主设备号也可以通过cat /proc/devices查看加载驱动对应的主设备号。系统通过主设备号才能将设备文件和驱动中定义的方法联起来,具体内核怎么实现的,还有待研究,我只知道在主次设备号是设备文件的inode结点的一部分,然后这个inode节点会传给驱动程序的write(),read()方法,在驱动程序中可以通过imajor(inode),iminor(inode)读出设备文件的主次设备号,通常只读次设备号来区分用同一驱动程序的几个类似功能的设备文件,在驱动程序中实现不同的方法。
    上述过程可能遇到的问题有:
           1、虚拟控制台看不到内核printk输出信息,用dmesg可以看到。或者切换到真实控制台tty下(非界面UBUNTU)也可以看到。
           2、insmod port.ko会出现request_region()失败,是因为UBUNTU自带的并口驱动已经把端口占了,所以需要sudo rmmod lp ppde parport_pc相关的驱动,然后再insmod port.ko就行了。
           然后就可以写用户空间测试程序了,我参照网上,修改成如下的测试程序:
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/ioctl.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #define DEV_NAME "/dev/phoenix_port" //必须和mknod建立的文件名一致
    
    int main()
    {
    //open phoenix_port
    int dev;
    dev=open(DEV_NAME,O_RDWR|O_NDELAY);
    if(dev<0)
    {
          printf("open dev error!\n");
            return -1;
    }
    //open right
    printf("have open dev!\n");
    int count = 1;   
    char state =0x00;
    while(1)
    {
    	if(!(count % 2))				//every two second
    	{
    		state = state ^ 0x01;
    		printf("write state:%x",state);
        	write(dev, &state, 1);
    	}
    	if(!(count % 1))				//every one second
    	{
    		state = state ^ 0x04;
    		printf("write state:%x",state);
    		write(dev, &state, 1);
    	}
    	count++;
    	sleep(1);
    }
    //close dev
    close(dev);
    return 0;
    }
    
           然后gcc 编译上面的的用户空间测试程序,sudo ./out执行程序,用demsg查看内核输出信息知道驱动程序ssize_t phoenix_write(struct file *filp, char *buf, size_t count, loff_t *fpos) 已经执行,并且写入了用户空间write()调用传入的数据。至此,我已经以为驱动程序成功的时候,拿万用表去测量并口管脚,发现管脚并无任何变化。然后就是各种寻找可能的问题了。
     
    3、解决步骤2中遇到的问题
          上面遇到的问题很费解了,差不多花了我一个多星期的时间各种寻找解决办法。去上网查过许多教程都是说request_region()成功后,用outb()写端口就行了问过一些驱动交流群也是如此。
           我只得改驱动程序进行各种尝试了:
           比如不用write(),而用ioctl()方法
           比如不用直接访问I/O端口,而是用remap()将端口映射到内存,X86是有独立的端口编址访问才对,所以我只是尝试。
           比如不用老式的注册设备方法register_chrdev()。而用新的 cdev_init() + cdev_add()。
           以上所有方法,均能注册设备成功,request_region()成功获得端口,用cat /proc/devices能看见设备驱动名称和主设备号, cat /proc/ioports能看见占用的端口,dmesg也能看见往端口0x386写数据了,但是结果都一样,并口没反应。
     
           最费力的方法是我去读内核的ppdev.h ppdev.c驱动文件,想看看它怎么写的。然后想把我的一部分驱动程序利用ppdev.h提供的接口,来定位我的驱动程序的问题所在。比如想把request_region替换为用ppdev.h中的if(ioctl(fd, PPCLAIM)) //方法,或者把write()替换为ppdev.h中的PPWDATA方法,来定位问题,都失败了。
     
            最后最后最后,折腾的我有点疯了。就在今天,我想起以前在哪看过一句话,大意是:写驱动开发,最好不要用LINUX发行版本带的内核,因为有的做过修改。而是要自己去下一个标准的内核源码,编译,安装,在这个标准内核源码上做开发。。。像快死的人抓住最后的救命稻草,我只得去一试,结果就刚刚的,经过换成标准内核,并口可以受驱动程序控制了。至此驱动程序勉强算是测试成功。
     
    4、结论
          虽然最后是测试成功了,但是为啥Ubuntu自带的内核测试不成功,还找不到原因,很奇怪。。。。。总不能产品厂商发行驱动时候,都得要普通Ubuntu用户自己去编译内核吧。
     
    5、过程中遇到的一些杂问题和解决办法。
           刚装的较老版本的UBUNTU,想用sudo apt-get install装任何软件都说找不到安装包,这时需要更新源信息。参http://www.cnblogs.com/eastson/archive/2012/08/24/2654163.html文章。即编辑/etc/apt/sources.list源文件(添加一些源,比如校内的或者搜狐之类的),再sudo apt-get update即可。好像有不用编制源文件的方法,是直接用一个什么命令。
         编译驱动的时候说file_operation  op结构中的 ioctl()方法无定义,去查找内核asm/ 下ioctl的头文件发现 3.0.0的内核中,ioctl()接口已经更名为unlocked_ioctl()和另外一种ioctl()。所以把取其中一个。

     

    6、下一步计划

           用FPGA开发外围设备卡,通过PCI总线或者ISA总线挂在研华的工控机上,自己做外围电路和写驱动程序。

    展开全文
  • 并口128964通过测试.rar

    2021-05-11 11:09:57
    基于stm32的12864液晶并口程序(完全通过测试本人亲写)
  • 在VMware中装了CentOS,用来...在测试LDD3(Linux Device Drivers 第三版)第9章的并口示例时,通过VM->Setting加入了并口,然后重新启动CentOS。完成上述操作后,用例子里面带的short_load加载测试模块时,出现如下提
    在VMware中装了CentOS,用来进行嵌入式开发。在测试LDD3(Linux Device Drivers 第三版)第9章的并口示例时,通过VM->Setting加入了并口,然后重新启动CentOS。完成上述操作后,用例子里面带的short_load加载测试模块时,出现如下提示:
    

    通过“cat /proc/ioports”查看/proc/ioports发现,系统已经加载了并口模块,如下图所示:

    为了能够测试short模块,需要卸载系统已经加载的并口模块,首先想到的就是rmmod parport,但是出现错误提示:

     

    根据提示,发现parport正在呗ppdev,lp,parport_pc使用,所以尝试先将这几个模块卸载,然后再卸载parport,操作如下:

    一切顺利。

    再查看/proc/ioports,并口模块parport已经成功卸载。

    然后重新运行./short_load,查看/dev/short* 发现short模块已经成功添加完成。

    展开全文
  • 并口测试代码

    2013-01-09 00:35:24
    很好的资料,非常适合初学者,是一个非常基本的程序,不难的。
  • 并口AVR-ISP测试软件

    2011-08-22 21:48:25
    并口ISP测试软件 说明:本软件的编写过程中,本人参考了网站上并口控制LCD液晶的程序,使用了其中的并口操作! 本软件只是测试版,支持MEGA8、MEGA16、MEGA32、MEGA64、MEGA128。但本人只测试过MEGA16和MEGA128...
  • 这是一款打印针断针测试程序,包括针测试内容 和 并口发送批处理文件。可以应用在所有的正规厂商的含并口的针式打印机上。
  • POS小票机测试程序

    2015-08-19 22:54:40
    一个pos机的测试程序,支持并口,串口,网口和usb口
  • HG1286412B的测试程序

    2009-10-02 15:28:50
    HG1286412B的测试程序 并口的程序,大家看看应该对因受会有帮助
  • 洛阳凡客软件小票打印机端口测试工具, RP-POS58N串/并口打印机演示程序.
  • 用来测试热敏小票打印机 提供单张测试、走纸、疲劳测试等功能 支持并口串口
  • 用来测试热敏小票打印机 提供单张测试、走纸、疲劳测试等功能 支持并口串口
  • 12864带字库与AD7705测试程序,采用并口
  • tm1638测试程序

    2019-04-18 15:38:29
    //移位,并口被锁存,串行转换开始 _nop_(); for(i=0;i;i++) //设定16位输入 { read_data; if(QH) { read_data|=QH; } CK=0; //下降沿 _nop_(); CK=1; _nop_(); //上升沿 } return read_data; ...
  • 用Delphi 7写的一个票据打印机测试程序,可以向串并口传输数据,采用Createfile、Writefile、Readfile,可发送开钱箱、倍高倍宽等可用的ESC/POS指令。
  • 单片机以4位并口通过CH365与计算机交换数据,其中计算机发出数据给单片机,单片机收到数据后返回到计算机。这是一个测试程序
  • 适用大部分品牌的24针针式打印机,USB和并口都可,绿色免安装,使用简单。
  • 注意,请根据使用的晶振频率修改参考程序中的 LD_WriteReg(0x19, LD_PLL_ASR_19); LD_WriteReg(0x1B, LD_PLL_ASR_1B); LD_WriteReg(0x1D, LD_PLL_ASR_1D); delay(10); LD_WriteReg(0xCD, 0x04); LD_...
  • 并口开发调试工具

    2013-01-08 16:29:46
    对于需要编写并口通讯程序的人员来说,可能会需要一款方便的并口调试工具,开发调试工具包包括三个功能模块:“并口调试器”、“并口测试信号发生器”和“并口监视器”,分别针对不同的使用需求。
  • CEIWEI ParallelMonitor并口监控是用于LPT设备端口监控的专业强大的系统实用程序软件。CEIWEI ParallelMonitor监控记录和分析系统中的所有并行端口的活动;追踪应用程序或驱动程序开发,并行设备测试和优化等过程中...

        CEIWEI ParallelMonitor并口监控 是用于LPT设备端口监控的专业强大的系统实用程序软件。CEIWEI  ParallelMonitor 监控记录和分析系统中的所有并行端口的活动;追踪应用程序或驱动程序开发,并行设备测试和优化等过程中可能出现的问题的理想工具。还提供过滤、搜索、数据导出和强大的数据拦截功能,可以将指定端口的数据流、控制流信息拦截并保存下来,供分析之用。查看并行端口状态的变化,拦截上行、下行的数据,处理速度快,拦截效率高,并且可以16进制、10进制、8进制、2进制显示输出数据,字符串则可以不同的编码显示输出,支持设备数据的Unicode/UTF8/UTF7编码解码,支持WinXP, Win7,Win10操作系统。

     

     

     

    淘宝购买https://item.taobao.com/item.htm?id=638643840143 

    ParallelMonitor主要功能:

    ·         支持监控并行端口类型:标准电脑25针/36针并行端口;

    ·         可以实时监控并采集并行端口数据;

    ·         可以同时监控多个并行端口;

    ·         监控已经被其他应用程序打开的并行端口;

    ·         支持监控视图:列表视图,Line视图、Dump视图、终端视图;

    ·         支持监控并行端口所有的Write/Read数据流;

    ·         支持监控所有并行端口IOCTL控制代码,并跟踪完整请求信息和参数;

    ·         支持自定义的监控视图数据记录的颜色、时间格式、字节换行长度、字节不同数制展示输出等;

    ·         支持监控会话管理:保存和加载所有监视数据,导出并重定向到文件功能;

    ·         支持监控视图数据导出ASCII文本,并支持自动重定向到文件(需要注册专业版本);

    ·         将所有记录的数据复制到剪贴板(需要注册企业版本);

    ·         支持列表视、Line视图、Dump视图间数据联动显示;

    ·         支持自定义IRP/IOCTL过滤工具。

     

    ParallelMonitor可用于: 

    ·         监控并行端口设备和任何Windows   App通信之间的数据传输;

    ·         监控并行端口打印机等所有与电脑的连接并行端口设备;

    ·         可用于并行端口程序与硬件开发调试

    ParallelMonitor的终端用户 

    ·         软件程序员和测试人员

    ·         软件质量控制工程师

    ·         并行端口打印机设备系统集成商

    ·         工业控制和SCADA设计工程师

     

     

     

    用户使用限制声明:

          本软件CEIWEI ParallelMonitor并口监控精灵 是用于软件工程师分析调试自己拥有完全知识产权的设备、软件的并行端口通信时,检测设备与软件并行端口通信协议的正确性,排查错误并行端口通信协议的工具; 所有用户不得用于非法监控,破解,逆向分析第三方软件(非自己完全知识产权的软件及设备)的并行端口通信协议,如有违反造成第三方软件的一切损失及法律责任,应由您自己承担责任,与本软件CEIWEI ParallelMonitor 并口监控无关。

     

    下载:http://www.ceiwei.com/down/CEIWEI_ParallelMonitor_20213.zip

     

    来源:http://www.ceiwei.com/mt/news/shownews.php?id=66

    展开全文
  • 设计了基于单片机对测试数据进行并口采集的系统,通过介绍打印机的工作模式和工作时序,给出了并口数据采集的原理、系统的接口电路和软件编程的流程图,且给出了中断程序的代码,最后通过用样本数据调试系统,证实该...
  • 并口开发调试工具包

    2007-10-24 09:27:18
    <br>软件说明: <br> 开发调试工具包包括三个功能模块:“并口调试器”、“并口测试信号发生器”和“并口监视器”, 分别针对不同的使用需求。 <br> 1、并口调试器 <br> 用于对并口的“数据寄存器”...
  • 当前版本:v2.0 开发背景: 对于需要编写并口通讯程序的人员来说,可能会需要一款方便的... 开发调试工具包包括三个功能模块:“并口调试器”、“并口测试信号发生器”和“并口监视器”, 分别针对不同的使用需求。
  • 经过测试,EPP/ECP模式下并口不能接收数据,而自己主板上没有单独的EPP模式!由于本人的并口为BI—DIRACTIONAL模式,只好采用软件握手方式。通过IRQ7并口中断处理数据。单片机用C51编程,STC5410AD做测试! read-rc-...
  • 设计了一个以CY7C68013A为接口芯片的并口转USB口的数据采集系统,讨论了CY7C68013A的性能及传输方式,给出了该系统的硬件设计方案,设计实现了USB2.0数据传输模块,阐述了系统的硬件设计、固件程序和驱动程序的设计...
  • Easy 51Pro v2.0(PCI转并口专用)...本次上传软件是在原程序的基础上对资源配置进行了修改并编译运行,经测试下载稳定可靠(在单片机及ISP下载线连接部分没问题的基础上)。此软件的版权仍归原作者所有。欢迎下载使用。
  • N76E003 驱动 UC1705并口屏(8080)

    千次阅读 2019-03-11 20:24:59
    程序中我们使用RS代替 下图为8080并口连接图 下图为N76E003引脚分配(因为没钱开板,所以本次全部使用热转印制作测试,故GPIO分配存在不合理的地方) 其中D0-D7使用下列函数赋值,具体操作就是每次右移一...

    Tips:本文主要代码源于原子哥STM32驱动8080液晶屏代码,在此表示感谢。
    点击这里下载UC1705数据手册

    通过数据手册可以得知CD引脚其实就是控制命令与数据切换的I/O。在程序中我们使用RS代替
    在这里插入图片描述
    下图为8080并口连接图
    在这里插入图片描述
    下图为N76E003引脚分配(因为没钱开板,所以本次全部使用热转印制作测试,故GPIO分配存在不合理的地方)
    在这里插入图片描述
    其中D0-D7使用下列函数赋值,具体操作就是每次右移一次,到最低位与1进行&运算

    void SET_DATA(uchar val)
    {
    	P04=val&1;
    	P03=(val>>1)&1;
    	P01=(val>>2)&1;
    	P00=(val>>3)&1;
    	P10=(val>>4)&1;
    	P11=(val>>5)&1;
    	P12=(val>>6)&1;
    	P13=(val>>7)&1;
    }
    

    其次所有的GPIO设置为强推挽模式

    P00_PushPull_Mode;				
    P01_PushPull_Mode;				
    P02_PushPull_Mode;				
    P03_PushPull_Mode;				
    P04_PushPull_Mode;				
    P05_PushPull_Mode;				
    P06_PushPull_Mode;				
    P07_PushPull_Mode;				
    P10_PushPull_Mode;				
    P11_PushPull_Mode;				
    P12_PushPull_Mode;				
    P13_PushPull_Mode;				
    P14_PushPull_Mode;				
    P15_PushPull_Mode;				
    P16_PushPull_Mode;				
    P17_PushPull_Mode;				
    P30_PushPull_Mode;
    

    下图为UC1705芯片初始化流程
    在这里插入图片描述
    这里以软复位为例,命令为0XE2
    在这里插入图片描述

    void LCD_Write_Byte(uchar Cmd,uchar Dat)//根据数据手册进行操作
    {   
    	LCD_CS=0;  //片选
    	LCD_RS=Cmd;//选择是发送命令or数据
    	LCD_RD=0;
    	LCD_WR=0;
    	SET_DATA(Dat);
    	LCD_RD=1;
    	Timer0_Delay1ms(2);
    	LCD_CS=1;
    	LCD_RD=0;
    }
    
     LCD_Write_Byte(0,0xE2);//发送软复位命令
    

    其余命令不在此赘述,以下为完整代码

    #include "N76E003.h"
    #include "Common.h"
    #include "Delay.h"
    #include "SFR_Macro.h"
    #include "Function_define.h"
    
    
    #define uint unsigned int
    #define uchar unsigned  char
    
    
    sbit LCD_CS=P0^5; //片选端口
    sbit LCD_RST=P0^6;//复位
    sbit LCD_RS=P0^7;//数据/命令切换   C/D
    sbit LCD_WR=P3^0;//写数据
    sbit LCD_RD=P1^7;//读数据
    
    
    
    
    const uchar Number8X16[]={
    /*--  文字:  0  --*/
    /*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
    0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,
    
    
    /*--  文字:  1  --*/
    /*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
    0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
    
    /*--  文字:  2  --*/
    /*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
    0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,
    
    /*--  文字:  3  --*/
    /*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
    0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,
    
    /*--  文字:  4  --*/
    /*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
    0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,
    
    /*--  文字:  5  --*/
    /*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
    0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,
    
    /*--  文字:  6  --*/
    /*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
    0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,
    
    /*--  文字:  7  --*/
    /*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
    0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,
    
    /*--  文字:  8  --*/
    /*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
    0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,
    
    /*--  文字:  9  --*/
    /*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
    0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,
    
    };
    
    
    
    
    void SET_DATA(uchar val)
    {
    	P04=val&1;
    	P03=(val>>1)&1;
    	P01=(val>>2)&1;
    	P00=(val>>3)&1;
    	P10=(val>>4)&1;
    	P11=(val>>5)&1;
    	P12=(val>>6)&1;
    	P13=(val>>7)&1;
    }
    
    /**********************************************************************************
    **函数名:void LCD_Write_Byte(u8 Cmd,u8 Dat)
    **功能:对LCD12864写命令
    **说明:无
    **参数: Cmd =0  命令 Cmd=1 数据
    **********************************************************************************/
    void LCD_Write_Byte(uchar Cmd,uchar Dat)	   //LCD写入函数
    {   
    	LCD_CS=0;  
    	LCD_RS=Cmd;
    	LCD_RD=0;
    	LCD_WR=0;
    	SET_DATA(Dat);
    	LCD_RD=1;
    	Timer0_Delay1ms(2);
    	LCD_CS=1;
    	LCD_RD=0;
    }
    
    
    ///**********************************************************************************
    //**函数名:void LCD_Write_Byte(u8 Cmd,u8 Dat)
    //**功能:对LCD12864写命令
    //**说明:无
    //**参数: Cmd =0  命令 Cmd=1 数据
    //**********************************************************************************/
    void LCD_Write_Byte80(uchar Cmd,uchar Dat)	   //LCD写入函数
    {   
    //	u16 para;
    	LCD_CS=0;  
      LCD_RS=Cmd;
    	LCD_WR=0;
    	SET_DATA(Dat);
    	Timer0_Delay1ms(2);
    	LCD_RD=1;
    	Timer0_Delay1ms(2);
    	LCD_CS=1;
    }
    
    ///**********************************************************************************
    //**函数名:void LCD_Reset()
    //**功能:对LCD12864复位
    //**说明:无
    //**********************************************************************************/
    void LCD_Reset()  //LCD硬件复位
    {
    	LCD_RST=0;
    	Timer0_Delay1ms(50);
    	LCD_RST=0;
    	Timer0_Delay1ms(50);
    	LCD_RST=1;
    	Timer0_Delay1ms(50);
    }
    
    
    
    
    void LCD_Coor(uchar x, uchar y)	   //LCD坐标控制
    {
     LCD_Write_Byte(0,0xb0+y);  //设置页地址
     LCD_Write_Byte(0,(x>>4)+0x10);//设置列地址高4位 
     LCD_Write_Byte(0,x&0x0f);  //设置列地址低4位
    }
    
    
    
    void LCD_Clr()  //清屏函数
    {
       uchar i,j; 
       for(i=0;i<9;i++)
    		{ 
    			LCD_Coor(0,i); 
    			for(j=0;j<132;j++) 
    			{ 
    				LCD_Write_Byte(1,0x00); 
    			}
    		}  
    }
    
    
    
    
    
    void LCD_UC1705_Init()
    {
      LCD_Reset();
      Timer0_Delay1ms(20);
      LCD_Write_Byte(0,0xE2);  软件复位
    	Timer0_Delay1ms(20);
    	//--表格第8个命令,0xA0段(左右)方向选择正常方向(0xA1为反方向)--//
      LCD_Write_Byte(0,0xA0);  //ADC select segment direction 
      Timer0_Delay1ms(20);
    	//--表格第15个命令,0xC8普通(上下)方向选择选择反向,0xC0为正常方向--//
      LCD_Write_Byte(0,0xC8);  //Common direction 
      Timer0_Delay1ms(20);
    	//--表格第9个命令,0xA6为设置字体为黑色,背景为白色---//
    	//--0xA7为设置字体为白色,背景为黑色---//
      LCD_Write_Byte(0,0xA2);  // //reverse display
      Timer0_Delay1ms(20);
    	//--表格第10个命令,0xA4像素正常显示,0xA5像素全开--//
    	LCD_Write_Byte(0,0xA4);  // //normal display
      Timer0_Delay1ms(20);
    	//--表格第11个命令,0xA3偏压为1/7,0xA2偏压为1/9--//
    	LCD_Write_Byte(0,0xA2);  //bias set 1/9
      Timer0_Delay1ms(20);
      //--表格第19个命令,这个是个双字节的命令,0xF800选择增压为4X;--//
    	//--0xF801,选择增压为5X,其实效果差不多--//
    	LCD_Write_Byte(0,0xF8);  //Boost ratio set
      Timer0_Delay1ms(20);	
    	LCD_Write_Byte(0,0x01);  //x4
      Timer0_Delay1ms(20);	
      //--表格第18个命令,这个是个双字节命令,高字节为0X81,低字节可以--//
    	//--选择从0x00到0X3F。用来设置背景光对比度。---/
    	LCD_Write_Byte(0,0x81);   //V0 a set
      Timer0_Delay1ms(20);
    	LCD_Write_Byte(0,0x23);  //
      Timer0_Delay1ms(20);
      //--表格第17个命令,选择调节电阻率--//
    	LCD_Write_Byte(0,0x25);  //Ra/Rb set
      Timer0_Delay1ms(20);
    	LCD_Write_Byte(0,0x2F);  //--表格第16个命令,电源设置。--//
      Timer0_Delay1ms(20);
      LCD_Write_Byte(0,0x40); //起始行从第一行开始
      Timer0_Delay1ms(20);
    //  LCD_Write_Byte(0,0xB0); 
    	
      Timer0_Delay1ms(20);
    // LCD_Write_Byte(0,0x10); 
     
       Timer0_Delay1ms(20);
     // LCD_Write_Byte(0,0x00); 
    	
      Timer0_Delay1ms(20);
      LCD_Write_Byte(0,0xAF); 	//显示开
      Timer0_Delay1ms(20);
    	LCD_Clr();
    }
    
    
    ///****************************************************************************/
    函数名称:Disp_Dat(uchar Row,uchar Col,uchar Number,uchar fs)
    函数功能:将显示数据输出到屏幕指定位置显示
    输入参数:low       行地址
    输入参数:Col      列地址
    输入参数:Number    显示数据
    输入参数:fs   显示方式(0,反显,否则正常显示)
    返 回 值:无
    ///****************************************************************************/
    void Disp_Dat(uchar Row,uchar Col,uchar Number,uchar fs)
    {
     uchar L_H,L_L;      //列
     uchar Page;         //页
     
     //计算页地址
     Page=0xb0+Row;
     L_H=0x10+(Col>>4);
     L_L=(Col&0x0f);
    
        LCD_Write_Byte(0,Page);
        LCD_Write_Byte(0,0x1f&L_H); //列地址,高低字节两次写入,从第0 列开始
        LCD_Write_Byte(0,L_L);
     
     if(fs==0)
     {
         LCD_Write_Byte(1,~Number); 
     }
     else
     {
         LCD_Write_Byte(1,Number); 
     }
    }
    
    ///****************************************************************************/
    函数名称:Disp_Nub8X16(uchar Row,uchar Col,uchar Number,uchar fs)
    函数功能:将25x48点阵数值输出到屏幕指定位置显示
    输入参数:low       行地址
    输入参数:Col      列地址
    输入参数:Number    显示数值
    输入参数:fs   显示方式(0,反显,否则正常显示)
    返 回 值:无
    ///****************************************************************************/
    void Disp_Nub8X16(uchar Row,uchar Col,uchar Number,uchar fs)
    {
     uchar i,j;
     uchar Temp;
     const uchar *STR_p;
     
     STR_p=&Number8X16[Number*16];
     for(i=0;i<2;i++)
     {
      for(j=Col;j<Col+8;j++)
      {
          //Temp=pgm_read_byte(STR_p);//
    		Temp=*STR_p;  
    		Disp_Dat(Row,j,Temp,fs);
    		STR_p++;
      }
      Row++;
     }
    }
    
    
    
    void main(void)
    {
    	uint x=0;
    P00_Quasi_Mode;				
    P01_Quasi_Mode;				
    P02_Quasi_Mode;				
    P03_Quasi_Mode;				
    P04_Quasi_Mode;				
    P05_Quasi_Mode;				
    P06_Quasi_Mode;				
    P07_Quasi_Mode;				
    P10_Quasi_Mode;				
    P11_Quasi_Mode;				
    P12_Quasi_Mode;				
    P13_Quasi_Mode;				
    P14_Quasi_Mode;				
    P15_Quasi_Mode;				
    P16_Quasi_Mode;				
    P17_Quasi_Mode;				
    P30_Quasi_Mode;
    
    	LCD_UC1705_Init();//初始化
    	Timer0_Delay1ms(10);
    		while(1)
    		{		
    					Disp_Nub8X16(0,2,x++,0);//执行累加显示数字
    					Timer0_Delay1ms(1000);
    					if(x>10)x=0;
    		}
    }
    

    在这里插入图片描述
    在这里插入图片描述

    展开全文

空空如也

空空如也

1 2 3 4 5 6
收藏数 116
精华内容 46
关键字:

并口测试程序