0、序言
博主最近开始入入门DSP,把学习过程中遇到的一些问题记录下来,希望有遇到同样问题的朋友能够及时解决
处理器型号:TMS320F28335
开发环境为:CCS9.3
仿真器:XDS100V2
操作系统:Windows10
报错信息:未能独立控制一组的部分管脚
1、背景
博主最近在调试步进电机与LCD1602等IO器件的时候发现了一个问题:如何同步控制一组GPIO的的部分管脚,而不影响同组的其他管脚。因为在例程中发现对于LCD1602写数据,或者步进电机控制相序,都是直接用*GpioDataRegs.GPADAT.all=0Xxxx*来进行控制,这种方法会造成其余Gpio意外操作。而在进行多外设实验时候,这会导致一些意外的发生。参看使用DATA寄存器操作IO的特殊情况,实际上TI的应用指南也给出了说明
先给出一些LCD1602与步进电机的信息,虽然这个器件是微控制器器件的学习过程中必然会接触的器件,且网络上资料非常多,不过我还是想推荐一些高质量可快速入门的资料。
-
LCD1602液晶屏
先给出一个直观的控制命令指令表,通过这个表大家应该就可以明白为什么在写地址时候要加0X80。此外,最高位非0位的位置其实就区分了指令类别。具体的使用方法可参看以下免积分链接(中英文手册)1602屏中英文资料
-
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驱动程序,此外还给出了步进电机的驱动代码以及接口电路图,通过宏定义配置了正反转以及单向励磁、两相励磁、一二相励磁的相关方法,欢迎大家免费下载步进电机驱动程序