聚豐項(xiàng)目 > 基于RISC-V的多功能遙控器設(shè)計(jì)
基于中科藍(lán)訊AB32VG1開發(fā)套件,設(shè)計(jì)實(shí)現(xiàn)一種能夠遠(yuǎn)程遙控多種無線設(shè)備的遙控裝置。 本項(xiàng)目準(zhǔn)備利用AB32VG1板載的藍(lán)牙功能,實(shí)現(xiàn)對(duì)多種藍(lán)牙設(shè)備遠(yuǎn)程控制,除此之外,還可以利用板載豐富的IO擴(kuò)展資源實(shí)現(xiàn)其他的無線遙控方案。
歸心上路

歸心上路
團(tuán)隊(duì)成員
歸心上路 軟件工程師
- AB32VG1開發(fā)套件
- 搖桿擴(kuò)展板
- ssd1306 1.3寸 OLED硬件整體框架如下如所示:

本項(xiàng)目使用的硬件資源包括 AB32VG1 開發(fā)平臺(tái),搖桿擴(kuò)展版(包含一個(gè)joystick搖桿和四個(gè)按鍵)、SSD1306 OLED ,使用板載的支持的藍(lán)牙實(shí)現(xiàn)無線通信功能。
本次項(xiàng)目實(shí)驗(yàn)軟件部分均是在RT-Thread Studio中進(jìn)行開發(fā)設(shè)計(jì),相關(guān)軟件包均能通過軟件倉庫獲取到。
## RT-Thread系統(tǒng)使用情況 和
本次項(xiàng)目實(shí)驗(yàn)中使hi用到的軟件包如下,包括ssd1306 oled驅(qū)動(dòng)包和bluetrum_sdk 包。使用到的組件包括串口、GPIO和軟件模擬IIC組件。
## 程序模塊說明
- 搖桿驅(qū)動(dòng)程序設(shè)計(jì)
搖桿主要使用的是ADC來進(jìn)行驅(qū)動(dòng),通過讀取搖桿中的電位器的電壓值,來判斷當(dāng)前搖桿的狀態(tài)。驅(qū)動(dòng)示例代碼如下。
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;
/* 查找設(shè)備 */
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;
}
/* 使能設(shè)備 */
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);
/* 轉(zhuǎn)換為對(duì)應(yīng)電壓值 */
vol = value * REFER_VOLTAGE / CONVERT_BITS;
rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);
/* 關(guān)閉通道 */
ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL_1);
return ret;
}- OLED驅(qū)動(dòng)程序
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();
}- 屏幕圖形繪制程序設(shè)計(jì)
- 遙控器應(yīng)用界面設(shè)計(jì)
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();
/* 查找設(shè)備 */
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;
}
/* 使能設(shè)備 */
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);
/* 轉(zhuǎn)換為對(duì)應(yīng)電壓值 */
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);
/* 轉(zhuǎn)換為對(duì)應(yīng)電壓值 */
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);
// 求坐標(biāo) 將 圓點(diǎn)的軸坐標(biāo)固定到圓周內(nèi)部
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);
}
/* 關(guān)閉通道 */
ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL_1);
ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL_2);
}
/* 導(dǎo)出到 msh 命令列表中 */
//MSH_CMD_EXPORT(adc_oled, adc voltage loop);
INIT_APP_EXPORT(adc_oled);- 代碼倉庫
ab32vg1-remote-control: rtt大賽作品 基于RISC-V的多功能遙控器設(shè)計(jì) (gitee.com)
演示效果已經(jīng)上傳B站,如果后續(xù)有更新,會(huì)同步更新視頻內(nèi)容。