机智云是智能硬件时代专为硬件提供后台支持的云服务平台,其服务内容主要包括统计分析、数据安全、远程管理、软件升级等。去年底机智云又迎来了2.0版本 gokit2,相较于GoKit1它在功能上没什么变化,而是将Gokit1的单板卡结构设计为控制板和功能板的双板卡结构,并通过兼容 arduino UNO的扩展接口座来连接。这种改变进一步更强了应用的灵活性,也为其它类型的控制板来支持功能板通过了方便。 就目前来讲,控制板有两种类型,一种是基于STM32 主控板,以 STM32F103C8T6为主控芯片;另一种则是基于 Atmel 主控板,以Atmega328为主控芯片。 GD32F450是兆易科技新推出的一款ARM产品,在GD32F450开发板上也配有Arduino接口,这样便为机智云控制板的种类扩展提供了相应的支持。 就机智云功能板来说,它提供了RGB_LED、小电机、红外感应器、小按键、温湿度传感器、WIFI模块及OLED接口等,如图1所示。 图1 机智云功能板
下面就以GD32F450开发板为控制核心,对RGB_LED、小电机、红外感应、小按键、温湿度传感器、串行通讯及OLED接口的使用加以介绍。若配上对GD32F450片内RTC、UART、A/D等资源的所用,则能够进一步增强实用性能。 图2 GD32F450开发板
要对机智云功能板进行编程,主要涉及各引脚关系的构建、GPIO口输入/输出功能的设置及高低电平输出语句的定义、输入电平的读取与判别、脉冲信号与时序的模拟等。 为了便于理解,这里按由简单到复杂的顺序来进行。 1.小电机 功能板上提供了一个小的直流电机,其接口电路如图3所示。它是通过L9110进行功率驱动,当在IA和IB两端施加相异的电平时,可控制电机的正反转。 图3 电机电路
电机与GD32F450的连接关系为: IA-PB10 IB-PE14 小电机的初始化函数为: - void MODER_init(void)
- {
- rcu_periph_clock_enable(RCU_GPIOB);
- gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_10);
- gpio_output_options_set(GPIOB,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_10);
- GPIO_BC(GPIOB) = GPIO_PIN_10;
- rcu_periph_clock_enable(RCU_GPIOE);
- gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_14);
- gpio_output_options_set(GPIOE,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_14);
- GPIO_BC(GPIOE) = GPIO_PIN_14;
- }
复制代码 使用如下高低电平输出语句即可使电机转动,互换高低电平即可实现反向转动。 GPIO_BOP(GPIOB) = GPIO_PIN_10; // 输出高电平 GPIO_BC(GPIOE) = GPIO_PIN_14; // 输出低电平 2.小按键 利用板载的小按键,可进行相应功能的控制,其电路如图4所示。 图4 按键电路
按键与GD32F450的连接关系为: K1-PB14 K2-PB15 按键的初始化函数为: K1键控制电机转动的语句如下: GPIO_BC(GPIOE) = GPIO_PIN_14; if(RESET==gpio_input_bit_get(GPIOB,GPIO_PIN_14)) RGB_Write_Data(0xff,0x00,0x00); // K1 { GPIO_BOP(GPIOE) = GPIO_PIN_14; //输出高电平 } else { GPIO_BC(GPIOE) = GPIO_PIN_14; //输出低电平 } 3.红外感应 板载的红外感应器用于避障或感应控制,其电路如图5所示。
图5 红外感应电路
电路的作用是:在TCRT5000的一端是一个可发出红外光的二极管,另一端是一个接受器。在无遮挡的情况下,受到照射使电路导通并在AOUT端输出低电平。在LM393的电路中,其作用是充当一个AOUT与电位器设定电位的比较器,以产生阀值开关的效果。当IR_OUT为低电平时,LED2被点亮,否则被熄灭。通过采集IR_OUT的状态即可启动感应开关的作用。 IR_OUT与GD32F450的连接关系为: IR_OUT-PD4 IR_OUT的初始化函数为: - void IR_init(void)
- {
- rcu_periph_clock_enable(RCU_GPIOD);
- gpio_mode_set(GPIOD, GPIO_MODE_INPUT, GPIO_PUPD_NONE,GPIO_PIN_4);
- gpio_output_options_set(GPIOD,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_4);
- GPIO_BC(GPIOD) = GPIO_PIN_4;
- }
复制代码 以IR控制电机正反转的语句如下: if (RESET== gpio_input_bit_get(GPIOD,GPIO_PIN_4)) { GPIO_BOP(GPIOB) = GPIO_PIN_10; GPIO_BC(GPIOE) = GPIO_PIN_14; } else { GPIO_BC(GPIOB) = GPIO_PIN_10; GPIO_BOP(GPIOE) = GPIO_PIN_14; } 4.RGB_LED 通常RGB_LED的使用是无需**驱动电路的,故使用起来很简单,只需输出高低电平即可控制其点亮与否。然而在机智云的功能板上却是由P9813来驱动和控制RGB_LED,其接口电路如图6所示。 图6 RGB_LED接口电路
那使用P9813又有何特别之处呢?其主要用途在于,可以串行方式来传送控制信号,并起到控制RGB亮度的作用。而在通常情况下,这是需要使用PWM来实现的。在信号传送过程中,它是通过32个脉冲信号来把控制数据传递到P9813中,再由RGB引脚来输出和控制RGB_LED。 P9813与GD32F450的连接关系为: SDA-PB7 SCL-PB6 A0-PA3 输出高低电平的定义语句为: #define SDA_1 GPIO_BOP(GPIOB) = GPIO_PIN_7; #define SDA_0 GPIO_BC(GPIOB) = GPIO_PIN_7; #define SCL_0 GPIO_BOP(GPIOB) = GPIO_PIN_6; #define SCL_1 GPIO_BC(GPIOB) = GPIO_PIN_6; RGB_LED的初始化函数为: - void RGB_init(void)
- {
- rcu_periph_clock_enable(RCU_GPIOB);
- rcu_periph_clock_enable(RCU_GPIOA);
- gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_6|GPIO_PIN_7);
- gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6|GPIO_PIN_7);
- GPIO_BC(GPIOB) = GPIO_PIN_6|GPIO_PIN_7;
- gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_3);
- gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_3);
- GPIO_BC(GPIOA) = GPIO_PIN_3;
- }
复制代码
RGB_LED的控制函数如下: - void RGB_Write_Data(uint8_t R,uint8_t G,uint8_t B)
- {
- uint32_t RGB_Data = 0;
- uint8_t i;
- RGB_Data |= 0xC0000000;
- RGB_Data |= ((uint32_t)((~B) & 0xc0)) << 22;
- RGB_Data |= ((uint32_t)((~G) & 0xc0)) << 20;
- RGB_Data |= ((uint32_t)((~R) & 0xc0)) << 18;
- RGB_Data |= ((uint32_t)B) << 16;
- RGB_Data |= ((uint32_t)G) << 8;
- RGB_Data |= R;
- for (i=0;i<32;i++)
- {
- if((RGB_Data & 0x80000000) != 0)
- {
- SDA_1;
- }
- else
- {
- SDA_0;
- }
- RGB_Data <<= 1;
- SCL_0;
- SCL_1;
- }
- SDA_0;
- for (i=0;i<32;i++)
- {
- SCL_0;
- SCL_1;
- }
- }
复制代码 实现呼吸灯的程序为: - uint8_t i=0;
- RGB_init();
- GPIO_BOP(GPIOA) = GPIO_PIN_3;
- RGB_Write_Data(0x00,0x00,0x00);
- for (i=0;i<125;i++)
- {
- RGB_Write_Data(0x00,0x00,i);
- delay_1ms(20);
- }
- for (i=125;i>0;i--)
- {
- RGB_Write_Data(0x00,0x00,i);
- delay_1ms(20);
- }
- for (i=0;i<125;i++)
- {
- RGB_Write_Data(0x00,0x00,i);
- delay_1ms(20);
- }
- for (i=125;i>0;i--)
- {
- RGB_Write_Data(0x00,0x00,i);
- delay_1ms(20);
- }
复制代码
实现色彩环的程序如下: - while(1)
- {
- for (i=0;i<255;i++)
- {
- RGB_Write_Data(i,0x00,255-i);
- delay_1ms(20);
- }
- for (i=0;i<255;i++)
- {
- RGB_Write_Data(255-i,i,0x00);
- delay_1ms(20);
- }
- for (i=0;i<255;i++)
- {
- RGB_Write_Data(0x00,255-i,i);
- delay_1ms(20);
- }
- }
复制代码
RGB_LED的显示效果如图7所示。 图7 RGB_LED显示效果
使用红外感应器作为感应提示器的语句如下: if(RESET== gpio_input_bit_get(GPIOD,GPIO_PIN_4)) { RGB_Write_Data(0x00,0x00,0xff); // 蓝色 } else { RGB_Write_Data(0xff,0x00,0x00); // 红色 } 实现感应提示的效果如图8。 图8 感应控制
5.OLED接口 功能板上配有OLED接口,该接口适用于SPI接口的OLED屏,其电路如图9所示。由于LCD5110屏用的比较广泛,故这里介绍一下以该接口实现LCD5110屏的显示。由于两者的接口并不完全一致,因此所以需要做些改造,具体的做法是将GND与NC引脚连接,以此向LCD5110的SCE引脚提供片选信号,其它引脚则只需修改引脚的定义即可。 图9 OLED接口
LCD5110屏与GD32F450的连接关系为: CS-GND RESET-PE6 D/C-PE2 SDIN-PE4 SCL-PD0 LED-PD1 LCD5110各引脚输出高低电平的定义语句如下: #define DC_1 GPIO_BOP(GPIOE) = GPIO_PIN_2; #define DC_0 GPIO_BC(GPIOE) = GPIO_PIN_2; #define RST_1 GPIO_BOP(GPIOE) = GPIO_PIN_6; #define RST_0 GPIO_BC(GPIOE) = GPIO_PIN_6; #define LCD_SCLK_1 GPIO_BOP(GPIOD) = GPIO_PIN_0; #define LCD_SCLK_0 GPIO_BC(GPIOD) = GPIO_PIN_0; #define LCD_SDIN_1 GPIO_BOP(GPIOE) = GPIO_PIN_4; #define LCD_SDIN_0 GPIO_BC(GPIOE) = GPIO_PIN_4; LCD5110的引脚配置函数如下: - void SPI_CONFIG()
- {
- rcu_periph_clock_enable(RCU_GPIOE);
- gpio_mode_set (GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_2| GPIO_PIN_4| GPIO_PIN_6);
- gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_2| GPIO_PIN_4| GPIO_PIN_6);
-
- rcu_periph_clock_enable(RCU_GPIOD);
- gpio_mode_set (GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_0| GPIO_PIN_1);
- gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_0| GPIO_PIN_1);
- GPIO_BOP(GPIOD) = GPIO_PIN_1;
- }
复制代码
lcd5110初始化函数: - void LCD_init(void) //lcd5110测试化
- {
- RST_0;
- delay(100);
- RST_1;
- delay(100);
- RST_0;
- delay(100);
- RST_1;
- delay(100);
- LCD_write_byte(0x21,0);
- LCD_write_byte(0xc3,0);
- LCD_write_byte(0x10, 0);
- LCD_write_byte(0x20,0);
- LCD_write_byte(0x0C,0);
- LCD_clear();
- }
复制代码 主函数: - int main(void)
- {
- SPI_CONFIG();
- LCD_init();
- LCD_write_english_string(10,1,"GD32F450VE",0);
- LCD_write_english_string(36,2,"&",0);
- LCD_write_english_string(20,3,"IOTKIT",0);
- LCD_write_english_string(10,5,"2017.6.10",0);
- }
复制代码 其它驱动LCD110屏显示的函数基本无需变化,运行后的显示效果如图10所示。 图10 LCD5110屏显示效果
6.温湿度传感器 功能板上配有DHT11温湿度传感器,其接口电路如图11所示。DHT11与GD32F450的连接关系为: DHT11_D-PD3 图11 DHT11温湿度传感器电路
DHT11的基本定义语句为: #define DHT11_GPIO GPIOD #define DHT11_GPIO_CLKEN rcu_periph_clock_enable(RCU_GPIOD) #define DHT11_PIN GPIO_PIN_3 #define DHT11_PIN_SET gpio_bit_set(DHT11_GPIO,DHT11_PIN) #define DHT11_PIN_CLR gpio_bit_reset(DHT11_GPIO,DHT11_PIN) #define DHT11_PIN_Read gpio_input_bit_get(DHT11_GPIO,DHT11_PIN) DHT11的初始化函数为: - int DHT11_Init()
- {
- DHT11_GPIO_CLKEN;
- gpio_mode_set(DHT11_GPIO,GPIO_MODE_INPUT,GPIO_PUPD_NONE,DHT11_PIN);
- gpio_output_options_set(DHT11_GPIO,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,DHT11_PIN);
- DHT11_Reset();
- return DHT11_Check();
- }
复制代码 位读取函数为: - int DHT11_Read_Bit()
- {
- int retry=0;
- while(DHT11_PIN_Read&&retry<100)
- {
- retry++;
- Delay_us(1);
- }
- retry=0;
- while(!DHT11_PIN_Read&&retry<100)
- {
- retry++;
- Delay_us(1);
- }
- Delay_us(40);
- if(DHT11_PIN_Read) return 1;
- else return 0;
- }
复制代码 字节读取函数为: - char DHT11_Read_Byte()
- {
- char i,dat;
- dat=0;
- for(i=0;i<8;i++)
- {
- dat<<=1;
- dat|=DHT11_Read_Bit();
- }
- return dat;
- }
复制代码 数据读取函数为: - int DHT11_Read_Data(char *temp,char *humi)
- {
- char buf[5],i;
- DHT11_Reset();
- if(DHT11_Check()==0)
- {
- for(i=0;i<5;i++)
- {
- buf[i]=DHT11_Read_Byte();
- }
- if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
- {
- *humi=buf[0];
- *temp=buf[2];
- }
- }
- else return 1;
- return 0;
- }
复制代码
温湿度的检测程序为: - SPI_CONFIG();
- LCD_init();
- LCD_clear();
- LCD_write_english_string(0,0," Temp & Humi",0);
- LCD_write_english_string(0,2,"temp: C",0);
- LCD_write_english_string(0,4,"humi: %",0);
- while (1)
- {
- DHT11_Read_Data(&temp,&humi);
- delay_1ms(200);
- LCD_set_XY(32,2);
- LCD_write_char(temp/10+'0',0);
- LCD_write_char(temp%10+'0',0);
- LCD_set_XY(32,4);
- LCD_write_char(humi/10+'0',0);
- LCD_write_char(humi%10+'0',0);
- }
复制代码 温湿度检测效果如图12所示。 图12 温湿度显示效果
7.串行通讯 功能板上具有串行通讯功能,其接口电路如图13所示。串行通讯引脚与GD32F450的连接关系为: USART_RX-PD5 USART_TX-PD6 图13 串行通讯接口电路
串行通讯初始化函数: - void usb_to_uart_init(void)
- {
- rcu_periph_clock_enable(RCU_GPIOD);
- rcu_periph_clock_enable(RCU_USART1);
- gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_5);
- gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_6);
- gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_5);
- gpio_output_options_set(GPIOD,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_5);
- gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_6);
- gpio_output_options_set(GPIOD,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6);
- usart_deinit(USART1);
- usart_baudrate_set(USART1, 9600U);
- usart_receive_config(USART1, USART_RECEIVE_ENABLE);
- usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);
- usart_word_length_set(USART1, USART_WL_8BIT);
- usart_stop_bit_set(USART1, USART_STB_1BIT);
- usart_parity_config(USART1, USART_PM_NONE);
- usart_enable(USART1);
- }
复制代码利用串行通讯功能,可向EMW3162发送指令,进而实现WIFI通讯及控制。 结束语: 机智云是一个面向智能硬件时代开发平台,通过和新的ARM产品相结合能够不断提升产品的性能,这里通过它与GD32F450开发板的配合,便又增添了一种控制板的方式及一些附加功能,期待在大家共同努力下,机智云产品的性能能够越来越丰富。
|