概述
一、本次实验用到的器件:STM32C6T6最小系统板(连接摇杆模块),正点原子STM32ZET6精英板(蓝牙接收信号并实现LCD显示图像),两个HC-05模块,一个5针摇杆模块。
二、硬件连接:C6T6:PA9---HC05的RXD , PA10---TXD,5V供电,PA1---摇杆模块VRY,PA4---摇杆模块VRX(用于AD转换获取x,y轴的ADC值)
ZET6:PA9---HC05的RXD , PA10---TXD
三、最终效果(小圆点为实时摇杆位置,中央圆圈为死区,可根据实际使用设置后编写相关功能,本帖不涉及死区的使用,左上角为x,y轴的ADC值,最右上角ADC值最大,两个轴都约为4096)
四、实验原理
摇杆模块可看作x轴和y轴上各有一个电位器,摇杆处于不同位置,电位器所处状态不同,所输出的两个电压值会线性改变,这就使得我们可以通过测量x,y轴的电压值来得到摇杆的坐标位置,类似与识别电阻屏触摸位置的原理。在这里我使用C6T6的PA1(ADC_Channel_1)通过AD转换来测量x轴的ADC值,y轴使用PA4(ADC_Channel_4)C6T6的蓝牙模块设置为主机,将两个值发送给从机的ZET6。发送格式为printf("%d,%drn",adcx1,adcx4);
从机所做工作主要是分析主机所发来的字符串,例如主机发来的是453,3912,那么就需要计算4*100+5*10+3来获取x轴的电压tempx,计算3*1000+9*100+10*1+2获取y轴电压tempy。
len_y=len-(loc+1);//(len_y是tempy的位数)用于计算tempy的值
//fun(a,b)的功能是计算a的b次方、
//loc是","在字符数组的位置
//len为字符串总长度,
//例如收到的是123,432 len即为7,len_y为3,loc是3
for(i=loc,j=0,tempx=0;i>0;i--,j++)
{
tempx+=num[j]*fun(10,i-1);
}
for(i=len_y,j=1,tempy=0;i>0; i--,j++)
{
tempy+=num[loc+j]*fun(10,i-1);
}
//以上两个循环可简便地计算每次收到的两个ADC值
下一步便是图像显示,相关代码如下
(基本界面,一个正方形田字格,边长200像素,对角坐标为(20,50),(220,250))
LCD_DrawRectangle(20,50 ,220,250);
LCD_DrawLine(120, 50, 120, 250);
LCD_DrawLine(20, 150, 220, 150);
显示位置(将长宽分为4096份,再经过电压与坐标的线性关系计算出坐标,在该点画一个小圆圈)
LCD_Draw_Circle(20+(tempx1*200/4096)*200/200, 250-(tempy1*200/4096)*200/200, 4);
在图像显示方面还有要注意的一点:当坐标改变,在该店画出一个新的圆圈时,要消除上一个坐标的圆圈,代码如下(在上一个圆圈的位置画一个一样的白色圆圈覆盖它并重新画一下田字格)
if((tempx1!=tempx)||(tempy1!=tempy))
{
POINT_COLOR=WHITE;
LCD_Draw_Circle(20+(tempx1*200/4096)*200/200, 250-(tempy1*200/4096)*200/200, 4);
POINT_COLOR=BLUE;
LCD_DrawRectangle(20,50 ,220,250);
LCD_DrawLine(120, 50, 120, 250);
LCD_DrawLine(20, 150, 220, 150);
LCD_Draw_Circle(120, 150, 16);
}
ZET6的main文件
#include "delay.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "adc.h"
u16 fun(u16 a,u16 b)
{
u16 i=0,temp=1;
for(i=0;i<b;i++)
{
temp*=a;
}
return temp;
}
int main(void)
{
u16 t,i=0,j=0;
u16 loc;// ","所在的位置
u16 num[9];
u16 tempx=0,tempx1=0;
u16 tempy=0,tempy1=0;
u16 len,len_y=0;//总字符串长度和y轴量的字符串长度
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(9600);
LCD_Init();
POINT_COLOR=BLUE;
LCD_DrawRectangle(20,50 ,220,250);
LCD_DrawLine(120, 50, 120, 250);
LCD_DrawLine(20, 150, 220, 150);
LCD_Draw_Circle(120, 150, 16);
while(1)
{
for(i=0;i<9;i++)//刷新数组元素的值
{
num[i]=0;
}
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;
for(t=0;t<len;t++)
{
num[t]=USART_RX_BUF[t]-48;
if(num[t]>5000)
{
loc=t;
}
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
}
len_y=len-(loc+1);
for(i=loc,j=0,tempx=0;i>0;i--,j++)
{
tempx+=num[j]*fun(10,i-1);
}
for(i=len_y,j=1,tempy=0;i>0; i--,j++)
{
tempy+=num[loc+j]*fun(10,i-1);
}
LCD_ShowNum(0,0,tempx,4,16);
LCD_ShowNum(0,16,tempy,4,16);
if((tempx1!=tempx)||(tempy1!=tempy))//去除上一点,刷新屏幕
{
POINT_COLOR=WHITE;
LCD_Draw_Circle(20+(tempx1*200/4096)*200/200, 250-(tempy1*200/4096)*200/200, 4);
POINT_COLOR=BLUE;
LCD_DrawRectangle(20,50 ,220,250);
LCD_DrawLine(120, 50, 120, 250);
LCD_DrawLine(20, 150, 220, 150);
LCD_Draw_Circle(120, 150, 16);
}
tempx1=tempx;
tempy1=tempy;
POINT_COLOR=BLUE;
LCD_Draw_Circle(20+(tempx1*200/4096)*200/200, 250-(tempy1*200/4096)*200/200, 4);//用圆圈显示位置
USART_RX_STA=0;
}
}
}
C6T6的main文件
#include "led.h"
#include "sys.h"
#include "usart.h"
#include "adc.h"
int main(void)
{
u16 adcx1,adcx4;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(9600);
Adc_Init();
while(1)
{
adcx1=Get_Adc_Average(ADC_Channel_1,10);
adcx4=Get_Adc_Average(ADC_Channel_4,10);
printf("%d,%drn",adcx1,adcx4);
}
}
五、最后
蓝牙模块的设置要进入AT模式,内容较多,这里就不再赘述,有问题可以自行查阅,蓝牙连接方面我也是参考别人的教程。另外如果在阅读途中有疑问或发现错误可以私信我,工程文件也可以向我获取,第一次写帖子,经验不足,水平也有限,还请各位多多包涵。
最后
以上就是危机火龙果为你收集整理的STM32摇杆模块的蓝牙通信+LCD图形化的坐标显示的全部内容,希望文章能够帮你解决STM32摇杆模块的蓝牙通信+LCD图形化的坐标显示所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复