数码之家

 找回密码
 立即注册
搜索
查看: 412|回复: 15

[C51] 自已做了个用单片机的pwm无刷电机控制器

[复制链接]
发表于 2024-4-26 17:20:37 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
     偶得一无刷电机,想用在家里的旧电扇上,就自己做了个PWM控制器。

    不想在外壳上开孔,所以PCB图上按一般风扇的定时器大小画的,原理图很简单。
    程序是网上找的,做了一点修改,但仍有些bug, 不能直接套用的,要完善一下的!
    用的是STC8G1K08A单片机,,,过一段时间发个全部完工的成品。

4.jpg

3.jpg

2.jpg

1.jpg

motor.rar

9.88 KB, 下载次数: 1, 下载积分: 家元 -55

售价: 5 家元  [记录]

程序

打赏

参与人数 1家元 +90 收起 理由
家睦 + 90

查看全部打赏

发表于 2024-4-26 17:55:56 | 显示全部楼层
不错,可以考虑加上遥控功能
回复 支持 反对

使用道具 举报

发表于 2024-4-26 17:57:30 | 显示全部楼层
无刷电机改风扇是不是很静音,一直想搞一台的,就是看电机成本有点高
回复 支持 反对

使用道具 举报

发表于 2024-4-26 18:03:42 | 显示全部楼层
围观会画板的大佬...

--------------------
回复 支持 反对

使用道具 举报

发表于 2024-4-26 18:41:03 | 显示全部楼层
这板板不错,,手上有些从旧设备上拆下的这种电机,,一直不知怎么玩
回复 支持 反对

使用道具 举报

发表于 2024-4-26 19:05:05 | 显示全部楼层
板子画的不错哦
回复 支持 反对

使用道具 举报

发表于 2024-4-26 19:36:36 | 显示全部楼层
强势围观大神制作
回复 支持 反对

使用道具 举报

发表于 2024-4-27 11:08:59 | 显示全部楼层
分享一个开源的范例:
/*************        功能说明        **************


本程序试验使用STC8H1K28-LQFP32来驱动带霍尔传感器的无刷三相直流电机.


PWM的捕捉中断功能用来检测霍尔信号.
P0.3接的电位器控制转速, 处于中间位置为停止, 逆时针旋转电位器电压降低电机为逆时针转, 顺时针旋转电位器电压升高电机为顺时针转.
关于带霍尔传感器三相无刷直流电机的原理, 用户自行学习了解, 本例不予说明.


******************************************/




#define MAIN_Fosc                24000000L        //定义主时钟


#include        "STC8Hxxx.h"




#define ADC_START        (1<<6)        /* 自动清0 */
#define ADC_FLAG        (1<<5)        /* 软件清0 */


#define        ADC_SPEED        1                /* 0~15, ADC时钟 = SYSclk/2/(n+1) */
#define        RES_FMT                (1<<5)        /* ADC结果格式 0: 左对齐, ADC_RES: D9 D8 D7 D6 D5 D4 D3 D2, ADC_RESL: D1 D0 0  0  0  0  0  0 */
                                                        /*             1: 右对齐, ADC_RES: 0  0  0  0  0  0  D9 D8, ADC_RESL: D7 D6 D5 D4 D3 D2 D1 D0 */


#define CSSETUP                (0<<7)        /* 0~1,  ADC通道选择时间      0: 1个ADC时钟, 1: 2个ADC时钟,  默认0(默认1个ADC时钟) */
#define CSHOLD                (1<<5)        /* 0~3,  ADC通道选择保持时间  (n+1)个ADC时钟, 默认1(默认2个ADC时钟)                */
#define SMPDUTY                20                /* 10~31, ADC模拟信号采样时间  (n+1)个ADC时钟, 默认10(默认11个ADC时钟)                                */
                                                        /* ADC转换时间: 10位ADC固定为10个ADC时钟, 12位ADC固定为12个ADC时钟.                                 */


sbit PWM1   = P1^0;
sbit PWM1_L = P1^1;
sbit PWM2   = P1^2;
sbit PWM2_L = P1^3;
sbit PWM3   = P1^4;
sbit PWM3_L = P1^5;


u8        step;                //切换步骤
u8        PWM_Value;        // 决定PWM占空比的值
bit        B_RUN;                //运行标志
u8        PWW_Set;        //目标PWM设置
u8        YouMen;                //油门
bit        B_direct;        //转向, 0顺时针, 1逆时针
bit        B_4ms;                //4ms定时标志




/*************************/




//========================================================================
// 函数: u16        Get_ADC10bitResult(u8 channel))        //channel = 0~15
//========================================================================
u16        Get_ADC10bitResult(u8 channel)        //channel = 0~15
{
        u8 i;
        ADC_RES = 0;
        ADC_RESL = 0;
        ADC_CONTR = 0x80 | ADC_START | channel;
        NOP(5);                        //
        i = 255;                //超时限制
        while(i != 0)
        {
                i--;
                if((ADC_CONTR & ADC_FLAG) != 0)        break;        //等待ADC结束
        }
        ADC_CONTR &= ~ADC_FLAG;
        return        ((u16)ADC_RES * 256 + (u16)ADC_RESL);
}




void        Delay_500ns(void)
{
        NOP(6);
}


void StepMotor(void) // 换相序列函数
{
        PWMB_IER   = 0;
        PWMB_CCER1 = 0;
        PWMB_CCER2 = 0;


        step = P2 & 0x07;        //P2.0-HALL_A P2.1-HALL_B P2.2-HALL_C
        if(!B_direct)        //顺时针
        {
                switch(step)
                {
                case 2:  // 010, P2.0-HALL_A下降沿  PWM3, PWM2_L=1                //顺时针
                                PWMA_ENO = 0x00;        PWM1_L=0;        PWM3_L=0;
                                Delay_500ns();
                                PWMA_ENO = 0x10;        // 打开C相的高端PWM
                                PWM2_L = 1;                        // 打开B相的低端
                                PWMB_CCER2 = (0x01+0x00);        //P2.2 0x01:允许输入捕获, +0x00:上升沿, +0x02:下降沿
                                PWMB_IER   = 0x08;                        //P2.2 使能中断
                                break;
                case 6:  // 110, P2.2-HALL_C上升沿  PWM3, PWM1_L=1
                                PWMA_ENO = 0x10;        PWM2_L=0;        PWM3_L=0;        // 打开C相的高端PWM
                                Delay_500ns();
                                PWM1_L = 1;                        // 打开A相的低端
                                PWMB_CCER1 = (0x10+0x20);        //P2.1 0x10:允许输入捕获, +0x00:上升沿, +0x20:下降沿
                                PWMB_IER   = 0x04;                        //P2.1 使能中断
                                break;
                case 4:  // 100, P2.1-HALL_B下降沿  PWM2, PWM1_L=1
                                PWMA_ENO = 0x00;        PWM2_L=0;        PWM3_L=0;
                                Delay_500ns();
                                PWMA_ENO = 0x04;        // 打开B相的高端PWM
                                PWM1_L = 1;                        // 打开A相的低端
                                PWMB_CCER1 = (0x01+0x00);        //P2.0 0x01:允许输入捕获, +0x00:上升沿, +0x02:下降沿
                                PWMB_IER   = 0x02;                        //P2.0 使能中断
                                break;
                case 5:  // 101, P2.0-HALL_A上升沿  PWM2, PWM3_L=1
                                PWMA_ENO = 0x04;        PWM1_L=0;        PWM2_L=0;        // 打开B相的高端PWM
                                Delay_500ns();
                                PWM3_L = 1;                        // 打开C相的低端
                                PWMB_CCER2 = (0x01+0x02);        //P2.2 0x01:允许输入捕获, +0x00:上升沿, +0x02:下降沿
                                PWMB_IER   = 0x08;                        //P2.2 使能中断
                                break;
                case 1:  // 001, P2.2-HALL_C下降沿  PWM1, PWM3_L=1
                                PWMA_ENO = 0x00;        PWM1_L=0;        PWM2_L=0;
                                Delay_500ns();
                                PWMA_ENO = 0x01;        // 打开A相的高端PWM
                                PWM3_L = 1;                        // 打开C相的低端
                                PWMB_CCER1 = (0x10+0x00);        //P2.1 0x10:允许输入捕获, +0x00:上升沿, +0x20:下降沿
                                PWMB_IER   = 0x04;                        //P2.1 使能中断
                                break;
                case 3:  // 011, P2.1-HALL_B上升沿  PWM1, PWM2_L=1
                                PWMA_ENO = 0x01;        PWM1_L=0;        PWM3_L=0;        // 打开A相的高端PWM
                                Delay_500ns();
                                PWM2_L = 1;                        // 打开B相的低端
                                PWMB_CCER1 = (0x01+0x02);        //P2.0 0x01:允许输入捕获, +0x00:上升沿, +0x02:下降沿
                                PWMB_IER   = 0x02;                        //P2.0 使能中断
                                break;


                default:
                                break;
                }
        }


        else        //逆时针
        {
                switch(step)
                {
                case 4:  // 100, P2.0-HALL_A下降沿  PWM1, PWM2_L=1                //逆时针
                                PWMA_ENO = 0x00;        PWM1_L=0;        PWM3_L=0;
                                Delay_500ns();
                                PWMA_ENO = 0x01;        // 打开A相的高端PWM
                                PWM2_L = 1;                        // 打开B相的低端
                                PWMB_CCER1 = (0x10+0x00);        //P2.1 0x10:允许输入捕获, +0x00:上升沿, +0x20:下降沿
                                PWMB_IER   = 0x04;                        //P2.1 使能中断
                                break;
                case 6:  // 110, P2.1-HALL_B上升沿  PWM1, PWM3_L=1
                                PWMA_ENO = 0x01;        PWM1_L=0;        PWM2_L=0;        // 打开A相的高端PWM
                                Delay_500ns();
                                PWM3_L = 1;                        // 打开C相的低端
                                PWMB_CCER2 = (0x01+0x02);        //P2.2 0x01:允许输入捕获, +0x00:上升沿, +0x02:下降沿
                                PWMB_IER   = 0x08;                        //P2.2 使能中断
                                break;
                case 2:  // 010, P2.2-HALL_C下降沿  PWM2, PWM3_L=1
                                PWMA_ENO = 0x00;        PWM1_L=0;        PWM2_L=0;
                                Delay_500ns();
                                PWMA_ENO = 0x04;        // 打开B相的高端PWM
                                PWM3_L = 1;                        // 打开C相的低端
                                PWMB_CCER1 = (0x01+0x00);        //P2.0 0x01:允许输入捕获, +0x00:上升沿, +0x02:下降沿
                                PWMB_IER   = 0x02;                        //P2.0 使能中断
                                break;
                case 3:  // 011, P2.0-HALL_A上升沿  PWM2, PWM1_L=1
                                PWMA_ENO = 0x04;        PWM2_L=0;        PWM3_L=0;        // 打开B相的高端PWM
                                Delay_500ns();
                                PWM1_L = 1;                        // 打开A相的低端
                                PWMB_CCER1 = (0x10+0x20);        //P2.1 0x10:允许输入捕获, +0x00:上升沿, +0x20:下降沿
                                PWMB_IER   = 0x04;                        //P2.1 使能中断
                                break;
                case 1:  // 001, P2.1-HALL_B下降沿  PWM3, PWM1_L=1
                                PWMA_ENO = 0x00;        PWM2_L=0;        PWM3_L=0;
                                Delay_500ns();
                                PWMA_ENO = 0x10;        // 打开C相的高端PWM
                                PWM1_L = 1;                        // 打开A相的低端
                                PWMB_CCER2 = (0x01+0x00);        //P2.2 0x01:允许输入捕获, +0x00:上升沿, +0x02:下降沿
                                PWMB_IER   = 0x08;                        //P2.2 使能中断
                                break;
                case 5:  // 101, P2.2-HALL_C上升沿  PWM3, PWM2_L=1
                                PWMA_ENO = 0x10;        PWM1_L=0;        PWM3_L=0;        // 打开C相的高端PWM
                                Delay_500ns();
                                PWM2_L = 1;                        // 打开B相的低端
                                PWMB_CCER1 = (0x01+0x02);        //P2.0 0x01:允许输入捕获, +0x00:上升沿, +0x02:下降沿
                                PWMB_IER   = 0x02;                        //P2.0 使能中断
                                break;
       
                default:
                                break;
                }
        }
}




void PWMA_config(void)
{
        P_SW2 |= 0x80;                //SFR enable   


        PWM1   = 0;
        PWM1_L = 0;
        PWM2   = 0;
        PWM2_L = 0;
        PWM3   = 0;
        PWM3_L = 0;
        P1n_push_pull(0x3f);


        PWMA_PSCR = 3;                // 预分频寄存器, 分频 Fck_cnt = Fck_psc/(PSCR[15:0}+1), 边沿对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)), 中央对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)*2).
        PWMA_DTR  = 24;                // 死区时间配置, n=0~127: DTR= n T,   0x80 ~(0x80+n), n=0~63: DTR=(64+n)*2T,  
                                                //                                0xc0 ~(0xc0+n), n=0~31: DTR=(32+n)*8T,   0xE0 ~(0xE0+n), n=0~31: DTR=(32+n)*16T,
        PWMA_ARR    = 255;        // 自动重装载寄存器,  控制PWM周期
        PWMA_CCER1  = 0;
        PWMA_CCER2  = 0;
        PWMA_SR1    = 0;
        PWMA_SR2    = 0;
        PWMA_ENO    = 0;
        PWMA_PS     = 0;
        PWMA_IER    = 0;
//        PWMA_ISR_En = 0;


        PWMA_CCMR1  = 0x68;                // 通道模式配置, PWM模式1, 预装载允许
        PWMA_CCR1   = 0;                // 比较值, 控制占空比(高电平时钟数)
        PWMA_CCER1 |= 0x05;                // 开启比较输出, 高电平有效
        PWMA_PS    |= 0;                // 选择IO, 0:选择P1.0 P1.1, 1:选择P2.0 P2.1, 2:选择P6.0 P6.1,
//        PWMA_ENO   |= 0x01;                // IO输出允许,  bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,  bit3: ENO2N,  bit2: ENO2P,  bit1: ENO1N,  bit0: ENO1P
//        PWMA_IER   |= 0x02;                // 使能中断


        PWMA_CCMR2  = 0x68;                // 通道模式配置, PWM模式1, 预装载允许
        PWMA_CCR2   = 0;                // 比较值, 控制占空比(高电平时钟数)
        PWMA_CCER1 |= 0x50;                // 开启比较输出, 高电平有效
        PWMA_PS    |= (0<<2);        // 选择IO, 0:选择P1.2 P1.3, 1:选择P2.2 P2.3, 2:选择P6.2 P6.3,
//        PWMA_ENO   |= 0x04;                // IO输出允许,  bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,  bit3: ENO2N,  bit2: ENO2P,  bit1: ENO1N,  bit0: ENO1P
//        PWMA_IER   |= 0x04;                // 使能中断


        PWMA_CCMR3  = 0x68;                // 通道模式配置, PWM模式1, 预装载允许
        PWMA_CCR3   = 0;                // 比较值, 控制占空比(高电平时钟数)
        PWMA_CCER2 |= 0x05;                // 开启比较输出, 高电平有效
        PWMA_PS    |= (0<<4);        // 选择IO, 0:选择P1.4 P1.5, 1:选择P2.4 P2.5, 2:选择P6.4 P6.5,
//        PWMA_ENO   |= 0x10;                // IO输出允许,  bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,  bit3: ENO2N,  bit2: ENO2P,  bit1: ENO1N,  bit0: ENO1P
//        PWMA_IER   |= 0x08;                // 使能中断


        PWMA_BKR    = 0x80;                // 主输出使能 相当于总开关
        PWMA_CR1    = 0x81;                // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,  bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)
        PWMA_EGR    = 0x01;                //产生一次更新事件, 清除计数器和与分频计数器, 装载预分频寄存器的值
//        PWMA_ISR_En = PWMA_IER;        //设置标志允许通道1~4中断处理
}


//        PWMA_PS   = (0<<6)+(0<<4)+(0<<2)+0;        //选择IO, 4项从高到低(从左到右)对应PWM1 PWM2 PWM3 PWM4, 0:选择P1.x, 1:选择P2.x, 2:选择P6.x,
//  PWMA_PS    PWM4N PWM4P    PWM3N PWM3P    PWM2N PWM2P    PWM1N PWM1P
//    00       P1.7  P1.6     P1.5  P1.4     P1.3  P1.2     P1.1  P1.0
//    01       P2.7  P2.6     P2.5  P2.4     P2.3  P2.2     P2.1  P2.0
//    02       P6.7  P6.6     P6.5  P6.4     P6.3  P6.2     P6.1  P6.0
//    03       P3.3  P3.4      --    --       --    --       --    --


//========================================================================
// 函数: void PWMB_config(void)
// 描述: PPWM配置函数。
// 参数: noe.
// 返回: none.
// 版本: V1.0, 2021-5-10
// 备注:
//========================================================================
void PWMB_config(void)
{
        P_SW2 |= 0x80;                //SFR enable   


        PWMB_PSCR = 11;        // 预分频寄存器, 分频 Fck_cnt = Fck_psc/(PSCR[15:0]+1), 边沿对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)), 中央对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)*2).
        PWMB_DTR  = 0;        // 死区时间配置, n=0~127: DTR= n T,   0x80 ~(0x80+n), n=0~63: DTR=(64+n)*2T,  
                                        //                                0xc0 ~(0xc0+n), n=0~31: DTR=(32+n)*8T,   0xE0 ~(0xE0+n), n=0~31: DTR=(32+n)*16T,
        PWMB_CCER1  = 0;
        PWMB_CCER2  = 0;
        PWMB_CR1    = 0;                // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,  bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)
        PWMB_CR2    = 0;
        PWMB_SR1    = 0;
        PWMB_SR2    = 0;
        PWMB_ENO    = 0;        //IO禁止输出PWM,  bit6: ENO8P, bit4: ENO7P,  bit2: ENO5P,  bit0: ENO4P
        PWMB_PS     = 0;
        PWMB_IER    = 0;


        PWMB_CCMR1  = 0x31;                // 通道5模式配置, 配置成输入通道, 8个时钟滤波
//        PWMB_CCER1 |= (0x01+0x02);        // 0x01:允许输入捕获, +0x00:上升沿, +0x02:下降沿
        PWMB_PS    |= 0;                // 选择IO, 0:选择P2.0, 1:选择P1.7, 2:选择P0.0, 3:选择P7.4,
//        PWMB_IER   |= 0x02;                // 使能中断


        PWMB_CCMR2  = 0x31;                // 通道6模式配置, 配置成输入通道, 8个时钟滤波
//        PWMB_CCER1 |= (0x10+0x20);        // 0x10:允许输入捕获, +0x00:上升沿, +0x20:下降沿
        PWMB_PS    |= (0<<2);        // 0:选择P2.1, 1:选择P5.4, 2:选择P0.1, 3:选择P7.5,
//        PWMB_IER   |= 0x04;                // 使能中断


        PWMB_CCMR3  = 0x31;                // 通道7模式配置, 配置成输入通道, 8个时钟滤波
//        PWMB_CCER2 |= (0x01+0x02);        // 0x01:允许输入捕获, +0x00:上升沿, +0x02:下降沿
        PWMB_PS    |= (0<<4);        // 选择IO, 0:选择P2.2, 1:选择P3.3, 2:选择P0.2, 3:选择P7.6,
//        PWMB_IER   |= 0x08;                // 使能中断


        PWMB_EGR    = 0x01;                //产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值
        PWMB_SMCR   = 0x60;
        PWMB_BKR    = 0x00;                //主输出使能 相当于总开关
        PWMB_CR1   |= 0x01;                // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,  bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)


//        P2n_standard(0x07);        //通道5 6 7输出IO设置为准双向口
}


//        PWMB_PS   = (0<<6)+(0<<4)+(0<<2)+0;        //选择IO, 4项从高到低(从左到右)对应PWM8 PWM7 PWM6 PWM5
//  PWMB_PS    PWM8    PWM7    PWM6    PWM5
//    00       P2.3    P2.2    P2.1    P2.0
//    01       P3.4    P3.3    P5.4    P1.7
//    02       P0.3    P0.2    P0.1    P0.0
//    03       P7.7    P7.6    P7.5    P7.4




//========================================================================
// 函数: void PWMB_ISR(void) interrupt PWMB_VECTOR
// 描述: PWMB中断处理程序. 捕获数据通过 TIM1-> CCRnH / TIM1-> CCRnL 读取
// 参数: None
// 返回: none.
// 版本: V1.0, 2021-6-1
//========================================================================
void PWMB_ISR(void) interrupt PWMB_VECTOR
{
        PWMB_SR1 = 0;        //清除中断标志
        PWMB_SR2 = 0;        //清除中断标志


        if(B_RUN)        StepMotor();        //换相
}






void ADC_config(void)        //ADC初始化函数
{
        P1n_pure_input(0xc0);        //P1.7 P1.6设置为高阻输入
        P0n_pure_input(0x0f);        //P0.3~P0.0设置为高阻输入
        ADC_CONTR = 0x80 + 6;        //ADC on + channel
        ADCCFG = RES_FMT + ADC_SPEED;
        P_SW2 |=  0x80;        //访问XSFR
        ADCTIM = CSSETUP + CSHOLD + SMPDUTY;
}




void Timer0_config(void)        //Timer0初始化函数
{
        Timer0_16bitAutoReload(); // T0工作于16位自动重装
        Timer0_12T();
        TH0 = (65536UL-MAIN_Fosc/12 / 250) / 256; //4ms
        TL0 = (65536UL-MAIN_Fosc/12 / 250) % 256;
        TR0 = 1; // 打开定时器0


        ET0 = 1;// 允许ET0中断
}


void Timer0_ISR(void) interrupt 1        //Timer0中断函数
{
        B_4ms = 1;        //4ms定时标志
//        if(B_RUN)        StepMotor();        //换相, 增加定时器里换相可以保证启动成功.
}




/**********************************************/
void main(void)
{
        P2n_standard(0xf8);
        P3n_standard(0xbf);
        P5n_standard(0x10);
       
       
        PWMA_config();
        PWMB_config();
        ADC_config();
        Timer0_config();        //Timer0初始化函数
        PWW_Set = 0;


        EA  = 1; // 打开总中断


        while (1)
        {
                if(B_4ms)                // 4ms时隙
                {
                        B_4ms = 0;


                        YouMen  = (u8)(Get_ADC10bitResult(11) >> 2);        //油门是8位的, P0.3 ADC11-->控制电位器输入
                        if(YouMen >= 128)        PWW_Set = YouMen - 128, B_direct = 0;        //顺时针
                        else                                PWW_Set = 127 - YouMen, B_direct = 1;        //逆时针
                        PWW_Set *= 2;        //PWM设置值0~254


                        if(!B_RUN && (PWW_Set >= 30))                // PWM_Set >= 30, 并且电机未运行, 则启动电机
                        {
                                PWM_Value = 30;                        //启动电机的最低PWM, 根据具体电机而定
                                PWMA_CCR1L = PWM_Value;        //输出PWM
                                PWMA_CCR2L = PWM_Value;
                                PWMA_CCR3L = PWM_Value;
                                B_RUN = 1;                //标注运行
                                StepMotor();        //启动换相
                        }


                        if(B_RUN)        //正在运行中
                        {
                                if(PWM_Value < PWW_Set)        PWM_Value++;        //油门跟随电位器, 调速柔和
                                if(PWM_Value > PWW_Set)        PWM_Value--;
                                if(PWM_Value < 20)        // 停转
                                {
                                        B_RUN = 0;
                                        PWMB_IER   = 0;
                                        PWMB_CCER1 = 0;
                                        PWMB_CCER2 = 0;
                                        PWM_Value = 0;
                                        PWMA_ENO  = 0;
                                        PWMA_CCR1L = 0;
                                        PWMA_CCR2L = 0;
                                        PWMA_CCR3L = 0;
                                        PWM1_L=0;
                                        PWM2_L=0;
                                        PWM3_L=0;
                                }
                                else
                                {
                                        PWMA_CCR1L = PWM_Value;
                                        PWMA_CCR2L = PWM_Value;
                                        PWMA_CCR3L = PWM_Value;
                                }
                        }
                }


        }
}






回复 支持 反对

使用道具 举报

发表于 2024-4-27 11:10:40 | 显示全部楼层

硬件也一并开源:
image.png
回复 支持 反对

使用道具 举报

发表于 2024-4-27 13:26:15 | 显示全部楼层
ling11052001 发表于 2024-4-26 17:57
无刷电机改风扇是不是很静音,一直想搞一台的,就是看电机成本有点高 ...

静音那是肯定的并且运转很稳定,调速简单且范围大还线性好得很.我买了个无刷电机做了一个简易风扇没有做罩壳,很担心高速运转时扇叶飞出来,使用CH32V003提供PWM控制用鼠标中滚轮编码器.
回复 支持 反对

使用道具 举报

发表于 2024-4-27 13:45:52 | 显示全部楼层
看见就想起了应该再去薅一个几十的无刷风扇

打赏

参与人数 1家元 +30 收起 理由
ljlun + 30 熱心會員

查看全部打赏

回复 支持 反对

使用道具 举报

发表于 2024-4-27 21:27:30 来自手机浏览器 | 显示全部楼层
都是高手,收藏备用
回复 支持 反对

使用道具 举报

发表于 2024-4-27 21:47:37 | 显示全部楼层
ling11052001 发表于 2024-4-26 17:57
无刷电机改风扇是不是很静音,一直想搞一台的,就是看电机成本有点高 ...

卖了个无刷的风扇,风量可以调的比较小,不过似乎用不到风扇,都是空调了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-4-28 08:38:04 | 显示全部楼层
邪恶海盗 发表于 2024-4-26 18:03
围观会画板的大佬...

--------------------

瞎画的,电路板的设计规则都没有看过。如果复杂点的就抓瞎了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-4-28 08:40:56 | 显示全部楼层
jbm1 发表于 2024-4-26 19:36
强势围观大神制作

离高手  差十万八千里的,我就是一电子业余爱好者
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-5-8 03:55 , Processed in 0.280801 second(s), 15 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

快速回复 返回顶部 返回列表