精华内容
下载资源
问答
  • C语言扫雷程序代码,类似windows里扫雷游戏
  • C语言编写的程序,包含代码!,共初学者学习交流!
  • C语言编写的日历程序

    2013-04-03 11:38:04
    C语言编写的日历程序,含源代码和可执行程序,C语言课程设计专用,供大家交流学习。
  • c语言编写的程序代码,有效解决了编程困难问题。
  • c语言程序设计编写的,贪食蛇的源程序代码
  • c语言编写的五子棋代码,验证通过,可以给要移植到任何其他系统提供很好的参考价值
  • C语言编写的俄罗斯方块程序的源代码,要在turboc 环境下运行菜有效
  • c语言编写下列代码

    2021-05-18 23:13:59
    编写下列表达式前20项和的程序,要求自定义函数实现 e^x=1+x+x²/2!+x³/3!+……</p>
  • C语言程序,学习学习吧!!我想大家一定想看看,来看看吧,我们交流交流吧!!!
  • 圣诞节快到了,让我们用C语言制作一个圣诞表白程序 具体代码如下咯: // GreetingCardDemoDlg.cpp : 实现文件 // #include stdafx.h #include GreetingCardDemo.h #include GreetingCardDemoDlg.h #include ...
  • c语言编写简单图书馆系统程序代码,在dos下运行,是字符见面。
  • C语言编写的UDP协议通信程序 具体实现代码
  • 程序分为3个等级,纯C编写,界面可能不好看,供大家参考
  • C语言编写的与电脑下棋程序代码 精品文档 精品文档 收集于网络如有侵权请联系管理员删除 收集于网络如有侵权请联系管理员删除 精品文档 收集于网络如有侵权请联系管理员删除 #include "stdafx.h" #include<iostream>...
  • 代码是用c语言编写的电话簿程序,能够正常运行,功能全面,包括添加,删除,修改联系人等
  • C语言编写的计算器源程序;附有源代码的详细注解
  • C语言是一门面向过程、抽象化通用程序设计语言,广泛应用于底层开发。C语言能以简易方式编译、处理低级存储器。C语言是仅产生少量机器语言以及不需要任何运行环境支持便能运行高效率程序设计语言。尽管...
  • C语言编写的冰河病毒代码,用于网络安全技术方面的,这只是冰河的代码,另外还需要一个支撑程序,还有一个客户端才是完整的病毒
  • 使用C语言编写的程序,用于破解电信、联通等宽带账号的一个程序的源代码,内附有txt简要的使用说明,这个程序只能在Windows操作系统上进行的宽带密码的破解(偷获)
  • 这是一款经典小游戏,支持鼠标 支持汉字。分三种游戏难度
  • 如题,一个数据备份软件,有一个linux下代理模块,windows下主控端运行之后,备份Linux下数据时候,数据统计模块不好使,怎么定位这个功能模块代码位置?
  • 该文档按照人思维习惯和模块化程序设计思路,对C语言如何编写WINDOW服务程序做了深入探讨,并且贴出全部源代码
  • C语言原本是面向过程编程语言,而面向过程编程,比较繁琐,代码重用性较低。相对而言,面向对象编程,代码重用性高,同时便于理解,是一种更加先进编程方法。可喜是,C语言通过适当组织处理,也可以类似于C++...

    C语言原本是面向过程的编程语言,而面向过程编程,比较繁琐,代码重用性较低。相对而言,面向对象编程,代码重用性高,同时便于理解,是一种更加先进的编程方法。可喜的是,C语言通过适当组织处理,也可以类似于C++一样面向对象编程。下面就来介绍这种组织处理的过程(受linux C源码的启发)。

    1.事物归类
    面向对象,就是将研究或操作的硬件或变量(所谓对象)根据其属性及操作,归类到一起。例如,对于串口,有如下属性及操作:
    ①名称:usart1;②波特率;③缓冲区字节;④奇偶校验;⑤初始化:操作1;⑥发送字节:操作2;⑦发送字符串:操作3,等等。于是可以将这些属性和操作都归类到一个C结构体下。这个结构体就类似于一个串口类,所有的串口都可以定义成这种类的数据类型。这就完成了对象抽象化表示的过程。C代码举例如下:

    struct  USART_Class {           // 定义一个结构体类型,相当于一个类
    	char * module;
            USART_TypeDef *usart_num;
    	int  baud_rate;            // 属性1:波特率
    	int  buffer_size;          // 属性2:缓冲区字节数
    	void (*config)(void);           // 初始化操作
    	void (*send_byte)(USART_TypeDef *USARTx, uint8_t ch);   // 发送字节操作
    	void (*send_string)(USART_TypeDef *USARTx, char *str);  // 发送字符串操作
    };

    由于C结构体成员不能直接为函数,所以成员定义为指向函数的指针。上述代码中诸如(*config)即为函数指针。

    2.定义对象
    我们要研究或操作的,具有某一类特性的具体事物,即是对象,例如串口1,LED1、定时器1等。我们定义一个串口对象:

    struct USART_Class usart1_obj = {
        .module = "usart1",
        .usart_num = USART1;
        .baud_rate = 115200,
        .buffer_size = 4,
        .config = usart_config,
        .send_byte = usart_send_byte,
        .send_string = usart_send_string,
    };
    
    //对象usart1操作对应的函数
    void usart_config(void);
    void usart_send_byte(USART_TypeDef *USARTx, uint8_t ch);
    void usart_send_string(USART_TypeDef *USARTx, char *str);

    3.引用对象属性或操作
    引用对象的属性和操作,与引用结构体成员别无二致。例如,

    usart1_obj.config();        //完成串口1的初始化
    usart1_obj.send_byte(usart1.usart_num,'a');     //发送一个字节字母a

    通过以上三个步骤,就能实现C语言的面向对象编程。当然,中间还有一些细节过程,调试的时候也会出现各种bug。不过这都没关系,只要我们在实践中不断探究和总结,这些问题都会迎刃而解。

    展开全文
  • 文章目录RK3399外设驱动之SPI(二)用c语言编写spi测试程序Android.mk文件配置信息代码数据通信代码关于spidev.h使用ioctl函数收发数据使用read函数使用write函数测试 内核版本 Linux4.4 平台 rk3399 作者 ...

    RK3399外设之SPI驱动(二)用c语言编写spi测试程序

    内核版本 Linux4.4
    平台 rk3399
    作者 nineyole

    ​ 当我们使用spidev创建了驱动程序之后,就会生成/dev/spidevxxx的设备文件,这个时候就可以通过测试程序来测试其通信是否正常,本文重点分析了read write ioctl几个函数是如何调用。本章介绍的是在Android平台编写c的测试程序,当编写通过的时候,就可以尝试用封装jni,然后编写java程序。这个在下一章节介绍。

    Android.mk文件

    当我们使用Android编写的时候需要有一个mk文件来编译测试程序,针对spi测试程序的mk文件如下所示:

    LOCAL_PATH:= $(call my-dir)
    
    # HAL module implemenation, not prelinked and stored in
    
    # hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.board.platform>.so
    
    include $(CLEAR_VARS)
    
    LOCAL_PRELINK_MODULE := false
    
    LOCAL_SRC_FILES := spi-test.c
    
    LOCAL_MODULE:= spi-tests
    
    include $(BUILD_EXECUTABLE)
    
    include $(call all-makefiles-under,$(LOCAL_PATH))
    

    配置信息代码

    spi有许多配置信息,包括速度,片选,设备名称等。可以通过以下的函数来进行配置,当然也可以自己直接指定。

    static void parse_opts(int argc, char *argv[])
    {
        while (1) {
            static const struct option lopts[] = {
                { "device", 1, 0, 'D' },
                { "speed",  1, 0, 's' },
                { "delay",  1, 0, 'd' },
                { "bpw",   1, 0, 'b' },
                { "loop",  0, 0, 'l' },
                { "cpha",  0, 0, 'H' },
                { "cpol",  0, 0, 'O' },
                { "lsb",   0, 0, 'L' },
                { "cs-high", 0, 0, 'C' },
                { "3wire",  0, 0, '3' },
                { "no-cs",  0, 0, 'N' },
                { "ready",  0, 0, 'R' },
                { NULL, 0, 0, 0 },
            };
            int c;
            c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);
            if (c == -1)
                break;
            switch (c) {
                case 'D':
                    device = optarg;
                    break;
                case 's':
                    speed = atoi(optarg);
                    break;
                case 'd':
                    delay = atoi(optarg);
                    break;
                case 'b':
                    bits = atoi(optarg);
                    break;
                case 'l':
                    mode |= SPI_LOOP;
                    break;
                case 'H':
                    mode |= SPI_CPHA;
                    break;
                case 'O':
                    mode |= SPI_CPOL;
                    break;
                case 'L':
                    mode |= SPI_LSB_FIRST;
                    break;
                case 'C':
                    mode |= SPI_CS_HIGH;
                    break;
                case '3':
                    mode |= SPI_3WIRE;
                    break;
                case 'N':
                    mode |= SPI_NO_CS;
                    break;
                case 'R':
                    mode |= SPI_READY;
                    break;
                default:
                    print_usage(argv[0]);
                    break;
            }
        }
    }
    

    然后在main函数中有如下代码:

      parse_opts(argc, argv);
    

    这个其实就是调用了getopt_long来对argv的参数进行解析,可以方便的调用不同接口进行设置spi参数。

    比如调用的时候就可以使用以下代码指定速度。

    ./spi-test -s 960000
    

    数据通信代码

    关于spidev.h

    spidev.h中定义了spi_ioc_transfer结构体,以及针对底层spi操作的宏定义。其具体如下所示:

    #define SPI_CPHA    0x01
    #define SPI_CPOL    0x02
    #define SPI_MODE_0   (0|0)
    #define SPI_MODE_1   (0|SPI_CPHA)
    #define SPI_MODE_2   (SPI_CPOL|0)
    #define SPI_MODE_3   (SPI_CPOL|SPI_CPHA)
    #define SPI_CS_HIGH   0x04
    #define SPI_LSB_FIRST    0x08
    #define SPI_3WIRE    0x10
    #define SPI_LOOP    0x20
    #define SPI_NO_CS    0x40
    #define SPI_READY    0x80
    /* IOCTL commands */
    #define SPI_IOC_MAGIC      'k'
    struct spi_ioc_transfer {
      __u64    tx_buf;
      __u64    rx_buf;
      __u32    len;
      __u32    speed_hz;
      __u16    delay_usecs;
      __u8    bits_per_word;
      __u8    cs_change;
      __u32    pad;
    };
    /* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */
    #define SPI_MSGSIZE(N) \
      ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \
        ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0)
    #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
    /* Read / Write of SPI mode (SPI_MODE_0..SPI_MODE_3) */
    #define SPI_IOC_RD_MODE     _IOR(SPI_IOC_MAGIC, 1, __u8)
    #define SPI_IOC_WR_MODE     _IOW(SPI_IOC_MAGIC, 1, __u8)
    /* Read / Write SPI bit justification */
    #define SPI_IOC_RD_LSB_FIRST    _IOR(SPI_IOC_MAGIC, 2, __u8)
    #define SPI_IOC_WR_LSB_FIRST    _IOW(SPI_IOC_MAGIC, 2, __u8)
    /* Read / Write SPI device word length (1..N) */
    #define SPI_IOC_RD_BITS_PER_WORD  _IOR(SPI_IOC_MAGIC, 3, __u8)
    #define SPI_IOC_WR_BITS_PER_WORD  _IOW(SPI_IOC_MAGIC, 3, __u8)
    /* Read / Write SPI device default max speed hz */
    #define SPI_IOC_RD_MAX_SPEED_HZ   _IOR(SPI_IOC_MAGIC, 4, __u32)
    #define SPI_IOC_WR_MAX_SPEED_HZ   _IOW(SPI_IOC_MAGIC, 4, __u32)
    

    有的时候我们会新增对应的接口,比如在我们有一个demo中有增加一个复位的操作,就可以在spidev.h增加一条指令,如下,然后就可以在测试程序中调用了。

    #define SPI_IOC_WR_RESET_IC     _IOW(SPI_IOC_MAGIC, 5, __u32)
    

    在main.c中调用方式如下:

    reset=0;
    ret = ioctl(fd, SPI_IOC_WR_RESET_IC, &reset);
    

    能使用这个的前提是我们在内核驱动spidev.c的ioctl函数中有增加如下代码:

    case SPI_IOC_WR_RESET_IC:
    retval = __get_user(tmp, (u8 __user *)arg);
    if (retval == 0) {
        rk_spi_print("the SPI_IOC_WR_RESET_IC tmp is %d\n",tmp);
        reset_spidev();
    }
    break;
    

    使用ioctl函数收发数据

    如果我们的函数发送过去就会立即返回数据的话,我们也可以使用ioctl函数来进行通信,其demo如下:主要就是填充spi_ioc_transfer的结构体,然后调用ioctl函数来进行通信。这个函数的作用就是可以通过SPI_IOC_MESSAGE宏定义来进行数据交互。

    static int transfer(uint8_t * tx, uint8_t * rx, uint32_t length)
    {
        int ret;
        struct spi_ioc_transfer tr = {
            .tx_buf = (unsigned long)tx,
            .rx_buf = (unsigned long)rx,
            .len = length,
            .delay_usecs = delay,
            .speed_hz = speed,
            .bits_per_word = bits,
        };
        ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
        if (ret < 1)
            return pabort("can't send gpio message\n");
        return ret;
    }
    

    main.c中调用如下:

    transfer(fd, tx, rx, size);
    

    使用read函数

    ioctl函数进行数据交互的时候,是写入一个数据就会同时返回一个数据,而更多的时候,是要一次性写入很多数据才会返回,这个时候我们就需要单独的read函数,或者单独的write函数,测试程序中可以使用如下的函数进行读取。

    static int spi_read_n_byte(uint8_t*p_buf,uint16_t len)
    {
        uint16_t retry=0;
    #ifdef CS_ONE_BY_ONE
        for (int i = 0; i < (len); i++)
        {
            read(fd,&p_buf[i],1);
        }
    #else
        read(fd,p_buf,len);
    #endif
        return 0;
    }
    

    使用write函数

    测试程序中可以使用如下的函数进行读取。

    static int spi_wirte_n_byte(uint8_t*p_buf,uint16_t len)
    {
    #ifdef CS_ONE_BY_ONE
        for (int i = 0; i < len; ++i)
        {
            write(fd,&p_buf[i],1);
        }
    #else
        write(fd,p_buf,len);
    #endif
        return 0;
    }
    

    测试

    如何具体实施编写用户测试程序
    对于Android系统,可以在external目录新建一个spidev-test目录,新建一个android.mk文件,其内容如下:并且将spidev_test.c拷贝过来。

    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_PRELINK_MODULE := false
    LOCAL_SRC_FILES := spidev_test.c
    LOCAL_MODULE:= spidev_test
    include $(BUILD_EXECUTABLE)
    include $(call all-makefiles-under,$(LOCAL_PATH))
    

    然后经过如下的步骤,就可以编译生成一个spidev_test的文件。

    source build/envsetup.sh 
    lunch rk3399_all-userdebug
    cd external/spi-test
    mm
    

    通过adb push spidev_test到system/bin目录,然后执行即可

    具体可以参考kernel\Documentation\spi\spidev_test.c

    展开全文
  • c语言编写的音乐播放器源代码,是用c写的播放器,很经典的程序,适合初学者
  • C语言 程序代码编写规范 初级程序员 讨论版 前言 一个好的程序编写规范是编写高质量程序的保证清晰规范程序不仅仅是方便阅读更重要是能够便于检查错误提高调试效率从而最终保证软件质量和可维护性 说明 此文...
  • C片段 我学习C语言编写的C程序的代码片段和源代码
  • 这是贪吃蛇游戏的源程序,用c语言编写的,在tc上运行通过的。
  • 博文已经写得很详细了,这个是附带代码资源
  • C语言 程序代码编写规范

    千次阅读 2016-04-28 15:47:32
    前言 一个好的程序编写规范是编写高质量程序的保证...l 对于具有一定工程项目开发经验程序员,建议学习C语言程序代码编写规范—高级版。 目录 1 代码书写规范 2 注释书写规范 3 命名规范 4 其它一些小技

    前言

    一个好的程序编写规范是编写高质量程序的保证。清晰、规范的源程序不仅仅是方便阅读,更重要的是能够便于检查错误,提高调试效率,从而最终保证软件的质量和可维护性。

    说明

    l 本文档主要适用于刚刚开始接触编程的初学者。

    l 对于具有一定工程项目开发经验的程序员,建议学习C语言程序代码编写规范—高级版。

    目录

    1 代码书写规范

    2 注释书写规范

    3 命名规范

    4 其它一些小技巧和要求

    1 代码书写规范

    1.1函数定义

    花括号: { }

    每个函数的定义和说明应该从第1列开始书写。函数名(包括参数表)和函数体的花括号应该各占一行。在函数体结尾的括号后面可以加上注释,注释中应该包括函数名,这样比较方便进行括号配对检查,也可以清晰地看出来函数是否结束。

    范例1:函数的声明

    void matMyFunction(int n)

    {

    ……

    } /* matMyFunction*/

    1.2空格与空行的使用

    要加空格的场合

    l 在逗号后面和语句中间的分号后面加空格,如:

    int i, j, k;

    for (i = 0; i < n; i++)

    result = func(a, b, c);

    l 在二目运算符的两边各留一个空格,如

    a > b    a <= b  i = 0

    l 关键字两侧,如if () 不要写成if() 

    l 类型与指针说明符之间一定要加空格:

    char *szName;

    不加空格的场合

    l 在结构成员引用符号.和->左右两加不加空格:

    pStud->szName,  Student.nID

    l 不在行尾添加空格或Tab

    l 函数名与左括号之间不加空格:

     func()

    l 指针说明符号*与变量名间不要加空格:

    int *pInt; 不要写成: int * pInt;

    l 复合运算符中间不能加空格,否则会产生语法错误,如:

    a + = b      a < = b    都是错误的

    空行与换行

    l 函数的变量说明与执行语句之间加上空行;

    l 每个函数内的主要功能块之间加空行表示区隔;

    l 不要在一行中写多条语句.

    范例2:空行与换行

    int main()

    {

        int i, j, nSum = 0;  //变量说明

        

        for (i = 0; i < 10; i++)  //执行代码

        {

    for (j = 0; j < 10; j++)

    {

         nSum += i;

    }

        }

    }

    1.3缩进的设置

    根据语句间的层次关系采用缩进格式书写程序,每进一层,往后缩进一层

    有两种缩进方式:1,使用Tab键;2采用4个空格。

    整个文件内部应该统一,不要混用Tab键和4个空格,因为不同的编辑器对Tab键的处理方法不同。

    1.4折行的使用

    · 每行的长度不要超过80个字符,当程序行太长时,应该分行书写。

    · 当需要把一个程序行的内容分成几行写时,操作符号应该放在行末。

    · 分行时应该按照自然的逻辑关系进行,例如:不要把一个简单的逻辑判断写在两行上。

    · 分行后的缩进应该按照程序的逻辑关系进行对齐。例如:参数表折行后,下面的行应该在参数表左括号的下方。

    范例2:折行的格式

    dwNewShape = matAffineTransform(coords, translation,

      rotation);

    if (((new_shape.x > left_border) &&

    (new_shape.x < right_border)) &&

    ((new_shape.y > bottom_border) &&

    (new_shape.y < top_border)))

    {

        draw(new_shape);

    }

    1.5嵌套语句(语句块)的格式

    对于嵌套式的语句--即语句块(如,if、while、for、switch等)应该包括在花括号中。花括号的左括号应该单独占一行,并与关键字对齐。建议即使语句块中只有一条语句,也应该使用花括号包括,这样可以使程序结构更清晰,也可以避免出错。建议对比较长的块,在末尾的花括号后加上注释以表明该语言块结束。

    范例3:嵌套语句格式

    if (value < max) 

    {

        if (value != 0)

        {

             func(value);

        }

    }

    } else {

        error("The value is too big.");

    } /* if (value < max) */

    2 注释书写规范

    注释必须做到清晰,准确地描述内容。对于程序中复杂的部分必须有注释加以说明。注释量要适中,过多或过少都易导致阅读困难。

    2.1注释风格

    · C语言中使用一组(/* … */)作为注释界定符。

    · 注释内容尽量用英语方式表述。

    · 注释的基本样式参考范例4。

    · 注释应该出现在要说明的内容之前,而不应该出现在其后。

    · 除了说明变量的用途和语言块末尾使用的注释,尽量不使用行末的注释方式。

    范例4:几种注释样式

    /*

    * ************************************************

    * 强调注释

    * ************************************************

    */

    /*

    * 块注释

    */

    /* 单行注释 */

    //单行注释

    int i; /*行末注释*/

    2.2何时需要注释

    · 如果变量的名字不能完全说明其用途,应该使用注释加以说明。

    · 如果为了提高性能而使某些代码变得难懂,应该使用注释加以说明。

    · 对于一个比较长的程序段落,应该加注释予以说明。如果设计文档中有流程图,则程序中对应的位置应该加注释予以说明。

    · 如果程序中使用了某个复杂的算法,建议注明其出处。

    · 如果在调试中发现某段落容易出现错误,应该注明。

    3 命名规范

    3.1常量、变量命名

    l 符号常量的命名用大写字母表示。如:

    #define LENGTH 10

    l 如果符号常量由多个单词构成,两个不同的单词之间可以用下划线连接。如:

    #define MAX_LEN 50

    变量命名的基本原则:

    l 可以选择有意义的英文(小写字母)组成变量名,使人看到该变量就能大致清楚其含义。

    l 不要使用人名、地名和汉语拼音。

    l 如果使用缩写,应该使用那些约定俗成的,而不是自己编造的。

    l 多个单词组成的变量名,除第一个单词外的其他单词首字母应该大写。如:

    dwUserInputValue。

    3.2函数命名

    函数命名原则与变量命名原则基本相同。对于初学者,函数命名可以采用“FunctionName”的形式。

    4 其它一些小技巧和要求

    l 函数一般情况下应该少于100

    l 函数定义一定要包含返回类型,没有返回类型加void

    l 写比较表达式时,将常量放在左边

    10 == n

    NULL != pInt

    l 指针变量总是要初始或重置为NULL

    l 使用{}包含复合语句,即使是只有一行,如:

    if (1 == a)

    {

        x = 5;

    }
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,928
精华内容 3,171
热门标签
关键字:

c语言编写的代码程序

c语言 订阅