【问题】DSP28335如何同步控制一组GPIO的的部分管脚而不影响其他管脚

0、序言

博主最近开始入入门DSP,把学习过程中遇到的一些问题记录下来,希望有遇到同样问题的朋友能够及时解决
处理器型号:TMS320F28335
开发环境为:CCS9.3
仿真器:XDS100V2
操作系统:Windows10
报错信息:未能独立控制一组的部分管脚

1、背景

      博主最近在调试步进电机与LCD1602等IO器件的时候发现了一个问题:如何同步控制一组GPIO的的部分管脚,而不影响同组的其他管脚。因为在例程中发现对于LCD1602写数据,或者步进电机控制相序,都是直接用*GpioDataRegs.GPADAT.all=0Xxxx*来进行控制,这种方法会造成其余Gpio意外操作。而在进行多外设实验时候,这会导致一些意外的发生。参看使用DATA寄存器操作IO的特殊情况,实际上TI的应用指南也给出了说明
在这里插入图片描述
      先给出一些LCD1602与步进电机的信息,虽然这个器件是微控制器器件的学习过程中必然会接触的器件,且网络上资料非常多,不过我还是想推荐一些高质量可快速入门的资料。

  1. LCD1602液晶屏
          先给出一个直观的控制命令指令表,通过这个表大家应该就可以明白为什么在写地址时候要加0X80。此外,最高位非0位的位置其实就区分了指令类别。具体的使用方法可参看以下免积分链接(中英文手册)1602屏中英文资料
    在这里插入图片描述

  2. 28BYJ-48步进电机
    希望大家在学习过程中可以知其所以然,下面推荐两个步进电机的原理的透彻讲解,能够完全理解相序的原理、步进角的确定、工作方式的原理等。

步进电机是如何工作的!


28BYJ-48步进电机工作原理详细解读

2、解决方法

      通常我们之所以想控制一组IO的部分管教,是由于我们需要将一个数组赋值到部分IO上,而这个数组里面的元素0xxx对应的二进制位可以是0也可以是1。本来想用GpioDataRegs.GPADAT.all|=,GpioDataRegs.GPADAT.all&=,GpioDataRegs.GPADAT.all=
方法直接改变管脚输出电平而不影响其他的位置,但是|=只可以置1,&=只可以置0,如果目标位置上次的值不确定的话|=对新值赋0将会是失败的,eg:lcd1602中将命令字 0x38(unsigned char)赋值给GPIO20-27,则我们用GpioDataRegs.GPADAT.all|=0x03800000,虽然不会影响其他位可是会造成赋0失败,因为GPIO20-27上次的赋值不确定。同理GpioDataRegs.GPADAT.all&=0xf38fffff会造成赋1失败,GpioDataRegs.GPADAT.all=会影响其他位
比较靠谱的做法:GpioDataRegs.GPADAT.all&=-0x0ff00000,先置0使得上次位可控,再赋值GpioDataRegs.GPADAT.all|=0x03800000,不过这个将会出现第一节所述的问题,TI官方也不建议用GPADAT赋值。
      后来博主尝试了下面的方法稳定可靠,且不影响其他位,用GPASET置1,GPACLEAR置0

    Uint32 temp=0x00000000;//因为0x38是一个char,左移会溢出,而GIPOA寄存器位32位,故需要一个temp的变量
    temp|=0x38;
    temp<<=20;//移动到GPIO20-27位置上
    GpioDataRegs.GPASET.all = temp;//置1
    GpioDataRegs.GPACLEAR.all = (~temp)&0x0ff00000;//temp取反后一定要加一个0x0ff00000;将除GPIO20-27位外剔除,这样就做到了对相应为置0的操作

1602写数据命令驱动代码块:

void LCD1602_WriteCmd(Uchar8 cmd)
{
    Uint32 temp=0x00000000;
    temp|=cmd;
    temp<<=20;
    LCD1602_EN_SETL;
    LCD1602_RS_SETL;
    GpioDataRegs.GPASET.all = temp;
    GpioDataRegs.GPACLEAR.all = (~temp)&0x0ff00000;
    DELAY_US(500);
    LCD1602_EN_SETH;//允许
    DELAY_US(1000);
    LCD1602_EN_SETL;
}
void LCD1602_WriteData(Uchar8 dat)
{
    Uint32 temp=0x00000000;
    temp|=dat;
    temp<<=20;
    LCD1602_EN_SETL;
    LCD1602_RS_SETH;
    GpioDataRegs.GPASET.all = temp;
    GpioDataRegs.GPACLEAR.all = (~temp)&0x0ff00000;
    DELAY_US(500);
    LCD1602_EN_SETH;
    DELAY_US(1000);
    LCD1602_EN_SETL;
}

步进电机相序代码块:

Uchar8 forward2[]={0xc,0x6,0x3,0x9};
#if two_phase_excitation
for(j=0;j<4;j++)
    {
       GpioDataRegs.GPASET.all=forward2[j]<<2;
       GpioDataRegs.GPACLEAR.all=((~forward2[j])&0x0f)<<2;//设置低电平取反后一定要注意&0x0f只保留目标位
       DELAY_US(2000);
    }
#endif

2、相关代码

博主给出了,优化后的LCD1602的驱动代码以及接口电路图lcd1602驱动程序,此外还给出了步进电机的驱动代码以及接口电路图,通过宏定义配置了正反转以及单向励磁、两相励磁、一二相励磁的相关方法,欢迎大家免费下载步进电机驱动程序

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页