[开发板] CW32L010F8P6根据光强数据驱动42步进电机

[复制链接]
 楼主| suncat0504 发表于 2024-11-26 14:57 | 显示全部楼层 |阅读模式
本帖最后由 suncat0504 于 2024-11-26 15:02 编辑

前次完成了对I2C接口的BH1750的数据访问,以此为基础利用采集到的光强数据作为阈值条件驱动42步进电机。步进电机与螺杆联动,驱动诸如窗帘这样的机构。42步进电机的驱动采用比较简单的时序。

4相5线步进电机 28YBJ-48
图片1.png

电机使用4根驱动口线
正向驱动时,使用0x01,0x02,0x0,,0x08顺序,利用B0~B3驱动,反相驱动时,以相反的顺序驱动即可。由于是减速的,减速比为1/64,再加上联动螺杆的螺纹间距比较小,所以实际运行起来,正反转带动的螺杆上的行进部件走行会显得很慢。
为了实现步进方式的控制,在参考ATIM的例程的基础上,在原有的程序中加入了定时器ATIM的中断处理,利用定时器的定时周期作为步进电机步进脉冲时间间隔。如果这个时间周期不合适,是无法让步进电机运转起来的。经过尝试,按照以下配置可以让电机实现正反转。
1、系统时钟设置为16MHz。
2、设置ATIM的时钟为80分频,计数模式,计数值>=390即可,数值越大,速度越慢。
在定时器的中断处理中,根据光强情况,依次按照固定的定时周期向步进电机发送步进时序脉冲,从而实现电机的正反转。
在实际测试中,使用PA03、PA04、PB02、PB03作为驱动口,通过ULN2003驱动步进电机。原本是打算用PB0、PB1、PB02、PB03的,但不知为什么PB0、PB1无法作为独立的输出口使用。
整个装置是自己手工制作的,没啥欣赏性,只能作为参考、演示用。
图片2.png
装置中没有设置限位点(设置限位点需要额外追加位置传感器,并提供对应的GPIO输入口),所以把移动点的初始设置设置在螺杆的中心点,许可最大进步数为12000。BH1750光强传感器非常灵敏,虽然同样是在窗户附近,在冬日的上、下午时采集到的数据会有非常明显的变化。
下面是在光强的检测结果在设置的阈值点发生变化时,步进电机的正反转情况。
3.gif 4.gif
以下是主程序代码,也很简单。
  1. #include "main.h"
  2. #include "oled.h"

  3. #define I2C_BH1750ADDR        0x46

  4. #define  I2C1_SCL_GPIO_PORT       CW_GPIOA
  5. #define  I2C1_SCL_GPIO_PIN        GPIO_PIN_6    //如果改动口线则GPIO初始化代码需要做同步修改
  6. #define  I2C1_SDA_GPIO_PORT       CW_GPIOA
  7. #define  I2C1_SDA_GPIO_PIN        GPIO_PIN_5   //如果改动口线则GPIO初始化代码需要做同步修改

  8. //UARTx
  9. #define  DEBUG_UARTx                   CW_UART2
  10. #define  DEBUG_UART_CLK                SYSCTRL_APB1_PERIPH_UART2
  11. #define  DEBUG_UART_APBClkENx          SYSCTRL_APBPeriphClk_Enable1
  12. #define  DEBUG_UART_BaudRate           115200
  13. #define  DEBUG_UART_UclkFreq           16000000

  14. //UARTx GPIO
  15. #define  DEBUG_UART_GPIO_CLK           (SYSCTRL_AHB_PERIPH_GPIOB)
  16. #define  DEBUG_UART_TX_GPIO_PORT       CW_GPIOB
  17. #define  DEBUG_UART_TX_GPIO_PIN        GPIO_PIN_5
  18. #define  DEBUG_UART_RX_GPIO_PORT       CW_GPIOB
  19. #define  DEBUG_UART_RX_GPIO_PIN        GPIO_PIN_6

  20. //GPIO AF
  21. #define  DEBUG_UART_AFTX               PB05_AFx_UART2TXD()
  22. #define  DEBUG_UART_AFRX               PB06_AFx_UART2RXD()

  23. #define MAX_LIGHT1 150
  24. #define MAX_LIGHT2 150
  25. #define MAX_LIGHT 100

  26. //// LED用GPIO
  27. //#define LED_GPIO_PORT CW_GPIOB
  28. //#define LED_GPIO_PINS GPIO_PIN_2

  29. // 驱动步进马达的接口:PB00,PB01,PB02,PB03
  30. #define MOTOR_GPIO_PORT1 CW_GPIOA
  31. #define MOTOR_GPIO_PIN0 GPIO_PIN_3
  32. #define MOTOR_GPIO_PIN1 GPIO_PIN_4

  33. #define MOTOR_GPIO_PORT2 CW_GPIOB
  34. #define MOTOR_GPIO_PIN2 GPIO_PIN_2
  35. #define MOTOR_GPIO_PIN3 GPIO_PIN_3

  36. // 按钮Key:PB4,PA6
  37. #define KEY1_GPIO_PORT CW_GPIOB
  38. #define KEY1_GPIO_PIN GPIO_PIN_4

  39. void SYSCTRL_Configuration(void);
  40. void GPIO_Configuration(void);
  41. void NVIC_Configuration(void);
  42. void I2C_Configuration(void);
  43. void Delay(uint16_t nCount);
  44. void DelayMs(__IO uint16_t nCount);
  45. void DelayUs(__IO uint16_t nCount);
  46. void UART_Configuration(void);
  47. void ATIM_IRQHandlerCallBack(void);

  48. #ifdef __GNUC__
  49.     /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
  50.     set to 'Yes') calls __io_putchar() */
  51.     #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  52. #else
  53.     #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  54. #endif /* __GNUC__ */


  55. // ADC转换数据
  56. uint32_t valueAdc;
  57. // 中断标志
  58. volatile uint8_t gFlagIrq;
  59.    
  60. // 马达控制
  61. // 系统时钟设置为HSI时钟3分频,16MHz, PCLK、HCLK不分频,PCLK=HCLK=SysClk=16MHz
  62. // ATIM边沿计数,上计数模式,80分频,ARR设置为19999,溢出周期200ms
  63. // 每隔200模式,通过PB0~PB3输出步进电机的控制信号
  64. #define MOTOR_MAX_STEP 12000
  65. // 顺时针驱动信号
  66. uint16_t motor_driver_s[4] = {1, 2, 4, 8};
  67. // 逆时针驱动信号
  68. uint16_t motor_driver_n[4] = {8, 4, 2, 1};
  69.         
  70. // 马达驱动信号间隔(200ms)
  71. uint16_t motor_delay=200;
  72. // 马达步进步数 : 发送一个完整周期,算一步
  73. int32_t motor_step = 0;
  74. // 马达正反转时,脉冲标志,范围0-3,按照顺时针/逆时针的脉冲顺序发送驱动信号
  75. uint8_t motor_step_no=0;

  76. typedef struct {
  77.     uint8_t    direction ;      // 转动方向 1-顺时针;2-逆时针;0-停转
  78.     uint8_t    no;              // 当前脉冲编号,0-3
  79.     int32_t    stepcnt;         // 步进计数
  80. } MOTOR_InitTypeDef;

  81. MOTOR_InitTypeDef motor;

  82. /**
  83. * [url=home.php?mod=space&uid=247401]@brief[/url] 配置ATIM
  84. *
  85. */

  86. void ATIM_Configuration(void) {
  87.     ATIM_InitTypeDef ATIM_InitStruct = {DISABLE,0};

  88.     ATIM_InitStruct.BufferState = ENABLE;                               //使能缓存寄存器   
  89.     ATIM_InitStruct.CounterAlignedMode = ATIM_COUNT_ALIGN_MODE_EDGE;    //边沿对齐
  90.     ATIM_InitStruct.CounterDirection = ATIM_COUNTING_UP;                //向上计数;
  91.     ATIM_InitStruct.CounterOPMode = ATIM_OP_MODE_REPETITIVE;            //连续运行模式   
  92.     ATIM_InitStruct.Prescaler = 80-1;                                   // 80分频
  93.     ATIM_InitStruct.ReloadValue = 599;                                // 重载周期499+1
  94.     ATIM_InitStruct.RepetitionCounter = 0;                              // 重复周期0

  95.     ATIM_Init(&ATIM_InitStruct);
  96.     ATIM_ITConfig(ATIM_IT_UIE, ENABLE);             // 有重复计数器溢出产生进入中断
  97.    
  98.     ATIM_Cmd(ENABLE);
  99. }

  100. /**
  101. * [url=home.php?mod=space&uid=247401]@brief[/url] 配置UART
  102. *
  103. */
  104. void UART_Configuration(void) {
  105.     UART_InitTypeDef UART_InitStructure = {0};

  106.     UART_InitStructure.UART_BaudRate = DEBUG_UART_BaudRate;
  107.     UART_InitStructure.UART_Over = UART_Over_16;
  108.     UART_InitStructure.UART_Source = UART_Source_PCLK;
  109.     UART_InitStructure.UART_UclkFreq = DEBUG_UART_UclkFreq;
  110.     UART_InitStructure.UART_StartBit = UART_StartBit_FE;
  111.     UART_InitStructure.UART_StopBits = UART_StopBits_1;
  112.     UART_InitStructure.UART_Parity = UART_Parity_No ;
  113.     UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;
  114.     UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx;
  115.     UART_Init(DEBUG_UARTx, &UART_InitStructure);
  116. }

  117. int32_t main(void) {
  118.     uint8_t bh1750cmd[] = {0x01};
  119.     uint8_t bh1750dat[8] = {0,0,0,0,0,0,0,0};
  120.     float val = 0;
  121.     //uint16_t v = motor.no%4;
  122.    
  123.     // 马达控制初始化
  124.     motor.direction = 0;
  125.     motor.no = 0;
  126.     motor.stepcnt = 0;
  127.    
  128.          //时钟初始化
  129.     SYSCTRL_Configuration();
  130.         
  131.         //IO口初始化
  132.     GPIO_Configuration();
  133.    
  134.     //配置UART
  135.     UART_Configuration();
  136.    
  137.     printf("\r\nStart test ... \r\n");
  138.    
  139.     // 初始化I2C外设
  140.     I2C_Configuration();
  141.    
  142.     // 初始化OLED
  143.     OLED_Init();
  144.    
  145.     // 显示光强标签:当前光强:
  146.     SYSTEM_Init();
  147.    
  148.     // 显示参数
  149.     OLED_ShowNum(76, 0, 0, 6, 16);
  150.         
  151.     // 设置ATIM参数
  152.     ATIM_Configuration();
  153.    
  154.     /* 允许ATIM中断 */
  155.     NVIC_Configuration();

  156.     while (1) {
  157. //        // LED
  158. //        GPIO_TogglePin(LED_GPIO_PORT, LED_GPIO_PINS);

  159.         // 采集光强数据:BH1750(I2C方式)
  160.         bh1750cmd[0] = 0x01;  // PowerOn
  161.         I2C_MasterSendDataToSlave(CW_I2C1, I2C_BH1750ADDR, bh1750cmd, 1);
  162.         //bh1750cmd[0] = 0x10;  // 高分辨率连续测量命令=0x10,测量时间120mS
  163.         bh1750cmd[0] = 0x23;  // 一次低分辨率测量命令=0x23,测量时间16mS
  164.         I2C_MasterSendDataToSlave(CW_I2C1, I2C_BH1750ADDR, bh1750cmd, 1);
  165.         DelayMs(20);        // 根据测量模式,调整为足够的等待时间,等待测试完成
  166.         I2C_MasterRecDataFromSlave(CW_I2C1, I2C_BH1750ADDR, bh1750dat, 2);
  167.         val = (bh1750dat[0]>>8 | bh1750dat[1])/1.2;
  168.         
  169.         // 显示光强数据
  170.         printf("\r\nBH1750 Value = %f", val);
  171.         OLED_ShowNum(76, 0, (int)val, 6, 16);
  172.         
  173.         // 根据光强值,确定步进电机正转还是反转
  174.         if (val >= MAX_LIGHT && motor.stepcnt < MOTOR_MAX_STEP) {
  175.             motor.direction = 1;
  176.             OLED_ShowChinese(48, 16, 11, 16);
  177.         } else if (val < MAX_LIGHT && motor.stepcnt > 0) {
  178.             motor.direction = 2;
  179.             OLED_ShowChinese(48, 16, 14, 16);
  180.         } else {
  181.             motor.direction = 0;
  182.             OLED_ShowChinese(48, 16, 9, 16);
  183.         }
  184.         // 显示步进计数
  185.         OLED_ShowNum(76, 16, (int)motor.stepcnt , 6, 16);
  186.         OLED_Refresh();
  187.     }   
  188. }

  189. void ATIM_IRQHandlerCallBack(void) {
  190.     uint8_t v = 0;
  191.    
  192.     if (ATIM_GetITStatus(ATIM_STATE_UIF)) {
  193.         // 清除中断标志位
  194.         ATIM_ClearITPendingBit(ATIM_STATE_UIF);
  195.         
  196.         // 根据马达状态,发出控制信号
  197.         if (motor.direction == 0) {
  198.             // 禁止转动
  199.             GPIO_WritePin(CW_GPIOB, MOTOR_GPIO_PIN0, GPIO_Pin_RESET);
  200.             GPIO_WritePin(CW_GPIOB, MOTOR_GPIO_PIN1, GPIO_Pin_RESET);
  201.             GPIO_WritePin(CW_GPIOB, MOTOR_GPIO_PIN2, GPIO_Pin_RESET);
  202.             GPIO_WritePin(CW_GPIOB, MOTOR_GPIO_PIN3, GPIO_Pin_RESET);
  203.             motor.no=0;
  204.         } else {
  205.             // 根据正反转,获取不同的时序驱动数据
  206.             if (motor.direction == 1) {
  207.                 v = motor_driver_s[motor.no];
  208.             } else if (motor.direction == 2) {
  209.                 v = motor_driver_n[motor.no];
  210.             } else {
  211.                 return;
  212.             }
  213.             
  214.             // 输出驱动数据到GPIO口
  215.             if (v==1) {
  216.                 GPIO_WritePin(CW_GPIOA, MOTOR_GPIO_PIN1, GPIO_Pin_RESET);
  217.                 GPIO_WritePin(CW_GPIOB, MOTOR_GPIO_PIN2, GPIO_Pin_RESET);
  218.                 GPIO_WritePin(CW_GPIOB, MOTOR_GPIO_PIN3, GPIO_Pin_RESET);
  219.                 GPIO_WritePin(CW_GPIOA, MOTOR_GPIO_PIN0, GPIO_Pin_SET);
  220.             } else if (v==2) {
  221.                 GPIO_WritePin(CW_GPIOA, MOTOR_GPIO_PIN0, GPIO_Pin_RESET);
  222.                 GPIO_WritePin(CW_GPIOB, MOTOR_GPIO_PIN2, GPIO_Pin_RESET);
  223.                 GPIO_WritePin(CW_GPIOB, MOTOR_GPIO_PIN3, GPIO_Pin_RESET);
  224.                 GPIO_WritePin(CW_GPIOA, MOTOR_GPIO_PIN1, GPIO_Pin_SET);
  225.             } else if (v==4) {
  226.                 GPIO_WritePin(CW_GPIOA, MOTOR_GPIO_PIN0, GPIO_Pin_RESET);
  227.                 GPIO_WritePin(CW_GPIOA, MOTOR_GPIO_PIN1, GPIO_Pin_RESET);
  228.                 GPIO_WritePin(CW_GPIOB, MOTOR_GPIO_PIN3, GPIO_Pin_RESET);
  229.                 GPIO_WritePin(CW_GPIOB, MOTOR_GPIO_PIN2, GPIO_Pin_SET);
  230.             } else if (v==8) {
  231.                 GPIO_WritePin(CW_GPIOA, MOTOR_GPIO_PIN0, GPIO_Pin_RESET);
  232.                 GPIO_WritePin(CW_GPIOA, MOTOR_GPIO_PIN1, GPIO_Pin_RESET);
  233.                 GPIO_WritePin(CW_GPIOB, MOTOR_GPIO_PIN2, GPIO_Pin_RESET);
  234.                 GPIO_WritePin(CW_GPIOB, MOTOR_GPIO_PIN3, GPIO_Pin_SET);
  235.             }

  236.             // 根据正反转,计算下一次时序脉冲数据,并调整步进计数
  237.             if (motor.direction == 1) {
  238.                 // 正转
  239.                 if (motor.stepcnt<MOTOR_MAX_STEP) {
  240.                     motor.stepcnt++;
  241.                     motor.no=(motor.no+1)%4;
  242.                 } else {
  243.                     // 超出步进上限,停止转动
  244.                     motor.direction = 0;
  245.                 }
  246.                
  247.             } else if (motor.direction == 2) {
  248.                 // 反转
  249.                 if (motor.stepcnt>0) {
  250.                     motor.stepcnt--;
  251.                     motor.no=(motor.no+1)%4;
  252.                 } else {
  253.                     // 返回上电的初始位置时,停止转动
  254.                     motor.direction = 0;
  255.                 }
  256.             }
  257.         }
  258.     }

  259. }

  260. /**
  261.   * @brief  Configures the different system clocks.
  262.   * @param  None
  263.   * @retval None
  264.   */
  265. void SYSCTRL_Configuration(void) {
  266.         SYSCTRL_HSI_Enable(SYSCTRL_HSIOSC_DIV3);       // 三分频,16MHz主频(48/3)
  267.     //SYSCTRL_HSI_Enable(SYSCTRL_HSIOSC_DIV6);
  268.     __SYSCTRL_ATIM_CLK_ENABLE();     // ATIM用时钟
  269.     __SYSCTRL_GPIOA_CLK_ENABLE();    // PA用PORT时钟
  270.     __SYSCTRL_GPIOB_CLK_ENABLE();    // PB用PORT时钟
  271.     __SYSCTRL_I2C_CLK_ENABLE();      // I2C用PORT时钟
  272.    
  273.     //外设时钟使能
  274.     SYSCTRL_AHBPeriphClk_Enable(DEBUG_UART_GPIO_CLK, ENABLE);
  275.     DEBUG_UART_APBClkENx(DEBUG_UART_CLK, ENABLE);   
  276. }

  277. /**
  278.   * @brief  Configure the GPIO Pins.
  279.   * @param  None
  280.   * @retval None
  281.   */

  282. // 初始化GPIO口
  283. void GPIO_Configuration(void) {
  284.     GPIO_InitTypeDef GPIO_InitStructure  = {0};
  285.    
  286.     // 按钮(PB4)
  287.     GPIO_InitStructure.IT = GPIO_IT_NONE;
  288.     GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
  289.     GPIO_InitStructure.Pins = KEY1_GPIO_PIN;
  290.     GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);
  291.    
  292.    
  293.     // 步进电机GPIO口:PA03、PA04、PB02、PB03
  294.     GPIO_InitStructure.IT = GPIO_IT_NONE;
  295.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  296.    
  297.     GPIO_InitStructure.Pins = MOTOR_GPIO_PIN0 | MOTOR_GPIO_PIN1;
  298.     GPIO_Init(MOTOR_GPIO_PORT1, &GPIO_InitStructure);

  299.     GPIO_InitStructure.Pins = MOTOR_GPIO_PIN2 | MOTOR_GPIO_PIN3;
  300.     GPIO_Init(MOTOR_GPIO_PORT2, &GPIO_InitStructure);


  301.     // PA05、PA06复用为SDA、SCL
  302.         PA05_AFx_I2C1SDA();
  303.         PA06_AFx_I2C1SCL();
  304.     GPIO_InitStructure.Pins = I2C1_SCL_GPIO_PIN | I2C1_SDA_GPIO_PIN;
  305.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
  306.     GPIO_Init(I2C1_SCL_GPIO_PORT, &GPIO_InitStructure);
  307.    
  308.     // 初始化串口:PB6 - RX, PB5 - TX
  309.     GPIO_WritePin(DEBUG_UART_TX_GPIO_PORT, DEBUG_UART_TX_GPIO_PIN,GPIO_Pin_SET);    // 设置TXD的默认电平为高,空闲

  310.     GPIO_InitStructure.Pins = DEBUG_UART_TX_GPIO_PIN;
  311.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  312.     GPIO_Init(DEBUG_UART_TX_GPIO_PORT, &GPIO_InitStructure);

  313.     GPIO_InitStructure.Pins = DEBUG_UART_RX_GPIO_PIN;
  314.     GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
  315.     GPIO_Init(DEBUG_UART_RX_GPIO_PORT, &GPIO_InitStructure);

  316.      //UART TX RX 复用
  317.     DEBUG_UART_AFTX;
  318.     DEBUG_UART_AFRX;
  319. }

  320. // 初始化I2C参数
  321. void I2C_Configuration(void) {
  322.         
  323.         I2C_InitTypeDef I2C_InitStruct = {0};
  324.         
  325.         //I2C初始化
  326.     // 串行时钟发生器采用 PCLK 作为输入时钟,通过 1 个 8bit的计数器计数,输出所需波特率的 I2C 时钟信号。
  327.         I2C_InitStruct.PCLK_Freq    = 16000000;               // fSCL = fPCLK / 8 / ( BRR + 1 )
  328.     I2C_InitStruct.I2C_SCL_Freq = 1000000;                // SCL频率=1MHz
  329.     I2C_InitStruct.I2C_SCL_Source = I2C_SCL_SRC_GPIO;     //
  330.     I2C_InitStruct.I2C_SDA_Source = I2C_SDA_SRC_GPIO;     //
  331.         
  332.         I2C1_DeInit();
  333.     I2C_Master_Init(CW_I2C1,&I2C_InitStruct);//初始化模块
  334.         I2C_AcknowledgeConfig(CW_I2C1,ENABLE);//ACK打开
  335.     I2C_Cmd(CW_I2C1, ENABLE);//模块使能   
  336. }

  337. /**
  338.   * @brief  Configure the nested vectored interrupt controller.
  339.   * @param  None
  340.   * @retval None
  341.   */
  342. void NVIC_Configuration(void) {
  343.     __disable_irq();
  344.     //NVIC_EnableIRQ(I2C1_IRQn);
  345.     NVIC_EnableIRQ(ATIM_IRQn);      // 允许ATIM中断
  346.     __enable_irq();
  347. }




  348. /**
  349. * @brief 循环延时
  350. *
  351. * @param nCount
  352. */
  353. void Delay(__IO uint16_t nCount) {
  354.     /* Decrement nCount value */
  355.     while (nCount != 0) {
  356.         nCount--;
  357.     }
  358. }
  359. void DelayMs(__IO uint16_t nCount) {
  360.     /* Decrement nCount value */
  361.     while (nCount-- != 0) {
  362.         Delay(1300);
  363.     }
  364. }
  365. void DelayUs(__IO uint16_t nCount)
  366. {
  367.     /* Decrement nCount value */
  368.     while (nCount-- != 0) {
  369.         Delay(130);
  370.     }
  371. }

  372. /**
  373. * @brief Retargets the C library printf function to the UART.
  374. *
  375. */
  376. PUTCHAR_PROTOTYPE
  377. {
  378.     UART_SendData_8bit(DEBUG_UARTx, (uint8_t)ch);

  379.     while (UART_GetFlagStatus(DEBUG_UARTx, UART_FLAG_TXE) == RESET);

  380.     return ch;
  381. }

  382. size_t __write(int handle, const unsigned char * buffer, size_t size)
  383. {
  384.     size_t nChars = 0;

  385.     if (buffer == 0)
  386.     {
  387.         /*
  388.          * This means that we should flush internal buffers.  Since we
  389.          * don't we just return.  (Remember, "handle" == -1 means that all
  390.          * handles should be flushed.)
  391.          */
  392.         return 0;
  393.     }


  394.     for (/* Empty */; size != 0; --size)
  395.     {
  396.         UART_SendData_8bit(DEBUG_UARTx, *buffer++);
  397.         while (UART_GetFlagStatus(DEBUG_UARTx, UART_FLAG_TXE) == RESET);
  398.         ++nChars;
  399.     }

  400.     return nChars;
  401. }


  402. /******************************************************************************
  403. * EOF (not truncated)
  404. ******************************************************************************/
  405. #ifdef  USE_FULL_ASSERT
  406. /**
  407.   * @brief  Reports the name of the source file and the source line number
  408.   *         where the assert_param error has occurred.
  409.   * @param  file: pointer to the source file name
  410.   * @param  line: assert_param error line source number
  411.   * [url=home.php?mod=space&uid=266161]@return[/url] None
  412.   */
  413. void assert_failed(uint8_t *file, uint32_t line) {
  414.     /* USER CODE BEGIN 6 */
  415.     /* User can add his own implementation to report the file name and line number,
  416.        tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  417.     /* USER CODE END 6 */
  418. }
  419. #endif /* USE_FULL_ASSERT */



AdaMaYun 发表于 2024-12-10 11:15 | 显示全部楼层
非常不错的步进案例
LOVEEVER 发表于 2024-12-12 08:44 | 显示全部楼层
光感元气件其实就是ADC检测
 楼主| suncat0504 发表于 2024-12-12 09:03 | 显示全部楼层
LOVEEVER 发表于 2024-12-12 08:44
光感元气件其实就是ADC检测

应该是这样的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:大连伊飞特信息技术有限公司软件工程师
简介:本人于1993年毕业于大连理工大学。毕业后从事单片机开发工作5年,之后转入软件开发工作至今。

158

主题

4505

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部