一辆有脸蛋的小铲车

教程 余归 ⋅ 于 2021-10-01 00:07:31 ⋅ 365 阅读

如何使用CH549去做一个有脸蛋的小铲车呢

特别注明:此次作品由VeriMake大家族出品!

先不多直接说上图!!!

file

是不是有些激动了呢!不要着急待我慢慢给大家介绍下去。

首先是产品的3D建模部分

组成这个小车的打印零件有9个也都是一些很简单的零件组成的。

file

模型的爆炸视图,直观的展示所有的零件。
结构介绍:大臂和头部的动力来源是SG90舵机,车体移动的动力来源是N20减速电机。
零件之间相互连接大多数使用的是M2的自攻螺丝,少部分使用M3的螺丝与螺母连接,这种连接的办法降低了零件的打印难度。使一些精度相对低一些的打印机也可以打印出零件。

其次是产品的电路部分

file

主控采用的是:沁恒科技的CH549单片机

  • 增强型E8051内核CPU,速度比标准MCS51快8-15倍,特有XRAM数据快速复制指令;
  • 内置60KB Code Flash、1KB Data Flash和3KB BootLoader,支持USB和串口ISP;
  • 内置2KB XRAM和内部256B RAM;
  • 内嵌USB控制器和USB收发器,支持USB2.0全速和低速主机或设备,支持DMA;
  • 内嵌Type-C CC控制器,支持USB PD;
  • 提供支持 FAT12/FAT16/FAT32 文件系统的 U 盘文件级子程序库,实现读写 U 盘文件;
  • 提供3组定时器/计数器,支持3路引脚信号捕捉和8路PWM输出;
  • 提供4个全双工异步串口;
  • 提供1个SPI通信接口,支持主/从模式;
  • 提供与GPIO复用的16通道12位ADC模数转换器;
  • 提供16通道电容触摸按键;
  • 内置时钟和PLL,也可支持外部晶振。
  • 封装:SOP16、QFN28、LQFP48
  • 由于这个芯片的内核和传统的8051内核一致,这一点对一致使用STC系列单片机的同学就很有好了,这意味着软件程序方面大部分可以直接的Ctrl+C Ctrl+V
    file
    此次的PCB上面会插入这个小板子,这是由我们VeriMake工作室设计的一块基于CH549单片机的最小系统板。

    遥控采用的是:沁恒科技的CH9140蓝牙模块

    这个模块支持蓝牙BLE4.2,串口波特率最大1Mbps,最最最大的特点我认为是此模块设计的非常的迷你小巧,很适合做一些体积相对较小的电子制作。

    电机驱动采用的是:TC1508

    此驱动的峰值电流为2.5A,内部是双通道的功率MOS全桥,供给给N20电机使用绰绰有余。

    电源管理使用的是TP4056

    这个芯片的峰值充电电流为1A,通过调节PROG引脚的对地电阻即可修改充电电流
    遵循公式:Rporg=1200/Ibat;

    升压电路采用的是SX1308

    这是一款Boost升压芯片,配置3号引脚的上拉和下拉电阻即可修改输出端电压
    遵循公式Vout=Vref*(1+R上拉/R下拉);Vref为反馈电压0.6V
    file

    此电源用于提供舵机,单片机和OLED屏幕的电源。

    降压稳压芯片:此芯片用于给蓝牙模块提供一个3.3V的电源。

    电路方面的坑!!!

    舵机频繁工作的时候电流很大,升压部分输出电压被拉低,这会导致单片机电源被拉低复位,解决的办法是:在单片机的电源上面并联一个大电容,并且增加一个电流流向向内的二极管。

最后是产品的软件程序部分

程序方面的设置当然还是和STC51单片机一样的Keil,相信大部分同学都不会陌生。

外设端口定义

sbit djA1=P2^4;
sbit djA2=P2^2;
sbit djB1=P3^4;
sbit djB2=P3^5;//电机端口定义
sbit Arm=P0^4;//大臂舵机定义
sbit Head=P1^6;//头部舵机定义
sbit ledr=P1^4;//左转LED
sbit ledl=P1^5;//右转LED
由于控制两个电机的正反转则需要四个GPIO去控制
Arm和Head是大臂和头部两个舵机的信号端
ledr和ledl是车头下方的左边灯和右边灯
除此之外还有串口的端口没有定义,使用的是P26和P27端口

所定义的函数:

void Get_Value(void);//得到电池电压
void Device_Init();//外设初始化
void timer_init(void);//100us定时器初始化
void display();//显示表情和电量
void move_contrl();//车身移动控制
void led_contrl();//LED控制

外设初始化:初始化所有的软硬件外设 (初始化控制电机的GPIO电平,串口,定时器,OLED显示屏)

void Device_Init()//外设初始化
{
    djA1=0;
    djA2=0;
    djB1=1;
    djB2=1;//电机初始状态赋值       
    CH549UART1Init();//串口1初始化
    ADC_ExInit(3);//初始化ADC采集    
    mDelaymS(20);  
    OLED_Init();            //初始化OLED 
    mDelaymS(20);  
    OLED_Clear(); 
    mDelaymS(20);  
}

得到ADC端口电压:读取电池电压,进行电量检测

void Get_Value()
{
        ADC_ChSelect(CH0);//选择通道                              
        ADC_StartSample();//开启采样  
        while((ADC_CTRL&bADC_IF) == 0);    //查询等待标志置位
        ADC_CTRL = bADC_IF;//清除标志       
        Value=ADC_DAT;//电压转换,转换为当前检测管脚的电压的10倍(即3.7v显示37)
}
选择通道CH0是指P10端口,P10端口挂在了电池的VCC上面,得到数据之后将数据赋值给变量,供后续使用。

定时器初始化函数:(初始化定时器0为50us定时器,用来模拟软件PWM给舵机使用)

void timer_init()//定时器初始化
{
    TMOD=0x01;
    TH0=(65535-100)/256;
    TL0=(65535-100)%256;
    TR0=ET0=EA=1;
}

显示函数:(显示表情和当前电池剩余电量)

void display()
{
    static char k,time;
    if(dat<10&&dat==0)time++;
    if(time>=15&&dat==0) //当为静止状态
    {
        Get_Value();//查看电池电量
        OLED_DrawLine((128-Value)/2,128-((128-Value)/2),7,dat);//电量条显示
        time=0;
        k=!k;
    }
    if(dat==0&&k==0)    OLED_DrawBMP(0,0,128,50,eyes_open,dat);  //睁眼
    if(dat==0&&k==1)    OLED_DrawBMP(0,0,128,50,eyes_close,dat); //闭眼
    if(dat==1)  OLED_DrawBMP(0,0,128,50,forward,dat);                //前进
    if(dat==2)  OLED_DrawBMP(0,0,128,50,back_off,dat);               //后退   
    if(dat==3)  OLED_DrawBMP(0,0,128,50,turn_left,dat);              //左转
    if(dat==4)  OLED_DrawBMP(0,0,128,50,turn_right,dat);             //右转
}
这里的dat就是通过上位机(手机遥控APP)发送来的数据

file

标题提到表情这边的前进后退等等,对应显示的就是这边的表情,具体的实现使用专门的取模软件,导入图片设置好取模方式就可以直接用OLED显示器显示了。

file

想要复刻的小伙伴们可以自行导入像素密度为128*64的BMP格式的图片进去修改小车的表情

定时器0的中断服务函数:

void timer_zd() interrupt 1
{
    static int PWM;
    PWM++;
    TH0=(65535-100)/256;
    TL0=(65535-100)%256;//50us定时器
    if(PWM>=400)PWM=0;   //周期控制
    if(PWM>=move1) Arm=0;   //大臂控制
    else Arm=1;
    if(PWM>=move2) Head=0;//头部控制
    else Head=1;
}
模拟的PWM周期为20Ms,占空比通过move1和move2两个变量分别控制两个舵机,占空比的范围是0到12.5%。

Main函数:

void main() 
{
    CfgFsys();      //CH549时钟选择配置
    ledl=ledr=1;//led全部关闭
    Device_Init();//外设初始化
    move1=32;
    move2=18;
    timer_init();//定时器初始化
    while(1)
    {
        display();//显示函数
        move_contrl();//车身移动控制
        led_contrl();
    }
}
程序流程:时钟配置→外设初始化→while循环
循环内:显示函数显示表情,同时串口等待外部上位机发送信息,根据发送信息做出不同的反应。
回复数量: 0
    暂无评论~~
    • 请注意单词拼写,以及中英文排版,参考此页
    • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
    • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
    • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
    • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
    Ctrl+Enter