donatello1996

  • 2019-08-04
  • 发表了主题帖: 【麦昆试用】迟来的第四帖——试用Arduino IDE开发环境&定时器中断

    这个标题的因果关系应该反过来说,因为我想调通microbit主控板的定时器中断,在网上寻求答案,最终得知最便捷的方式是通过Arduino IDE开发环境实现,因为这个开发环境可以从开源社区下载安装一切纳入Arduino家族的开发板的资源并获得充足支持,在观看完代码之后,我发现Arduino IDE开源库里面对于microbit主控板的定时器中断例程实际上也是通过控制板上主控单片机nrf51822的寄存器实现的,将寄存器操作封装成类和对象的操作,正是Arduino开发的最常见操作。 首先下载Arduino IDE开发环境,这个不用多赘述,直接在arduino.cc官网下载即可,下载安装Arduino IDE这步很简单,安装Demo例程也很简单,难点在于安装器件支持包,这里先简单介绍下怎么安装micro:bit的DEMO例程。 打开ArduinoIDE,打开项目->库,搜索micro:bit,即可找到micro:bit所对应的Demo例程: 这个例程下有齐了micro:bit板子的大部分BSP(板级)Demo,如blink闪灯,定时器,按键,蓝牙控制器等,我选择这期主题——定时器,打开timerdemo: 然后到了最麻烦的一步(这步难度不高,就是很麻烦),那就是ArduinoIDE软件内部安装器件支持包了,这个跟电脑所在的网络环境息息相关,稍微有点差错都会下载失败,我被这个折腾了很久,最终是用公司的网络艰难完成的器件支持包安装,这里推荐大家使用离线安装的方式,离线安装方式繁琐但可以绕开ArduinoIDE内部蛋疼的联网机制: timerdemo定时器例程写法与普通的KEIL程序如出一辙,使用寄存器方式配置定时器,然后在中断服务函数里面触发,例程使用的是NRF52832主控的定时器2,有两个比较事件,在同一个中断服务函数里面触发: // This is a 'low level' demo showing how to use timer 2 (the only available timer really) // to blink an LED. This code turned into the matrix handler, so you cant use it and the // Adafruit_Microbit library at the same time but maybe its useful! const int COL1 = 3;     // Column #1 control const int LED = 26;     // 'row 1' led void start_timer(void) {       NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer;              // Set the timer in Counter Mode   NRF_TIMER2->TASKS_CLEAR = 1;                           // clear the task first to be usable for later   NRF_TIMER2->PRESCALER   = 8;     NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit;     //Set counter to 16 bit resolution   NRF_TIMER2->CC[0] = 32000;                               //Set value for TIMER2 compare register 0   NRF_TIMER2->CC[1] = 5;                                   //Set value for TIMER2 compare register 1        // Enable interrupt on Timer 2, both for CC[0] and CC[1] compare match events   NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos) | (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos);   NVIC_EnableIRQ(TIMER2_IRQn);        NRF_TIMER2->TASKS_START = 1;               // Start TIMER2 }      /** TIMTER2 peripheral interrupt handler. This interrupt handler is called whenever there it a TIMER2 interrupt  * Don't mess with this line. really.  */  extern "C"  { void TIMER2_IRQHandler(void) { timer_pal();  } } void timer_pal(void) {   if ((NRF_TIMER2->EVENTS_COMPARE[0] != 0) && ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0))   {     NRF_TIMER2->EVENTS_COMPARE[0] = 0;         //Clear compare register 0 event     Serial.println("TIMER2 Event C0");   }     if ((NRF_TIMER2->EVENTS_COMPARE[1] != 0) && ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE1_Msk) != 0))   {     NRF_TIMER2->EVENTS_COMPARE[1] = 0;         //Clear compare register 1 event     Serial.println("TIMER2 Event C1");   } }   void setup() {     Serial.begin(115200);   Serial.println("microbit is ready!");   // because the LEDs are multiplexed, we must ground the opposite side of the LED   pinMode(COL1, OUTPUT);   digitalWrite(COL1, LOW);       pinMode(LED, OUTPUT);     start_timer(); } void loop(){   Serial.println("blink!");   delay(500); }   这里小改了一下,波特率改成115200,定时器中断触发里面改成串口打印,看看运行效果:  

  • 2019-07-18
  • 回复了主题帖: 【麦昆试用】迟来的第二帖——调通小车上的基础输入\输出外设

    dcexpert 发表于 2019-7-17 13:34 用的是Arduino编程啊
    嗯,因为我熟悉C/C++家族的编程习惯,用python是真心不习惯

  • 回复了主题帖: 【麦昆试用】迟来的第三帖——无线控制小车简单篇

    dcexpert 发表于 2019-7-18 09:17 http://www.bittysoftware.com/apps/bitty_controller.html   bitty controller可以配合makecod ...
    有了解过这个软件,但是我还是想用lightblue抓一下透传的数据,不知道为啥不能识别,是MAC地址配置有问题还是配置了不可见

  • 发表了主题帖: 【麦昆试用】迟来的第三帖——无线控制小车简单篇

          小车上的microbit主控板没有富余的GPIO输入输出接口,使得我原本加8266wifi模块的想法落空了,主控板根本接不了8266除非飞线!我又不想飞线,怎么办?幸好我之前参加过e络盟比赛拿到过一块一模一样的microbit主控板,只不过是1.3版本(小车上的主控板是1.5版本,程序完全通用):      两个microbit主控板均可通过micro usb线插到电脑上并分开烧录不同的代码,以及分开串口通信: 然后进入正题,无线通信,microbit主控板上使用的无线通信芯片是北欧半导体的nrf58122,一开始我还以为是标准蓝牙协议栈,还用手机的LightBlue APP进行抓包,但是一无所获,说明主控板的协议栈不是标准蓝牙协议栈,需要在APP端加入一些高端操作(目前我还没学会的蓝牙物联网通信知识)才可以进行透传: 但是好在microbit主控板是一个高度集成,入门难度极其简单的开发套件,如果有两块microbit主控板在的话,可以直接进行同频道透传,先打开无线通信外设,遥控端和小车端都选择频道1进行通信,接收部分使用回调函数实现: 遥控端代码: #include <DFMicrobit_Radio.h> #include <Microbit_Matrix.h> void onRadioReceive(String message) { Serial.println(message); message=""; } void setup() { Radio.turnOn(); Radio.setGroup(1); Radio.setCallback(onRadioReceive); Serial.begin(115200); } void loop() { if(Button_A.isPressed()&&!Button_B.isPressed()) { Radio.send("1"); } else if(!Button_A.isPressed()&&Button_B.isPressed()) { Radio.send("2"); } else if(!Button_A.isPressed()&&!Button_B.isPressed()) { Radio.send("3"); } else if(Button_A.isPressed()&&Button_B.isPressed()) { Radio.send("4"); } } 小车端代码: #include <DFRobot_URM10.h> #include <Maqueen_Motor.h> #include <Microbit_Matrix.h> #include <DFRobot_NeoPixel.h> #include <DFMicrobit_Radio.h> DFRobot_URM10 urm10(1,2); Maqueen_Motor motor; DFRobot_NeoPixel rgb_display_15; void onRadioReceive(String message) { if(message=="1") { motor.motorRun(motor.LEFT,motor.CW,255); motor.motorRun(motor.RIGHT,motor.CW,255); rgb_display_15.setRangeColor(-1, -1, 0xff0000); } else if(message=="2") { motor.motorRun(motor.LEFT,motor.CCW,255); motor.motorRun(motor.RIGHT,motor.CCW,255); rgb_display_15.setRangeColor(-1, -1, 0x00ff00); } else if(message=="3") { motor.motorRun(motor.LEFT,motor.CW,0); motor.motorRun(motor.RIGHT,motor.CW,0); rgb_display_15.setRangeColor(-1, -1, 0x0000ff); } else if(message=="4") { motor.motorRun(motor.LEFT,motor.CW,255); motor.motorRun(motor.RIGHT,motor.CW,0); rgb_display_15.setRangeColor(-1, -1, 0xffffff); } } void setup() { Serial.begin(115200); rgb_display_15.begin(15, 4, 255); Radio.turnOn(); Radio.setGroup(1); Radio.setCallback(onRadioReceive); } int flag_open_ble=0; void loop() { } 看看效果:小车在前进、后退、停止时使用三种不同颜色的底灯进行表示,当按下遥控端A键时小车前进,按下遥控端B键时后退,同时按下时原地打转:

  • 2019-07-17
  • 发表了主题帖: 【麦昆试用】迟来的第二帖——调通小车上的基础输入\输出外设

           小车上有许多可用的外设如RGB灯,LED点阵,超声波模块,循迹模块等,要玩通小车,就要把板上的外设调一遍。        点阵用于输出HelloWorld有许多坛友已经试过了,我就充分利用点阵上的25个点,用于对应超声波探测模块的1~25厘米探测范围,每一个点代表一厘米,动态显示小车的障碍物距离,两个红色车灯用于显示底部循迹模块的信号,而小车底部的RGB底灯就只用于检测AB按键输入情况。 #include <DFRobot_URM10.h> #include <Maqueen_Motor.h> #include <Microbit_Matrix.h> #include <DFRobot_NeoPixel.h> DFRobot_URM10 urm10(1,2); Maqueen_Motor motor; DFRobot_NeoPixel rgb_display_15; void setup() { Serial.begin(115200); rgb_display_15.begin(15, 4, 255); } int distance=0,i,j; void loop() { distance=urm10.getDistanceCM(); distance/=5; if(distance>24)distance=24; for(i=0;i<=distance;i++) MMatrix.drawPixel(i/5,i%5,1); for(j=distance;j<=24;j++) MMatrix.drawPixel(j/5,j%5,0); if(digitalRead(13)) { digitalWrite(8,1); } else digitalWrite(8,0); if(digitalRead(14)) { digitalWrite(12,1); } else digitalWrite(12,0); if(Button_A.isPressed()&&Button_B.isPressed()) rgb_display_15.setRangeColor(-1, -1, 0xffffff); else if(Button_A.isPressed()&&!Button_B.isPressed()) rgb_display_15.setRangeColor(-1, -1, 0xff0000); else if(!Button_A.isPressed()&&Button_B.isPressed()) rgb_display_15.setRangeColor(-1, -1, 0x0000ff); else rgb_display_15.setRangeColor(-1, -1, 0x00ff00); }   循迹模块控制车灯:   按键控制尾灯: 超声波避障模块实时反馈到点阵屏:

  • 2019-07-16
  • 回复了主题帖: 【麦昆试用】麦昆新的超声波驱动

    看看代码怎么写

  • 发表了主题帖: 【麦昆试用】迟来的第一帖&小车不能同时驱动两轮反转的BUG

         小车收到将近两个月了,无奈一直忙于面试而没有空闲发布帖子,现在会陆续补上。      小车的拼装和开发环境搭建不再赘述,不过值得注意的是,小车的microbit Mind+开发环境在今年6月份的时候做了一次更新,mbed的最新驱动号为16466,放出最新的mbed串口驱动以方便win10的mbed开发者:      win10最新更新的201904版本系统似乎与mbed16466号驱动冲突,无奈之下只好降级到201811的老版本,如图是新版win10中存在的串口驱动无法识别的问题,该问题至今无解,只能通过降系统版本的方式解决:      小车拼装完成图,实际上小车在刚拿到手的时候就拼装好了,放这两个月了: 这里需要反映的一个问题,小车的电机模组驱动做得不是很好,在两轮都需要进行正反刹车的时候会出现单个轮直接停摆的BUG,这个BUG的存在使得小车只能做一些简单的,规律的运动,而无法实现酷炫的急刹车+倒车等运动: 如果只是针对一个轮子进行刹车运动的话倒是没有问题: 我通过个人薄弱的电机知识斗胆在论坛内抛砖引玉,希望有搞电机的相关大佬们可以讨论下此问题,也希望麦昆那边可以看到我的帖子,我猜测原因有二:第一,小车所使用的电机驱动芯片驱动力不足,无法实现两轮同时刹车+反转;第二,电机驱动芯片的死区控制做得不好(驱动力足够的前提)。

  • 2019-06-23
  • 发表了主题帖: 项目提交

    先起个草稿

  • 2019-03-15
  • 回复了主题帖: 联想栗子开发板评测活动获奖名单~

    谢谢管管谢谢EE谢谢栗子社区谢谢栗子:pleased:确认信息无误

  • 2019-03-12
  • 加入了学习《正点原子手把手教你学STM32-M7》,观看 STM32学习方法+视频说明

  • 2019-02-24
  • 回复了主题帖: 下载、评论赢双重好礼|PI 邀您跟littleshrimp一起拆解小米最新二合一充电宝

           首先是充电宝充电方式由原来的microUSB转为市电接口,这是一种革新,目前没有别家充电宝在小米之前做出这种方案,不过为啥要把microUSB舍弃掉呢,这个我就非常不解,我觉得两种充电方式共存最好。       输出5V3A中规中矩,如果之后推出5V4A就更上一层楼了。       由于我不懂模电,因此对QC协议和【INN2215K 是一款集成了 650 V MOSFET、同步整流、反馈和恒功率特性的适合USB-PD 和 QC 3.0 应用的离线式反激恒压/恒流开关 IC】这些知识点一脸懵逼,直接跳过。      【电池背面丝印为 ZMJ F8216AUBN 的 IC 网上说是紫米电子自己定制的一款单片机没找到资料,应该是用于电池温度检测、电池电量检测、LED 驱动等功能。】这个总算是稍微懂一点,就是一个专门应用与电池电量管理应用的单片机,并且还是定制的。       最后作者还实际用万用表来测试快充效果,确实很666,主要是因为我家的充电宝没有快充功能所以很羡慕。

  • 2019-01-28
  • 发表了主题帖: 【Nucleo G071评测】最终结项

         最终结项是结合QT上位机程序一起使用的,上位机程序采用串口通信,原理与串口助手大同小异只是做了一些简单的按钮用于控制下位机即G0板子,如框图所示,做了一个控制照明灯和三色RGB灯的按钮,以及采集温湿度和光照强度的进度条: 打开串口之后能接收到实时的温湿度和光照强度信息: 通过按钮控制LED照明灯和三色RGB灯: OLED上也是实时显示温湿度和光照强度信息: 上传上位机工程文件和G0板子工程文件:

  • 2019-01-27
  • 发表了主题帖: 【Nucleo G071评测】接上串口LORA模块进行实验&远程控制继电器

    本帖最后由 donatello1996 于 2019-1-27 23:18 编辑     原计划中需要用到两个LORA模块进行无线串口数据透传,大致的框图如下,仅仅是做了一个非常简单的示意图:     G0板子和CH340串口模块都连上LORA模块,两个LORA模块配置好通信的频率信道等,通过串口与G0板子和CH340模块通信,并且为了加强信号,两个LORA模块均使用5V供电,插上专用天线:         CH340模块连接电脑,可虚拟成串口:            G0板子单独供电,进行透传工作: 使用语句 sprintf(s,"%.1f℃ %.1f%%\n",temper_value,humi_value); UART1_Send_String(s); 并循环执行,可在虚拟串口终端打印温湿度信息: 光检测不够,再做个控制,如远程控制一个继电器,在中断处理函数中加入代码,检测电脑端串口LORA模块发出的数据,第5个字节的数据即rx_buf[4]控制PD6引脚电平,PD6上再接一个继电器,就可以实现远程控制继电器,为1则控制继电器闭合,为2则控制继电器断开: void UART_DMA_Get() {         if(recv_end_flag==1)         {                 recv_end_flag=0;                 //printf("rx_buf=%s\n",rx_buf);                 if(rx_buf[0]==0x01)                 {                         TIM3->CCR1=rx_buf[1];                         TIM3->CCR3=rx_buf[2];                         TIM3->CCR4=rx_buf[3];                         if(rx_buf[4]==0x01)                                 HAL_GPIO_WritePin(GPIOD,GPIO_PIN_6,0);                         else if(rx_buf[4]==0x02)                                 HAL_GPIO_WritePin(GPIOD,GPIO_PIN_6,1);                 }         }         HAL_UART_Receive_DMA(&huart1,(unsigned char*)rx_buf,BUFFERSIZE); }

  • 发表了主题帖: 【Nucleo G071评测】检测HTS221温湿度传感器数据

         庆科的扩展板上带有HTS221温湿度传感器,传感器走I2C总线,与之前的OLED屏幕共用总线,这个传感器啥都好,精度和采集速率要比DHT11快得多,就是工作方式是插值型,写程序计算数值有一丁点的繁杂: #define HTS221_ADDRESS                              0xBE #define HTS221_RES_CONF_ADDR                        0x10 #define HTS221_CTRL_REG1_ADDR                       0x20 #define HTS221_CTRL_REG2_ADDR                       0x21 #define HTS221_HUMIDITY_OUT_L_ADDR                  0x28 #define HTS221_H0_RH_X2_ADDR                        0x30 #define HTS221_H1_RH_X2_ADDR                        0x31 #define HTS221_T0_degC_X8_ADDR                      0x32 #define HTS221_T1_degC_X8_ADDR                      0x33 #define HTS221_T1_T0_MSB_X8_ADDR                    0x35 #define HTS221_H0_T0_OUT_L_ADDR                     0x36 #define HTS221_H1_T0_OUT_L_ADDR                     0x3A #define HTS221_T0_OUT_L_ADDR                        0x3C #define HTS221_T1_OUT_L_ADDR                        0x3E unsigned char buffer[4]; float t0,t1,h0,h1,humi_value=0,temper_value=0; short t0out,t1out,h0out,h1out,humi_temp=0,temper_temp=0; int HTS221_Init() {         I2C_GPIO_Init();         if(I2C_ReadData(0xbe,0x0f)==0xbc)         {                 I2C_WriteData(0xbe,0x80,HTS221_CTRL_REG1_ADDR);//启动                 I2C_WriteData(0xbe,0x03,HTS221_RES_CONF_ADDR);                 return 0;         }         return -1; } float mapFloat(int x,int in_min,int in_max,float out_min,float out_max) {   return (x-in_min)*(out_max-out_min)/(in_max-in_min)+out_min; } void HTS221_Read() {         I2C_WriteData(HTS221_ADDRESS,0x01,HTS221_CTRL_REG2_ADDR);         buffer[0]=I2C_ReadData(HTS221_ADDRESS,HTS221_HUMIDITY_OUT_L_ADDR);         buffer[1]=I2C_ReadData(HTS221_ADDRESS,HTS221_HUMIDITY_OUT_L_ADDR+1);         buffer[2]=I2C_ReadData(HTS221_ADDRESS,HTS221_HUMIDITY_OUT_L_ADDR+2);         buffer[3]=I2C_ReadData(HTS221_ADDRESS,HTS221_HUMIDITY_OUT_L_ADDR+3);                 temper_temp=((int)(buffer[3]

  • 2019-01-25
  • 回复了主题帖: 瑞萨电子RL78/G11目标板免费申请活动【50元京东卡获奖名单】

    50卡获奖确认,信息无误

  • 2019-01-24
  • 发表了主题帖: 【Nucleo G071评测】PWM呼吸灯

        评测一个开发板的定时器功能,最简单的方式就是评测它的呼吸灯功能,呼吸灯是由PWM波实现的,PWM则是由定时器产生的。     打开CubeMX初始化PC6 PC8 PC9三个引脚,分别映射为定时器3的CH1 CH3 CH4通道,用于驱动RGB灯的三个引脚,设置定时器3不分频(即分频值为0),独立时钟,计数值为100上限: 调好了之后就可以直接接RGB灯了,初始化函数如下: void TIM3_Init() {         GPIO_InitTypeDef GPIO_InitStruct;      __HAL_RCC_GPIOC_CLK_ENABLE();   __HAL_RCC_TIM3_CLK_ENABLE();           GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_9;   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;   GPIO_InitStruct.Pull = GPIO_NOPULL;   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;   GPIO_InitStruct.Alternate = GPIO_AF1_TIM3;   HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);           htim3.Instance = TIM3;   htim3.Init.Prescaler = 0;   htim3.Init.CounterMode = TIM_COUNTERMODE_UP;   htim3.Init.Period = 100;   htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;   HAL_TIM_PWM_Init(&htim3);   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;   HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);   sConfigOC.OCMode = TIM_OCMODE_PWM1;   sConfigOC.Pulse=0;   sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;   sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;   HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);         HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3);   HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4);         HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);         HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);         HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);                 TIM3->CCR1=0;         TIM3->CCR3=0;         TIM3->CCR4=0;        } 通过TIM3的CCRX寄存器来修改三个通道的占空比:                 TIM3->CCR1=0;                 TIM3->CCR3=0;                 TIM3->CCR4=0;                        for(i=0;iCCR1=i;                         Delay_ms(5);                 }                 Delay_ms(500);                 for(i=100;i>=0;i--)                 {                         TIM3->CCR1=i;                         Delay_ms(5);                 }                 for(i=0;iCCR3=i;                         Delay_ms(5);                 }                 Delay_ms(500);                 for(i=100;i>=0;i--)                 {                         TIM3->CCR3=i;                         Delay_ms(5);                 }                 for(i=0;iCCR4=i;                         Delay_ms(5);                 }                 Delay_ms(500);                 for(i=100;i>=0;i--)                 {                         TIM3->CCR4=i;                         Delay_ms(5);                 } 看看效果:

  • 发表了主题帖: 【Nucleo G071评测】I2C OLED&AD采集

        借助一块庆科出品的Arduino扩展板,插上Nucleo-G071板子之后,可以继续进行接下来的传感器实验。     首先是这块扩展板是自带了I2C接口的OLED扩展模块,占用接口为PB8 PB9,直接用模拟I2C时序进行通信即可: void OLED_WR_Byte(uint8_t data,char cmd) {         if(cmd)         {                 // HAL_I2C_Mem_Write(&hi2c1,0x78,0x40,1,&data,1,10);                 I2C_WriteData(0x78,data,0x40);         }   else         {                 //HAL_I2C_Mem_Write(&hi2c1,0x78,0,1,&data,1,10);                 I2C_WriteData(0x78,data,0);         } } void OLED_Set_Pos(char x,char y) {   uint8_t tmp[3] = {0xb0+y, ((x&0xf0)>>4)|0x10, (x&0x0f)|0x01};   OLED_WR_Byte(tmp[0],0);         OLED_WR_Byte(tmp[1],0);         OLED_WR_Byte(tmp[2],0); } void OLED_Clear(void)   {           int i,n;                             for(i=0;i

  • 2019-01-19
  • 发表了主题帖: 【Nucleo G071评测】SYSTICK&两种常用的低功耗模式对比

        单片机的SYSTICK计时器是非常常用的,这个计时器最厉害的地方在于不管是裸机程序还是RTOS程序,SYSTICK都能用作准确的计时,ARM系统中,在不调用TIM定时器的前提下,SYSTICK是较为理想的计时器,初始化简单,调用也简单。 初始化SYSTICK计时器需要用到一个int型的计时因子: int fac_us; 然后是设置SYSTICK外设的时钟源和分频值: HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); fac_us=64; 写好定时函数: void Delay_us(int nus) {                int temp;         SysTick->LOAD=nus*fac_us;         SysTick->VAL=0x00;         SysTick->CTRL=0x05;         do         {                 temp=SysTick->CTRL;         }         while((temp&0x01)&&!(temp&(1VAL=0x00; } void Delay_ms(int nms) {         for(int i=0;i

  • 2019-01-17
  • 回复了主题帖: 颁奖:瑞萨电子RL78/G11目标板免费申请活动【目标板获奖名单】

    40份京东卡呢?我比较关心这个

  • 2019-01-16
  • 发表了主题帖: 【Nucleo G071评测】串口1空闲中断+DMA实现不定长接收

        经过两天一夜的摸索,总算是搞清楚了G0系列型号的DMA的脾气,可以进行我接下来的串口不定长接收的DEMO。     G0系列的DMA只有一个外设DMA1,DMA1支持7个通道,这7个通道也是非常人性化地可以被任意分配到任何支持DMA传输的外设如串口、ADC、SPI接口等,这点我相信ST是在向NXP新出的RT1050系列学习。也就是说,串口1的RX接收DMA通道,可以是DMA1通道1,也可以是DMA1通道2,甚至可以是DMA1的通道7。由于板上的LPUART1外设已经用作调试打印了,所以我使用串口1即PA9 PA10用来外接串口模块做实验。     首先打开CubeMX,配置串口1以及DMA,如图,可以选择7个通道里面的任意一个,我选了DMA1通道1:     其它参数不变,像FIFO那个就不打开:     在生成的例程中,有一句语句非常重要,由于现在G0系列的DMA没有指定特定外设用特定通道,因此还需要一个DMAMUX控制器用来重映射通道,通俗来讲就是锁定通道,相关配置为DMA_InitTypeDef的Request成员变量,就是这个变量,昨晚折腾了我一晚上,因为CubeMX生成的例程里面默认是没有指定Request变量的:     然后是直接跟随官方配置即可,添加空闲中断检测与响应: void UART1_Init(int baud) {         __HAL_RCC_GPIOA_CLK_ENABLE();   __HAL_RCC_USART1_CLK_ENABLE();         __HAL_RCC_DMA1_CLK_ENABLE();                 GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;   GPIO_InitStruct.Pull = GPIO_PULLUP;   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;   GPIO_InitStruct.Alternate = GPIO_AF1_USART1;   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);           huart1.Instance = USART1;   huart1.Init.BaudRate = baud;   huart1.Init.WordLength = UART_WORDLENGTH_8B;   huart1.Init.StopBits = UART_STOPBITS_1;   huart1.Init.Parity = UART_PARITY_NONE;   huart1.Init.Mode = UART_MODE_TX_RX;   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;   huart1.Init.OverSampling = UART_OVERSAMPLING_16;   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;   huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;   HAL_UART_Init(&huart1);           HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8);   HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8);   HAL_UARTEx_DisableFifoMode(&huart1);         __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);         HAL_NVIC_SetPriority(USART1_IRQn,0,0);   HAL_NVIC_EnableIRQ(USART1_IRQn);                 hdma_usart1_rx.Instance=DMA1_Channel1;   hdma_usart1_rx.Init.Direction=DMA_PERIPH_TO_MEMORY;   hdma_usart1_rx.Init.PeriphInc=DMA_PINC_DISABLE;   hdma_usart1_rx.Init.MemInc=DMA_MINC_ENABLE;   hdma_usart1_rx.Init.PeriphDataAlignment=DMA_PDATAALIGN_BYTE;   hdma_usart1_rx.Init.MemDataAlignment=DMA_MDATAALIGN_BYTE;   hdma_usart1_rx.Init.Mode=DMA_NORMAL;   hdma_usart1_rx.Init.Priority=DMA_PRIORITY_VERY_HIGH;         hdma_usart1_rx.Init.Request=DMA_REQUEST_USART1_RX;   HAL_DMA_Init(&hdma_usart1_rx);   __HAL_LINKDMA(&huart1,hdmarx,hdma_usart1_rx);         HAL_UART_Receive_DMA(&huart1,(unsigned char*)rx_buf,BUFFERSIZE); } 写好中断服务函数,并在主程序中添加循环检测中断响应标志位的函数: void USART1_IRQHandler() {         uint32_t temp;         if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE))         {                 __HAL_UART_CLEAR_IDLEFLAG(&huart1);                 HAL_UART_DMAStop(&huart1);                 temp=__HAL_DMA_GET_COUNTER(&hdma_usart1_rx);                 printf("------%d-----\n",temp);                 rx_len=BUFFERSIZE-temp;                 recv_end_flag=1;         } } void UART_DMA_Get() {         if(recv_end_flag==1)         {                 //rx_len=0;                 recv_end_flag=0;                 printf("rx_buf=%s\n",rx_buf);         }         HAL_UART_Receive_DMA(&huart1,(unsigned char*)rx_buf,BUFFERSIZE); } 连接好硬件电路,即使用一个CH340串口模块连接板子的PA9 PA10: 看看效果:

统计信息

已有156人来访过

  • 芯币:491
  • 好友:1
  • 主题:40
  • 回复:42
  • 课时:--
  • 资源:--

留言

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


早晨五点 2018-7-13
在吗哥,我想请教您一个问题。我用HAL库的接收中断接收数据为什么接收到的数据总是变换次序?比如第2个数据变成第一个,第三个编程第二个。。。我应该怎么办呢?希望您能帮助我一下
查看全部