聚豐項目 > 基于RISC-V的多功能遙控器設計
基于中科藍訊AB32VG1開發套件,設計實現一種能夠遠程遙控多種無線設備的遙控裝置。 本項目準備利用AB32VG1板載的藍牙功能,實現對多種藍牙設備遠程控制,除此之外,還可以利用板載豐富的IO擴展資源實現其他的無線遙控方案。
歸心上路
分享歸心上路
團隊成員
歸心上路 軟件工程師
- AB32VG1開發套件
- 搖桿擴展板
- ssd1306 1.3寸 OLED硬件整體框架如下如所示:
本項目使用的硬件資源包括 AB32VG1 開發平臺,搖桿擴展版(包含一個joystick搖桿和四個按鍵)、SSD1306 OLED ,使用板載的支持的藍牙實現無線通信功能。
本次項目實驗軟件部分均是在RT-Thread Studio中進行開發設計,相關軟件包均能通過軟件倉庫獲取到。
## RT-Thread系統使用情況 和
本次項目實驗中使hi用到的軟件包如下,包括ssd1306 oled驅動包和bluetrum_sdk 包。使用到的組件包括串口、GPIO和軟件模擬IIC組件。
## 程序模塊說明
- 搖桿驅動程序設計
搖桿主要使用的是ADC來進行驅動,通過讀取搖桿中的電位器的電壓值,來判斷當前搖桿的狀態。驅動示例代碼如下。
static int adc_vol_sample(int argc, char *argv[]) { rt_adc_device_t adc_dev; rt_uint32_t value, vol; rt_err_t ret = RT_EOK; /* 查找設備 */ adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME); if (adc_dev == RT_NULL) { rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME); return RT_ERROR; } /* 使能設備 */ ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL_1); /* 讀取采樣值 */ value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL_1); rt_kprintf("the value is :%d \n", value); /* 轉換為對應電壓值 */ vol = value * REFER_VOLTAGE / CONVERT_BITS; rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100); /* 關閉通道 */ ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL_1); return ret; }
- OLED驅動程序
void ssd_1306_draw() { ssd1306_Init(); ssd1306_Fill(BLACK); ssd1306_DrawCircle(32, 32, 25,WHITE); // 32 32 ssd1306_Line(32, 7, 32, 57, WHITE); ssd1306_Line(7, 32, 57, 32, WHITE); ssd1306_fillCircle(32,32,2,WHITE); /* A */ ssd1306_DrawCircle(88, 30, 12,WHITE); /* B */ ssd1306_DrawCircle(115, 24, 12,WHITE); /* joystick */ ssd1306_Line(70, 50, 120, 50, WHITE); ssd1306_fillCircle(95,50,3,WHITE); ssd1306_Line(70, 60, 120, 60, WHITE); ssd1306_fillCircle(95,60,3,WHITE); ssd1306_UpdateScreen(); }
- 屏幕圖形繪制程序設計
- 遙控器應用界面設計
static void ctl_test() { rt_adc_device_t adc_dev; rt_uint32_t value, vol; rt_uint16_t x_x, x_y; rt_uint16_t joystick_x, joystick_y; rt_uint16_t joystick_y_max; rt_err_t ret = RT_EOK; rt_kprintf(" %s\n",__FUNCTION__); rt_kprintf("ssd1306_Init ... \n"); ssd1306_Init(); ssd1306_Fill(BLACK); ssd1306_DrawCircle(32, 32, 25,WHITE); // 32 32 ssd1306_Line(32, 7, 32, 57, WHITE); ssd1306_Line(7, 32, 57, 32, WHITE); ssd1306_fillCircle(32,32,2,WHITE); /* A */ ssd1306_DrawCircle(88, 30, 12,WHITE); /* B */ ssd1306_DrawCircle(115, 24, 12,WHITE); /* joystick */ ssd1306_Line(70, 50, 120, 50, WHITE); ssd1306_fillCircle(95,50,3,WHITE); ssd1306_Line(70, 60, 120, 60, WHITE); ssd1306_fillCircle(95,60,3,WHITE); ssd1306_UpdateScreen(); /* 查找設備 */ adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME); if (adc_dev == RT_NULL) { rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME); return RT_ERROR; } /* 使能設備 */ ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL_1); ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL_2); while(1) { /* 讀取采樣值 */ value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL_1); // rt_kprintf("PB2_ADC4 adc0 :%d \n", value); /* 轉換為對應電壓值 */ vol = value * REFER_VOLTAGE / CONVERT_BITS; // rt_kprintf("adc0 the voltage is :%d.%02d \n", vol / 100, vol % 100); // rt_kprintf("\r\n"); x_x = 70+ value * 50/CONVERT_BITS; joystick_x = 7 + value*50/CONVERT_BITS; /* 讀取采樣值 */ value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL_2); // rt_kprintf("PB1_ADC3 adc1 :%d \n", value); /* 轉換為對應電壓值 */ vol = value * REFER_VOLTAGE / CONVERT_BITS; // rt_kprintf("adc1 the voltage is :%d.%02d \n", vol / 100, vol % 100); x_y = 70+ value * 50/CONVERT_BITS; joystick_y = 57 - value*50 /CONVERT_BITS; ssd1306_fillCircle(32, 32, 37,BLACK); ssd1306_DrawCircle(32, 32, 25,WHITE); // 32 32 ssd1306_Line(32, 7, 32, 57, WHITE); ssd1306_Line(7, 32, 57, 32, WHITE); // 求坐標 將 圓點的軸坐標固定到圓周內部 joystick_y_max = sqrt(25*25-((joystick_x-32)*(joystick_x-32))); if(joystick_y>32) { if(joystick_y-32 >= joystick_y_max) joystick_y=joystick_y_max+32; } else if(joystick_y<32) { if(32-joystick_y >=joystick_y_max) joystick_y=32-joystick_y_max; } ssd1306_fillCircle(joystick_x,joystick_y,2,WHITE); // oled show // 局部清屏 ssd1306_fillRect(60, 46, 125, 66,BLACK); ssd1306_Line(70, 50, 120, 50, WHITE); ssd1306_Line(70, 60, 120, 60, WHITE); ssd1306_fillCircle(x_x,50,3,WHITE); ssd1306_fillCircle(x_y,60,3,WHITE); ssd1306_UpdateScreen(); rt_thread_mdelay(5); } /* 關閉通道 */ ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL_1); ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL_2); } /* 導出到 msh 命令列表中 */ //MSH_CMD_EXPORT(adc_oled, adc voltage loop); INIT_APP_EXPORT(adc_oled);
- 代碼倉庫
ab32vg1-remote-control: rtt大賽作品 基于RISC-V的多功能遙控器設計 (gitee.com)
演示效果已經上傳B站,如果后續有更新,會同步更新視頻內容。