[RISC-V MCU 应用开发]RISC-V MCU-遥控智能小车

先介绍一下CH32V307吧,赤菟V307是搭载沁恒自研RISC-V内核青稞V4F的高性能互联型MCU,主频支持144MHz,支持硬件浮点运算(FPU),提供八个UART接口、USB2.0高速接口(480Mbps)并内置了PHY收发器、千兆以太网MAC并集成10M PHY、2个CAN接口等丰富的外设资源。赤菟V307评估板自带WCH-Link仿真调试器,并配备丰富的板载资源,包括LCD显示屏、距离与环境光传感器、六轴姿态传感器、温湿度传感器、麦克风、蓝牙模块接口。


板子上有一个蓝牙BLE模块,所以想着用这个模块开发一个基于蓝牙控制的小车系统。该系统采用了上位机和下位机两个部分。下位机采用的是CH32V307作为主控制器,通过PWM控制小车,并通过AHT10读取环境温湿度,并将参数显示在LCD上,通过MOS模块驱动加湿器模块。下位机和上位机通过蓝牙模块进行交互,下位机将温湿度数据发送给APP,同时,上位机通过APP将数据发给下位机。APP通过android studio编写。
系统框图如下所示。


建立系统工程文件,记得要选择是CH32V307的芯片,这里没有使用操作系统。


该开发板提供的资料不少,很多的源代码都不需要自己来编写的,使用官网的代码即可。

 建立的工程如下所示。


因为我们后期需用到AHT11和LCD,所以将两个系统文件复制到工程文件下。


这里的驱动文件就不再赘述了。使用用来读取数据和显示数据使用。
首先,要实现的是读取温湿度数据并将该数据显示在LCD,并发送数据到蓝牙上。
驱动代码中已经提供了如何获取温湿度数据,这里只要需要调用即可。

 temperature = AHT10_Read_Temperature();

            humidity = AHT10_Read_Humidity();

            lcd_set_color(BLACK,GREEN);

            lcd_show_string(30, 192, 16,"Temperature : %5d", (int)(temperature));

            lcd_show_string(30, 208, 16,"Humidity    : %5d", (int)(humidity));

为了更好的实现控制,这里不使用延时函数,而是采用定时器实现内部时钟,采用的是定时器2实现中断计数的功能。
然后通过时间差实现1s采集和更新一次数据的功能。计算时间差的函数如下

u32 get_tDiff(u32 lt)

{

    return timer_cnt-lt;

}

timer_cnt为全局变量,用于定时器的计数,形成系统时钟。

void TIM2_IRQHandler(void)

{

    if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查TIM2中断是否发生。

      {

        TIM_ClearITPendingBit(TIM2,TIM_IT_Update);    //清除TIM2的中断挂起位。

timer_cnt++;

      }

}

BLE模块的数据主要是通过串口实现的 ,只要向串口发送数据,手机端就可以收到相关的数据了。
串口的配置这里就不再赘述了,官网提供个代码已经实现了,只需要简单的复制就行了。
这里是将温湿度数据转换为json格式的数据,发送到手机上,然后在手机端进行解析,将温湿度数据显示在手机上。
实现的代码如下所示。

        if(get_tDiff(last_time0)>1000){

            last_time0=timer_cnt;

            temperature = AHT10_Read_Temperature();

            humidity = AHT10_Read_Humidity();

            lcd_set_color(BLACK,GREEN);

            lcd_show_string(30, 192, 16,"Temperature : %5d", (int)(temperature));

            lcd_show_string(30, 208, 16,"Humidity    : %5d", (int)(humidity));

            sprintf(s_Str,"{\"t\":%d,\"h\":%d}",(int)(temperature),(int)(humidity));

            while(uartWriteBLEstr(s_Str)==RESET);

        }

为了能够更好的控制小车,这里使用的是PWM来控制,PWM的占空比可以通过手机端进行操作。
其初始化代码如下所示,pwm.h

/*

 * pwm.h

 *

 *  Created on: Jun 8, 2022

 *      Author: flying

 */



#ifndef USER_PWM_H_

#define USER_PWM_H_





void initPwm(void);



#endif /* USER_PWM_H_ */

pwm.c,配置的定时器3的1和2通道,分别对PB0和PB1输出PWM信号,并通过驱动电路实现小车的控制。
PWM的周期为1ms,默认的占用比为50%;

#include "pwm.h"

void initPwm(void)

{

    GPIO_InitTypeDef GPIO_InitStructure={0};

        TIM_OCInitTypeDef TIM_OCInitStructure={0};

        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};

        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE );

        RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE );

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_Init( GPIOB, &GPIO_InitStructure );

        TIM_TimeBaseInitStructure.TIM_Period = 1000-1;

        TIM_TimeBaseInitStructure.TIM_Prescaler = 72-1;

        TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;

        TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;

        TIM_TimeBaseInit( TIM3, &TIM_TimeBaseInitStructure);

        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

        TIM_OCInitStructure.TIM_Pulse = 0;

        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

        TIM_OC3Init( TIM3, &TIM_OCInitStructure );

        TIM_OC4Init( TIM3, &TIM_OCInitStructure );

        TIM_CtrlPWMOutputs(TIM3, ENABLE );

        TIM_OC3PreloadConfig( TIM3, TIM_OCPreload_Disable );

        TIM_OC4PreloadConfig( TIM3, TIM_OCPreload_Disable );

        TIM_ARRPreloadConfig( TIM3, ENABLE );

        TIM_Cmd( TIM3, ENABLE );

}

下面开始对小车的控制方式进行设计,分别涉及到前进、后退、左转和右转、停止三个功能。
其实现函数如下所示。

uint16_t speed=500;

void foward(void)

{

    GPIO_WriteBit(GPIOE, GPIO_Pin_13,Bit_RESET);

    GPIO_WriteBit(GPIOE, GPIO_Pin_15,Bit_RESET);

    TIM_SetCompare3(TIM3, speed);

    TIM_SetCompare4(TIM3, speed);

}



void back(void)

{

    GPIO_WriteBit(GPIOE, GPIO_Pin_13,Bit_SET);

    GPIO_WriteBit(GPIOE, GPIO_Pin_15,Bit_SET);

    TIM_SetCompare3(TIM3, 0);

    TIM_SetCompare4(TIM3, 0);

}



void left(void)

{

    GPIO_WriteBit(GPIOE, GPIO_Pin_13,Bit_RESET);

    GPIO_WriteBit(GPIOE, GPIO_Pin_15,Bit_RESET);

    TIM_SetCompare3(TIM3, 0);

    TIM_SetCompare4(TIM3, speed);

}

void right(void)

{

    GPIO_WriteBit(GPIOE, GPIO_Pin_13,Bit_RESET);

    GPIO_WriteBit(GPIOE, GPIO_Pin_15,Bit_RESET);

    TIM_SetCompare3(TIM3, speed);

    TIM_SetCompare4(TIM3, 0);

}

void stop(void)

{    GPIO_WriteBit(GPIOE, GPIO_Pin_13,Bit_RESET);

    GPIO_WriteBit(GPIOE, GPIO_Pin_15,Bit_RESET);

    TIM_SetCompare3(TIM3, 0);

    TIM_SetCompare4(TIM3, 0);

}

 小车部分的实现图片。


然后再开始设计BLE的控制程序,这个代码参考的是沁恒的BLE程序,下载链接如下所示。
https://www.wch.cn/downloads/WCHBleLib_MultiOS_ZIP.html
只需要简单修改几个代码就可以,然后是修改发送的功能,
在安卓里面定义显示温湿度的TextView和控制按键Button
然后修改MainActivity.java的功能
这里显示温湿度的代码在private void updateValueTextView(final byte[] data) 中,修改代码为

 JSONObject jb = new JSONObject(new String(data));





            double tt =jb.getDouble("t");

            tv_tt.setText(""+tt +" ℃");

            tt =jb.getDouble("h");

            tv_temp.setText(""+tt +" %");

这样温湿度数据就会显示了。
下面实现发送的代码。前面根据xml文件的ID,将实例化该空间。
因为代码重复性太大,这里就拿左转命令来介绍,当发送‘A’的时候小车实现前进,
在APP实现的代码

        btn_qian.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                if (!checkBtEnabled()) {

                    showToast("请先打开蓝牙");

                    return;

                }

                try {

                    byte[] bytes = new byte[0];

                    bytes = "A".getBytes("utf-8");

                    write(SendType.TYPE_SINGLE, bytes, 0);

                } catch (UnsupportedEncodingException e) {

                    e.printStackTrace();

                }

            }

        });

在单片机里面实现控制的方式就是

            if(buffer[0]=='A'){

                foward();

}

 buffer[0]=0;

设计的APP界面如下所示。


因为视频上传不了,所以放两张操作图片吧。
---------------------
作者:51xlf
链接:https://bbs.21ic.com/icview-3237324-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CH32V307VCT6智能车是基于赤菟CH32V307开发板开发的智能配送小车。该智能车模拟工业物流智能运输系统,要分为循迹系统和识别系统。循迹系统通过使用传感器进行识别,并控制小车的前进、后退和转弯。识别系统则负责匹配所需货物,并具备装载和自动识别所需物品的能力。在出发时,小车装载指定货物,并按照设定好的程序沿着规定的路线前进。在途经指定地点时,识别系统会识别需要卸载的货物,并将其卸下后继续前进。在货物全部卸载完毕后,小车会返回指定地点。该系统要设计用于工厂流水线物料及工业园区货物配送,在工业物流智能运输中有广泛的应用。\[1\] 关于控制小车的前进、后退和转弯,项目中使用了四个轮子,通过给轮子分别赋予电平来控制正转或反转。右侧轮子编为一组,左侧轮子编为一组,通过控制左侧和右侧分别是正转还是反转来控制小车的运动方向。此外,通过控制PWM波的区间长度来控制小车的车速。\[2\] 循迹系统要依靠两个传感器TR5000和比较器LM393芯片进行识别,通过传感器进行识别,并通过一个引脚来输出识别的结果。然而,在该项目中原本计划将小车与一个固定桩进行匹配识别,即在小车到达指定的地点后将小车与固定桩进行通信连接,但最终发现无法实现该功能。\[2\] 在代码中,可以看到定义了左前轮和左后轮的引脚号码,分别为55和56。这些引脚用于控制小车的轮子运动。\[3\] #### 引用[.reference_title] - *1* *2* *3* [2022嵌入式芯片与系统设计竞赛](https://blog.csdn.net/DMC_8848/article/details/126442167)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值