迪文科技论坛

 找回密码
 立即注册
搜索
查看: 1228|回复: 2

【开源】利用自重力实现横竖屏切换(二)

[复制链接]

4

主题

4

回帖

438

积分

中级会员

Rank: 3Rank: 3

积分
438
发表于 2020-12-5 21:49:28 | 显示全部楼层 |阅读模式
本帖最后由 湘江旧迹秋心 于 2020-12-5 21:53 编辑

       在帖子【开源】利用自重力实现横竖屏切换(一)中分享的是MPU6050采用IIC通信的方案,虽然这种方案的成本很低(预估也就几块钱),但由于大多数迪文标准屏并没有引出I/O口,也就无法进行通信,所以这种情况下就可以采用JY61模块,利用串口进行通信。
首先,这儿我们需要在屏幕上做好DGUS工程:两张背景图,横屏和竖屏的,注意,两张背景图上必须是一模一样的控件,即他们的地址,功能要相同,唯一的区别在于方向,这样切屏的效果实际为页面改变,如下图所示效果。
                          
第二步,将JY61接到屏幕的串口2上,切记串口要交叉连接,同时将模块和屏幕固定在一起,这样才能准确读出屏幕的姿态参数。
如图,切记进行固定,同时保证液晶屏和JY61的三轴重合。
第三步,程序编写
首先我们来看一下JY61的数据协议。

(1)串口通信参数
电平:TTL
波特率:9600/115200 bps
停止位:1
校验位0
(2)数据包
模块发送至上位机每帧数据分为3个数据包,分别为加速度包、角速度包和角度包,3个数据包顺序输出。波特率115200时每隔10ms输出一帧数据。
由于我们只用角度数据包,所以只解析这一部分即可,其他两个数据包,如果有感兴趣的可以玩一玩。
接下来我们再看一下串口助手打印数据的效果:我们可以看到三个数据包依次接收。


接下来,我们来写串口接收函数:(PS:由于本人手头没有屏,所以所写的程序段并未进行验证,存在一些不可避免的错误,欢迎大家指出)
externunsigned char xdata Re_buf[11],ucStrAngle[6];
u8uart2_busy=0;
u16uart2_rx_count=0;
externu8 change_flag;
u16 uart2_rx_count=0;
voidUART2_ISR_PC(void)    interrupt 4
{
    u8 res=0;
    EA=0;
    if(RI0==1)
    {if(RI0==1)
    {
                   res=SBUF0;
                   Re_buf[uart2_rx_count]=res;
                   if(uart2_rx_count==0&&Re_buf[0]!=0x55)
                       {
                 change_flag=0;
                 return;
               }
                   uart2_rx_count++;
                   if(uart2_rx_count==11)             //接收到11个数据
                   {
                       uart2_rx_count=0;
                       if(Re_buf [1]==0x53)
                       {
                           ucStrAngle[0]=Re_buf[2];
                           ucStrAngle[1]=Re_buf[3];
                           ucStrAngle[2]=Re_buf[4];
                           ucStrAngle[3]=Re_buf[5];
                           ucStrAngle[4]=Re_buf[6];
                           ucStrAngle[5]=Re_buf[7];
                   change_flag=1;
                    break;
                       }
                   }
                   RI0=0;     
    }
   
    }
    if(TI0==1)
   {
        TI0=0;
        uart2_busy=0;
    }
   EA=1;
}
此时,角度值保存在ucStrAngle[6]中,我们需要对数据进行使用。
如下图,如果我们对液晶屏的三个轴固定后,则其也有三个欧拉角,我们通过判断欧拉角的大小来确定方向。
  
判断角度这一部分逻辑取决于JY61相对于液晶屏的安装位置关系,我们这里不做讨论,直接看主程序即可。
(PS:由于本人手头没有屏,所以所写的程序段并未进行验证,存在一些不可避免的错误,欢迎大家指出)
u8 change_flag=0;
unsigned char xdata Re_buf[11],ucStrAngle[6];
float angle[3];
u8 polution;
void main(void)
{
    u8 direct[16]={0x5A,0x00,0x00,0x3C,0x5A,0x00,0x00,0x3D,0x5A,0x00,0x00,0x3E,0x5A,0x00,0x00,0x3F);
    u8 PIC_ID[8]={0x5A,0x01,0x00,0x01,0x5A,0x01,0x00,0x02);
    while (1)
    {
    if (change_flag==1)
    {
    angle[0] = ((short)(ucStrAngle[1]<<8| ucStrAngle[0]))/32768.0*180;   //X轴滚转角(x 轴)
    angle[1] = ((short)(ucStrAngle[3]<<8| ucStrAngle[2]))/32768.0*180;   //Y轴俯仰角(y 轴)
    angle[2] = ((short)(ucStrAngle[5]<<8| ucStrAngle[4]))/32768.0*180;   //Z轴偏航角(z 轴)

    polution=direction_change(void);
        //这里分别以polution的值为0,1,2,3表示0度(横屏),90度(竖屏),180度,270度;假设横屏为1号页面,竖屏为2号页面
    sys_write_vp(System_Config_VP,(u8*)&direct+(u8)polution,9);
    sys_delay_ms(10);
    sys_write_vp(PIC_Set_VP,(u8*)&PIC_ID+((u8)polution&0X01),4);
    sys_delay_ms(10);
    change_flag=1
    }
}
到了这一步,我们已经完成了所有的工作。
事实上,JY61能够输出温度值,我们可以利用这一点进行液晶屏温度检测,做到高温报警保护功能。
T= ((short)(ucStrAngle[7]<<8 | ucStrAngle[6]))/340.0+36.25;//即数据包第8位和第9位数据
作为一个嵌入式业余爱好者,欢迎大家批评指正,如果有好的想法,可以互相交流。









本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

4

主题

134

回帖

2801

积分

金牌会员

Rank: 6Rank: 6

积分
2801
发表于 2020-12-7 09:29:59 | 显示全部楼层
如果只是页面改变,要注意显示控件的显示角度是不会改变的。
回复

使用道具 举报

4

主题

4

回帖

438

积分

中级会员

Rank: 3Rank: 3

积分
438
 楼主| 发表于 2020-12-7 11:52:10 | 显示全部楼层
xiangliverygood 发表于 2020-12-7 09:29
如果只是页面改变,要注意显示控件的显示角度是不会改变的。

我用了两条指令,其中sys_write_vp(System_Config_VP,(u8*)&direct+(u8)polution,9);就是用来改变显示方向的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|迪文科技论坛 ( 京ICP备05033781号-1 )

GMT+8, 2024-12-21 22:40 , Processed in 0.114529 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表