tinnu

  • 2019-02-06
  • 发表了主题帖: CC3200套件OURS-SDK-WFB_探索3——freertos移植失败

    此内容由EEWORLD论坛网友tinnu原创,如需转载或用于商业用途需征得作者同意并注明出处 原本以为freertos移植挺简单的,结果一下就被打脸了。 与常见的freertos移植不同,ti例程里面移植没有使用systick定时器(可能在汇编文件里面使用了,我没看出来)这导致我完全无法像在st和nxp平台那样顺手,只能完全按着例程来……毕竟人家使用的时基是什么都不知道,就更别说自己捣鼓了。 移植的工程完全按照例程里面的freertos_demo来: 移植 1、include选项卡设置: 2、加入库: 如果不想用官方给你做好的freertos库,可以加入以下文件,经过验证,这些文件的效果和.a库是一样的,虽然都不能成功运行,但编译没有错误,运行都是卡在vApplicationMallocFailedHook这个内存分配的钩子函数里面: 3、全局声明 4、工程目录文件 mian是使用freertos_demo的例程,这个例程对于套件例程和官方的launchpad例程是一样的 运行结果: 能够正常初始化,但一旦调用了os相关的函数: osi_MsgQCreate(&MsgQ, "MSGQ", MAX_MSG_LENGTH, 10);复制代码 或者xTaskCreate初始化创建任务并分配内存的函数,就会进入vApplicationMallocFailedHook这个钩子函数。 void vApplicationMallocFailedHook() {     //Handle Memory Allocation Errors     while(1)     {     } }复制代码 一些挣扎: 由于钩子函数vApplicationMallocFailedHook主要是针对内存分配出错,所以尝试过调大configTOTAL_HEAP_SIZE和各个任务的堆栈,但都无补于事 一些猜想: 由于无论调用什么内存分配函数都会产生内存分配的错误,初步怀疑是freertos+ccs的例程在内存分配上有问题。ccs一般都是配合ti_rtos的,freertos趟坑的人少,本身存在bug也不奇怪。 不过也只是猜想而已,本身freertos的功底小半桶水见底,连时基怎么产生的也没看出来: 1、用ctrl+H搜过systick相关字符,真的一个函数都没有 2、也没有发现有哪里调用了xPortSysTickHandler 3、也没发现调用了其他定时器 编译通过,但无法分配内存的freertos工程:

  • 发表了主题帖: CC3200套件OURS-SDK-WFB_探索2

    本帖最后由 tinnu 于 2019-2-6 22:18 编辑 此内容由EEWORLD论坛网友tinnu原创,如需转载或用于商业用途需征得作者同意并注明出处 (一)函数库问题 OURS-SDK-WFB套件本身自带了一个sdk包,这个TI官网下载下来的sdk包非常类似,但经过自己研究还是有些出入的 官方自带的example跟套件自带的example尤其明显,打开common里面的gpio_if文件,就可以看到两者对三个rgb灯的端口定义不一样: 官方定义,用于launch_pad板 //***************************************************************************** // Variables to store TIMER Port,Pin values //***************************************************************************** unsigned int g_uiLED1Port = 0,g_uiLED2Port = 0,g_uiLED3Port = 0; unsigned char g_ucLED1Pin,g_ucLED2Pin,g_ucLED3Pin; #define GPIO_LED1 9 #define GPIO_LED2 10 #define GPIO_LED3 11复制代码 OURS-SDK-WFB套件的定义: //***************************************************************************** // Variables to store TIMER Port,Pin values //***************************************************************************** unsigned int g_uiLED1Port = 0,g_uiLED2Port = 0,g_uiLED3Port = 0; unsigned char g_ucLED1Pin,g_ucLED2Pin,g_ucLED3Pin; #define GPIO_LED1 30 #define GPIO_LED2 22 #define GPIO_LED3 28复制代码 因此如果使用OURS-SDK-WFB套件建议使用套件的common文件夹 (二)路径问题 由于换了个工作环境,结果路径出了些问题,发现了当初路径设计的一些缺陷的地方。 当初的路径都是使用绝对路径的,现在替换为相对路径,前面用宏表示,方便转移工程文件。${WorkspaceDirPath}代替开头那部分,省略了工作空间部分的路径: (三)全局声明 类似keil里面C/C++选项下面的define,ccs或者说eclipse下面也有类似的地方: 右键——properties: 像上图就是在freertos工程定义了USE_FREERTOS的全局宏

  • 加入了学习《配合CCS使用CC3200》,观看 使用CC3200的CCS

  • 2019-01-24
  • 回复了主题帖: 【新人必看】TI M4个人收集所有资料倾情大放送。。。。。。。。。。。。

    哈哈顶一个

  • 发表了主题帖: CC3200套件——OURS-SDK-WFB初上手

    本帖最后由 tinnu 于 2019-1-24 00:37 编辑 OURS-SDK-WFB是上上一年圣诞前后申请的,相隔也有一年时间,可惜当时忙着捣鼓各种事情,最终还是没能参加TI的比赛。 今天开箱准备捣鼓一下,没想到这玩意真的是折腾人啊 (一)开箱 正所谓再丑的板子,只要黑油就高大上。再牛逼的板子,只要是绿油就矮穷挫。 不过板子不仅黑油盖,而且排布也非常漂亮。 (二)资料获取 首先,这个套件的资料光盘我就不多吐槽了,基本没听说过有谁成功地读过这张光盘。 不过里面 资料也很好获取,直接搜索“OURS-SDK-WFB”就可以找到。 不过从光盘这件事情就可以以小窥大,这套件,它的内在……绝对不像它外表看起来那么漂亮。 18M的压缩包,看到这个大小我就隐约有点感觉了,一打开,三个文件: 解压了code,在里面找来找去也没有什么说明书之类的,看来唯一的说明就是根目录下面的那个pdf了 那个PDF有兴趣自己去找,然后用心感受……基本上……也是没什么大用的东西: 以上这页纸就是关于GPIO操作的所有内容,可以看到,这个pdf就类似个操作说明一类的东西,不能指望它是x点原子xtm32库函数开发指南。 code里面的例程,也是众多芯片公司官方例程的一贯尿性,全部搅在一起,根本没办法知道这个工程要搭配哪些文件,分离一个例程出来工作量相当不小。 (三)开发环境搭建 TI,大名鼎鼎的德州仪器,全世界最牛逼的芯片公司,做事当然不能跟那些妖艳的xx苟同,否则怎么凸显自己的高大上?因此它家的编译器也要标新立异: CCS(CCSTUDIO Code Composer Studio):TI家御用IDE 当然,此外用IAR、GCC也会可以的,但唯有KEIL不行。君不见,Keil Software的面子谁敢不给,德州仪器就敢! 不过啊,人家牛逼是一个原因,其实还有一个很重要的原因:你看啊,keil不是要收费吗? 这时候小明同学就举手了,一脸骄傲地说他用keil没花半分钱。 对于这个问题,大家用心感受下面这张图,我就不多说了: 虽然有大佬用虚拟机测过30年也依然是可以用的,但天知道Keil Software有什么手段,微软都说了,你KXS的系统它是知道得一清二楚的,到时候来一招釜底抽薪,该补交的学费还是得乖乖上缴。 这么一看,CCS就牛逼了,人家免费! 然后我兴高采烈地去官网填了一大堆资料,终于把这个15M的软件下了下来: 运行: 这…… 找了半天,总管是把一个804M的压缩包下了下来,这下就不用下载什么JRE,直接安装完成 (四)搭建工程 CCS是基于eclipse的,但电子工程师,有几个会捣鼓eclipse,基本都被keil毒害得差不多,就跟那种离开vs就不会编程的小白差不多,顶多就捣鼓捣鼓QT顶天了。幸好在下有些linux功底,摸索了半天终于是把这个工程给捣鼓了出来。 1、首先在工作空间目录创建一个drive文件夹,从code里面搬几个文件过去: common driverlib inc 2、创建工程,把例程3.1 blinky下面的.c和.h文件搬到工程目录下 3、工程处邮件——properties 在Include Options下面加入头文件位置: 在File Search Path下面加入common下面的静态库: 4、把主板下面的拨码盘第三位拨到1 5、连接主板与PC 6、点击工具链上面的绿色小虫子进行debug 7、这时候会弹出仿真器相关配置: 按照上图选好后点击保存 8、enjoy it (五)其余资料的链接 这个套件里面的资料可以用贫乏来形容了,所幸社区还捣鼓了一番launchpad,是另一款CC3200的板子,资料可以借鉴,里面有函数API手册和芯片手册: 丰富的资料 少量的资料 这块板子的资料

  • 2019-01-18
  • 回复了主题帖: 【GD32F350开发分享三】定时器T0中断:内部高速时钟源

    cliff.xu 发表于 2019-1-16 10:47 我按你的设置测得输出为200Ms。 同样的定时器设置, Timer0测得200ms, Timer2测得100Ms. 留个痕迹 ...
    咳咳,那个问题后来发现是因为没有设置对时钟源,用了没有焊上的外部时钟,结果直接用了内部8M的高速时钟(没有任何倍频)……选对时钟源之后就能按时输出了

  • 2018-11-19
  • 回复了主题帖: 四轴视觉机械臂——基于F350下位机

    特效化妆师 发表于 2018-11-1 16:16 一定不要忽视我啊,我辣么可爱的
    呃……主要是这两个月都要赶着考研复习进度,现在我的复习进度非常尴尬……如果可以的话十二月之后再交流?{:1_133:}

  • 回复了主题帖: 四轴视觉机械臂——基于F350下位机

    bqgup 发表于 2018-10-20 18:05 楼主,不知道你的舵机电路解决没,我这儿有一个调试好的舵机电路图,如果您需要的话,我就发给你看看用不用 ...
    我目前主要的pwm传输距离有些问题,我之前为这个搞了挺久的,别人推荐我用开关电路,但也只能传输40cm左右,多一点就不稳。如果版主有方案那就太好了,不过这两个月正在赶着考研复习,等十二月之后再请教可行:loveliness:

  • 2018-10-19
  • 发表了主题帖: 四轴视觉机械臂——基于F350下位机

    本帖最后由 tinnu 于 2018-10-20 00:23 编辑 (一)软硬件结构 上位机:连接摄像头,进行图像识别、用户交互 下位机:指令解析,信息上报,传感器信息采集,电机脉冲控制,空间位置顺解逆解 机械结构:3轴+1轴+1夹持架。 (二)机械结构部分介绍 底部三轴采用步进电机控制,保证精度; 主要负重的主轴和副轴采用42bygh48,旋转轴采用42bygh34。 (关于这个电机的问题真的坑啊……我设计的机械臂有点太大了,不断加传动比都很容易出现力矩不够的情况,1.0版的机械臂1:3.5的传动比,一直换到42bygh48都不行,42bygh48基本是市面上常见的步进里面力矩最大的……而且这个步进电机也是贼贵,几个几个的买真的吃不消……最后不行,改版弄出了一个2.0般的机械臂,1:5的传动比) 末端旋转轴采用mg996舵机控制; 夹持架采用mg996 (三)硬件结构 一开始是用cnc shield控制板+一块自己焊的接口板(接角度传感器+限位开关): 后来自己画了一块: 黑油板是不是很酷?其实因为我犯了个很难受的错误,导致一些地线没接上,所以其实这个板子背后有好几根飞线来着…… 舵机供电也是个巨坑,我设计了两个供电方案保证成功: LM7805从12V转到5V: 还有一个就是直接usb供 (四)下位机功能1、传感器信息采集步进电机这种东西虽然常用于开环控制,但奈何那都是力矩经过验算的情况,我这个容易遇到力矩大的角度的机械臂不知道什么时候就失步了,所以用两个mpu6050反馈主轴和副轴的角度信息。不过这个反馈并非数控传统意义上的闭环控制,只是运动结束之后同步一下。此外,如果传感器损坏或者接触不良等恶劣情况下系统也会转为开环控制。程序设计中也为adxl345提供了接口,不过因为时间关系还没来得及实现,不过相比于mpu6050,前者还是比较实惠的,虽然mpu6050可以姿态融合,但奈何对采集速度要求严格,间隔一大就读不出来,结果还是直接读角度算了。2、信息上报:下位机接口有两个,USART2的串口和基于USART1的esp8266无线模块,可以通过SERIAL交互、tcp socket交互上报设计了专门的上报体系,不会影响电机控制算法。3、电机脉冲控制:保证电机脉冲控制的优先度最高,采用定时器生成时基、控制时基单元数量控制电机运动速度的方式。4、指令解析:为了保证指令的识别度我没用标准的NC指令,自己设计了一套:指令以_&为开始,以;结束,包含直接传入xy坐标、前后左右、旋转、夹持、翻转、复位、查询:int command_operate(u8 *USART_RX_BUF,u16 USART_RX_STA) {         double x_dis=x_current,y_dis=y_current;                //保存临时路程变量         u16 speed;                                                                        //保存临时速度参数              char SearchChar[USART_REC_LEN];         char command[3]="0";     double command_num[3]={0};                  u16 len = USART_RX_STA&0x3fff;         u8 CommandCount = 0;                  //1、获取指令、参数         memcpy(SearchChar, USART_RX_BUF, len);         CommandCount = search4(SearchChar, command, command_num);                  if(CommandCount

  • 2018-10-05
  • 回复了主题帖: F350的pwm配置不成功

    到现在依然没有发现问题在哪,但改用TIMER1的CH1通道,通过PA1输出 即 把上面的TIMER15改为TIMER1、CH0改为CH1、PA6改为PA1 又可以正常输出,初步认为是TIMER1定时器有一些TIMER15定时器无法配置的功能,或者TIMER15本身有bug void pwm_pin_config(void) {         rcu_periph_clock_enable(RCU_GPIOA);                 gpio_af_set(GPIOA, GPIO_AF_2,                                 GPIO_PIN_1);     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,                   GPIO_PIN_1);     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,                             GPIO_PIN_1); } /*!     \ brief配置TIMER外设     \ param [in] none     \ param [out] none     \ retval无 */ void pwm_timer_config(void) {     timer_parameter_struct timer_initpara;         timer_oc_parameter_struct pwm_initpara;                 pwm_pin_config();             rcu_periph_clock_enable(RCU_TIMER1);     timer_deinit(TIMER1);     timer_initpara.prescaler = 1800-1;     timer_initpara.alignedmode = TIMER_COUNTER_EDGE;     timer_initpara.counterdirection = TIMER_COUNTER_UP;     timer_initpara.period = 1200-1;     timer_initpara.clockdivision = TIMER_CKDIV_DIV1;         timer_initpara.repetitioncounter = 0;     timer_init(TIMER1,&timer_initpara);     /* TIMERf1通道控制更新中断启用*/ //    timer_interrupt_enable(TIMER1,TIMER_INT_UP); //        nvic_irq_enable(TIMER1_IRQn,0,1);                 /*         第二步:比较模式配置:         设置CHxCOMSEN位来配置输出比较影子寄存器;         设置CHxCOMCTL位来配置输出模式(置高电平/置低电平/反转);         设置CHxP/CHxNP位来选择有效电平的极性;         设置CHxEN使能输出。         */         pwm_initpara.outputstate = TIMER_CCX_ENABLE;         pwm_initpara.ocpolarity = TIMER_OC_POLARITY_HIGH;         //pwm_initpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;                 timer_channel_output_config(TIMER1, TIMER_CH_1, &pwm_initpara);         timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_PWM1);         timer_channel_output_shadow_config(TIMER1, TIMER_CH_1, TIMER_OC_SHADOW_ENABLE);         /*         第四步:通过TIMERx_CAR寄存器和TIMERx_CHxCV寄存器配置输出比较时基:         CHxVAL可以在运行时根据你所期望的波形而改变         */         timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, 1000);             /* TIMER1计数器启用*/     timer_enable(TIMER1); }复制代码

  • 2018-10-03
  • 发表了主题帖: F350的pwm配置不成功

    本帖最后由 tinnu 于 2018-10-4 00:44 编辑 void pwm_pin_config(void) {         rcu_periph_clock_enable(RCU_GPIOA);              gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLDOWN,                   GPIO_PIN_6|GPIO_PIN_7);     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ,                             GPIO_PIN_6|GPIO_PIN_7);         gpio_af_set(GPIOA, GPIO_AF_5,                                 GPIO_PIN_6|GPIO_PIN_7); } void pwm_timer_config(void) {     timer_parameter_struct timer_initpara;         timer_oc_parameter_struct pwm_initpara;                  pwm_pin_config();              rcu_periph_clock_enable(RCU_TIMER15);     timer_deinit(TIMER15);     timer_initpara.prescaler = 1800-1;     timer_initpara.alignedmode = TIMER_COUNTER_EDGE;     timer_initpara.counterdirection = TIMER_COUNTER_UP;     timer_initpara.period = 1200-1;     timer_initpara.clockdivision = TIMER_CKDIV_DIV1;         // timer_initpara.repetitioncounter = 0;     timer_init(TIMER15,&timer_initpara);     /* TIMERf15通道控制更新中断启用*/ //    timer_interrupt_enable(TIMER16,TIMER_INT_UP); //        nvic_irq_enable(TIMER16_IRQn,0,1);                  pwm_initpara.outputstate = TIMER_CCX_ENABLE;         //pwm_initpara.outputnstate = TIMER_CCXN_DISABLE;         pwm_initpara.ocpolarity = TIMER_OC_POLARITY_HIGH;         pwm_initpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;                  timer_channel_output_config(TIMER15, TIMER_CH_0, &pwm_initpara);                  timer_channel_output_mode_config(TIMER15, TIMER_CH_0, TIMER_OC_MODE_PWM1);                  timer_channel_output_pulse_value_config(TIMER15, TIMER_CH_0, 1000);                  timer_channel_output_shadow_config(TIMER15, TIMER_CH_0, TIMER_OC_SHADOW_ENABLE);     /* TIMER15计数器启用*/     timer_enable(TIMER15); }复制代码 实测定时器部分配置是没问题的,用中断闪烁led成功了,但PA6引脚保持低电平没有pwm波产生

  • 2018-10-02
  • 回复了主题帖: 【GD32F350开发分享三】定时器T0中断:内部高速时钟源

    我用内部晶振108的,类似楼主的方法配置:     timer_initpara.prescaler = 1000-1;     timer_initpara.alignedmode = TIMER_COUNTER_EDGE;     timer_initpara.counterdirection = TIMER_COUNTER_UP;     timer_initpara.period = 10800-1;     timer_initpara.clockdivision = TIMER_CKDIV_DIV1;复制代码 这样子感觉应该是(10800*1000)/108000=100ms中断一次,可是实际是1s中断一次,想不通有什么问题……

  • 2018-09-27
  • 发表了主题帖: F350串口那些事

    本帖最后由 tinnu 于 2018-9-27 19:40 编辑 (一)丰富的串口功能 首先必须承认GD的USART做得相当丰富,LIN、ModBus有类似断开帧检测功能,开起来相当有意思,不过这个阶段还展示不打算尝鲜,首要目标是事先串口普通发送和接收中断。 (二)串口使能 demo里面已经有了串口使能的示例程序: void EvbUart1Config(void) {     rcu_periph_clock_enable(RCU_GPIOA);     rcu_periph_clock_enable(RCU_USART1);     /* connect port to USART1_Tx */     gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_2);     /* connect port to USARTx_R1 */     gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_3);     /* configure USART1 Tx as alternate function push-pull */     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_2);     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_2);     /* configure USART2 Rx as alternate function push-pull */     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_3);     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_3);     /* USART2 configure */     usart_deinit(USART1);     usart_baudrate_set(USART1,115200);     usart_receive_config(USART1, USART_RECEIVE_ENABLE);     usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);     usart_enable(USART1); }复制代码 (三)printf的重定向输出,把原子的直接搬过来改一下发送函数就可以了 ////////////////////////////////////////////////////////////////// //加入以下代码,支持printf函数,而不需要选择use MicroLIB          #if 1 #pragma import(__use_no_semihosting)             //标准库需要的支持函数                  struct __FILE {         int handle; }; FILE __stdout;       //定义_sys_exit()以避免使用半主机模式    _sys_exit(int x) {         x = x; } //重定义fputc函数 int fputc(int ch, FILE *f) {               usart_data_transmit(USART1, (uint8_t)ch);     while(RESET == usart_flag_get(USART1, USART_FLAG_TBE));         return ch; } #endif 复制代码 (四)USART接收器 用户手册里面这样解释接收器:
    当一个数据帧接收完成,USART_STAT寄存器中的RBNE置位,如果设置了USART_CTL0寄存器中相应的中断使能位RBNEIE,将会产生中断。在USART_STAT寄存器中可以观察接收状态标志。 当接收到一帧数据,而RBNE位还没有被清零,随后的数据帧将不会存储在数据接收缓冲区中。 USART_STAT 寄存器中的溢出错误标志位ORERR 将置位。如果使能DMA 并置位 USART_CTL2寄存器中ERRIE位或者置位RBNEIE,将产生中断。 在一个接收过程中,RBNE、NERR、PERR、FERR和ORERR总是同时置位。如果没有使能 DMA,软件需检查RBNE中断是否由NERR、PERR、FERR或者ORERR置位产生。
    里面涉及了很多寄存器,也可以参考: 总的来说,就是接收器完了之后,置位RBNE(接收完成)寄存器。 再看看USART接收器寄存器,发现只有9个位,也就是接收器一帧只有一个字节。 那怎么操作就很明显了:接收一个字节置位一次,把RBNEIE(中断使能位)使能之后就会进入中断服务函数! (五)中断服务函数 那么中断服务函数是什么呢? 因为GD跟ST的库各种相似,我们可以参考一下ST的代码形式:
    stm32的启动文件startup_stm32f10x_md.s中有:DCD USART1_IRQHandler
    那GD的启动文件也类似的找到,在88行: 原来也是USART1_IRQHandler 接下来依然是借鉴原子的服务函数: #define USART_REC_LEN                          200          //定义最大接收字节数 200 #define u8 unsigned char #define u16 unsigned short 复制代码 //串口1中断服务程序 //注意,读取USARTx->SR能避免莫名其妙的错误           u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节. u16 USART_RX_STA=0;                        //接收状态标记        void USART1_IRQHandler(void)                        //串口1中断服务程序 {         u8 Res;         if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)         {                 Res =usart_data_receive(USART1);        //读取接收到的数据                 usart_interrupt_flag_clear(USART1, USART_INT_FLAG_RBNE);        //清除标志位,否则不会读取下一帧                                 if((USART_RX_STA&0x8000)==0)//接收未完成                 {                         if(USART_RX_STA&0x4000)//接收到了0x0d                         {                                 if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始                                 else USART_RX_STA|=0x8000;        //接收完成了                         }                         else //还没收到0X0D                         {                                        if(Res==0x0d)USART_RX_STA|=0x4000;                                 else                                 {                                         USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;                                         USART_RX_STA++;                                         if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收                                           }                                          }                 }                             } } 复制代码 (六)中断使能 根据上面的表格,可以发现,需要使能的控制位是RBNEIE(中断使能位); 在USART的库里面我们发现了这个函数: 因此调用方法:         usart_interrupt_enable(USART1,USART_INT_RBNE);复制代码 但是程序运行后发现并不能进入中断,百般思量没有头绪,又去翻了一下ST的例程,终于发现还有个NVIC的东西需要设置! GD的库跟ST还是有些出入的,NVIC的设置形式可以借鉴systick里面的调用形式:     NVIC_SetPriority(USART1_IRQn, 0x00U);         NVIC_EnableIRQ(USART1_IRQn);复制代码 接收中断成功! 补充内容 (2018-10-2 20:54): 关于最后中断分组处,值得注意: NVIC_SetPriority、NVIC_EnableIRQ都属于弱定义的函数,在core_cm4里面。 gd有专门封装了nvic相关函数,在"gd32f3x0_misc.h"里面,nvic_irq_enable一个函数拥有以上两个函数的作用 补充内容 (2018-10-2 20:55): 此外还要用nvic_priority_group_set函数设置一下抢断优先级和子优先级

    1. 【原创】 CC3200套件OURS-SDK-WFB_探索3——freertos移植失败 4/223 【无线连接】 2019-02-06
    2. 【原创】 CC3200套件OURS-SDK-WFB_探索2 1/167 【无线连接】 2019-02-06
    3. 【原创】 CC3200套件——OURS-SDK-WFB初上手 3/428 【无线连接】 2019-01-24
    4. 【GD32F350作品提交】 四轴视觉机械臂——基于F350下位机 11/1027 【GD32 MCU】 2018-10-19
    5. 【问题讨论】 F350的pwm配置不成功 1/469 【GD32 MCU】 2018-10-03
    6. 【经验分享】 F350串口那些事 2/366 【GD32 MCU】 2018-09-27
    1. 哈哈顶一个
    2. cliff.xu 发表于 2019-1-16 10:47 我按你的设置测得输出为200Ms。 同样的定时器设置, Timer0测得200ms, Timer2测得100Ms. 留个痕迹 ...
      咳咳,那个问题后来发现是因为没有设置对时钟源,用了没有焊上的外部时钟,结果直接用了内部8M的高速时钟(没有任何倍频)……选对时钟源之后就能按时输出了
    3. 四轴视觉机械臂——基于F350下位机 11/1027 【GD32 MCU】 2018-11-19
      特效化妆师 发表于 2018-11-1 16:16 一定不要忽视我啊,我辣么可爱的
      呃……主要是这两个月都要赶着考研复习进度,现在我的复习进度非常尴尬……如果可以的话十二月之后再交流?{:1_133:}
    4. 四轴视觉机械臂——基于F350下位机 11/1027 【GD32 MCU】 2018-11-19
      bqgup 发表于 2018-10-20 18:05 楼主,不知道你的舵机电路解决没,我这儿有一个调试好的舵机电路图,如果您需要的话,我就发给你看看用不用 ...
      我目前主要的pwm传输距离有些问题,我之前为这个搞了挺久的,别人推荐我用开关电路,但也只能传输40cm左右,多一点就不稳。如果版主有方案那就太好了,不过这两个月正在赶着考研复习,等十二月之后再请教可行:loveliness:
    5. F350的pwm配置不成功 1/469 【GD32 MCU】 2018-10-05
      到现在依然没有发现问题在哪,但改用TIMER1的CH1通道,通过PA1输出 即 把上面的TIMER15改为TIMER1、CH0改为CH1、PA6改为PA1 又可以正常输出,初步认为是TIMER1定时器有一些TIMER15定时器无法配置的功能,或者TIMER15本身有bug void pwm_pin_config(void) {         rcu_periph_clock_enable(RCU_GPIOA);                 gpio_af_set(GPIOA, GPIO_AF_2,                                 GPIO_PIN_1);     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,                   GPIO_PIN_1);     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,                             GPIO_PIN_1); } /*!     \ brief配置TIMER外设     \ param [in] none     \ param [out] none     \ retval无 */ void pwm_timer_config(void) {     timer_parameter_struct timer_initpara;         timer_oc_parameter_struct pwm_initpara;                 pwm_pin_config();             rcu_periph_clock_enable(RCU_TIMER1);     timer_deinit(TIMER1);     timer_initpara.prescaler = 1800-1;     timer_initpara.alignedmode = TIMER_COUNTER_EDGE;     timer_initpara.counterdirection = TIMER_COUNTER_UP;     timer_initpara.period = 1200-1;     timer_initpara.clockdivision = TIMER_CKDIV_DIV1;         timer_initpara.repetitioncounter = 0;     timer_init(TIMER1,&timer_initpara);     /* TIMERf1通道控制更新中断启用*/ //    timer_interrupt_enable(TIMER1,TIMER_INT_UP); //        nvic_irq_enable(TIMER1_IRQn,0,1);                 /*         第二步:比较模式配置:         设置CHxCOMSEN位来配置输出比较影子寄存器;         设置CHxCOMCTL位来配置输出模式(置高电平/置低电平/反转);         设置CHxP/CHxNP位来选择有效电平的极性;         设置CHxEN使能输出。         */         pwm_initpara.outputstate = TIMER_CCX_ENABLE;         pwm_initpara.ocpolarity = TIMER_OC_POLARITY_HIGH;         //pwm_initpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;                 timer_channel_output_config(TIMER1, TIMER_CH_1, &pwm_initpara);         timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_PWM1);         timer_channel_output_shadow_config(TIMER1, TIMER_CH_1, TIMER_OC_SHADOW_ENABLE);         /*         第四步:通过TIMERx_CAR寄存器和TIMERx_CHxCV寄存器配置输出比较时基:         CHxVAL可以在运行时根据你所期望的波形而改变         */         timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, 1000);             /* TIMER1计数器启用*/     timer_enable(TIMER1); }复制代码
    6. 我用内部晶振108的,类似楼主的方法配置:     timer_initpara.prescaler = 1000-1;     timer_initpara.alignedmode = TIMER_COUNTER_EDGE;     timer_initpara.counterdirection = TIMER_COUNTER_UP;     timer_initpara.period = 10800-1;     timer_initpara.clockdivision = TIMER_CKDIV_DIV1;复制代码 这样子感觉应该是(10800*1000)/108000=100ms中断一次,可是实际是1s中断一次,想不通有什么问题……
    7. 先累积一点芯币先
    8. STM32F4XX中文数据手册 166/15767 【stm32/stm8】 2017-10-16
      两份有什么不同吗?
    9. 一下是写函数的错误时序,很奇怪,明明是同一段代码,第二位却丢失了下降沿
    10. 我用楼主的函数,发现读是正常的,但写部分时序不知道为什么,明明是同一段代码,第一位、第三位以后的都是正常的,第二位的scl下降沿却丢失了,无论如何都调不出来。最后是把写函数的case条件全部移后以为才成功。 我的写函数: 5'd9,5'd10,5'd11,5'd12,5'd13,5'd14,5'd15,5'd16:                         begin                         isQ <= 1'b1;                         if(C1 == 3'd5)                                 rSDA <= rData[5'd16 - i];                                                 if(C1 <= 3'd4)                rSCL <= 1'b0;                         else if(C1 == (TF+TLOW))                rSCL <= 1'b1;                                                 if(C1 == TCLK -1'b1)                                 begin C1 <= 8'b0; i <= i + 1'b1;        end                         else        C1 <= C1 + 1'b1;                         end
    11. 楼主,你写数据伪函数那里有个错误: rSDA <= oData[5'd14 - i]; 是rData,不是oData
    12. 原谅在下挖坟,在下不是很看得懂楼主的程序……C1是什么啊?还有为什么要二次起始位?
  • TA暂时无记录哦~
  • TA暂时无记录哦~
  • TA暂时无记录哦~
TA暂时无记录哦~

最近访客

< 1/1 >

统计信息

已有16人来访过

  • 芯币:52
  • 好友:--
  • 主题:6
  • 回复:12
  • 课时:--
  • 资源:--

留言

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


现在还没有留言