zoukankan      html  css  js  c++  java
  • 利用WinCE的精准计时函数来输出pwm信号以便控制舵机

    FL2440的板子只有TOUT0和TOUT1引出了扩展管脚,而TOUT0与GPB0复用,GPB0又连接着蜂鸣器,所以一用TOUT0输出pwm信号蜂鸣器就大叫不止,而TOUT1又因为Wince系统使用Timer1作为系统定时器,所以在Wince下用TOUT1输出pwm信号会马上死机。

    本打算用定时器的中断函数来输出pwm信号,但是感觉WinCE封装ADS下的__irq函数很难搞,无意中发现WinCE有比较精准的计时函数,决定干脆用这个来做pwm信号以便控制舵机。

    关键代码:

    需要头文件:

    #include "ceddk.h"
    #include "pkfuncs.h"
    #include "Windows.h"
    #include "Winbase.h"

    1、ms级精准延时函数accurateDelay_ms(),主要知识点有LARGE_INTEGER数据类型,QueryPerformanceFrequency()函数来计算计数频率,QueryPerformanceCounter来计算起始计数和终止计数,起始计数与终止计数的差就是过程中产生了多少计数,再用这个过程计数除以计数频率,就是过程消耗的时间,这个时间比较灵活,用0.01进行因子计算就是ms级,用0.00001计算就是微秒级。输入参数n来决定延时n毫秒。

    BOOL accurateDelay_ms(double n) //ms级的精确延时函数
    {
        LARGE_INTEGER litmp;
        LONGLONG QPart1,QPart2;
        double dfFreq,dfMinus,dfTim;
    
        QueryPerformanceFrequency(&litmp);
        dfFreq = (double)litmp.QuadPart;//获得计数器的时钟频率
        QueryPerformanceCounter(&litmp);
        QPart1 = litmp.QuadPart;//获得当前初始值
        do
        {
            QueryPerformanceCounter(&litmp);
            QPart2 = litmp.QuadPart;//获得终止值
            dfMinus = (double)(QPart2-QPart1);
            dfTim = dfMinus/dfFreq;
        }while(dfTim<0.01*n);
        return TRUE;
    }

    2、PWM信号产生函数:

    功能:先逆时针旋转180度,然后顺时针旋转360度,再逆时针旋转180度回到起始位置。

    通过int型变量duojiCnt来控制舵机转到哪个角度,通过每个while函数的第一个accurateDelay()来控制旋转的方向,每个while函数的第二个accurateDelay()来控制旋转快慢,delay()函数是个软件延时函数,delay(200)是为了保证舵机每一次都有充分的时间完成旋转。

        duojiCnt = 11;
        while(duojiCnt > 0)
        {
            v_IOPregs->rGPBDAT |= 1<<6;
            accurateDelay_ms(0.1);
            v_IOPregs->rGPBDAT &= ~(1<<6);
            accurateDelay_ms(10);
            duojiCnt--;
        }
        delay(200);
        duojiCnt = 22;
        while(duojiCnt > 0)
        {
            v_IOPregs->rGPBDAT |= 1<<6;
            accurateDelay_ms(0.4);
            v_IOPregs->rGPBDAT &= ~(1<<6);
            accurateDelay_ms(10);
            duojiCnt--;
        }
        delay(200);
        duojiCnt = 12;
        while(duojiCnt > 0)
        {
            v_IOPregs->rGPBDAT |= 1<<6;
            accurateDelay_ms(0.1);
            v_IOPregs->rGPBDAT &= ~(1<<6);
            accurateDelay_ms(10);
            duojiCnt--;
        }
        delay(200);
  • 相关阅读:
    PHP实现邮件的自动发送
    为PostgreSQL的表自动添加分区
    django
    django的logging模块
    job
    python 类的方法带的self理解
    java
    choice_set的理解
    django
    proxy_next_upstream带来的坑和加载sticky模块
  • 原文地址:https://www.cnblogs.com/wuqi1003/p/3145428.html
Copyright © 2011-2022 走看看