2回答

1收藏

基于GD32F450的机智云功能板应用

GD32 GD32 6238 人阅读 | 2 人回复 | 2017-06-13

本帖最后由 jennyzhaojie 于 2017-6-14 17:04 编辑

   
1.开发背景
      在GD32F450开发板上配有Arduino接口,若以该接口与机智云的功能板相配合,则可拓展该开发板的功能。就目前来讲,对机智云功能提供支持的核心底板有两种,一种是基于STM32F103的,另一种则是基于ATMEGA328的。以GD32F450开发板来支持机智云功能板则可以又增加一种对其进行支持的核心底板。  
就机智云功能板来说,它提供了RGB_LED、小电机、红外感应器、小按键、温湿度传感器、WIFI模块及OLED接口等,如图1所示。受时间的制约,这里仅对RGB_LED、小电机、红外感应、小按键及OLED接口的使用展开说明。
此外,配合片内的RTC、UART、A/D等资源,还实现了RTC电子时钟、串行通讯及A/D采集等功能,在配备传感器和继电器的情况下可进一步增强实用性。

图1 机智云功能板

     要对机智云功能板进行编程,主要涉及各引脚的关系构建、GPIO口输入/输出功能的设置及高低电平输出语句的定义、输入电平的读取与判别、脉冲信号与时序的模拟等。
为了便于理解,我们按由简单到复杂的顺序来进行。

2.各功能模块的功能实现

1)小电机
功能板上提供了一个小的直流电机,其接口电路如图2所示。它是通过L9110进行功率驱动,当在IA和IB两端施加相异的电平时,可控制电机的正反转。

图2  电机电路

  电机与GD32F450的连接关系为:
  IA-PB10  
  IB-PE14     
  小电机的初始化函数为:
  1. void MODER_init(void)
  2. {
  3.     rcu_periph_clock_enable(RCU_GPIOB);
  4.     gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_10);
  5.     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_10);
  6.     GPIO_BC(GPIOB) = GPIO_PIN_10;
  7.     rcu_periph_clock_enable(RCU_GPIOE);
  8.     gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_14);
  9.     gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_14);
  10.     GPIO_BC(GPIOE) = GPIO_PIN_14;
  11. }
复制代码
  使用如下高低电平输出语句即可使电机转动,互换高低电平即可实现反向转动。      
  GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_SET);      //输出高电平
  GPIO_WriteBit(GPIOB, GPIO_Pin_4, Bit_RESET);   //输出低电平

2)小按键
利用板载的小按键,可进行相应功能的控制,其电路如图3所示。

图3  按键电路

按键与GD32F450的连接关系为:
K1-PB14
K2-PB15
按键的初始化函数为:
  1. void KEY_init(void)
  2. {   // K1、K2
  3.     rcu_periph_clock_enable(RCU_GPIOB);
  4.     gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_NONE,GPIO_PIN_15|GPIO_PIN_14);
  5.     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_15|GPIO_PIN_14);
  6.     GPIO_BC(GPIOB) = GPIO_PIN_15|GPIO_PIN_14;
  7. }  
复制代码
  K1键控制电机转动的语句如下:
GPIO_WriteBit(GPIOB, GPIO_Pin_4, Bit_RESET);
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)==RESET)   //  K1
{
                GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_SET);   //  MODOR
}
else
{
                GPIO_WriteBit(GPIOB, GPIO_Pin_5, Bit_RESET);
}

3)红外感应
板载的红外感应器是用于避障控制的,其电路如图4所示。


图4  红外感应电路

电路的作用作用为:在TCRT5000的一端是一个可发出红外光的二极管,另一端是一个接受器。在无遮挡的情况下,受到照射使电路导通并在AOUT端输出低电平。在LM393的电路中,其作用是充当一个AOUT与电位器设定电位的比较器,以产生阀值开关的效果。当IR_OUT为低电平时,LED2被点亮,否则被熄灭。通过采集IR_OUT的状态即可启动感应开关的作用。

IR_OUT与GD32F450的连接关系为:
IR_OUT-PD4
IR_OUT的初始化函数为:
  1. void IR_init(void)
  2. {
  3.     rcu_periph_clock_enable(RCU_GPIOD);
  4.     gpio_mode_set(GPIOD, GPIO_MODE_INPUT, GPIO_PUPD_NONE,GPIO_PIN_4);
  5.     gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4);
  6.     GPIO_BC(GPIOD) = GPIO_PIN_4;
  7.   }
复制代码
以IR控制电机正反转的语句如下:
if (RESET== gpio_input_bit_get(GPIOD,GPIO_PIN_4))  GPIO_BOP(GPIOB) = GPIO_PIN_10;  else         GPIO_BC(GPIOB) = GPIO_PIN_10;

4)RGB_LED
通常RGB_LED的使用是无需外围驱动电路的,故使用起来十分简单,只需输出高低电平即可控制其点亮与否。然而在机智云的功能板上却是以P9813来驱动和控制RGB_LED,其接口电路如图5所示。


图5  RGB_LED接口电路

那使用P9813又有何特别之处呢?其主要用途在于,可以串行方式来传送控制信号,并起到控制RGB亮度的作用。而通常情况下,这是需要通过PWM来实现的。在信号传送过程中,是通过32个脉冲信号来把控制数据传递到P9813中,再由RGB引脚加以输出来控制RGB_LED。
P9813与GD32F450的连接关系为:
SDA-PB7
SCL-PB6
A0-PA3

RGB_LED的初始化函数为:
  1. void RGB_init(void)
  2. {
  3.     rcu_periph_clock_enable(RCU_GPIOB);
  4.     rcu_periph_clock_enable(RCU_GPIOA);
  5.     gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_6|GPIO_PIN_7);
  6.     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6|GPIO_PIN_7);
  7.     GPIO_BC(GPIOB) = GPIO_PIN_6|GPIO_PIN_7;

  8.     gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_3);
  9.     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_3);
  10.     GPIO_BC(GPIOA) = GPIO_PIN_3;
  11. }
复制代码
RGB_LED的控制函数如下:
  1. void RGB_Write_Data(uint8_t R,uint8_t G,uint8_t B)
  2. {
  3.   uint32_t RGB_Data = 0;
  4.   uint8_t i;
  5.   RGB_Data |= 0xC0000000;
  6.   RGB_Data |= ((uint32_t)((~B) & 0xc0)) << 22;
  7.   RGB_Data |= ((uint32_t)((~G) & 0xc0)) << 20;
  8.   RGB_Data |= ((uint32_t)((~R) & 0xc0)) << 18;
  9.   RGB_Data |= ((uint32_t)B) << 16;            
  10.   RGB_Data |= ((uint32_t)G) << 8;
  11.   RGB_Data |= R;
  12.   for (i=0;i<32;i++)
  13.   {
  14.        if((RGB_Data & 0x80000000) != 0)
  15.        {
  16.          SDA_1;
  17.        }
  18.        else
  19.        {
  20.          SDA_0;
  21.         }
  22.        RGB_Data <<= 1;
  23.         SCL_0;
  24.         SCL_1;
  25.    }
  26.    SDA_0;         
  27.    for (i=0;i<32;i++)
  28.    {
  29.         SCL_0;
  30.         SCL_1;
  31.    }        
  32. }
复制代码
实现呼吸灯的程序为:
  1.       uint8_t i=0;
  2.       RGB_init();
  3.       GPIO_BOP(GPIOA) = GPIO_PIN_3;
  4.       RGB_Write_Data(0x00,0x00,0x00);
  5.       for (i=0;i<125;i++)
  6.       {
  7.       RGB_Write_Data(0x00,0x00,i);
  8.       delay_1ms(20);
  9.       }
  10.       for (i=125;i>0;i--)
  11.       {
  12.       RGB_Write_Data(0x00,0x00,i);
  13.       delay_1ms(20);
  14.       }
  15.       for (i=0;i<125;i++)
  16.       {
  17.       RGB_Write_Data(0x00,0x00,i);
  18.       delay_1ms(20);
  19.       }
  20.       for (i=125;i>0;i--)
  21.       {
  22.       RGB_Write_Data(0x00,0x00,i);
  23.       delay_1ms(20);
  24.       }
复制代码
实现色彩环的程序如下:
  1. while(1)
  2. {
  3.       for (i=0;i<255;i++)
  4.       {
  5.             RGB_Write_Data(i,0x00,255-i);
  6.             delay_1ms(20);
  7.       }
  8.       for (i=0;i<255;i++)
  9.       {
  10.             RGB_Write_Data(255-i,i,0x00);
  11.             delay_1ms(20);
  12.       }
  13.       for (i=0;i<255;i++)
  14.       {
  15.             RGB_Write_Data(0x00,255-i,i);
  16.             delay_1ms(20);
  17.       }
  18. }
复制代码
RGB_LED的显示效果如图6所示。


图6  RGB_LED显示效果

使用红外感应器作为感应提示器的语句如下:
if(RESET== gpio_input_bit_get(GPIOD,GPIO_PIN_4))          // IR
{
      RGB_Write_Data(0x00,0x00,0xff);    //  蓝色
}
else
{
       RGB_Write_Data(0xff,0x00,0x00);  //  红色
}
实现感应提示的效果如图7所示。

图7  未遮挡状态

5)OLED接口
在功能板上提供了OLED接口,该接口适用于一种SPI接口的OLED屏,其引脚分配如图8所示。由于LCD5110屏使用的比较广泛,故这里介绍任何以该接口实现LCD5110屏的显示。由于两者的接口并不完全一致,因此所以需要做些改造,具体的做法是将GND与NC引脚连接,以为LCD5110的SCE引脚提供片选信号。其它引脚只需修改引脚定义即可。

图8 OLED接口

LCD5110屏与GD32F450的连接关系为:
CS-GND
RESET-PE6
D/C-PE2
SDIN-PE4
SCL-PD0
LED-PD1

LCD5110各引脚输出高低电平的定义语句如下:
  1. #define SDA_1   gpio_bit_set(GPIOB,GPIO_PIN_7);
  2. #define SDA_0   gpio_bit_reset(GPIOB,GPIO_PIN_7);
  3. #define SCL_0   gpio_bit_set(GPIOB,GPIO_PIN_6);
  4. #define SCL_1   gpio_bit_reset(GPIOB,GPIO_PIN_6);
  5. #define DC_1 gpio_bit_set(GPIOE, GPIO_PIN_2);
  6. #define DC_0 gpio_bit_reset(GPIOE, GPIO_PIN_2);
  7. #define RST_1 gpio_bit_set(GPIOE, GPIO_PIN_6);
  8. #define RST_0 gpio_bit_reset(GPIOE, GPIO_PIN_6);
  9. #define LCD_SCLK_1 gpio_bit_set(GPIOD, GPIO_PIN_0);
  10. #define LCD_SCLK_0 gpio_bit_reset(GPIOD, GPIO_PIN_0);
  11. #define LCD_SDIN_1 gpio_bit_set(GPIOE, GPIO_PIN_4);
  12. #define LCD_SDIN_0 gpio_bit_reset(GPIOE, GPIO_PIN_4);
复制代码

LCD5110的引脚配置函数如下:
  1. void SPI_CONFIG()
  2. {
  3. rcu_periph_clock_enable(RCU_GPIOE);
  4. gpio_mode_set          (GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,   GPIO_PIN_2| GPIO_PIN_4| GPIO_PIN_6);
  5. gpio_output_options_set(GPIOE, GPIO_OTYPE_PP,    GPIO_OSPEED_50MHZ,GPIO_PIN_2| GPIO_PIN_4| GPIO_PIN_6);
  6.   
  7. rcu_periph_clock_enable(RCU_GPIOD);
  8. gpio_mode_set          (GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,   GPIO_PIN_0| GPIO_PIN_1);
  9. gpio_output_options_set(GPIOD, GPIO_OTYPE_PP,    GPIO_OSPEED_50MHZ,GPIO_PIN_0| GPIO_PIN_1);
  10. GPIO_BOP(GPIOD) = GPIO_PIN_1;
  11. }
复制代码
  1. void LCD_init(void)
  2. {
  3. RST_0;
  4. delay(100);
  5. RST_1;
  6. delay(100);
  7. RST_0;
  8. delay(100);
  9. RST_1;
  10. delay(100);
  11. LCD_write_byte(0x21,0);
  12. LCD_write_byte(0xc3,0);
  13. LCD_write_byte(0x10, 0);
  14. LCD_write_byte(0x20,0);
  15. LCD_write_byte(0x0C,0);
  16. LCD_clear();
  17. }
复制代码
  1. int main(void)
  2. {
  3. SPI_CONFIG();
  4. LCD_init();
  5. LCD_write_english_string(10,1,"GD32F450VE",0);
  6. LCD_write_english_string(36,2,"&",0);
  7. LCD_write_english_string(20,3,"IOTKIT",0);
  8. LCD_write_english_string(10,5,"2017.6.10",0);
  9. }
复制代码
其它驱动LCD110屏显示的函数基本无需变化,运行后的显示效果如图9所示。

图9  LCD5110屏显示效果

6)串行通讯
EMW3162与GD32F450的连接关系为:
USART_RX-PD5
USART_TX-PD6
A6-NC
图9  EMW3162原理图

利用串行通讯功能,可向EMW3162发送指令,进而实现WIFI通讯及控制。

7)GD32F450内部资源使用
在GD32F450内部,同样存在较多的外设资源,如RTC、A/D、TIMER等,在与机智云功能板配合的情况下,也发挥很大的作用,如使用RTC实现数字时钟,其效果如图10所示。使用A/D,则看进行模拟信号的数据采集,在添加传感器时可实现智能家居管控及安防处理等。

图10 数字时钟

使用MCU内部的TIMER可对小大家进行PWM调速,其中TIMER1的通道2对应小电机的IA(B10)。
在控制过程中,只需向IB提供低电平即可。
实现不断变化给定速度的程序如下:
   while (1)
  {
     static uint8_t i = 0;
     static uint32_t pwm_cnt = 0;
     delay_1ms(500);//  控制速率变换
     if(pwm_cnt < 800)
     pwm_cnt = pwm_cnt + 100;
     else
     {
                       pwm_cnt = 0;
                       i = 0;
     }
     timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_2,pwm_cnt);
  }


   实现A/D采集的程序如下:
   /* system clocks configuration */
    rcu_config();
    /* GPIO configuration */
    gpio_config();
    /* SYSTICK configuration */
    systick_config();
    /* ADC configuration */
   adc_config();
   adc_resolution_config(ADC1,ADC_RESOLUTION_12B);
         adc_oversample_mode_config(ADC1,ADC_OVERSAMPLING_ALL_CONVERT,ADC_OVERSAMPLING_SHIFT_NONE,ADC_OV    ERSAMPLING_SHIFT_NONE);
  adc_oversample_mode_disable(ADC1);
  while(1)
  {
                       adc_enable(ADC1);
                       adc_software_trigger_enable(ADC1,ADC_REGULAR_CHANNEL);
                       while(RESET == adc_flag_get(ADC1,ADC_FLAG_EOC));
                       delay_1ms(2);
                       sj=ADC_RDATA(ADC1);     //配LCD5110屏显示函数,以显示A/D检测值sj。
  }

结语:
机智云功能板是一个功能较强的开发板,将它与GD32F450相配合可以达到优势互补的效果,受时间的限制,目前先探索到这里,后面若有时间可添加DHT11温湿度检测与显示控制等。


视频:由于该设计为涉及与语音或视频相关的内容,以图片即可展示效果故这里从略。

源代码:

JZY_2main.rar

3.45 KB, 下载次数: 9

分享到:
回复

使用道具 举报

回答|共 2 个

倒序浏览

沙发

jennyzhaojie

发表于 2017-6-20 10:10:51 | 只看该作者

新近又将DHT11的温湿度检测补充上了,其实现的界面如下图所示。至此再移植上WIFI通讯就完满了!
板凳

wendesy

发表于 2018-1-13 15:30:56 | 只看该作者

感谢分享!!!!!!!!!!
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条