利用dsp电机测速及详解
摘要
通过按键实现加速,减速,停止功能,利用中断测速,采用软件延时去抖动,具体实现方法看代码。
程序清单
#pragma CODE_SECTION(vect,"vect")
unsigned int *pmem=0;
#define IMR *(pmem+0x0000)
#define IFR *(pmem+0x0001)
#define PMST *(pmem+0x001d)
#define SWCR *(pmem+0x002b)
#define SWWSR *(pmem+0x0028)
#define CLKMD *(pmem+0x0058)
#define ST1 *(pmem+0x007)
#define PRD0 *(pmem+0x0025) /* timer0 period register */
#define TCR0 *(pmem+0x0026) /* timer0 control register */
#define uchar unsigned char
#define ulong unsigned long
#define uint unsigned int
uchar flag=0x0;
uchar flag1=0x0;
uint count=0x0;
uint count1=0x0;
uint k=0x0;
ioport unsigned portc001; //键盘地址
ioport unsigned port8003; //液晶屏CS1地址读指令
ioport unsigned port8004; //液晶屏CS1地址写指令
ioport unsigned port8005; //液晶屏CS1地址写数据 ioport unsigned port8000; //液晶屏CS2地址
ioport unsigned port8001; //液晶屏CS2地址
ioport unsigned port8002; //液晶屏CS2地址
#define cs1 port8003
#define cs1rd port8004
#define cs1wd port8005
#define cs2 port8000
#define cs2rd port8001
#define cs2wd port8002ioport unsigned portc005; //直流电机地址
#define djcs portc005
static const uchar table4[]={
//;-- 0 -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0x80,0x3F,0x00,0xE0,0xFF,0x01,0xE0,0xFF,0x01,0x70,0x80,0x03,0x10,
0x00,0x02,0x10,0x00,0x02,0x70,0x80,0x03,0xE0,0xFF,0x01,0xE0,0xFF,0x01,0x80,0x3F,
0x00,0x00,0x00,0x00,
//;-- 1 -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0xE0,
0xFF,0x03,0xF0,0xFF,0x03,0xF0,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
//;-- 2 -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0xC0,0x01,0x03,0xE0,0xC1,0x03,0xF0,0xE1,0x03,0x30,0xF0,0x02,0x10,
0x78,0x02,0x30,0x1C,0x02,0xF0,0x0F,0x02,0xE0,0x07,0x02,0xC0,0x03,0x02,0x00,0x00,
0x00,0x00,0x00,0x00,
///;-- 3 -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0xC0,0xE0,0x00,0xE0,0xE0,0x01,0xF0,0xE0,0x03,0x30,0x04,0x03,0x10,
0x04,0x02,0x30,0x0E,0x03,0xF0,0xFF,0x03,0xE0,0xFB,0x01,0xC0,0xF1,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
//;-- 4 -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x3C,0x00,0x00,0x2E,0x00,0x80,0x27,0x00,0xE0,
0x21,0x00,0xF0,0xFF,0x03,0xF0,0xFF,0x03,0xF0,0xFF,0x03,0x00,0x20,0x00,0x00,0x20,
0x00,0x00,0x00,0x00,
//;-- 5 -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0x00,0xC0,0x00,0xF0,0xC7,0x01,0xF0,0xC7,0x03,0xF0,0x07,0x03,0x10,
0x03,0x02,0x10,0x03,0x03,0x10,0xFF,0x03,0x10,0xFF,0x01,0x10,0xFC,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
//;-- 6 -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0x80,0x7F,0x00,0xE0,0xFF,0x01,0xE0,0xFF,0x03,0x70,0x06,0x03,0x10,
0x02,0x02,0x30,0x06,0x03,0x70,0xFE,0x03,0x70,0xFC,0x01,0x60,0xF8,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
//;-- 7 -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x03,0x10,0xE0,0x03,0x10,
0xFC,0x03,0x90,0xFF,0x00,0xF0,0x1F,0x00,0xF0,0x03,0x00,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
//;-- 8 -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0xC0,0xF1,0x00,0xE0,0xFB,0x01,0xF0,0xFB,0x03,0x30,0x0E,0x03,0x10,
0x04,0x02,0x10,0x04,0x02,0x30,0x0E,0x03,0xF0,0xFB,0x03,0xE0,0xFB,0x01,0xC0,0xF1,
0x00,0x00,0x00,0x00,
//;-- 9 -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0xC0,0x87,0x01,0xE0,0x8F,0x03,0xF0,0x9F,0x03,0x30,0x18,0x03,0x10,
0x10,0x02,0x30,0x98,0x03,0xF0,0xFF,0x01,0xE0,0xFF,0x00,0x80,0x3F,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,//;-- A -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x03,0x00,0xE0,0x03,0x00,0xFC,0x03,0x80,0xFF,0x00,0xF0,0x3F,0x00,0xF0,
0x21,0x00,0xF0,0x3F,0x00,0x80,0xFF,0x00,0x00,0xFC,0x03,0x00,0xE0,0x03,0x00,0x00,
0x03,0x00,0x00,0x00,
//;-- B -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0xF0,0xFF,0x03,0xF0,0xFF,0x03,0xF0,0xFF,0x03,0x10,0x04,0x02,0x10,
0x04,0x02,0x10,0x04,0x02,0x30,0x0E,0x03,0xF0,0xFF,0x03,0xE0,0xFB,0x01,0xC0,0xF1,
0x00,0x00,0x00,0x00,
//;-- C -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0x00,0x7F,0x00,0xC0,0xFF,0x01,0xE0,0xFF,0x01,0x70,0x80,0x03,0x10,
0x00,0x02,0x10,0x00,0x02,0x30,0x00,0x03,0xF0,0xF1,0x03,0xE0,0xF1,0x01,0xC0,0x71,
0x00,0x00,0x00,0x00,
//;-- D -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0xF0,0xFF,0x03,0xF0,0xFF,0x03,0xF0,0xFF,0x03,0x10,0x00,0x02,0x10,
0x00,0x02,0x30,0x00,0x03,0x70,0x80,0x03,0xE0,0xFF,0x01,0xC0,0xFF,0x00,0x80,0x7F,
0x00,0x00,0x00,0x00,
//;-- E -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0xF0,0xFF,0x03,0xF0,0xFF,0x03,0xF0,0xFF,0x03,0x10,0x04,0x02,0x10,
0x04,0x02,0x10,0x04,0x02,0x10,0x04,0x02,0x10,0x04,0x02,0x10,0x00,0x02,0x00,0x00,
0x00,0x00,0x00,0x00,
//;-- F -- ** 黑体, 16 **
//; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=12x21, 调整后为: 12x24
0x00,0x00,0x00,0xF0,0xFF,0x03,0xF0,0xFF,0x03,0xF0,0xFF,0x03,0x10,0x08,0x00,0x10,
0x08,0x00,0x10,0x08,0x00,0x10,0x08,0x00,0x10,0x08,0x00,0x10,0x00,0x00,0x10,0x00,
0x00,0x00,0x00,0x00,
};void cpu_init() /*初始化DSP*/
{asm(" ssbx intm"); //复位指令 禁止总中断asm(" ssbx xf"); //总清零PMST=0xe8; //设置处理器工作模式状态寄存器SWWSR=0x7fff; //设置软件等待状态,确保处理器初始化期间CPU和外部慢速器件正 //常通信SWCR=0x0001; //软件等待控制寄存器,等待状态翻倍IMR=0x010c; //允许int2-3和tint中断IFR=0xffff; //清除所有中断CLKMD=0x000; //时钟模式恢复asm(" rsbx intm"); //开总中断asm(" rsbx xf"); //打开数据口
}void zldj() //直流电机测试程序
{ TCR0=0x10;PRD0=0x99; TCR0=0xc20;
}void delay100ms() //利用for循环软件延时100ms
{int i,j,k;
for (i=0;i<40;i++)
for (j=0;j<12;j++)
for (k=0;k<20;k++);
}void delay10ms() //利用for循环软件延时10ms
{int i,j,k;
for (i=0;i<2;i++)
for (j=0;j<2;j++)
for (k=0;k<2;k++);
}void dicenga(void) /*片选1的查询函*/
{delay10ms();
}void dicengb(void) /*片选2的查询函数*/
{ delay10ms();
}void lcdwc1(uchar dat) /*片选1的写控制?*/
{
dicenga();
cs1rd=dat;
delay10ms();
}void lcdwc2(uchar dat) /*片选2的写控制字函数*/
{
dicengb();
cs2rd=dat;
delay10ms();
}void lcdwd1(uchar dat) /*片选1的写数据函数*/
{
dicenga();
cs1wd=dat;
delay10ms();}void lcdwd2(uchar dat) /*片选2的写数据函数*/
{
dicengb();
cs2wd=dat;
delay10ms();}void lcdreset(void) //液晶屏初始化或者说复位
{uchar dat;dat=0x3f;lcdwc1(dat);lcdwc2(dat);dat=0xc0;lcdwc1(dat);lcdwc2(dat);
}void lcdwd(uchar dat,uchar ypos,uchar xpos) //判断其在哪个屏
{
uchar bbb;
bbb=dat;
dat=xpos;
if(dat<64) {
dat=bbb;lcdwd1(dat);}
else{
dat=bbb;lcdwd2(dat);}
}void lcdpos(uchar ypos,uchar xpos) //设置显示位置
{
uchar bbb;
bbb=xpos;
if(bbb<64){
bbb=ypos;
bbb=bbb&0x07;
bbb=bbb+0x0B8;
lcdwc1(bbb);
bbb=xpos;
bbb=bbb&0x3f;
bbb=bbb+0x40;
lcdwc1(bbb);}
else{
bbb=ypos;
bbb=bbb&0x07;
bbb=bbb+0x0b8;
lcdwc2(bbb);
bbb=xpos;
bbb=bbb&0x3F;
bbb=bbb+0x40;
lcdwc2(bbb);}
}void lcdwrite(uchar dat,uchar ypos,uchar xpos) //LCD写入函数
{
lcdpos( ypos, xpos);
lcdwd(dat,ypos,xpos);
}void lcdfill() /*液晶屏清屏程序*/
{
uchar dat,ypos, xpos;
dat=0x0;
for(ypos=0;ypos<=7;ypos++){for(xpos=0;xpos<=127;xpos++){lcdwrite(dat,ypos,xpos);}}
}void dataplay(uchar vxpos,uchar vypos,uchar dat2) // 数字显示子程序
{uchar dat1,ypos,xpos; //vxpos是列的起始地址//vypos是行的起始地址 ulong x;x=dat2*36; //确定查表地址for(xpos=vxpos+0;xpos<vxpos+12;xpos++){for(ypos=vypos+2;ypos<vypos+5;ypos++){dat1=table4[x];lcdwrite(dat1,ypos,xpos);x=x+1;}}
}
/************************* 主程序 **************************************/
void main()
{ cpu_init(); //芯片初始化lcdreset(); //LCD复位lcdfill(); //清屏djcs=0x00; //直流电机初始化zldj(); //直流电机测试for(;;) //等待按键{};
}
/***************************************************************************/interrupt void timer() //定时器测试
{ count=count+1;if(count==0x3e7) //1000*1000{count=0x0;count1=count1+1;if(count1==0x63) //1000*100{count1=0x0;flag=0x01;} }
}interrupt void djout() // 速度测试 这个信号是来自于光电开关的
{ uchar vxpos;uchar vypos;uint dat2,dat3,dat4;uint kaaa; k=k+1; //保留测试值if(flag==1){kaaa=k/4; //获取转速dat2=kaaa/100; //取整获取百位dat3=(kaaa-dat2*100)/10; //获取十位dat4=kaaa-dat2*100-dat3*10; //获取个位vxpos=0x30;vypos=0x0;dataplay(vxpos,vypos,dat2); //显示百位dat2=dat3;vxpos=0x3c;vypos=0x0;dataplay(vxpos,vypos,dat2); //显示十位dat2=dat4;vxpos=0x48;vypos=0x0;dataplay(vxpos,vypos,dat2); //显示个位flag=0x00; //测试结束标志位清零k=0x0; //测试值清零}
}interrupt void keyint0() //键盘测试
{ int a;a=portc001;a=a&0xff00;if(a!=0xff00) //判断是否有键按下{delay10ms(); //延时去抖动a=portc001;a=a&0xff00;a=a&0xff00;a=a&0xff00;a=a&0xff00;switch(a) //判断是哪个键按下{case 0xfe00: break;case 0xfd00: break;case 0xfb00: break;case 0xf700: break;case 0xef00: break;case 0xdf00: djcs=0x1; //选择转速1break;case 0xbf00: djcs=0x2; //选择转速2break;case 0x7f00: lcdfill(); //清屏djcs=0x0; //电机停转 break;}}
}void vect() //中断向量文件配置
{asm(" .ref _c_int00");asm(" .ref _keyint0");asm(" .ref _djout"); asm(" .ref _timer"); asm(" b _c_int00"); /* reset */asm(" nop");asm(" nop");asm(" rete"); /* nmi */asm(" nop");asm(" nop");asm(" nop");asm(" rete"); //asm(" nop");asm(" nop");asm(" nop");asm(" rete");asm(" nop");asm(" nop");asm(" nop");asm(" rete");asm(" nop");asm(" nop");asm(" nop");asm(" rete");asm(" nop");asm(" nop");asm(" nop");asm(" rete");asm(" nop");asm(" nop");asm(" nop");asm(" rete");asm(" nop");asm(" nop");asm(" nop");asm(" rete");asm(" nop");asm(" nop");asm(" nop");asm(" rete");asm(" nop");asm(" nop");asm(" nop");asm(" rete");asm(" nop");asm(" nop");asm(" nop");asm(" rete");asm(" nop");asm(" nop");asm(" nop");asm(" rete");asm(" nop");asm(" nop");asm(" nop");asm(" rete");asm(" nop");asm(" nop");asm(" nop");asm(" rete");asm(" nop");asm(" nop");asm(" nop");asm(" rete");asm(" nop");asm(" nop");asm(" nop");asm(" rete "); /* int0 */asm(" nop");asm(" nop");asm(" nop");asm(" rete"); /* int1 */asm(" nop");asm(" nop");asm(" nop");asm(" b _keyint0"); /* int2 */asm(" nop");asm(" nop");asm(" b _timer"); /* tint0 */asm(" nop");asm(" nop");asm(" rete"); /* brint0 */asm(" nop");asm(" nop");asm(" nop");asm(" rete"); /* bxint0 */asm(" nop");asm(" nop");asm(" nop");asm(" rete"); /* dmac0 */asm(" nop");asm(" nop");asm(" nop");asm(" rete"); /* tint1 */asm(" nop");asm(" nop");asm(" nop");asm(" b _djout"); /* int3 */asm(" nop");asm(" nop");asm(" rete"); /* hpint */asm(" nop");asm(" nop");asm(" nop");asm(" rete "); /* brint1 */asm(" nop");asm(" nop");asm(" nop");asm(" rete"); /* bxint1 */asm(" nop");asm(" nop");asm(" nop");asm(" rete"); /* dmac4 */asm(" nop");asm(" nop");asm(" nop");asm(" rete"); /* dmac5 */asm(" nop");asm(" nop");asm(" nop");asm(" nop");asm(" nop");asm(" nop");asm(" nop");
}
结果图
结束语
希望可以帮助更多人,如有误,请各位帮忙斧正,谢谢!
@2
利用dsp电机测速及详解相关推荐
- STM32应用开发实践教程:智能小车电机测速模块的应用开发
3.4.1 任务分析 本任务要求设计一个可实现智能小车电机测速的应用程序,具体要点如下. ① 取一个电机作为测速对象. ② 支持按键控制,使用 4 个按键,功能描述如下: Key1 控制电机正转, ...
- 寻迹小车 FOLLOWME—— 电机测速及转速控制
寻迹小车 FOLLOWME-- 之五:电机测速及转速控制 此篇涉及电机的测速和转速控制. 寻迹小车 FollowMe -- 之五:电机测速及转速控制 作者:Hanker 前面已完成了车的主体,控制部分 ...
- matlab 测速电机,一种精准的电机测速方法与流程
本发明涉及电机测速领域,特别地,涉及一种精准的电机测速方法. 背景技术: 通常对电机进行转速测量,需要在电机内部安装某些传感器,但会降低电机运行可靠性,甚至某些电机无法在内部加装传感器.目前国内外常用 ...
- STM32 CubeMax 编码器电机测速 原理与实现
编码器电机测速 部分参考:https://blog.csdn.net/lzzzzzzm/article/details/119416134 其他参考部分见图片水印 1. 编码器种类及原理 常见的编码器 ...
- STM32之增量式编码器电机测速
STM32之增量式编码器电机测速 编码器 编码器种类 按监测原理分类 光电编码器 霍尔编码器 按输出信号分类 增量式编码器 绝对式编码器 编码器参数 分辨率 精度 最大响应频率 信号输出形式 编码器倍 ...
- python 文字语音朗读-python 利用pyttsx3文字转语音过程详解
这篇文章主要介绍了python 利用pyttsx3文字转语音过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 # -*- coding: ut ...
- PX4飞控中利用EKF估计姿态角代码详解
PX4飞控中利用EKF估计姿态角代码详解 PX4飞控中主要用EKF算法来估计飞行器三轴姿态角,具体c文件在px4\Firmware\src\modules\attitude_estimator_ekf ...
- python脚本语言采用声音作为手段_python 利用pyttsx3文字转语音过程详解
这篇文章主要介绍了python 利用pyttsx3文字转语音过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下# -*- coding: utf ...
- python ks值计算_利用Python计算KS的实例详解
在金融领域中,我们的y值和预测得到的违约概率刚好是两个分布未知的两个分布.好的信用风控模型一般从准确性.稳定性和可解释性来评估模型.sOf免费资源网 一般来说.好人样本的分布同坏人样本的分布应该是有很 ...
最新文章
- 如何让Keil MDK兼容Keil C51?
- shell脚本按行读取文件的几种方式
- 客户端连接mysql 自动断开_MySql连接空闲8小时自动断开的原因及连接池配置方法...
- 不懂 ZooKeeper?没关系,这一篇给你讲的明明白白
- 搭建一款开源的微信商城小程序:海风小店
- hdu 1760 DFS+博弈
- 95 后程序员一出校门就拿年薪 32 万?
- Java基础练习之流程控制(一)
- dojo省份地市级联之地市Dao接口类(四)
- 2022年固定资产管理系统的概况
- vc语言c1083错误,VC编程之VS error C1083: 无法打开包括文件:“gl\glew.h”: No such file or directory\...
- 深蓝学院-视觉SLAM十四讲-第一章作业
- 嵌入式系统开发笔记15:CJ/T-188 冷热量表协议解析4
- 硕士管理类199联考论说文真题素材
- 强化学习(1)-什么是强化学习
- 高校图书馆借阅排行榜:Top40好书推荐
- 【附源码】Java计算机毕业设计飞越青少儿兴趣培训机构管理系统(程序+LW+部署)
- 梯度、雅克比矩阵、海森矩阵、多元泰勒公式
- poj解题报告——2386
- 三分钟了解,阁中物电商是什么样的平台