找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2478|回复: 0
打印 上一主题 下一主题
收起左侧

我的第一次声音定位之旅 广义互相关算法 附MCU源程序

[复制链接]
跳转到指定楼层
楼主
大二暑假的时候做了一次声音定位项目,做成了一个声音导向仪,在德州仪器的TI单片机上实现,运用了广义互相关的算法,简单地寻找了四个方向的角度,并用控制舵机来旋转。

纪念一下。

制作出来的实物图如下:


使用的M4核tm4c1294ncpdt芯片

单片机源程序如下:
  1. #include <stdbool.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include "inc/hw_memmap.h"
  6. #include "inc/hw_types.h"
  7. #include "inc/hw_gpio.h"
  8. #include "inc/tm4c1294ncpdt.h"
  9. #include "inc/hw_epi.h"
  10. //#include "inc/hw_ints.h"         //和"inc/tm4c1294ncpdt.h"里面的宏定义重复了
  11. #include "driverlib/epi.h"
  12. #include "driverlib/gpio.h"
  13. #include "driverlib/sysctl.h"
  14. #include "driverlib/rom.h"
  15. #include "driverlib/rom_map.h"
  16. #include "driverlib/pin_map.h"
  17. #include "driverlib/pwm.h"
  18. #include "driverlib/systick.h"
  19. #include "driverlib/interrupt.h"
  20. #include "driverlib/ssi.h"
  21. #include "driverlib/fpu.h"
  22. #include "driverlib/adc.h"
  23. #include "utils/uartstdio.h"
  24. #include "TFTinit/TFT_400x240_OTM4001A_16bit.h"
  25. //#include "TFTinit/picture.h"
  26. #include "TOUCHinit/TOUCH_TSC2046.h"
  27. #include "EPIinit/EPIinit.h"

  28. //Todo
  29. #include  "math.h"
  30. #include "driverlib/timer.h"
  31. #include "utils/uartstdio.h"

  32. //Todo
  33. /*项目分类*/
  34. typedef enum{
  35.         noun,//空
  36.         return_main,//返回
  37.         pj1,//显示时钟
  38.         pj2,//音乐播放器
  39.         pj3,//声音定位
  40.         wrong,//错误选择,
  41. } Project;

  42. /*自定义变量*/
  43. //Todo
  44. #define _NOP() _nop()
  45. #define SLAVE_ADDRESS_W 0x3A //写ADXL345L时的从机地址
  46. #define SLAVE_ADDRESS_R 0x3B //读ADXL345L时的从机地址

  47. double tem,tem_tmp;//温度(*100)
  48. Project choose_pj = noun;

  49. volatile uint32_t show_flag=0;//是否显示了时钟
  50. volatile uint32_t start_flag=0;//是否进入主页


  51. volatile uint32_t musicplay_once=0,musicplay_rotate=0;//单次演奏和循环演奏
  52. volatile uint32_t time = 0,time1=0,time2=0;;//时间
  53. volatile uint32_t mg[3]={0x00,0x00,0x00};
  54. volatile uint32_t touch_cnt=0;
  55. #define touch_cnt_max 5
  56. uint32_t page=1;
  57. uint32_t array_num;

  58. //*****************************************************************************
  59. //
  60. // System clock rate in Hz.
  61. //
  62. //*****************************************************************************
  63. uint32_t g_ui32SysClock;

  64. extern uint32_t GetData[21];

  65. uint32_t TouchXData[21];
  66. uint32_t TouchYData[21];

  67. //Todo
  68. /*舵机初始化*/
  69. void ServoInit()//对所有PWM generator进行初始化
  70. {
  71.             SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);//PWM0模块使能

  72.             SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);//GPIOF模块使能

  73.             GPIOPinConfigure(GPIO_PF1_M0PWM1);//设置引脚复用功能为PWM
  74. //            GPIOPinConfigure(GPIO_PK4_M0PWM6);
  75. //            GPIOPinConfigure(GPIO_PK5_M0PWM7);

  76.             GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1);//配置相应引脚用于PWM功能
  77. //            GPIOPinTypePWM(GPIO_PORTK_BASE, GPIO_PIN_4);//外扩引脚
  78. //            GPIOPinTypePWM(GPIO_PORTK_BASE, GPIO_PIN_5);

  79.              PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN |PWM_GEN_MODE_NO_SYNC);//配置PWM发生器为减计数、立即更新方式
  80.              PWMGenConfigure(PWM0_BASE, PWM_GEN_1, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
  81. //             PWMGenConfigure(PWM0_BASE, PWM_GEN_2, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
  82. //             PWMGenConfigure(PWM0_BASE, PWM_GEN_3, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);

  83.               PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, 60000);//配置PWM工作频率为120MHz/8/120000=125Hz
  84. //              PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, 120000);
  85. //              PWMGenPeriodSet(PWM0_BASE, PWM_GEN_2, 50000);
  86. //              PWMGenPeriodSet(PWM0_BASE, PWM_GEN_3, 50000);
  87.               PWM0_CC_R = PWM_CC_USEPWM | PWM_CC_PWMDIV_8;

  88.             PWMOutputState( PWM0_BASE, PWM_OUT_1_BIT, true);
  89.             //PWMOutputState(PWM0_BASE, PWM_OUT_1_BIT | PWM_OUT_2_BIT | PWM_OUT_3_BIT, true);//使能PWM输出信号
  90.             //PWMOutputState(PWM0_BASE, PWM_OUT_4_BIT | PWM_OUT_5_BIT | PWM_OUT_6_BIT, true);//使能PWM输出信号

  91.             PWMGenEnable(PWM0_BASE, PWM_GEN_0);//使能相应PWN发生器模块
  92. //            PWMGenEnable(PWM0_BASE, PWM_GEN_1);
  93. //            PWMGenEnable(PWM0_BASE, PWM_GEN_2);
  94. //            PWMGenEnable(PWM0_BASE, PWM_GEN_3);
  95. }

  96. //Todo
  97. //声音定位

  98. /** * adc采集数据长度 */
  99. #define ADC_DATA_LEN    2048
  100. /* * adc采集完成标志位 */
  101. volatile uint8_t  AdcFinishFlag = 0;
  102. /* * adc双buff缓冲区  缓冲完成的区域序号 */
  103. volatile uint8_t  AdcBuffIndex = 0;
  104. /** adc数组下标 */
  105. volatile uint32_t adcCount = 0;

  106. /* * ADC数据   adc0 1 2 3 采集麦克风信号
  107. *
  108. *     2     1
  109. *
  110. *     3     0    */
  111. __attribute__ ((aligned(256)))  volatile int16_t g_adc0Data[2][ADC_DATA_LEN];
  112. __attribute__ ((aligned(256)))  volatile int16_t g_adc1Data[2][ADC_DATA_LEN];
  113. __attribute__ ((aligned(256)))  volatile int16_t g_adc2Data[2][ADC_DATA_LEN];
  114. //__attribute__ ((aligned(256)))  volatile int16_t g_adc3Data[2][ADC_DATA_LEN];

  115. /* * 互相关结果 */
  116. float g_acor1[2][30];
  117. float g_acor2[2][30];
  118. //float g_acor3[2][30];
  119. //float g_acor4[2][30];

  120. /* * 声音角度 */
  121. float g_Angle   = 0;
  122. /* * ADC数据   adc0 1 2 3 采集麦克风信号
  123. *
  124. *     2     1
  125. *
  126. *     3     0
  127. *
  128. *    PD2    PB5
  129. *
  130. *   (PK1)    PB4
  131. *     */
  132. //引脚对应通道、通道连接采样序列、采样序列使能
  133. void VoiceInit(void)
  134. {
  135.         // 初始化ADC0/       初始化PB4、PB5为TypeADC
  136.         SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
  137.         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
  138.         GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_4);
  139.         GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_5);
  140.         // 初始化ADC1/      初始化PK0、PK1TypeADC
  141.         SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
  142.         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
  143.         GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_2);
  144. //        GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_1);

  145.     // 配置ADC0的采集序列2给PB4        //配置ADC0采样序列2的步骤0,PB4的模拟通道是AIN10(ADC_CTL_CH10)
  146.         ADCSequenceConfigure(ADC0_BASE, 2, ADC_TRIGGER_PROCESSOR, 0);
  147.         ADCSequenceStepConfigure(ADC0_BASE, 2, 0, ADC_CTL_CH10 | ADC_CTL_END | ADC_CTL_IE);

  148.         //配置ADC0的采集序列1给PB5        //配置ADC0采样序列1的步骤0,PB5的模拟通道是AIN11(ADC_CTL_CH11)
  149.         ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
  150.         ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH11 | ADC_CTL_END | ADC_CTL_IE);
  151. //
  152. //    // 配置ADC1的采集序列2给PD2        //配置ADC1采样序列2的步骤0,PK0的模拟通道是AIN13(ADC_CTL_CH13)
  153.         ADCSequenceConfigure(ADC1_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
  154.         ADCSequenceStepConfigure(ADC1_BASE, 0, 0, ADC_CTL_CH13 | ADC_CTL_END | ADC_CTL_IE);

  155. //        //配置ADC0的采集序列1给PK1        //配置ADC1的采样序列1的步骤0,PK1的模拟通道是AIN17(ADC_CTL_CH17)
  156. //        ADCSequenceConfigure(ADC1_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
  157. //        ADCSequenceStepConfigure(ADC1_BASE, 1, 0, ADC_CTL_CH17 | ADC_CTL_END | ADC_CTL_IE);

  158.         // 使能ADC采集序列   //清中断
  159.         ADCSequenceEnable(ADC0_BASE, 2);
  160.         ADCSequenceEnable(ADC0_BASE, 1);
  161.         ADCSequenceEnable(ADC1_BASE, 0);
  162. //        ADCSequenceEnable(ADC1_BASE, 1);

  163.         ADCIntClear(ADC0_BASE, 2);
  164.         ADCIntClear(ADC0_BASE, 1);
  165.         ADCIntClear(ADC1_BASE, 0);
  166. //        ADCIntClear(ADC1_BASE, 1);

  167. //        CCU6_InitConfig(CCU60, CCU6_Channel0, 100);  //100us进入一次中断  中断中采集adc数据

  168. }

  169. /*!  * @brief   采集中断服务函数   声音信号采集  * @date     2020/4/28  */
  170. void VoiceGetSample(void)
  171. {
  172.         static uint8_t adcIndex = 0;
  173.         if(adcCount >= ADC_DATA_LEN)
  174.         {
  175.                 adcCount = 0;
  176.                 AdcFinishFlag = 1;
  177.                 /* 切换buff缓冲区 */
  178.                 if(adcIndex == 0)
  179.                 {
  180.                         adcIndex = 1;
  181.                         AdcBuffIndex = 0;
  182.                 }
  183.                 else
  184.                 {
  185.                         adcIndex = 0;
  186.                         AdcBuffIndex = 1;
  187.                 }
  188.         }

  189.         // 触发采集
  190.         ADCProcessorTrigger(ADC0_BASE, 2);
  191.         ADCProcessorTrigger(ADC0_BASE, 1);
  192.         ADCProcessorTrigger(ADC1_BASE, 0);
  193. //        ADCProcessorTrigger(ADC1_BASE, 1);
  194.         // 等待采集结束  // 获取采集结果
  195.         while(!ADCIntStatus(ADC0_BASE, 2, false)) ;
  196.         ADCSequenceDataGet(ADC0_BASE, 2, &g_adc0Data[adcIndex][adcCount]);

  197.         while(!ADCIntStatus(ADC0_BASE, 1, false)) ;
  198.         ADCSequenceDataGet(ADC0_BASE, 1, &g_adc1Data[adcIndex][adcCount]);

  199.         while(!ADCIntStatus(ADC1_BASE, 0, false)) ;
  200.         ADCSequenceDataGet(ADC1_BASE, 0, &g_adc2Data[adcIndex][adcCount]);
  201. //
  202. //        while(!ADCIntStatus(ADC1_BASE, 1, false)) ;
  203. //        ADCSequenceDataGet(ADC1_BASE, 1, &g_adc3Data[adcIndex][adcCount]);

  204.         adcCount++;
  205. }
  206. /*!
  207.   * @brief        归一化处理
  208.   *
  209.   * @param    x   : 要处理数据
  210.   * @param    len : 要处理数据长度
  211.   * @date     2020/4/28
  212.   */
  213. void Normal(int16_t *x, uint16_t len)
  214. {
  215.         float sum = 0;
  216.         int   i;
  217.         for(i = 0; i < len; i++)
  218.         {
  219.                 sum += x[i];
  220.         }
  221.         sum = sum / len;
  222.         for(i = 0; i < len; i++)
  223.         {
  224.                 x[i] -= sum;
  225.         }
  226. }
  227. /*!
  228.   * @brief         互相关
  229.   *
  230.   * @param    acor1:  y0 y1 互相关结果
  231.   * @param    acor2:  y1 y2互相关结果
  232.   * @param    acor3:  y0 y2互相关结果
  233.   * @param    acor4:  y1 y3互相关结果
  234.   * @param    y0   : 互相关数据 y0
  235.   * @param    y1   : 互相关数据 y1
  236.   * @param    y2   : 互相关数据 y2
  237.   * @param    y3   : 互相关数据 y3
  238.   * @param    len  : 互相关数据长度
  239.   * @date     2020/4/28
  240.   */
  241. //void Xcorr(float *acor1, float *acor2, float *acor3, float *acor4, int16_t *y0, int16_t *y1, int16_t *y2, int16_t *y3, uint16_t len)
  242. void Xcorr(float *acor1, float *acor2, int16_t *y0, int16_t *y1, int16_t *y2,  uint16_t len)
  243. {
  244. //        float sum3 = 0;
  245. //        float sum4 = 0;
  246.         float sum1 = 0;
  247.         float sum2 = 0;
  248.         int delay, i, j;
  249.         for(delay = -15; delay < 15; delay++)              //30个互相关的值
  250. //        for(delay = -len + 1; delay < len; delay++)       //len个互相关的值
  251.         {
  252.                 sum1 = 0;
  253.                 sum2 = 0;
  254. //                sum3 = 0;
  255. //                sum4 = 0;
  256.                 for(i = 0; i < len; i++)
  257.                 {
  258.                         j = i + delay;
  259.                         if((j < 0))
  260.                         {
  261.                                 sum1 += 0.0001f * y0[j + len] * y1[i];     //缩小一定倍数,防止溢出
  262.                                 sum2 += 0.0001f * y1[j + len] * y2[i];
  263. //                                sum3 += 0.0001f * y0[j + len] * y2[i];
  264. //                                sum4 += 0.0001f * y1[j + len] * y3[i];
  265.                         }
  266.                         else if ((j >= len))
  267.                         {
  268.                                 sum1 += 0.0001f * y0[j - len] * y1[i];
  269.                                 sum2 += 0.0001f * y1[j - len] * y2[i];
  270. //                                sum3 += 0.0001f * y0[j - len] * y2[i];
  271. //                                sum4 += 0.0001f * y1[j - len] * y3[i];
  272.                         }
  273.                         else
  274.                         {
  275.                                 sum1 += 0.0001f * y0[j] * y1[i];
  276.                                 sum2 += 0.0001f * y1[j] * y2[i];
  277. //                                sum3 += 0.0001f * y0[j] * y2[i];
  278. //                                sum4 += 0.0001f * y1[j] * y3[i];
  279.                         }
  280.                 }
  281.                 acor1[15 + delay] = (float)sum1;
  282.                 acor2[15 + delay] = (float)sum2;
  283. //                acor3[15 + delay] = (float)sum3;
  284. //                acor4[15 + delay] = (float)sum4;
  285.         }
  286. }



  287. /*!
  288.   * @brief    得到最大相关位置
  289.   *
  290.   * @param    acor1: 互相关结果
  291.   * @param    acor2: 互相关结果
  292.   * @param    acor3: 互相关结果
  293.   * @param    acor4: 互相关结果
  294.   * @param    len  : 数据长度  (与delay 对应)
  295.   * @param    index: 存放相关结果最大值下标
  296.   * @date     2020/4/28
  297.   */
  298. void SeekMaxAcor(float * acor1, float * acor2, int16_t len, int16_t *index)
  299. {
  300.         int16_t i = 0;

  301.         index[0] = 0;
  302.         index[1] = 0;
  303. //        index[2] = 0;
  304. //        index[3] = 0;
  305.         for(i = 1; i < len; i++)
  306.         {
  307.                 if(acor1[i] > acor1[index[0]])
  308.                 {
  309.                         index[0] = i;
  310.                 }
  311.                 if(acor2[i] > acor2[index[1]])
  312.                 {
  313.                         index[1] = i;
  314.                 }
  315. //                if(acor3[i] > acor3[index[2]])
  316. //                {
  317. //                        index[2] = i;
  318. //                }
  319. //                if(acor4[i] > acor4[index[3]])
  320. //                {
  321. //                        index[3] = i;
  322. //                }
  323.         }

  324.         index[0] = len/2 - index[0];                  //下标结果变成负数的关键!
  325.         index[1] = len/2 - index[1];
  326. //        index[2] = len/2 - index[2];
  327. //        index[3] = len/2 - index[3];
  328. }
  329. /*!
  330.   * @brief    麦克风数据处理  获取角度信息
  331.   *
  332.   * @param    无
  333.   *
  334.   * @return   最大相关位置
  335.   *
  336.   * @note     无
  337.   *
  338.   * @see
  339.   *
  340.   * @date     2020/4/28
  341.   */
  342. void VoiceProcess(void)
  343. {
  344. //        if(AdcFinishFlag)
  345. //        {
  346. //                /* 数据处理    */
  347. //                Normal((int16_t *)g_adc0Data[AdcBuffIndex], ADC_DATA_LEN);
  348. //                Normal((int16_t *)g_adc1Data[AdcBuffIndex], ADC_DATA_LEN);
  349. //                Normal((int16_t *)g_adc2Data[AdcBuffIndex], ADC_DATA_LEN);
  350. //                Normal((int16_t *)g_adc3Data[AdcBuffIndex], ADC_DATA_LEN);
  351. //
  352. //                for(int i = 0; i < ADC_DATA_LEN; i ++)
  353. //                {
  354. //          /* 上报匿名上位机  看原始数据波形 */
  355. //                        ANO_DT_send_int16(g_adc0Data[AdcBuffIndex][i], g_adc1Data[AdcBuffIndex][i], g_adc2Data[AdcBuffIndex][i], g_adc3Data[AdcBuffIndex][i], 0, 0, 0, 0);
  356. //                }
  357. //
  358. //                AdcFinishFlag = 0;
  359. //        }
  360.         if(AdcFinishFlag)
  361.         {
  362.                 //存放相关峰值下标
  363.                 int16_t acorIndex[4];
  364.                 // 记录时间
  365. //                uint32_t nowTime = STM_GetNowUs(STM0);
  366.                 // 数据处理
  367.                 Normal((int16_t *)g_adc0Data[AdcBuffIndex], ADC_DATA_LEN);
  368.                 Normal((int16_t *)g_adc1Data[AdcBuffIndex], ADC_DATA_LEN);
  369.                 Normal((int16_t *)g_adc2Data[AdcBuffIndex], ADC_DATA_LEN);
  370. //                Normal((int16_t *)g_adc3Data[AdcBuffIndex], ADC_DATA_LEN);
  371.                 // 互相关
  372.         Xcorr((float *)&g_acor1[AdcBuffIndex], (float *)&g_acor2[AdcBuffIndex], (int16_t *)&g_adc0Data[AdcBuffIndex], (int16_t *)&g_adc1Data[AdcBuffIndex], (int16_t *)&g_adc2Data[AdcBuffIndex], ADC_DATA_LEN);
  373.         //  g_acor1:  麦克风0 麦克风1 互相关结果
  374.         //  g_acor2:  麦克风1 麦克风2 互相关结果

  375.                 // 获取最大相关峰值
  376.                 SeekMaxAcor((float *)&g_acor1[AdcBuffIndex], (float *)&g_acor2[AdcBuffIndex], 30, acorIndex);
  377.                 //acorIndex[0]存放g_acor1峰值的下标
  378.                 //acorIndex[1]存放g_acor1峰值的下标
  379.                 //acorIndex[2]存放g_acor1峰值的下标
  380.                 //acorIndex[3]存放g_acor1峰值的下标
  381. //                pidVoice_error=acorIndex[1];//下标偏差

  382.                 // 四组相关数据 最大最小结果下标
  383.                 uint8_t IndexMax = 0, IndexMin = 0;

  384.                 //找到绝对值最小和最大的值下标
  385.                 uint8_t i = 0;
  386.                 for(i = 1; i < 2; i++)
  387.                 {
  388.                         if(abs(acorIndex[i]) >= abs(acorIndex[IndexMax]))    //绝对值最小
  389.                         {
  390.                                 IndexMax = i;
  391.                         }
  392.                         if(abs(acorIndex[i]) <= abs(acorIndex[IndexMin]))
  393.                         {
  394.                                 IndexMin = i;
  395.                         }
  396.                 }
  397.                 // 判断大致方位
  398.                 if(IndexMin == 0)
  399.                 {
  400.                         if(acorIndex[1] > 0)
  401.                         {g_Angle = 0;}
  402.                         else
  403.                         {g_Angle = 180;}
  404.                 }

  405.                 else if(IndexMin == 1)
  406.                 {
  407.                         if(acorIndex[0] > 0)
  408.                         {g_Angle = 270 ;}
  409.                         else
  410.                         {g_Angle = 90;}
  411.                 }

  412. //                else if(IndexMin == 2)
  413. //                {
  414. //                        if(acorIndex[3] > 0)
  415. //                        {g_Angle = 45;}
  416. //                        else
  417. //                        {g_Angle =225;}
  418. //                }
  419. //
  420. //                else if(IndexMin == 3)
  421. //                {
  422. //                        if(acorIndex[2] > 0)
  423. //                        {g_Angle =315;}
  424. //                        else
  425. //                        {g_Angle=135;}
  426. //                }

  427. //                nowTime = STM_GetNowUs(STM0) - nowTime;
  428. //                VoiceCalculatorTime=nowTime;
  429. //                TFTLCD_ShowData(138,90,(int)g_Angle,WHITE,BLACK);//
  430.                 AdcFinishFlag = 0;
  431.         }
  432. }

  433. /****用于声音采集,0.1ms一次****/
  434. void Timer2BIntHandler()
  435. {
  436.         unsigned long Status;
  437.         TimerDisable(TIMER2_BASE, TIMER_B);
  438.         Status=TimerIntStatus(TIMER2_BASE,true);

  439.         if(Status==TIMER_TIMB_TIMEOUT)
  440.         {
  441.                 VoiceGetSample();
  442.         }
  443.         TimerIntClear(TIMER2_BASE, Status);//计时清零
  444.         TimerLoadSet(TIMER2_BASE, TIMER_B, 0.1*g_ui32SysClock/1000);//控制计时器的计时长度100us,0.1ms
  445.         TimerEnable(TIMER2_BASE, TIMER_B);//定时器使能
  446. }



  447. void Timer3BIntHandler()
  448. {
  449.         unsigned long Status;
  450.         TimerDisable(TIMER3_BASE, TIMER_B);
  451.         Status=TimerIntStatus(TIMER3_BASE,true);

  452.         if(Status==TIMER_TIMB_TIMEOUT)
  453.         {
  454.                 if(g_Angle==0)
  455.                 {
  456.                         PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1,7500);
  457.                         PWMPulseWidthSet(PWM0_BASE, PWM_OUT_1,36500);
  458. ……………………

  459. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有代码51hei提供下载:
Final最终版本工程.rar (334.72 KB, 下载次数: 35)

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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