传媒学子

  • 2019-05-28
  • 加入了学习《小梅哥Intel SoC FPGA开发与应用培训课程》,观看 soc开发工具

  • 加入了学习《小梅哥Intel SoC FPGA开发与应用培训课程》,观看 soc基本概念

  • 评论了课程: EEWORLD大学堂----小梅哥Intel SoC FPGA开发与应用培训课程

    不错不错

  • 加入了学习《FPGA设计思想与验证方法视频教程(小梅哥主讲)》,观看 第十二课 嵌入式块RAM使用之双口RAM

  • 加入了学习《FPGA设计思想与验证方法视频教程(小梅哥主讲)》,观看 第一课 科学的FPGA开发流程(中)

  • 加入了学习《FPGA设计思想与验证方法视频教程(小梅哥主讲)》,观看 第一课 科学的FPGA开发流程(上)

  • 加入了学习《FPGA设计思想与验证方法视频教程(小梅哥主讲)》,观看 作者语_芯航线FPGA开发板介绍

  • 2019-05-27
  • 加入了学习《基于GD32E231的金鱼自动投喂机器人设计》,观看 基于GD32E231的金鱼自动投喂机器人设计

  • 2019-05-26
  • 加入了学习《智能房车控制系统作品演示》,观看 作品演示

  • 回复了主题帖: [GD32E231 DIY大赛]作品提交:观赏鱼缸控制器

    牛,手巧

  • 加入了学习《EE网友DIY作品:都市青年家庭安防卫士》,观看 都市青年家庭安防卫士

  • 发表了主题帖: 07. 基于GD32E231的金鱼自动投喂机器人设计

    本帖最后由 传媒学子 于 2019-5-26 19:36 编辑 基于GD32E231的金鱼自动投喂机器人设计作品提交 一、项目背景 长时间出差不在家,家里的金鱼会挨饿。因此,为了让金鱼在主人不在家的时候不会挨饿,基于4自由度机械手臂和GD32E231设计一款基于自动投喂机器人。 GD32E231通过生成PWM来控制机械臂,同时按照预先设定的时间,从固定地方去取鱼食,放入鱼缸,通过多次人工训练,让机械臂根据人工训练的数据,实现自动计算投喂取食位置。 同时还可以增加一些辅助功能,通过串口或者板载ADC加上光敏电阻来大概获取GD32E231的内部温度和鱼缸周围光照情况,天黑暗时可以打开台灯等照明设备。 该系统采用了GD32E231的以下功能:1. UART 高性能异步通信接口2. GPIO 通用输入输出接口3. 72MHz主频4. RTC实时时钟5. Timer0定时器触发DMA传输6. DMA传输7. Timer2 启动四通道PWM来连接机械臂8. 外部中断ETI9. ADC 内部模数转换 从实际测试效果和项目推进过程中所用的模块具体运行情况来看,GD32E231这款处理器,定时器功能强大,定时器2可以输出4路PWM,而且ADC功能也很实用,可用于普通的机器人应用。 二、系统设计本项目基于兆易创新公司生产的GD32E231arm处理器,作为《基于GD32E231的金鱼自动投喂机器人设计》的主控处理器,负责读取光照数据,比对定时时间,执行自动或者手动投喂任务。图2.1 基于GD32E231的金鱼自动投喂机器人架构图2.1 硬件设计 硬件设计采用Arduino转接板,电源采用5V3A供电+电脑USB-串口供电,具体硬件电路如下:图2.2部分硬件连接图2.2软件设计 软件设计主要围绕ov5640的驱动来实施的,程序实施原理图如下图2.3程序框架图 程序流程图如下: 代码参看: EEWORLD论坛_作品提交贴附件, 代码工程路径:Auto_Feed_Robot\auto_feed_robot\Projects\auto_feed_robot\MDK-ARM\ 部分函数:void adc_rcu_config(void); void adc_gpio_config(void); void adc_dma_config(void); void adc_timer_config(void); void adc_config(void); void display_adc_value(void); void rtc_setup(void); void rtc_show_time(void); void rtc_pre_config(void); void rtc_comp_time(void); void led_config(void); void led_flash(int times); void exti_config(void); void gpio_config(void); void pwm_timer_clock_enable(void); void pwm_timer_config(uint32_t timer); void control_motor(uint8_t motor_tag, uint32_t pulse); void auto_feed_fish(void); 复制代码 三、项目完成情况 项目历时30天(2019年4月27日到2019年5月26日),项目完成了预期的所有内容,并额外扩展了光敏传感器和串口显示功能。 图3.1实物图 实现的功能主要有:1. 定时器0触发ADC,并通过DMA传输数据2. 定时器2配置四通道PWM,实现对机械臂的控制3. 通过人工训练,得到较好的抓取位置和释放位置4. 通过不断尝试,克服了电源峰值功率不能满足机械臂快速调整的弊端,通过平滑调整,实现对机械臂的控制5. 成功实现RTC模块,通过RTC模块,实现定时启动投喂,每次投喂次数可设定,默认为3次,可设定每天投喂几次,何时投喂6. 串口显示系统信息,方便调试和人工交互 四、项目总结与展望 4.1 项目总结 (1) 项目实现了对机械臂的控制,并且能够实现抓取鱼食进行投喂。 (2) 项目实现了对鱼缸所处光照情况的采集,用于打开灯或者关闭等,项目中以LED4模拟实现。 (3) 同时,增加了常用的串口模块,方便用于扩展和交互。 4.2 未来的优化搭建web服务器,实现远程控制机械臂。 4.3 论坛发帖情况 [GD32E231 DIY大赛] 01. GD32E231-start以及创意内容介绍http://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1075713&fromuid=363532(出处: 电子工程世界-论坛) [GD32E231 DIY大赛] 02. 为何PWM的占空比不能在外部中断服务函数中更改?http://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1076014&fromuid=363532(出处: 电子工程世界-论坛) [GD32E231 DIY大赛] 03. 忽视运放设置会导致PB1输出电压不正确http://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1076051&fromuid=363532(出处: 电子工程世界-论坛) [GD32E231 DIY大赛] 04. 机械臂艰难的组装过程http://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1077469&fromuid=363532(出处: 电子工程世界-论坛) [GD32E231 DIY大赛] 05. 自动喂鱼机器人之PWM篇http://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1077467&fromuid=363532(出处: 电子工程世界-论坛) [GD32E231 DIY大赛] 06. 自动喂鱼机器人之ADC/DMA/TIMER0/串口篇http://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1077838&fromuid=363532(出处: 电子工程世界-论坛) 07. 基于GD32E231的金鱼自动投喂机器人设计http://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=1078206&fromuid=363532(出处: 电子工程世界-论坛) 五、致谢 感谢论坛一如既往的支持,感谢GD公司提供开发板和样片,感谢各位坛友的帮助,让我们支持国产,奋发图强,砥砺前行!

  • 2019-05-21
  • 发表了主题帖: [GD32E231 DIY大赛] 06. 自动喂鱼机器人之ADC/DMA/TIMER0/串口篇

    [GD32E231 DIY大赛] 06. 自动喂鱼机器人之ADC/DMA/TIMER0/串口篇 这里用到了光敏电阻来监测鱼缸周围的光照度。 从内部ADC采集,定时器0的比较事件0触发ADC转换,ADC转换的结果将随着模拟值输入的改变而改变。 转换结果由DMA 搬运到SRAM 中,最后判断AD的值是否大于一定数值。 具体程序如下: 首先涉及以下函数和变量: __IO uint16_t ad_value[220];  //day:ad_value 2500 void adc_rcu_config(void); void adc_gpio_config(void); void adc_dma_config(void); void adc_timer_config(void); void adc_config(void); void display_adc_value(void);复制代码/*!     \brief      RCU configuration function for ADC     \param[in]  none     \param[out] none     \retval     none */ void adc_rcu_config(void) {     /* enable the GPIO clock */     //rcu_periph_clock_enable(RCU_GPIOA);     //rcu_periph_clock_enable(RCU_GPIOB);     //rcu_periph_clock_enable(RCU_GPIOC);    // rcu_periph_clock_enable(RCU_GPIOF);     /* ADCCLK = PCLK2/6 */     rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);     /* enable DMA clock */     rcu_periph_clock_enable(RCU_DMA);     /* enable ADC clock */     rcu_periph_clock_enable(RCU_ADC);     /* enable TIMER0 clock */     rcu_periph_clock_enable(RCU_TIMER0); } /*!     \brief      GPIO configuration function for ADC     \param[in]  none     \param[out] none     \retval     none */ void adc_gpio_config(void) {     /* configure PA2(ADC channel2) as analog input */     gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_2); } /*!     \brief      DMA configuration function for ADC     \param[in]  none     \param[out] none     \retval     none */ void adc_dma_config(void) {     dma_parameter_struct dma_init_struct;     /* initialize DMA channel0 */     dma_deinit(DMA_CH0);     dma_init_struct.direction    = DMA_PERIPHERAL_TO_MEMORY;     dma_init_struct.memory_addr  = (uint32_t)ad_value;     dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;     dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;     dma_init_struct.number       = 220;     dma_init_struct.periph_addr  = (uint32_t)&(ADC_RDATA);     dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;     dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;     dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;     dma_init(DMA_CH0, &dma_init_struct);         /* configure DMA mode */     dma_circulation_enable(DMA_CH0);     dma_memory_to_memory_disable(DMA_CH0);         /* enable DMA channel0 */     dma_channel_enable(DMA_CH0); } /*!     \brief      TIMER configuration function for ADC     \param[in]  none     \param[out] none     \retval     none */ void adc_timer_config(void) {     timer_oc_parameter_struct timer_ocintpara;     timer_parameter_struct timer_initpara;     timer_deinit(TIMER0);     /* TIMER0 configuration */     timer_initpara.prescaler         = 5;     timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;     timer_initpara.counterdirection  = TIMER_COUNTER_UP;     timer_initpara.period            = 399;     timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;     timer_initpara.repetitioncounter = 0;     timer_init(TIMER0, &timer_initpara);     /* CH0 configuration in PWM mode1 */     timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_LOW;     timer_ocintpara.outputstate = TIMER_CCX_ENABLE;     timer_channel_output_config(TIMER0, TIMER_CH_0, &timer_ocintpara);     timer_channel_output_pulse_value_config(TIMER0, TIMER_CH_0, 100);     timer_channel_output_mode_config(TIMER0, TIMER_CH_0, TIMER_OC_MODE_PWM1);     timer_channel_output_shadow_config(TIMER0, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);     /* auto-reload preload enable */     timer_auto_reload_shadow_enable(TIMER0);     timer_primary_output_config(TIMER0, ENABLE); } /*!     \brief      ADC configuration function     \param[in]  none     \param[out] none     \retval     none */ void adc_config(void) {     /* ADC channel length config */     adc_channel_length_config(ADC_REGULAR_CHANNEL, 1);     /* ADC regular channel config */     adc_regular_channel_config(0, ADC_CHANNEL_2, ADC_SAMPLETIME_55POINT5);     /* ADC external trigger enable */     adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);     /* ADC external trigger source config */     adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_T0_CH0);     /* ADC data alignment config */     adc_data_alignment_config(ADC_DATAALIGN_RIGHT);     /* enable ADC interface */     adc_enable();     /* ADC calibration and reset calibration */     adc_calibration_enable();     /* ADC DMA function enable */     adc_dma_mode_enable(); } void display_adc_value(void) {           printf("\r\n%d\r\n",ad_value[0]); } 复制代码 ad转换我只用了第一个值,其实DMA传输会不停的循环传输。 主函数中这样用: gd_eval_com_init(EVAL_COM1,115200);   adc_rcu_config();     adc_gpio_config();           adc_dma_config();     adc_timer_config();     adc_config();          /* TIMER0 counter enable for ADC */     timer_enable(TIMER0);                 /* test on channel0 transfer complete flag */                 while( !dma_flag_get(DMA_CH0, DMA_FLAG_FTF));                 display_adc_value();复制代码 然后在while(1) 中执行display_adc_value(); 就能把值实时打印到串口。 DMA配置完会不断循环写入到buffer中,配置完成后CPU不需要参与,我们在循环中,可以直接读取AD值,这些值在配置DMA时是循环覆盖写入的。 printf是采用串口显示, 具体方法如下,在keil的魔术棒option里,Target中,勾选Use MicroLIB, 然后添加如下子程序,重新映射串口,/* retarget the C library printf function to the USART */ int fputc(int ch, FILE *f) {     usart_data_transmit(EVAL_COM1, (uint8_t)ch);     while(RESET == usart_flag_get(EVAL_COM1, USART_FLAG_TBE));     return ch; }复制代码 关于串口初始化:gd_eval_com_init(EVAL_COM1,115200); 其是在gd32e231c_start.c、gd32e231c_start.h中定义的: gd32e231c_start.h //-----------------added by user--------------------------// /* eval board low layer COM */ #define COMn                             1U   //定义数组大小 /* definition for COM0, connected to USART0 */ #define EVAL_COM1                        USART0 #define EVAL_COM1_CLK                    RCU_USART0 #define EVAL_COM1_TX_PIN                 GPIO_PIN_9 #define EVAL_COM1_RX_PIN                 GPIO_PIN_10 #define EVAL_COM_GPIO_PORT               GPIOA #define EVAL_COM_GPIO_CLK                RCU_GPIOA #define EVAL_COM_AF                      GPIO_AF_1 /* configure COM port */ void gd_eval_com_init(uint32_t com, uint32_t baud);复制代码 gd32e231c_start.c static rcu_periph_enum COM_CLK[COMn]  = {EVAL_COM1_CLK}; static uint32_t COM_TX_PIN[COMn]      = {EVAL_COM1_TX_PIN}; static uint32_t COM_RX_PIN[COMn]      = {EVAL_COM1_RX_PIN};复制代码 void gd_eval_com_init(uint32_t com, uint32_t baud) {     uint32_t COM_ID;        if(EVAL_COM1 == com){         COM_ID = 0U;     }else{     }     /* enable COM GPIO clock */     rcu_periph_clock_enable(EVAL_COM_GPIO_CLK);     /* enable USART clock */     rcu_periph_clock_enable(COM_CLK[COM_ID]);     /* connect port to USARTx_Tx */     gpio_af_set(EVAL_COM_GPIO_PORT, EVAL_COM_AF, COM_TX_PIN[COM_ID]);     /* connect port to USARTx_Rx */     gpio_af_set(EVAL_COM_GPIO_PORT, EVAL_COM_AF, COM_RX_PIN[COM_ID]);     /* configure USART Tx as alternate function push-pull */     gpio_mode_set(EVAL_COM_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, COM_TX_PIN[COM_ID]);     gpio_output_options_set(EVAL_COM_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, COM_TX_PIN[COM_ID]);     /* configure USART Rx as alternate function push-pull */     gpio_mode_set(EVAL_COM_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, COM_RX_PIN[COM_ID]);     gpio_output_options_set(EVAL_COM_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, COM_RX_PIN[COM_ID]);     /* USART configure */     usart_deinit(com);    // usart_baudrate_set(com, 115200U);           usart_baudrate_set(com, baud);     usart_receive_config(com, USART_RECEIVE_ENABLE);     usart_transmit_config(com, USART_TRANSMIT_ENABLE);     usart_enable(com); }复制代码 注意串口0还是1。 -------------------------------------------

  • 2019-05-20
  • 回复了主题帖: [GD32E231 DIY大赛] 04. 机械臂艰难的组装过程

    hujj 发表于 2019-5-19 20:54 看了几遍还没有明白这机械手的结构原理。
    很简单,四个舵机,转向,控制舵机就行

  • 回复了主题帖: [GD32E231 DIY大赛] 04. 机械臂艰难的组装过程

    dcexpert 发表于 2019-5-19 21:16 这种机械臂有两种,一种是较便宜的亚克力板做的,另一种是用金属结构件,使用舵机进行控制。舵机是50HZ的PW ...
    对对,我就是亚克力,采用的就是一点一点变化,变化大了,就掉电了。。。

  • 回复了主题帖: [GD32E231 DIY大赛] 03. 忽视运放设置会导致PB1输出电压不正确

    小涛电子 发表于 2019-5-19 23:03 231的运放怎么用 手册上好像资料不多 比如我要放大 输入脚和输出脚接电阻? 正反向输入脚为什么距离这么远 ...
    就当做正常的运放就行,貌似是轨至轨的,SPEC上有参数。 就是一个运放,怎么接都行

  • 2019-05-19
  • 发表了主题帖: [GD32E231 DIY大赛] 04. 机械臂艰难的组装过程

    本帖最后由 传媒学子 于 2019-5-19 18:29 编辑 [GD32E231 DIY大赛] 04. 机械臂艰难的组装过程 夹杂这省钱和锻炼自己动手能力的动机下,我掏了160多大洋买了一个四自由度的小型机械臂组装散件,本来以为比较组装起来比较简单,但可能是我太幼稚了,如果知道组装这么费劲,还不如直接多掏30多,买个成品,这里还是奉劝大家如果时间不是很充裕的话,还是买个成品的机械臂。毕竟我们是电子工程师,花费太多的时间在组装上,会影响心情的。 1.买来是这个样子的... 当时就有点抓狂了,没想到抓狂的事情还在后边。。。 #2. 初见框架# #3. 组装即将完成时,突然一根亚克力板断了。。。顿时懵逼了# 胶带缠了一下,凑合着用,后来商家又给发了一根。 #4.状况频出 一一击破# 组装完了,不会动?? 原来是螺丝拧的太紧了。 组装完了,动的异常?? 原来是电源功率不够。 花了近1个星期的闲暇时间,终于搞定了。。。 下一贴 分析如何用GD32产生PWM控制机械臂。

  • 发表了主题帖: [GD32E231 DIY大赛] 05. 自动喂鱼机器人之PWM篇

    [GD32E231 DIY大赛] 05. 自动喂鱼机器人之PWM篇 1.舵机基本工作原理 一般机器人控制都离不开舵机控制,这里先简单讲解一下舵机的基本工作原理: 一般而言,舵机的基准信号都是周期为20ms,宽度为1.5ms。这个基准信号定义的位置为中间位置。其中间位置的脉冲宽度是一定的,那就是1.5ms。 我是参考: https://blog.csdn.net/weixin_38075894/article/details/80027600. 20ms基准频率就是50Hz, 这个一般的单片机都是很容易生成的。 我的机械臂上的舵机型号是MG90S,是一个小舵机,机械臂是4自由度的,因此就是4个。 GD32E231的定时器功能是非常强大的,TIMER2可以同时输出四个通道的PWM,PWM可以设定不同的脉宽。 2.硬件配置 因为GD32E231start开发板,兼容arduino接口,因此我采用了arduino的转接板,转接板仅仅是转接功能,具体如下: 具体的接口配置: PB4 TIMER2_CH0 D3 PB5 TIMER2_CH1 D4 PB0 TIMER2_CH2 D9 PB1 TIMER2_CH3 D8 3程序如下: void gpio_config(void); void pwm_timer_clock_enable(void); void pwm_timer_config(uint32_t timer);复制代码 void gpio_config(void) { rcu_periph_clock_enable(RCU_GPIOB); /* configure PB2 output 0 */ gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_2); gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_2); gpio_bit_reset(GPIOB, GPIO_PIN_2);//disable opa, ENA is connected to PB2, ENA = 0, diable opa, else, enable ENA, NOT be float /* configure PB4(TIMER2 CH0) as alternate function */ gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4); gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4); gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_4); /* configure PB5(TIMER2 CH1) as alternate function */ gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5); gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_5); gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_5); /* configure PB0(TIMER2 CH2) as alternate function */ gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0); gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_0); gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_0); /* configure PB1(TIMER2 CH3) as alternate function */ gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1); gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1); gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_1); }复制代码/*! \brief enable clock of the TIMER peripheral \param[in] none \param[out] none \retval none */ void pwm_timer_clock_enable() { rcu_periph_clock_enable(RCU_TIMER2); }复制代码void pwm_timer_config(uint32_t timer) { /* ----------------------------------------------------------------------- TIMER2CLK is 100KHz TIMER2 channel0 duty cycle = (25000/ 50000)* 100 = 50% ----------------------------------------------------------------------- */ timer_oc_parameter_struct timer_ocintpara; timer_parameter_struct timer_initpara; timer_deinit(timer); /* TIMER configuration */ timer_initpara.prescaler = 719; timer_initpara.alignedmode = TIMER_COUNTER_EDGE; timer_initpara.counterdirection = TIMER_COUNTER_UP; timer_initpara.period = 1999; timer_initpara.clockdivision = TIMER_CKDIV_DIV1; timer_initpara.repetitioncounter = 0; timer_init(timer,&timer_initpara); /* configurate CH0 in PWM mode0 */ timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; timer_ocintpara.outputstate = TIMER_CCX_ENABLE; timer_channel_output_config(timer,TIMER_CH_0,&timer_ocintpara); timer_channel_output_pulse_value_config(timer,TIMER_CH_0,150-1); timer_channel_output_mode_config(timer,TIMER_CH_0,TIMER_OC_MODE_PWM0); timer_channel_output_shadow_config(timer,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE); timer_auto_reload_shadow_enable(timer); timer_enable(timer); delay_1ms(500); timer_disable(timer); timer_channel_output_config(timer,TIMER_CH_1,&timer_ocintpara); timer_channel_output_pulse_value_config(timer,TIMER_CH_1,150-1); timer_channel_output_mode_config(timer,TIMER_CH_1,TIMER_OC_MODE_PWM0); timer_channel_output_shadow_config(timer,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE); timer_auto_reload_shadow_enable(timer); timer_enable(timer); delay_1ms(500); timer_disable(timer); timer_channel_output_config(timer,TIMER_CH_2,&timer_ocintpara); timer_channel_output_pulse_value_config(timer,TIMER_CH_2,250-1); timer_channel_output_mode_config(timer,TIMER_CH_2,TIMER_OC_MODE_PWM0); timer_channel_output_shadow_config(timer,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE); timer_auto_reload_shadow_enable(timer); timer_enable(timer); delay_1ms(500); timer_disable(timer); timer_channel_output_config(timer,TIMER_CH_3,&timer_ocintpara); timer_channel_output_pulse_value_config(timer,TIMER_CH_3,160-1); //160~200, Claw form close to open timer_channel_output_mode_config(timer,TIMER_CH_3,TIMER_OC_MODE_PWM0); timer_channel_output_shadow_config(timer,TIMER_CH_3,TIMER_OC_SHADOW_DISABLE); timer_auto_reload_shadow_enable(timer); timer_enable(timer); delay_1ms(500); }复制代码 然后,如果要改变特定通道的PWM宽度,可以用timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_0, value)函数. 由于舵机瞬态电流比较大,务必增大电流或者制作专用驱动电路,否则GD32E231会因为电压瞬间降低而引起复位。 我这里采用5V 3A的供电加上USB供电,并且在程序中,平滑PWM值的改变,才勉强实现系统的稳定工作。 可以采用这种法法来实现舵机平滑切换: /*! \brief config the specific steering motor 0,1,2,3 \param[in] motor_tag: 0,1,2,3; pulse: 50~250, mid=150 0.5ms~2.5ms \param[out] none \retval none */ void control_motor(uint8_t motor_tag, uint32_t pulse) { uint8_t i; if(motor_tag == 0) { if(pulse>=current_value[0]) { for(i=current_value[0];i = pulse; i--) //in case of big current to pulse MCU system { timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_0,i-1); delay_1ms(20); } } current_value[0] = pulse; } else if (motor_tag == 1) { if(pulse>=current_value[1]) { for(i=current_value[1];i = pulse; i--) //in case of big current to pulse MCU system { timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_1,i-1); delay_1ms(20); } } current_value[1] = pulse; } else if (motor_tag == 2) { if(pulse>=current_value[2]) { for(i=current_value[2];i = pulse; i--) //in case of big current to pulse MCU system { timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_2,i-1); delay_1ms(30); } } current_value[2] = pulse; } else if (motor_tag == 3) { if(pulse>=current_value[3]) { for(i=current_value[3];i = pulse; i--) //in case of big current to pulse MCU system { timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_3,i-1); delay_1ms(50); } } current_value[3] = pulse; } }复制代码 主函数中: pwm_timer_clock_enable(); pwm_timer_config(TIMER2);复制代码

  • 回复了主题帖: “我和intel SoC FPGA”+ 搞不懂的arm硬核开发

    小梅哥 发表于 2019-5-19 14:38 如果只是简单的物联网,不需要高速数据交互,其实还是蛮简单的。基本上把Linux应用开发掌握熟练就可以了。 ...
    嗯嗯,一直就是零散的学,我这边抽空把linux和一些网络基础补补,多谢小梅哥指点

  • 2019-05-14
  • 回复了主题帖: [颁奖]读RT-Thread技术好书,写读书笔记

    信息正确,多谢论坛~

最近访客

< 1/4 >

统计信息

已有187人来访过

  • 芯币:2299
  • 好友:3
  • 主题:76
  • 回复:318
  • 课时:3
  • 资源:1

留言

你需要登录后才可以留言 登录 | 注册


warmeros 2018-11-25
你好,在么
查看全部