Navigation

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    1. Home
    2. chshwei
    C
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups

    chshwei

    @chshwei

    2
    Reputation
    9
    Posts
    4
    Profile views
    0
    Followers
    0
    Following
    Joined Last Online

    chshwei Follow

    Best posts made by chshwei

    • RE: 怎么重新编译D1 debian系统内核,目前提供的D1 debian镜像内核没有开启某些配置,如IP_NF_NAT,在测试docker中不能正常使用。

      正在计划把内核开放出来,目前正在测试中,请耐心等待

      posted in RVBoards系列(RISC-V SoC Board)
      C
      chshwei

    Latest posts made by chshwei

    • RE: 「RVBoards-哪吒」D1 Debian系统镜像和安装方法

      @aixb 请重新下载镜像制作,现在已扩展到10GB,可以满足大部分人的需求,后续会推出自动扩展内存空间的版本,谢谢反馈

      posted in RVBoards系列(RISC-V SoC Board)
      C
      chshwei
    • RVBoards-D1内存 1GB不够怎么办,交换 ”文件/分区" 为你解忧

      一、基础知识

          SWAP就是LINUX下的虚拟内存分区,它的作用是在物理内存使用完之后,将磁盘空间(也就是SWAP分区)虚拟成内存来使用.
          它和Windows系统的交换文件作用类似,但是它是一段连续的磁盘空间,并且对用户不可见。
      
          需要注意的是,虽然这个SWAP分区能够作为"虚拟"的内存,但它的速度比物理内存可是慢多了,
          因此如果需要更快的速度的话,并不能寄厚望于SWAP,最好的办法仍然是加大物理内存.SWAP分区只是临时的解决办法.    
      
          linux下得分区推荐一个交换分区,一个根分区,其中交换分区如上所说作为redhat或者其它虚机所划分的内存不够时候来使用!    
      
          交换分区(swap)的合理值一般在内存的2 倍左右,可以适当加大。
          实际上具体还是以实际应用为准,swap为内存的2倍也不过是一种以讹传讹的说法。
          如果交换分区的使用都超过4GB以上了,可想而知服务器的性能应该差很多了。    
      
          Linux下可以创建两种类型的交换空间,一种是swap分区,一种是swap文件。
          前者适合有空闲的分区可以使用,后者适合于没有空的硬盘分区,硬盘的空间都已经分配完毕。
      

      二、创建交换文件

          在d1开发板上直接运行以下命令
           #1、在根目录创建交换文件swapfile,bs为块大小,count为块的数量
              sudo dd if=/dev/zero of=/swapfile bs=64M count=16
           #2、格式化交换文件
              sudo mkswap /swapfile
           #3、挂载交换文件
              sudo swapon /swapfile
           #如果,不再使用交换文件,如下卸载并删除
           #4、卸载交换文件
              sudo swapoff /swapfile
           #5、删除交换文件
              sudo rm /swapfile
          #top命令查看交换文件是否生效
              top - 10:57:07 up 11 min,  1 user,  load average: 1.00, 1.08, 0.80
              Tasks:  93 total,   1 running,  92 sleeping,   0 stopped,   0 zombie
              %Cpu(s):  0.3 us,  0.3 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
              MiB Mem :    992.7 total,     67.3 free,    140.3 used,    785.1 buff/cache
          #"*************MiB Swap表示交换文件使用情况**************"
              MiB Swap:   1024.0 total,   1024.0 free,      0.0 used.    831.7 avail Mem  
                  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND  
                  794 root      20   0    7044   2828   2252 R   1.0   0.3   0:04.21 top      
                  641 root      20   0   18084   3904   1612 S   0.7   0.4   0:03.06 systemd+ 
                  118 root      20   0   18084   5236   2960 S   0.3   0.5   0:01.90 systemd+ 
                  143 avahi     20   0    5028   2696   2272 S   0.3   0.3   0:01.44 avahi-d+ 
                  623 root      -2   0       0      0      0 S   0.3   0.0   0:00.33 xradio_+ 
      

      三、创建交换分区

             #注:请提前对sd卡进行备件,防止数据丢失
            下面分区方式仅适用于RVBoards_D1_Debianv_img_v0.5镜像 ,
            删除原sd卡mmcblk0p6分区,新建swap分区和新的扩展存储分区
            原sd卡mmcblk0p6分区是扩展存储分区,不会影响系统运行
      
      
            [email protected]:~# fdisk -l         #fdisk -l查看分区信息
                Disk /dev/mmcblk0: 29.72 GiB, 31914983424 bytes, 62333952 sectors
                Units: sectors of 1 * 512 = 512 bytes
                Sector size (logical/physical): 512 bytes / 512 bytes
                I/O size (minimum/optimal): 512 bytes / 512 bytes
                Disklabel type: gpt
                Disk identifier: AB6F3888-569A-4926-9668-80941DCB40BC
                Device          Start      End  Sectors  Size Type
                /dev/mmcblk0p1    41464    47549     6086    3M Microsoft basic data
                /dev/mmcblk0p2    47550    48053      504  252K Microsoft basic data
                /dev/mmcblk0p3    48054    48557      504  252K Microsoft basic data
                /dev/mmcblk0p4    49152   251903   202752   99M Microsoft basic data
                /dev/mmcblk0p5   253358 10739117 10485760    5G Microsoft basic data
                /dev/mmcblk0p6 10739712 62333948 51594237 24.6G Linux filesystem
      
            [email protected]:~# fdisk /dev/mmcblk0    #利用fdisk 命令对sd卡重新分区
      
                    Welcome to fdisk (util-linux 2.36.1).
                    Changes will remain in memory only, until you decide to write them.
                    Be careful before using the write command.
                    Command (m for help): d                                   #输入’d‘,删除第6分区
                    Partition number (1-6, default 6): 6                      #输入’6‘,删除第6分区
                    Partition 6 has been deleted.
                    Command (m for help): n                                   #输入’n‘,新建分区
                    Partition number (6-8, default 6): 6                      #输入’6‘,新建6分区
                    First sector (48558-62333948, default 10739712):          #输入’回车‘,选择默认启始位置
                    #输入分区大小
                    Last sector, +/-sectors or +/-size{K,M,G,T,P} (10739712-62333948, default 62333948): 30000000 
                    Created a new partition 6 of type 'Linux filesystem' and of size 9.2 GiB.
                    Command (m for help): n                                   #输入’n‘,新建分区
                    Partition number (7,8, default 7):                        #输入’7‘,新建7分区
                    First sector (48558-62333948, default 30001152):          #输入’回车‘,选择默认启始位置
                    #输入分区大小,直接输入“回车”,默认大小
                    Last sector, +/-sectors or +/-size{K,M,G,T,P} (30001152-62333948, default 62333948):
                    Created a new partition 7 of type 'Linux filesystem' and of size 15.4 GiB.
                    Command (m for help): w                                   #输入’w‘,完成分区,写入并退出
                    The partition table has been altered.
                    Syncing disks.
      
            [email protected]:~# fdisk -l    #查看新分区信息
                    Disk /dev/mmcblk0: 29.72 GiB, 31914983424 bytes, 62333952 sectors
                    Units: sectors of 1 * 512 = 512 bytes
                    Sector size (logical/physical): 512 bytes / 512 bytes
                    I/O size (minimum/optimal): 512 bytes / 512 bytes
                    Disklabel type: gpt
                    Disk identifier: AB6F3888-569A-4926-9668-80941DCB40BC
                    Device            Start      End  Sectors  Size Type
                    /dev/mmcblk0p1    41464    47549     6086    3M Microsoft basic data
                    /dev/mmcblk0p2    47550    48053      504  252K Microsoft basic data
                    /dev/mmcblk0p3    48054    48557      504  252K Microsoft basic data
                    /dev/mmcblk0p4    49152   251903   202752   99M Microsoft basic data
                    /dev/mmcblk0p5   253358 10739117 10485760    5G Microsoft basic data
                    /dev/mmcblk0p6 10739712 30000000 19260289  9.2G Linux filesystem
                    /dev/mmcblk0p7 30001152 62333948 32332797 15.4G Linux filesystem
      
            [email protected]:~# mkswap /dev/mmcblk0p6    #格式化交换分区
                    Setting up swapspace version 1, size = 9.2 GiB (9861263360 bytes)
                    no label, UUID=a38e9d65-5619-4ec5-b9cb-5547da777295
      
            [email protected]:~# mkfs.ext4 /dev/mmcblk0p7 #格式化扩展存储分区
                    mke2fs 1.46.2 (28-Feb-2021)
                    Creating filesystem with 4041599 4k blocks and 1011840 inodes
                    Filesystem UUID: 63494eb8-ffed-43fd-a630-d8a8c5c3397d
                    Superblock backups stored on blocks: 
                            32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208
      
                    Allocating group tables: done                            
                    Writing inode tables: done                            
                    Creating journal (16384 blocks): 
                    done
                    Writing superblocks and filesystem accounting information: done   
      
      #编辑 /etc/fstab,挂载交换分区和存储分区
            [email protected]:~# vim /etc/fstab 
                    # UNCONFIGURED FSTAB FOR BASE SYSTEM
                    /dev/mmcblk0p5  /       ext4    rw      0       1
                    /dev/mmcblk0p6 swap    swap    defautls        0       0
                    /dev/mmcblk0p7  /mnt       ext4    rw      0       2
      #重启后,用top命令查看交换分区是是否生效
            [email protected]:~# top     #MiB Swap表示交换文件使用情况
                    top - 12:38:23 up 1 min,  1 user,  load average: 3.01, 1.09, 0.39
                    Tasks: 100 total,   1 running,  99 sleeping,   0 stopped,   0 zombie
                    %Cpu(s):  1.0 us,  1.0 sy,  0.0 ni, 88.3 id,  9.7 wa,  0.0 hi,  0.0 si,  0.0 st
                    MiB Mem :    992.7 total,    679.9 free,    139.9 used,    172.9 buff/cache
                    'MiB Swap:   9404.4 total,   9404.4 free,      0.0 used.    832.1 avail Mem '
                        PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND  
                        205 avahi     20   0    5028   2708   2296 S   1.0   0.3   0:00.26 avahi-d+ 
                         59 root     -51   0       0      0      0 S   0.7   0.0   0:01.02 irq/56-+ 
                        725 root      20   0    7044   2868   2288 R   0.7   0.3   0:00.09 top      
                        554 root      20   0   18092   5476   3184 S   0.3   0.5   0:00.37 systemd+ 
                          1 root      20   0   94772   8500   6012 S   0.0   0.8   0:03.08 systemd  
                          2 root      20   0       0      0      0 S   0.0   0.0   0:00.00 kthreadd 
                          3 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_gp 
      
      posted in RVBoards系列(RISC-V SoC Board)
      C
      chshwei
    • RE: 联网问题

      试一试手动配置ip地址,如果不行的话,更新一下最新版的v0.5版本的镜像试试

      posted in 提问反馈
      C
      chshwei
    • RE: 怎么重新编译D1 debian系统内核,目前提供的D1 debian镜像内核没有开启某些配置,如IP_NF_NAT,在测试docker中不能正常使用。

      正在计划把内核开放出来,目前正在测试中,请耐心等待

      posted in RVBoards系列(RISC-V SoC Board)
      C
      chshwei
    • RE: 开发第一步就卡住了,是网络原因还是?

      使用date命令更新下系统时间,默认系统时间不对,apt update会出错

      posted in RVBoards系列(RISC-V SoC Board)
      C
      chshwei
    • RE: 这个kernel调试打印可以去掉,否则i2cdetect格式不对

      @qhddz 请问是您自己写的驱动吗?出现这样的信息可能是您驱动有问题,i2c发送失败导致的,请查检您的驱动程序或设备是否存在问题

      posted in RVBoards系列(RISC-V SoC Board)
      C
      chshwei
    • RE: 关于PLIC中断

      没有与你要求相同的demo,你可以参考mini_car的中定时器中断设置的代码,配置按键中断,下面代码是mini_car的,仅供参考

      // See LICENSE for license details.
      /**************************************************************
       ** 作者: Alvin Xu of PerfXLab
       ** 本程序展示了蜂鸟的PWM功能,蜂鸟中定义了PWM0、PWM1、PWM2三个PWM控制寄存器,每个PWMx可以输出
       ** 4路PWM波,所以最多可以提供12路PWM波输出。本程序用到了PWM1的4路PWM波输出
       **
       ** 引脚硬件连接
       ** PWM输出,本程序用到了D3和D4输出
       ** PWM1_0用PWM_CMP0控制占空比,对应D4引脚(20)
       ** PWM1_1用PWM_CMP1控制占空比,对应D3_SCL引脚(19)
       ** PWM1_2用PWM_CMP2控制占空比,对应D5引脚(21)
       ** PWM1_3用PWM_CMP3控制占空比,对应D6引脚(22)
       **
       ** 红外信号(left)   ------------>  D0
       ** 红外信号(right)  ------------>  D1
       **
       ** 电机驱动模块      开发板
       ** IN1 ------------> D8
       ** IN2 ------------> D9
       ** IN3 ------------> D10
       ** IN4 ------------> D11
       ** ENA ------------> D3_SCL
       ** ENB ------------> D4
       **
       **舵机信号线 ------------> D5
       **
       **超声波收发模块           开发板
       **引脚 Trig  ------------>  A0
       **引脚 Echo  ------------>  A1
       **引脚 Vcc   ------------>  5V VCC
       **引脚 Gnd   ------------>  GND
      **************************************************************/
      /**********************************************************************
      ** 程序修改记录:
      ** 2018-8-1
      ** 1、修改了hifive1.h内的智能车的宏定义,直接在主程序文件里面写了新的宏定义
      ** 2、备注了定时器内的模拟pwm波的代码,添加了硬件pwm代码
      ** 2018-8-7
      ** 1、程序目前可以实现循迹功能、超声波测距回显、超声波控制小车启停的功能
      ** 2、接下来需要添加一路PWM,控制舵机旋转 D5引脚输出控制舵机的PWM
      ** 2018-8-8
      ** 1、要求实现的功能:
      **当小车靠近墙壁的时候,超声波检测到距离过近,停止小车前进,测量左边和右边的距离,比较两者,选择向距离大的一边转弯。
      **需要添加的代码:
      **(1)左转弯90度(2)右转弯90度(3)当小车靠近墙壁的时候,对多舵机和超声波以及直流电机的组合操作
      **2、设计程序
      **3、添加了void motor_right()、void motor_left()、void motor_stop()函数。并且测试完毕,可以实现90度的转弯
      **4、添加了void ultrasonic_control()函数,内部的逻辑编写完毕,等待配件到达后组装测试
      ***********************************************************************/
      //========================== smart-car-gpio===========================//
      #define	run	1
      #define stop 0
      #define	left_monitor	D0_RX1
      #define	right_monitor	D1_TX1
      
      #define	car_motor_IN1		D8
      #define	car_motor_IN2		D9
      #define	car_motor_IN3		D10
      #define	car_motor_IN4		D11
      
      #define car_motor_ENA		D3_SCL
      #define	car_motor_ENB		D4
      
      #define servo_motor			D5//控制舵机 输出PWM的引脚
      //2018-8-7
      #define servo_motor_right		PWM1_REG(PWM_CMP2)  = 0xffff/1000*125;  // PWM高电平为0.5ms 舵机为0度
      #define servo_motor_middle		PWM1_REG(PWM_CMP2)  = 0xffff/1000*125*3;// PWM高电平为1.5ms 舵机为90度
      #define servo_motor_left		PWM1_REG(PWM_CMP2)  = 0xffff/1000*125*5;// PWM高电平为2.5ms 舵机为180度
      //2018-8-8
      #define left_monitor_run_fast    PWM1_REG(PWM_CMP1) = 0xffff/9*4 // 4/9 PWM
      #define right_monitor_run_fast   PWM1_REG(PWM_CMP0) = 0xffff/9*4 // 4/9 PWM
      
      #define left_monitor_run    PWM1_REG(PWM_CMP1) = 0xffff/9*2 // 2/9 PWM
      #define right_monitor_run   PWM1_REG(PWM_CMP0) = 0xffff/9*2 // 2/9 PWM
      #define left_monitor_stop   PWM1_REG(PWM_CMP1) = 0
      #define right_monitor_stop  PWM1_REG(PWM_CMP0) = 0
      //===================================================================//
      
      #include <stdio.h>
      #include <stdlib.h>
      #include "platform.h"
      #include <string.h>
      #include "plic/plic_driver.h"
      #include "encoding.h"
      #include <unistd.h>
      #include "stdatomic.h"
      
      void reset_demo (void);
      uint32_t GPIO_SET(uint32_t pin_num,uint32_t pin_val,uint32_t pin_model);
      void smartcar_init(void);
      void tracking_car_control(void);
      uint32_t read_pin_val(uint32_t pin_num);
      int delay_us(uint32_t time_x);
      void PWM_init();
      volatile void wait_ms(uint64_t ms);
      float ultrasonic(void);
      void ultrasonic_control();
      void motor_right();
      void motor_left();
      void motor_run();
      void motor_stop();
      void motor_back();
      void motor_forward();
      
      
      volatile int ultrasonic_run = 1;//超声波检测标志
      
      //=================================================================
      // Structures for registering different interrupt handlers
      // for different parts of the application.
      typedef void (*function_ptr_t) (void);
      void no_interrupt_handler (void) {};
      function_ptr_t g_ext_interrupt_handlers[PLIC_NUM_INTERRUPTS];
      // Instance data for the PLIC.
      plic_instance_t g_plic;
      
      //******************************************************************
      //函数名:  wait_ms()
      //作者:    Alvin Xu of PerfXLab
      //日期:    2018-08-01
      //功能:    调用一次产生ms毫秒的软件延时
      //输入参数:ms :毫秒数
      //返回值:  无
      //修改记录:无
      //******************************************************************
      volatile void wait_ms(uint64_t ms)//busy wait for the specified time
      {
        static const uint64_t ms_tick = RTC_FREQ/1000;
        volatile uint64_t * mtime  = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME);
        uint64_t then = (ms_tick * ms) + *mtime;
        while(*mtime<then);
      }
      
      
      
      //******************************************************************
      //函数名:  reset_demo
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:    定时器初始化程序
      //输入参数:无
      //返回值:  无
      //修改记录:无
      //******************************************************************
      void reset_demo ()
      {
        // Disable the machine & timer interrupts until setup is done.
        clear_csr(mie, MIP_MEIP);
        clear_csr(mie, MIP_MTIP);
      
        for (int ii = 0; ii < PLIC_NUM_INTERRUPTS; ii ++)
        {
          g_ext_interrupt_handlers[ii] = no_interrupt_handler;
        }
          // Set the machine timer to go off in 0.01 seconds.
          // The
          volatile uint64_t * mtime       = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME);
          volatile uint64_t * mtimecmp    = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
          uint64_t now = *mtime;
          uint64_t then = now + 0.1*RTC_FREQ;
          *mtimecmp = then;
      
          // Enable the Machine-External bit in MIE
          set_csr(mie, MIP_MEIP);
      
          // Enable the Machine-Timer bit in MIE
          set_csr(mie, MIP_MTIP);
      
          // Enable interrupts in general.
          set_csr(mstatus, MSTATUS_MIE);
      }
      
      //******************************************************************
      //函数名:  GPIO_SET
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:    配置蜂鸟的引脚
      //输入参数:pin_num:引脚名
      //			pin_val:引脚值,1或0
      //			pin_model:引脚模式,写input表示输入,写output表示输出
      //返回值:  无
      //修改记录:无
      //******************************************************************
      uint32_t GPIO_SET(uint32_t pin_num,uint32_t pin_val,uint32_t pin_model)
      {
          uint32_t input_val;
          if(pin_model==output)
           {
      	    GPIO_REG(GPIO_OUTPUT_EN) |= (0x01<<pin_num);
              if(pin_val==1)
      		{
      	     GPIO_REG(GPIO_OUTPUT_VAL) |=(0x01<<pin_num);
      		}
              if(pin_val==0)
      		{
      	     GPIO_REG(GPIO_OUTPUT_VAL) &=~(0x01<<pin_num);
      		}
          }
          if(pin_model==input)
          {
      	GPIO_REG(GPIO_INPUT_EN) |= (0x01<<pin_num);
      
      
      		input_val=GPIO_REG(GPIO_INPUT_VAL) &(0x01<<pin_num);
      		if(input_val!=0)
      		{
      			input_val=1;
      		}else
      		{
      			input_val=0;
      		}
      		return	input_val;
          }
       return 0;
      }
      
      //******************************************************************
      //函数名:  smartcar_control
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:   小车控制函数。实现小车的自动寻迹功能
      //输入参数:无
      //返回值:  无
      //修改记录:无
      //******************************************************************
      void tracking_car_control()
      {
      	uint32_t left_val,right_val;
      
      	left_val=read_pin_val(left_monitor);//读取左边寻迹模块的检测信号
      	right_val=read_pin_val(right_monitor);//读取右边寻迹模块的检测信号
      
      	if(left_val==1)
      	{
      		right_monitor_run;//使能右边电机
      	}
      	if(right_val==1)
      	{
      		left_monitor_run;	//使能左边电机
      	}
      	if(left_val==0)
      	{
      		right_monitor_stop;//失能右边电机
      	}
      	if(right_val==0)
      	{
      		left_monitor_stop;//失能左边电机
      	}
      	/*if(ultrasonic_run == 0)
      	{
      		motor_stop();
      	}*/
      
      }
      //******************************************************************
      //函数名:  motor_stop
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:   关闭小车的两个电机
      //输入参数:无
      //返回值:  无
      //修改记录:无
      //******************************************************************
      void motor_stop()
      {
      	right_monitor_stop;
      	left_monitor_stop;
      }
      //******************************************************************
      //函数名:  motor_run
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:   启动小车的两个电机
      //输入参数:无
      //返回值:  无
      //修改记录:无
      //******************************************************************
      void motor_run()
      {
      	right_monitor_run;
      	left_monitor_run;
      }
      
      //******************************************************************
      //函数名:  motor_forward
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:   实现小车车轮向后转
      //输入参数:无
      //返回值:  无
      //修改记录:无
      //******************************************************************
      void motor_forward()
      //可以通过修改延时时间或者输出pwm波的占空比来调整转弯的角度
      //目前调用一次可以原地 向左 旋转90度左右
      {
      	//左轮前转
      	GPIO_SET(car_motor_IN1		,0,output);
      	GPIO_SET(car_motor_IN2		,1,output);
      	//右轮前转
      	GPIO_SET(car_motor_IN3		,0,output);
      	GPIO_SET(car_motor_IN4		,1,output);
      
      	motor_run();
      }
      
      //******************************************************************
      //函数名:  motor_back
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:   实现小车车轮向后转
      //输入参数:无
      //返回值:  无
      //修改记录:无
      //******************************************************************
      void motor_back()
      {
      	//左轮后转
      	GPIO_SET(car_motor_IN1		,1,output);
      	GPIO_SET(car_motor_IN2		,0,output);
      	//右轮后转
      	GPIO_SET(car_motor_IN3		,1,output);
      	GPIO_SET(car_motor_IN4		,0,output);
      
      	motor_run();
      }
      //******************************************************************
      //函数名:  motor_left
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:   可以通过修改延时时间或者输出pwm波的占空比来调整转弯的角度
      //     目前调用一次可以原地 向左 旋转90度左右
      //输入参数:无
      //返回值:  无
      //修改记录:无
      //******************************************************************
      void motor_left()
      {
      	//左轮后转
      	GPIO_SET(car_motor_IN1		,1,output);
      	GPIO_SET(car_motor_IN2		,0,output);
      	//右轮前转
      	GPIO_SET(car_motor_IN3		,0,output);
      	GPIO_SET(car_motor_IN4		,1,output);
      
      	right_monitor_run_fast;
      	left_monitor_run_fast;
      	wait_ms(300);
      	motor_stop();
      }
      
      //******************************************************************
      //函数名:  motor_right
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:   可以通过修改延时时间或者输出pwm波的占空比来调整转弯的角度
      //		目前调用一次可以原地 向右 旋转90度左右
      //输入参数:无
      //返回值:  无
      //修改记录:无
      //******************************************************************
      void motor_right()
      
      {
      	//左轮前转
      	GPIO_SET(car_motor_IN1		,0,output);
      	GPIO_SET(car_motor_IN2		,1,output);
      	//右轮后转
      	GPIO_SET(car_motor_IN3		,1,output);
      	GPIO_SET(car_motor_IN4		,0,output);
      
      	right_monitor_run_fast;
      	left_monitor_run_fast;
      	wait_ms(300);
      	motor_stop();
      }
      
      //******************************************************************
      //函数名:  ultrasonic
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:   实现 超声波测距功能,并将距离返回到Serial Terminal
      //输入参数:无
      //返回值:  distance
      //修改记录:无
      //******************************************************************
      float distance=0;
      float ultrasonic()
      {
      	uint64_t t1=0,t2=0;
      
      	GPIO_SET(A1,0,input);//将A1配置为输入,接收超声波输入信号
      	GPIO_SET(A0,1,output);
      	delay_us(1);//触发超声测距模块,产生12.4us的电平
      	GPIO_SET(A0,0,output);
      
      	while( read_pin_val(A1) == 0 );	//A1输入为0时等待
      	t1 = get_timer_value();
      	while( read_pin_val(A1) == 1 );//A1输入为1时计数,测量高电平长度
         	t2 = get_timer_value();
         	distance =( (float)(t2-t1) )/RTC_FREQ*340/2;
      
      	printf("%.2f厘米   \n \n",distance*100);//将测得的距离回传到Terminal里面显示
      
      	wait_ms(80);
      
      	return distance;
      }
      //******************************************************************
      //函数名:  ultrasonic_control
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:    超声波避障功能的控制逻辑
      //输入参数:无
      //返回值:  无
      //修改记录:无
      //******************************************************************
      void ultrasonic_control()
      {
      	ultrasonic();//触发超声波模块,并测量距离,给标志位置位(用led显示状态)
      
      	float distance_left = 0, distance_right = 0;
      	if( distance < 0.15   )//小于0.15米,停车
      	{
      		motor_stop();//停车
      		GPIO_SET(ledD3,1,output);
      
      		servo_motor_left;
      		wait_ms(500);
      		distance_left = ultrasonic();
      		wait_ms(500);
      		servo_motor_right;
      		wait_ms(500);
      		distance_right = ultrasonic();
      		wait_ms(500);
      		servo_motor_middle;
      
      		if(distance_left >= distance_right)
      			motor_left();
      		else
      			motor_right();
      
      		motor_forward();
      
      
      	}
      	else
      	{
      		GPIO_SET(ledD3,0,output);
      		motor_run();
      	}
      }
      
      //******************************************************************
      //函数名:  PWM_init
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:    PWM功能的寄存器配置和初始化
      //输入参数:无
      //返回值:  无
      //修改记录:无
      //******************************************************************
      void PWM_init()
      {
      	  //初始化PWM1寄存器为全0
      	  PWM1_REG(PWM_CFG)   = 0;
      	  //使能PWM1的4路PWM波  |  避免毛刺	| 计数器清零	|  配置计数器分频系数
      	  PWM1_REG(PWM_CFG)   = (PWM_CFG_ENALWAYS| PWM_CFG_DEGLITCH | PWM_CFG_ZEROCMP | 0xA);
      	  //
      	  PWM1_REG(PWM_COUNT) = 0;
      	  //选择IOF模式为IOF1
      	  GPIO_REG(GPIO_IOF_SEL)  |= ( (1 << car_motor_ENA) | (1 << car_motor_ENB) | (1 << servo_motor) );
      	  //IOF使能,使io口可以输出PWM波
      	  GPIO_REG(GPIO_IOF_EN )  |= (1 << car_motor_ENA) ;
      	  GPIO_REG(GPIO_IOF_EN )  |= (1 << car_motor_ENB);
      	  GPIO_REG(GPIO_IOF_EN )  |= (1 << servo_motor);
      	  //输出取反
      	  GPIO_REG(GPIO_OUTPUT_XOR)|= ( (1 << car_motor_ENA) | (1 << car_motor_ENB) | (1 << servo_motor) );
      	  //配置占空比
      	  PWM1_REG(PWM_CMP0)  = 0;//0% PWM  一个周期的时钟个数(分频后) 160000
      	  PWM1_REG(PWM_CMP1)  = 0;//0% PWM 0xffff/5
      	  PWM1_REG(PWM_CMP2)  = 0;//0% PWM高电平为5ms
      
      	  //配置输出频率为 244/8 Hz,频率最小可以到 244/(2^15) Hz
      	  //PWM1_REG(PWM_CFG) |= 0;//为原频率的 2的0次方 分之一
      }
      
      //******************************************************************
      //函数名:  smartcar_init
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:    小车Io口的初始化
      //输入参数:无
      //返回值:  无
      //修改记录:无
      //******************************************************************
      void smartcar_init()
      {
      	//超声距离检测指示端口灯初始化
      	GPIO_SET(ledD3,1,output);
      
      	//初始化红外模块输出信号的接收端口
      	GPIO_SET(left_monitor	,0,input);
      	GPIO_SET(right_monitor	,0,input);
      
      	//确定电机方向向前行
      	GPIO_SET(car_motor_IN3		,0,output);
      	GPIO_SET(car_motor_IN4		,1,output);
      	GPIO_SET(car_motor_IN1		,0,output);
      	GPIO_SET(car_motor_IN2		,1,output);
      }
      //******************************************************************
      //函数名:  read_pin_val
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:    读输入引脚的电平
      //输入参数:pin_num
      //返回值:  1或0
      //修改记录:无
      //******************************************************************
      uint32_t read_pin_val(uint32_t pin_num)
      {
      	if((GPIO_REG(GPIO_INPUT_VAL))&(0x01<<pin_num))
      	{
      		return 1;
      	}
      	else
      		return 0;
      }
      //******************************************************************
      //函数名:  delay_us
      //作者:    PerfXLab
      //日期:    2018-07-04
      //功能:    time_x = 1 时产生12.4us的延时
      //输入参数:time_x
      //返回值:  无
      //修改记录:无
      //******************************************************************
      int delay_us(uint32_t time_x)//time_x = 1 时产生12.4us的延时
      {
      	volatile uint32_t num;
      //注意不要将volatile语句删除,否则编译器会自动优化掉延时函数,导致延时函数无法工作
      	num = 25*time_x;
      	while(num>0)
      		{num--;}
      return 0;
      }
      
      //==============以下两个函数是中断函数接口=====================================//
      /*Entry Point for PLIC Interrupt Handler*/
      void handle_m_ext_interrupt()
      {
        plic_source int_num  = PLIC_claim_interrupt(&g_plic);
        if ((int_num >=1 ) && (int_num < PLIC_NUM_INTERRUPTS))
        {
          g_ext_interrupt_handlers[int_num]();
        }
        else
        {
          exit(1 + (uintptr_t) int_num);
        }
        PLIC_complete_interrupt(&g_plic, int_num);
      }
      /*Entry Point for Machine Timer Interrupt Handler*/
      void handle_m_time_interrupt()
      {
      	clear_csr(mie, MIP_MTIP);
      
      	volatile uint64_t * mtime       = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME);
      	volatile uint64_t * mtimecmp    = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
      	uint64_t now = *mtime;
      	uint64_t then = now +0.1*RTC_FREQ;
      	*mtimecmp = then;
      
      	//ultrasonic();
      
      	// Re-enable the timer interrupt.
      	set_csr(mie, MIP_MTIP);
      }
      //============================================================================//
      
      
      //============================================================================//
      //	主函数
      //=============================================================================//
      int main(int argc, char **argv)
      {
      
        /**************************************************************************
         * Set up the PLIC
         *************************************************************************/
         PLIC_init(&g_plic,
       	    PLIC_CTRL_ADDR,
       	    PLIC_NUM_INTERRUPTS,
       	    PLIC_NUM_PRIORITIES);
      
         GPIO_SET(ledD3,1,output);	//测试端口初始化
         smartcar_init();             //初始化相关端口
         PWM_init();    				//初始化PWM1
         servo_motor_middle;			//控制舵机使超声波模块面向向前方
         motor_forward();				//使能直流电机,小车前进
         while (1)
      	{
      		//两种功能可以选择使用
      		//方法是备注掉不用的那一行代码
      		
      	    ultrasonic_control();	//超声波避障功能
      	   // tracking_car_control();  //循迹小车功能
      
      	}
      
      }
      
      
      posted in Perf-V系列(RISC-V Core FPGA Board)
      C
      chshwei
    • RE: 关于PLIC中断

      请问您用的是哪个ip核!?

      posted in Perf-V系列(RISC-V Core FPGA Board)
      C
      chshwei
    • RE: 温湿度传感器代码问题

      请问有没有验证delay_us的准确性?

      posted in Perf-V系列(RISC-V Core FPGA Board)
      C
      chshwei