单片机控制马达驱动IC的应用

news2024/11/19 3:38:04

8位机最常见的应用单片机驱动马达IC工作,马达可支持无级调速(PWM),正转,反转,刹车。该应用简单高效适应于各种应用,节约成本的不二选择。

今天就跟大家分享曾经做过的马达驱动IC的应用。

主电路由8位单片机提供控制信号,正转,反转,PWM调速,以及一个峰值电流400ma的马达驱动IC构成。见电路图。

S1按一下正转,按一下停机

S2按一下反转,按一下停机

S3按一下加一级速度

S4按一下减一级速度

由于硬件不支持PWM,PWM使用IO模拟的方式产生。

/* =========================================================================
 * Project:       GPIO_Setting
 * File:          main.c
 * Description:   Set GPIO of PORTB
 *                  1. PORTB I/O state
 *                      - PB4 set input mode and enable pull-high resistor
 *                      - PB2 set output mode 
 *                      - PB1 set input mode and enable pull-low resistor
 *                      - PB0 set open-drain output mode                               
 *                                                          
 * Author:        JasonLee
 * Version:       V1.1                              
 * Date:          2018/09/07
 =========================================================================*/
#include <ny8.h>
#include "ny8_constant.h"
#include <stdint.h>
#define UPDATE_REG(x)    __asm__("MOVR _" #x ",F")

uint8_t pwmdcycle = 0;  //计数1000为一个周期
uint8_t pwmduty1 = 0;
uint8_t pwmduty2 = 0;
uint8_t pwmduty1s = 0;
uint8_t pwmduty2s = 0;
uint8_t spstate = 1;
uint8_t direction = 0; //stop 0  fw 1 bk 2

//uint8_t spdstate = 1;     //10档
int16_t seccount = 0;    

int16_t tim1count = 0;
int16_t tim1scount = 0;
uint8_t sw1flg = 0;
int16_t tim2count = 0;
int16_t tim2scount = 0;
uint8_t sw2flg = 0;
uint16_t tim3count = 0;
uint8_t sw3flg = 0;
uint8_t tim4count = 0;
uint8_t sw4flg = 0;

void peripinit(void)
{
    //;Initial GPIO  
    //      ; PORTB I/O state
    //        ; PB0、PB1、PB2 set output mode and enable pull-high resister   
    BPHCON = (uint8_t) ~( C_PB5_PHB | C_PB4_PHB | C_PB2_PHB) ;        // Enable PB5、PB4、PB2 Pull-High Resistor,others disable
    IOSTB = (uint8_t) (C_PB5_Input | C_PB4_Input | C_PB3_Input | C_PB2_Input) ;    // Set PB5、PB3、PB3 PB2 to output mode,others set to input mode
    PORTB = 0x00;
    
    //;Initial time1
    //      ;instrclk i_hrc 4/4M  div = 1  计数8次溢出即可
    //      ;
    TMR1 = 0xC8;    //到0下溢出中断,计数 //4M/200 = 20K/20 = 1K
    T1CR1 = C_TMR1_Reload | C_TMR1_En;   //自动重载
    T1CR2 = C_TMR1_ClkSrc_Inst | C_PS1_Dis ;  //指令时钟
   
    //T1CR1 =( T1CR1 | C_TMR1_En ); //使能定时器
    INTE = INTE | C_INT_TMR1;    
}

//尽量减小中断代码时长
void isr_hw(void) __interrupt(0)
{
    if(INTFbits.T1IF)        //占空比为 cycle-duty
    {
        pwmdcycle++;       
         
        if( pwmdcycle == pwmduty1s )
        {
            if(direction == 1)  //FW
            {
                PORTBbits.PB0 = 1;
                PORTBbits.PB1 = 0;
            }
            else if(direction == 2)  //BK
            {
                PORTBbits.PB0 = 0;
                PORTBbits.PB1 = 1;
            }
            else if(direction == 0)    //停机
            {
                PORTBbits.PB0 = 0;
                PORTBbits.PB1 = 0;
            }
        }
        
        if(pwmdcycle == 20)
        {
            pwmduty1s = pwmduty1;  //必须保证周期结束才能更改此值
            pwmduty2s = pwmduty2;  //必须保证周期结束才能更改此值
            PORTBbits.PB1 = 0;
            PORTBbits.PB0 = 0;
            pwmdcycle = 0;
            
            seccount ++;
        }
        INTFbits.T1IF = 0;
    }
}

void main(void)
{
    DISI();
    peripinit();
    ENI();
      
    while(1)
    {
        //PB2 正转 
        if(PORTBbits.PB4 == 0)
        {
            if(sw1flg == 0)
            {
                tim1count = seccount + 3000;
                tim1scount = seccount + 40;
                sw1flg = 1;
            }
            
            if((tim1count == seccount)&&(sw1flg == 2))
            {
                if(direction != 0)        //关机
                {
                    direction = 0;
                    
                }
                else 
                {
                    direction = 1;
                    spstate = 1;
                }
                sw1flg = 3;
            }
            if((seccount ==  tim1scount)&&(sw1flg == 1))
            {
                sw1flg = 2;
            }
        }
        else
        {
            if(sw1flg == 2 )                //短按有效
            {
                if(direction == 1)
                {
                    direction = 2;
                }
                else if(direction == 2)
                {
                    direction = 1;
                }
            }
            
            tim1count = 0;
            tim1scount = 0;
            sw1flg = 0;
        }
        //PB3 
        if(PORTBbits.PB3 == 0)
        {
            if(sw2flg == 0)
            {
                tim2count = seccount + 3000;    //延时3s
                tim2scount = seccount + 40 ;
                sw2flg = 1;
            }
            
            if((tim2count == seccount)&&(sw2flg == 2))
            {
                if(direction != 0)        //开机
                {
                    direction = 0;
                    
                }
                else 
                {
                    direction = 1;
                    spstate = 1;
                }
                sw2flg = 3;
            }
            
            if((seccount ==  tim2scount)&&(sw2flg == 1))
            {
                sw2flg = 2;
            }
        }
        else
        {
            if(sw2flg == 2 )
            {
                if(direction == 1)
                {
                    direction = 2;
                }
                else if(direction == 2)
                {
                    direction = 1;
                }
            }
            tim2count = 0;
            tim2scount = 0;
            sw2flg = 0;
        }
        //PB5 加速换挡
        if(PORTBbits.PB5 == 0)
        {
            if(sw3flg == 0)
            {
                tim3count = seccount + 30;
                sw3flg = 1;
            }
            
            if((tim3count == seccount)&&(sw3flg == 1))
            {
                spstate ++;
                if(spstate == 11)
                {
                    spstate = 1;
                }
                sw3flg = 2;
            }
        }
        else
        {
            tim3count = 0;
            sw3flg = 0;
        }
        
    
        //CLRWDT(); //pb4/pb5_加减速
        if(spstate == 1)
        {
            pwmduty1 = 10;
        }
        else if(spstate == 2)
        {
            pwmduty1 = 9;
        }
        else if(spstate == 3)
        {
            pwmduty1 = 8;
        }
        else if(spstate == 4)
        {
            pwmduty1 = 7;
        }
        else if(spstate == 5)
        {
            pwmduty1 = 6;
        }
        else if(spstate == 6)
        {
            pwmduty1 = 5;
        }
        else if(spstate == 7)
        {
            pwmduty1 = 4;
        }
        else if(spstate == 8)
        {
            pwmduty1 = 3;
        }
        else if(spstate == 9)
        {
            pwmduty1 = 2;
        }
        else if(spstate == 10)
        {
            pwmduty1 = 1;
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/72410.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

类的加载器

文章目录1. 概述1.1 大厂面试题1.2 类加载的分类1.3 类加载器的必要性1.4 命名空间1.5 类加载机制的基本特征2. 类的加载器分类2.1 引导类加载器2.2 扩展类加载器2.3 系统类加载器2.4 用户自定义类加载器3. 测试不同的类的加载器4. ClassLoader源码解析4.1 ClassLoader的主要方…

测量电源纹波-正确测量方法

测量纹波需要注意的点&#xff1a; 1、用弹簧探针&#xff1b; 2、测量位置在输出电容两端&#xff1b; 3、示波器选择‘20M’&#xff1b; 4、示波器选择‘交流耦合’&#xff1b; 5、示波器探头‘X1’&#xff0c;示波器设置‘X1’&#xff1b;(10:1的探头&#xff0c;实际上…

Stable Diffusion V2.1非标准分辨率图像高清渲染

Stable Diffusion V2.1非标准分辨率图像高清渲染 Stable Diffusion V2.1发布&#xff0c;支持非标准分辨率图像高清渲染。 SD2.1在线体验 在线体验地址:Stable Diffusion 模型包括&#xff1a; NovelAI&#xff0c;NovelAI的模型训练使用了数千个网站的数十亿张图片&#xf…

如何给图片加水印?分享怎么给图片加水印的方法

当我们在平台上发布自己精心拍摄的照片&#xff0c;或分享自己总结的知识点时&#xff0c;难免会遇到一些人盗用自己图片的情况。这时候&#xff0c;我们就会给图片添加上水印&#xff0c;从而来防止自己的图片被盗&#xff0c;那要怎么给图片加水印呢&#xff1f;别着急&#…

《自己动手写CPU》学习记录(3)——第4章/Part 1

目录 引言 致谢 平台 ori 指令 流水线结构建立 模型 简单的MIPS五级流水线结构 设计 宏定义 程序计数器 译码 通用寄存器 指令执行 内存访问 指令ROM 顶层文件 处理器顶层 SOPC顶层 功能仿真 TestBench 仿真结果 执行时间 时序细节 引言 本篇学习书本…

Java大型企业进销存系统源码带文字搭建教程

技术架构 技术框架&#xff1a;SpringBoot Spring Data Jpa SpringMvc Shiro安全认证 完整权限系统 easyui 运行环境&#xff1a;jdk8 IntelliJ IDEA maven 宝塔面板 本地搭建教程&#xff1a; 1.下载源码&#xff0c;小皮面板创建一个数据库&#xff0c;导入db_jxc2.…

nodejs模板引擎的使用

前后端不分离的情况(数据都来源于后端,前后端不可以分离使用) npm i express art-template express-art-template --S 先下载模板引擎,模板渲染,还有experss服务器的包 js代码 //导入express服务器第三方的包 const express require("express") //导入模板引擎 con…

Spring Cloud(十六):微服务分布式唯一ID

分布式唯一ID 特点方案 雪花算法 特点开源实现优缺点 替代方案 UUIDMongdbSeata数据库生成Redis 基于美团的 Leaf分布式 ID 微服务 Leaf-segment 数据库方案 双 buffer 优化 — TP999 数据波动大 Leaf 高可用容灾 — DB 可用性Leaf-snowflake 雪花方案 弱依赖 ZooKeeper 解决时…

加减大师-第10届蓝桥杯Scratch选拔赛真题精选

[导读]&#xff1a;超平老师计划推出Scratch蓝桥杯真题解析100讲&#xff0c;这是超平老师解读Scratch蓝桥真题系列的第98讲。 蓝桥杯选拔赛每一届都要举行4~5次&#xff0c;和省赛、国赛相比&#xff0c;题目要简单不少&#xff0c;再加上篇幅有限&#xff0c;因此我精挑细选…

Vue学习笔记--第一章(尚硅谷学习视频总结)

目录 一、第一章 Vue核心 1.1. Vue简介 1.1.1. 官网 1.1.2. 介绍与描述 1.1.3. Vue 的特点 1.1.4. 与其它 JS 框架的关联 1.1.5. Vue 周边库 1.2.初识Vue 1.3. 模板语法 1.4. 数据绑定 1.5 el与data的两种写法 1.6 MVVM模型 1.7 Vue中的数据代理 1.8.事件处理 1.…

从零学习 InfiniBand-network架构(九) —— IB协议中子网本地地址

从零学习 InfiniBand-network架构&#xff08;九&#xff09; —— IB协议中子网本地地址 &#x1f508;声明&#xff1a; &#x1f603;博主主页&#xff1a;王_嘻嘻的CSDN主页 &#x1f511;未经作者允许&#xff0c;禁止转载 &#x1f6a9;本专题部分内容源于《InfiniBand-n…

鸿蒙3.0应用开发若干问题及上架总结

1.如何去掉默认标题栏&#xff0c;实现全屏显示&#xff1f; 在config.json中的ability配置信息中添加属性&#xff1a; "abilities": [ {..."metaData": {"customizeData": [{"name": "hwc-theme","value": &q…

Buildroot系列开发(五)bootloader简述

参考&#xff1a;百问网 文章目录1.什么是Boot-loader?2.有哪些bootloader?哪些支持linux&#xff1f;3.Bootloader支持的Flash设备4.Bootloader支持的文件系统类型4.Bootloader支持的CPU架构5.Bootloader总结1.什么是Boot-loader? 2.有哪些bootloader?哪些支持linux&#…

广州蓝景分享——前端学习5 种在 JavaScript 中获取字符串第一个字符的方法

在本文中&#xff0c;我们将研究多种方法来轻松获取 JavaScript 中字符串的第一个字符。 1.charAt() 方法 要获取字符串的第一个字符&#xff0c;我们可以在字符串上调用 charAt() &#xff0c;将 0 作为参数传递。例如&#xff0c;str.charAt(0) 返回 str 的第一个字符。 c…

AT1106S(PHS/EN输入接口通道0.8A低压H桥直流刷式电机驱动IC)

描述 泛海微AT1106S为摄像机、消费类产品、玩具和其它低电压或者电池供电的运动控制类应用提供了一个集成的电机驱动器解决方案。泛海微AT1106S能够驱动一个直流电机或其他诸 如螺线管的器件。输出驱动模块由N MOS功率管构成的H桥组成&#xff0c;以驱动电机绕组。泛海微AT110…

车企接连押注「重感知」 ,高精地图真会被弃用?

实现高阶智能驾驶&#xff0c;“重感知”是否为大势所趋&#xff1f; 答案正日益明晰。 2022年&#xff0c;以特斯拉为代表的“重感知”阵营&#xff0c;押注者正日趋增多。以在2022年尝试落地城市NOA的三家厂商为例&#xff1a;毫末智行一早便属“重感知”阵营&#xff1b;小…

【20221208】【每日一题】目标和

给你一个整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 或 - &#xff0c;然后串联起所有整数&#xff0c;可以构造一个 表达式 &#xff1a; 例如&#xff0c;nums [2, 1] &#xff0c;可以在 2 之前添加 &#xff0c;在 1 之前添加 - &#xff0c;然后串…

5G无线技术基础自学系列 | SA移动性管理流程

素材来源&#xff1a;《5G无线网络规划与优化》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 SA移动性管理流程包括站内切换、Xn切换…

Java基础之序列化和反序列化

序列化的实现 java.io中的对象流提供了序列化和反序列化对象的方法 对象输出流 ObjectOutputStream 构造方法&#xff1a; ObjectOutputStream(OutputStream out) 保存对象的方法&#xff1a; void writeObject(Object obj) 对象输入流 ObjectInputStream 构造方法&…

使用 MySQL、Thymeleaf 和 Spring Boot Framework 上传、存储和查看图像

在本文中&#xff0c;我们将使用 Spring Boot 框架从头开始构建映像库应用程序&#xff0c;用户可以在其中列出其映像。 以下是我们将在应用程序中实现的功能。 用户可以列出他们的图像以及详细信息&#xff0c;例如&#xff0c; 名字描述图像价格。&#xff08;如果他们想卖…