单片机程序 运动控制_单片机与单片机对应控制led灯程序 - CSDN
  • 单片机控制步进电机-单片机程序(avr) 硬件线路连接图见上一篇文章 软件: ICCV7 FOR AVR-写程序 Progisp-烧程序 速度S曲线生成器(后续后单独讲解)-生成S曲线数组代码 硬件: Atmega16 ASP下载线 杜邦...

    单片机控制步进电机-单片机程序(avr)

    硬件线路连接图见上一篇文章:https://blog.csdn.net/LuDanTongXue/article/details/87869557

    软件
    ICCV7 FOR AVR-写程序
    Progisp-烧程序
    速度S曲线生成器(后续后单独讲解)-生成S曲线数组代码
    硬件
    Atmega16
    ASP下载线
    杜邦线

    控制原理:
    利用单片机定时器控制IO口高低电平产生脉冲,通过定时器控制每个脉冲的时间,以及脉冲的个数,从而控制步进电机速度以及转动角度,实现步进电机开环控制能力。步进电机常用的运动控制过程是:【静止】-【S曲线加速】-【匀速】-【S曲线减速】-【停止】,优点是速度平缓上升与下降,能够输出较大的扭矩,不容易失步、堵转。
    以下会以【静止】-【正转180°】-【反转180°】-【停止】该运动控制过程进行演示,其中加减速过程均采用S曲线控制。
    速度曲线具体控制过程是:
    第一段S曲线加速30°:1转/秒启动,5转/秒结束
    第二段匀速运动120°:5转/秒匀速
    第三段S曲线减速30°:5转/秒启动,0.5转/秒结束
    第四段S曲线反转加速30°:0.5转/秒启动,5转/秒结束
    第五段匀速反转运动120°:5转/秒匀速
    第六段S曲线反转减速30°:5转/秒启动,1转/秒结束

    V-T图:
    速度时间图
    S-T图:
    在这里插入图片描述

    代码如下:(适用于Atmega16芯片,如用51芯片需要稍作改动)

    //头文件
    #include<iom16v.h>
    #include<macros.h>//SEI()函数_NOP()BIT();
    #define uint unsigned int
    #define uchar unsigned char
    
    //步进电机接口定义
    #define ENA0 (PORTA &=~BIT(0))//电机由脉冲控制
    #define ENA1 (PORTA |=BIT(0))//电机掉电、自由状态
    #define DIR0 (PORTA &=~BIT(1))//电机正方向转动
    #define DIR1 (PORTA |=BIT(1))//电机反方向转动
    #define PUL0 (PORTA &=~BIT(2))//低电位
    #define PUL1 (PORTA |=BIT(2))//高电位
    
    
    unsigned int n0;//脉冲计数,用来控制电机转角
    uchar duan;//步进电机曲线分段控制参数
    uchar kaiguanflag;//该参数为0时,步进电机的启动开关才有效
    
    
    //定义MEGA16接口输入输出
    void port_init(void)
    {
     PORTA = 0xFF; //BIT(4)为电机启动开关  BIT(5)电机释放开关
     DDRA  = 0x0F; 
     PORTB = 0xFF; 
     DDRB  = 0xFF; 
     PORTC = 0xFF; 
     DDRC  = 0xFF; 
     PORTD = 0xFF; 
     DDRD  = 0x02;
    }
    
    
    //ms延时函数
    void delay_1ms(void) 
    {  
    unsigned int i;  
    for(i=1;i<(unsigned int)(11.059*143-2);i++);//定义晶振频率
    }  
    void delay(unsigned int n)//延时微妙级 
    {  
    unsigned int i; 
    for(i=0;i<n;i++) 
    delay_1ms(); 
    }
    
    
    //主程序
    //曲线数组的生成后续文章会单独分析
    //第一段S曲线加速30°:1转/秒启动,5转/秒结束
    A[67]={0XE5CF,0XE5EF,0XE614,0XE63E,0XE66E,0XE6A4,0XE6E2,0XE728,0XE777,0XE7D0,0XE832,0XE8A0,0XE919,0XE99E,0XEA2F,0XEACB,0XEB73,0XEC25,0XECE0,0XEDA3,0XEE6C,0XEF38,0XF006,0XF0D4,0XF19E,0XF264,0XF323,0XF3D9,0XF485,0XF526,0XF5BC,0XF646,0XF6C4,0XF737,0XF79E,0XF7FB,0XF84E,0XF898,0XF8D9,0XF913,0XF946,0XF972,0XF999,0XF9BB,0XF9D9,0XF9F3,0XFA09,0XFA1C,0XFA2D,0XFA3C,0XFA49,0XFA54,0XFA5D,0XFA65,0XFA6C,0XFA72,0XFA78,0XFA7C,0XFA80,0XFA83,0XFA86,0XFA89,0XFA8B,0XFA8D,0XFA8F,0XFA90,0XFA91};
    
    //第三段S曲线减速30°:5转/秒启动,0.5转/秒结束
    B[67]={0XFA8F,0XFA8D,0XFA8B,0XFA89,0XFA87,0XFA84,0XFA81,0XFA7D,0XFA79,0XFA73,0XFA6D,0XFA67,0XFA5F,0XFA55,0XFA4A,0XFA3E,0XFA2F,0XFA1F,0XFA0B,0XF9F5,0XF9DB,0XF9BD,0XF99A,0XF972,0XF944,0XF90F,0XF8D2,0XF88C,0XF83C,0XF7E0,0XF777,0XF700,0XF678,0XF5DE,0XF531,0XF46F,0XF396,0XF2A4,0XF199,0XF073,0XEF33,0XEDD9,0XEC65,0XEAD9,0XE939,0XE786,0XE5C4,0XE3FA,0XE22A,0XE05B,0XDE91,0XDCD2,0XDB21,0XD983,0XD7FB,0XD68B,0XD534,0XD3F8,0XD2D6,0XD1CF,0XD0E1,0XD00B,0XCF4C,0XCEA2,0XCE0B,0XCD86,0XCD10};
    
    //第四段S曲线反转加速30°:0.5转/秒启动,5转/秒结束
    C[67]={0XCD86,0XCE0B,0XCEA2,0XCF4C,0XD00B,0XD0E1,0XD1CF,0XD2D6,0XD3F8,0XD534,0XD68B,0XD7FB,0XD983,0XDB21,0XDCD2,0XDE91,0XE05B,0XE22A,0XE3FA,0XE5C4,0XE786,0XE939,0XEAD9,0XEC65,0XEDD9,0XEF33,0XF073,0XF199,0XF2A4,0XF396,0XF46F,0XF531,0XF5DE,0XF678,0XF700,0XF777,0XF7E0,0XF83C,0XF88C,0XF8D2,0XF90F,0XF944,0XF972,0XF99A,0XF9BD,0XF9DB,0XF9F5,0XFA0B,0XFA1F,0XFA2F,0XFA3E,0XFA4A,0XFA55,0XFA5F,0XFA67,0XFA6D,0XFA73,0XFA79,0XFA7D,0XFA81,0XFA84,0XFA87,0XFA89,0XFA8B,0XFA8D,0XFA8F,0XFA90};
    
    //第六段S曲线反转减速30°:5转/秒启动,1转/秒结束
    D[67]={0XFA90,0XFA8F,0XFA8D,0XFA8B,0XFA89,0XFA86,0XFA83,0XFA80,0XFA7C,0XFA78,0XFA72,0XFA6C,0XFA65,0XFA5D,0XFA54,0XFA49,0XFA3C,0XFA2D,0XFA1C,0XFA09,0XF9F3,0XF9D9,0XF9BB,0XF999,0XF972,0XF946,0XF913,0XF8D9,0XF898,0XF84E,0XF7FB,0XF79E,0XF737,0XF6C4,0XF646,0XF5BC,0XF526,0XF485,0XF3D9,0XF323,0XF264,0XF19E,0XF0D4,0XF006,0XEF38,0XEE6C,0XEDA3,0XECE0,0XEC25,0XEB73,0XEACB,0XEA2F,0XE99E,0XE919,0XE8A0,0XE832,0XE7D0,0XE777,0XE728,0XE6E2,0XE6A4,0XE66E,0XE63E,0XE614,0XE5EF,0XE5CF,0XE5B3};
    
    
    void main(void)
    {
    TCCR1B=0X01;//不分频(定时小于5.9毫秒) 
    TCNT1=0XE5F0;//存放初值,根据A[0]值确定
    TIMSK|=0x00;//定时器中断关
    SREG=0X80;//总中断开
    port_init();//IO口初始化
    DIR0;//定一个初始转向
    ENA1;//上电后步进电机为自由状态
    while(1)
    {
    //本程序将PA4口设置为一个开关,当PA4口与单片机GND连通时,电机开始启动,硬件图里面没有画出该部分
     if((PINA&0x10)==0 & kaiguanflag==0)//启动键
     {
      delay(10);//软件滤波
      if((PINA&0x10)==0 & kaiguanflag==0)
      {
      kaiguanflag=1;//防止在电机转动过程中再进入该部分程序
      n0=0;
      DIR1;//规定转向
      ENA0;//电机处于可操作状态
      TIMSK|=BIT(2);//开16位定时器1中中断,电机启动
      }
     }
    
    //本程序将PA5口设置为一个开关,当PA5口与单片机GND连通时,电机处于掉电自由状态,防止在不用过程中电机一直带电发热,同时可以用手去转动电机,硬件图里面没有画出该部分
     if((PINA&0x20)==0)//切换步进电机可控状态
     {
      delay(10);
      if((PINA&0x20)==0)
      ENA1; 
     }
    }
    }
    
    #pragma interrupt_handler time1:9//ATMEGA16定时器time1中断
    void time1(void)
    {
     switch(duan)//控制曲线处于哪个加速段
     {
    //已第一段为例解释,后面几段原理一样
    case 0: //第一段S曲线加速30°:1转/秒启动,5转/秒结束
    
      TCNT1=A[n0];//设置定时器初值
      PORTA ^=BIT(2);//PA2口取反,产生高低电平形成脉冲
      if((PINA & BIT(2))==0)//两次中断产生一个脉冲,取其中一次进行脉冲计数
       {
        n0++;
       	  if(n0==67)//判断是否到达指定脉冲数
    	  {
    		duan++;//到达脉冲个数之后,进入下一段速度
    		n0=0;//清零
    	  }
       	}break;
       	
    case 1: //第二段匀速运动120°:5转/秒匀速
      TCNT1=0XFA99;//匀速5r/s;
      PORTA ^=BIT(2);
      if((PINA & BIT(2))==0)
       {
        n0++;
    	if(n0==267)
    	{
    	 duan++;
    	 n0=0;
    	}
       }break;
       
    case 2: //第三段S曲线减速30°:5转/秒启动,0.5转/秒结束
      TCNT1=B[n0];
      PORTA ^=BIT(2);
      if((PINA & BIT(2))==0)
       {
        n0++;
       	  if(n0==67)
    	  {
    	    duan++;
    	    n0=0;
                DIR0;//开始换向
    	  }
       	}break;
       	
    case 3: //第四段S曲线反转加速30°:0.5转/秒启动,5转/秒结束
      TCNT1=C[n0];
      PORTA ^=BIT(2);
      if((PINA & BIT(2))==0)
       {
        n0++;
       	  if(n0==67)
    	  {
    	    duan++;
    	    n0=0;
    	  }
       	}break;
       	
    case 4: //第五段匀速反转运动120°:5转/秒匀速
      TCNT1=0XFA99;//转速5r/s;
      PORTA ^=BIT(2);
      if((PINA & BIT(2))==0)
       {
        n0++;
       	  if(n0==267)
    	  {
    	    duan++;
    	    n0=0;
    	  }
       	}break;
    case 5: //第六段S曲线反转减速30°:5转/秒启动,1转/秒结束
      TCNT1=D[n0];
      PORTA ^=BIT(2);
      if((PINA & BIT(2))==0)
       {
        n0++;
       	  if(n0==67)
    	     {
    		      duan=0;
    		      kaiguanflag=0;//PA4开关标志清零,等待下一次PA4开关启动
    		      TIMSK=0x00;//关闭中断,电机停止
    	      }
       	}break;
     default:duan=0;kaiguanflag=0;TIMSK=0x00;break;
      } 
    }
    

    演示动画:
    将单片机PA4口与GND口连通(时间有限没有接开关),步进电机按照上述设计的曲线进行运动,实现正转180°后反转180°回到原点。
    (视频不好传,GIF质量不怎么好,将就看看)。(微信ID:saskingku)
    在这里插入图片描述

    展开全文
  • 悬挂运动控制系统,包含原理图,源程序,包含各大学对悬挂运动控制系统研究
  • 运动控制程序

    2020-07-21 09:59:58
    描述运动控制的。非常有效果,速度非常流畅
  • 控制器内置完整的控制程序,用户只需设定相应的参数,控制器能自行检测到脉冲信号并同时控制四台电机工作。该控制器也支持手动操作,用户可根据情况自行运作。该控制器的特点就是结构简单,专用性强,操作简捷,...
  • 手把手教你单片机程序框架(连载) 大家好,我叫吴坚鸿,从事单片机项目开发已经有快十年了。现在借21IC这个平台把我认为最有价值的东西分享给大家。我这个技术贴每个星期更新一两篇,直到我江郎才尽为止。再次感谢...

    这个是转载的

    http://bbs.21ic.com/icview-691804-1-1.html

    [51单片机] 从业将近十年!手把手教你单片机程序框架(连载)
    大家好,我叫吴坚鸿,从事单片机项目开发已经有快十年了。现在借21IC这个平台把我认为最有价值的东西分享给大家。我这个技术贴每个星期更新一两篇,直到我江郎才尽为止。再次感谢21IC给我们提供这个交流分享的平台。

    第一节:吴坚鸿谈初学单片机的误区。

    第二节:delay()延时实现LED灯的闪烁。

    第三节:累计主循环次数使LED灯闪烁。

    第四节:累计定时中断次数使LED灯闪烁。

    第五节:蜂鸣器的驱动程序。

    第六节:在主函数中利用累计主循环次数来实现独立按键的检测。

    第七节:在主函数中利用累计定时中断的次数来实现独立按键的检测。

    第八节:在定时中断函数里执行独立按键的扫描程序。

    第九节:独立按键的双击按键触发。

    第十节:两个独立按键的组合按键触发。

    第十一节:同一个按键短按与长按的区别触发。

    第十二节:按住一个独立按键不松手的连续步进触发。

    第十三节:按住一个独立按键不松手的加速匀速触发。

    第十四节:矩阵键盘的单个触发。

    第十五节:矩阵键盘单个触发的压缩代码编程。

    第十六节:矩阵键盘的组合按键触发。

    第十七节:两片联级74HC595驱动16个LED灯的基本驱动程序。

    .第十八节:把74HC595驱动程序翻译成类似单片机IO口直接驱动的方式。

    第十九节:依次逐个点亮LED之后,再依次逐个熄灭LED的跑马灯程序。

    第二十节:依次逐个亮灯并且每次只能亮一个灯的跑马灯程序。

    第二十一节:多任务并行处理两路跑马灯。

    第二十二节:独立按键控制跑马灯的方向。

    第二十三节:独立按键控制跑马灯的速度。

    第二十四节:独立按键控制跑马灯的启动和暂停。

    第二十五节:用LED灯和按键来模拟工业自动化设备的运动控制。

    第二十六节:在主函数while循环中驱动数码管的动态扫描程序。

    第二十七节:在定时中断里动态扫描数码管的程序。

    第二十八节:数码管通过切换窗口来设置参数。

    第二十九节:数码管通过切换窗口来设置参数,并且不显示为0的高位。

    第三十节:数码管通过闪烁来设置数据。

    第三十一节:数码管通过一二级菜单来设置数据的综合程序。

    第三十二节:数码管中的倒计时程序。

    第三十三节:能设置速度档位的数码管倒计时程序。

    第三十四节:在数码管中实现iphone4S开机密码锁的程序。

    第三十五节:带数码管显示的象棋比赛专用计时器。

    第三十六节:带数码管显示的加法简易计算器。

    第三十七节:数码管作为仪表盘显示跑马灯的方向,速度和运行状态。

    第三十八节:判断数据尾来接收一串数据的串口通用程序框架。

    第三十九节:判断数据头来接收一串数据的串口通用程序框架。

    第四十节:常用的自定义串口通讯协议。

    第四十一节:在串口接收中断里即时解析数据头的特殊程序框架。

    第四十二节:通过串口用delay延时方式发送一串数据。

    第四十三节:通过串口用计数延时方式发送一串数据。

    第四十四节:从机的串口收发综合程序框架

    第四十五节:主机的串口收发综合程序框架

    第四十六节:利用AT24C02进行掉电后的数据保存。

    第四十七节:操作AT24C02时,利用“一气呵成的定时器延时”改善数码管的闪烁现象。

    第四十八节:利用DS1302做一个实时时钟 。

    第四十九节:利用DS18B20做一个温控器 。

    第五十节:利用ADC0832采集电压信号,用平均法和区间法进行软件滤波处理。

    第五十一节:利用ADC0832采集电压信号,用连续N次一致性的方法进行滤波处理。

    第五十二节:程序后续升级修改的利器,return语句鲜为人知的用法。

    第五十三节:指针的第一大好处,让一个函数可以封装多个相当于return语句返回的参数。

    第五十四节:指针的第二大好处,指针作为数组在函数中的输入接口。

    第五十五节:指针的第三大好处,指针作为数组在函数中的输出接口。

    第五十六节:指针的第四大好处,指针作为数组在函数中的输入输出接口。

    第五十七节:为指针加上紧箍咒const,避免意外修改了只做输入接口的数据。

    第五十八节:指针的第五大好处,指针在众多数组中的中转站作用。

    第五十九节:串口程序第40,44,45节中存在一个bug,特此紧急公告。

    第六十节:用关中断和互斥量来保护多线程共享的全局变量。

    第六十一节:组合BCD码,非组合BCD码,以及数值三者之间的相互转换和关系。

    第六十二节:大数据的加法运算。

    第六十三节:大数据的减法运算。

    第六十四节:大数据的乘法运算。

    第六十五节:大数据的除法运算。

    第六十六节:单片机外部中断的基础。

    第六十七节:利用外部中断实现模拟串口数据的收发。

    第六十八节:单片机C语言的多文件编程技巧。

    第六十九节:使用static关键字可以减少全局变量的使用。

    第七十节:深入讲解液晶屏的构字过程。

    第七十一节:液晶屏的字符,16点阵,24点阵和32点阵的显示程序。

    第七十二节:在液晶屏中把字体顺时针旋转90度显示的算法程序。

    第七十三节:在液晶屏中把字体镜像显示的算法程序。

    第七十四节:在液晶屏中让字体可以跨区域无缝对接显示的算法程序。

    第七十五节:在12864液晶屏中让字体以1个点阵为单位进行移动显示的算法程序。

    第七十六节:如何把一个任意数值的变量显示在液晶屏上。

    第七十七节:在1个窗口里通过移动光标来设置不同参数的液晶屏菜单程序。

    第七十八节:在多个窗口里通过移动光标来设置不同参数的液晶屏菜单程序。

    第七十九节:通过主菜单移动光标来进入子菜单窗口的液晶屏程序。

    第八十节:调用液晶屏内部字库来显示汉字或字符的坐标体系和本质。

    第八十一节:液晶屏显示串口发送过来的任意汉字和字符。

    第八十二节:如何通过调用液晶屏内部字库把一个任意数值的变量显示出来。

    第八十三节:矩阵键盘输入任意数字或小数点的液晶屏显示程序。

    第八十四节:实时同步把键盘输入的BCD码数组转换成数值的液晶屏显示程序。

    第八十五节:实时同步把加减按键输入的数值转换成BCD码数组的液晶屏显示程序。

    第八十六节:数字键盘与液晶菜单的综合程序。

    第八十七节:郑文显捐赠的工控项目源代码。

    第八十八节:电子称连续不断从串口对外发送数据,单片机靠关键字快速截取有效数据串。

    第八十九节:用单片机内部定时器做一个时钟。

    第九十节:针对行程开关感应器,分享一种既能及时响应,又能抗干扰处理的识别思路。

    展开全文
  • 51单片机串口控制io带动气缸运动,附带protues电路仿真,单片机C语言程序源代码
  • 51单片机控制的两轴步进电机联动程序,暂时只写出了直线插补程序
  • 转载连接: http://chitaautomation.blog.163.com/blog/static/2262161282013112885620912/运动控制卡与驱动器有什么不同 运动控制卡是用来发脉冲或模拟量给驱动器的...属于主从关系。用户可基于运动控制卡编写...

    转载连接: http://chitaautomation.blog.163.com/blog/static/2262161282013112885620912/


    运动控制卡与驱动器有什么不同 
    运动控制卡是用来发脉冲或模拟量给驱动器的,驱动器接收到控制卡发过来的脉冲或模拟量控制电机按照预定的程序来控制电机运动。属于主从关系。用户可基于运动控制卡编写上位机控制系统,从而实现不同数控设备的运动控制。

     


    为什么伺服运动控制的时候有人用工控机加伺服运动板卡?我之前接触到的是PLC+运动控制模块+伺服驱动器那么请问?运动板卡控制运动的时候怎么编程控制?采用什么语言?
    运动控制卡,也是一款产品,在你购买时,厂家会提供相应的驱动程序,相应函数说明,以及简单的应用案例,你可以通过一些高级编程语言(VB,VC,C++,VS等等),按设计要求,自己开发相应的应用控制软件。


     PLC控制好还是运动控制卡控制好

    这个不能一概而论标准机使用专用控制器,运动控制卡,PLC都可以,比如点胶机,CNC,标准机床等非标机一般使用PLC比较多,也有使用运动控制卡的,根据电气工程师的习惯和专长而定(有的是计算机专业的,有的是电气专业的,还有的是电子专业的),CNC机器的话,小型CNC机台会选择运动控制卡比如雕刻机,大中型机台会选择西门子,法拉克等的数控系统,另外选择什么样的系统还跟客户的价位相关,若几万到十多万,只能选择运动控制卡做.

     


    南宁哪个学校有开运动控制卡培训班啊!我即将毕业想了解一下这方面的知识。就像一下内容的:运动控制基础,运动控制卡的接线,运动控制卡的使用,运动控制卡的驱动安装,调用函数的讲解,上位机控制程序的编写,电脑通过运动控制卡控制步进伺服电机进行定位控制.

    找些运动控制卡的说明书看看吧,国内固高,雷赛,阿尔泰克都有国外的可以看看PMAC,TRIO等硬件说明书,软件说明书,这方面的书都很少,去那里找人教?我找遍深圳图书馆,也才几本关于机器视觉和运动控制卡方面的书!!

    现在可以回答他:来智达培训吧!!

    运动控制卡研究现状

    运动控制卡在高精领域比PLC更好,二次开发性更强,未来将会是PC-BASE卡与系统总线统治数控界,但PLC也不会退出市场因为其价格低廉,完全可以胜任不少要求不高的工作.节省成本国内做运动控制卡的做工质量方面均于国外有着相当大的差距,BUG非常的多(我并非不支持国产,但要按事实说话)现在主要还是以日本\美国\台湾等地区产的卡为主流.

     

    PC机上面用的运动控制卡可以用来干什么哦
    控制步进电机和伺服电机的运动。精确定位电机的运动达到控制机械的目的。比方说精密车床的运动轴,pcb板打孔设备的运动轴,精密的焊线设备,大型纺织机等等。


    工业控制:PLC,运动控制卡,单片机有何不同,哪位大虾祥解?
    这3种东西不可类比吧。从控制核心来说,PLC和单片机勉强可以相提并论,运动控制卡完全是另外一种东西,它是自动控制的一部分,是附属于计算机主机的。PLC编程简单,维护方便,但是价格较高,一个4轴的运动控制单元加上CPU单元和输入输出口,2万以上。运动控制卡价格也不低,4轴的大牌子也要6000,具体价格也不是很清楚,你可以向研华咨询。它的编程好像是C语言的。单片机价格低,但是要搞一个复杂的自控系统,其工作量之大难以想象,硬件软件都会极其复杂,现在基于单片机的工业自动化控制系统极少了。但是由于它的价格优势,在批量的产品上还是很有优势的。

    感谢百度知道的网友的问答


    展开全文
  • 使用无线技术,通过单片机串口通信,达到控制小车运动的目的。
  • 之前一直很奇怪一个问题,每次写好单片机程序之后,用烧录软件进行烧录时,能看到烧录文件也就是hex的文件大小:我用的单片机芯片是STM32F103C8T6,程序储存器(flash)只有64...

    之前一直很奇怪一个问题,每次写好单片机程序之后,用烧录软件进行烧录时,能看到烧录文件也就是hex的文件大小:

    我用的单片机芯片是STM32F103C8T6,程序储存器(flash)只有64K。

    从上图可以看出,hex有128K。

    我有两点疑问,

    1. 只是一个很简单的平衡小车程序而已,有128K,这么大吗?

    2. 就算有128K,能下载到只有64K容量的单片机中去?

    这可能是一道送命题!

    下面开始我们的探索之旅,以STM32开发为例。

    在keil中进行程序编译之后,在界面部分:

    很多朋友估计看到这界面,也只关心2个点:

    第一、自己编写的程序是否正确生成了hex!

    第二、自己编写的程序有没有错误,有没有警告!


    在图中红线部分:

    有4个:Code、RO-data、RW-data、ZI-data。
    Code:表示所要执行的代码,程序中所有的函数都位于此处。
    RO-data:表示只读数据,程序中所定义的全局常量数据和字符串都位于此处。
    RW-data:表示已初始化的读写数据,程序中定义并且初始化的全局变量和静态变量位于此处。
    ZI-data:表示未初始化的读写数据,程序中定义了但没有初始化的全局变量和静态变量位于此处。


    从描述中可以得出:

    1. 下载到单片机FLASH的程序是:Code+RO-data+RW-data(上图中数据为字节数,kb=byte/1024);

    hex=(39546+5862+12428)/1024=56.48

    2. 运行在RAM中的数据是:RW-data+ZI-data;

    原来window下显示的hex大小,并非是我们下载到单片机中的hex大小。

    关于为什么显示不同,这又是一个十分有趣的问题,有兴趣的朋友可以一起探讨下。

    最后,貌似C8T6这个芯片的资源差不多被我榨干了,要考虑换芯片了~


    题 外 话

    昨天带了学弟们去参加了湖南省2019年的研究生电子设计竞赛,现场倒是十分有趣。

    很多好玩但我又看不懂的作品。

    往期好文合集

    谈一谈无人机的编队控制方法。戳这里>>

    干货 | 双目摄像头实现手势识别,完美还原人体运动手势。戳这里>>

    这篇文章后,不要再问我怎么做一台智能车了。戳这里>>

    电子工程师也有“鄙视链”!软件硬件无一幸免!戳这里>>

    //end

    若觉得文章不错,转发分享,也是我们继续更新的动力。

    5T资源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,PCB、FPGA、DSP、labview、单片机、等等

    在公众号内回复「更多资源」,即可免费获取,期待你的关注~

    长按识别图中二维码关注

    展开全文
  • 本来接触单片机挺久了的,但是一直只是停留在非常初级的认识阶段,本科的时候上过几门课,但是从来没有自己捣鼓过单片机,这次突然来了兴趣,感觉一下子学到了好多东西,在这里好好整理一下。这篇文章只适合于入门...

    本来接触单片机挺久了的,但是一直只是停留在非常初级的认识阶段,本科的时候上过几门课,但是从来没有自己捣鼓过单片机,这次突然来了兴趣,感觉一下子学到了好多东西,在这里好好整理一下。这篇文章只适合于入门阶段的小白阅读,高手请绕道。

    12年年初的时候购买了一套普中科技的“单片机开发试验仪”,好多次想好好学学,结果每一次都半途而废,主要原因还是周围的人都不会用,有问题都不知道找谁问,结果锁到箱子里一直到现在。因为最近需要用到一个步进电机,而这个步进电机需要用PWM波控制。以前也用过电机,直流无刷的、交流伺服等等,但是都是RS232、RS485或者Can总线协议,从来没有用PWM波控制过。废话不多说,直接入正题。

    硬件

    单片机型号:STC90C516RD+
    步进电机型号:39HS4012A4 1.8° 1.2A
    这里写图片描述
    步进电机驱动器型号:M415B 1.5A
    这里写图片描述

    代码

    源代码

    #include <reg52.h>
    
    unsigned char timer1; 
    sbit DIR=P1^0; //位定义DIR为P1.0口
    sbit ENA=P1^1; //位定义ENA为P1.1口
    sbit PWM=P1^2; //位定义PWM为P1.2口
    
    void system_Ini()
    {
        TMOD|= 0x11;
        TH1 = 0xfe; //11.0592MHz 0.5ms定时
        TL1 = 0x33;
        TR1 = 1; //启动T1定时
        IE =0x8A; //开T0,T1中断,开总中断
    }
    
    main()
    {
        system_Ini(); //调用子函数,初始化定时器T1
        while(1)
        { 
            if(timer1>100)
            {
                timer1=0; //输出占空比0.7的PWM脉冲
            }
            if(timer1<30)
            {
                PWM=0;
            }
            else 
            {
                PWM=1;
            }
        }
    }
    
    /*************************************
    [ t1 (0.5ms)中断] 中断中做 PWM 输出
    ------------1000/(0.02ms*250)=200Hz
    *************************************/
    void T1zd(void) interrupt 3 //3 为定时器1的中断号 1 定时器0的中断号 0 外部中断1 2 外部中断2 4 串口中断
    {
        TH1 = 0xfe; //11.0592 初始化定时器
        TL1 = 0x33;
        timer1++; //计数+1
    }

    代码解释

    #include <reg52.h> //包含了单片机系统的头文件
    unsigned char timer1; //定义一个无符号字符常量timer1,用来给定时器计数用
    
    sbit DIR=P1^0; //位定义DIR为P1.0口,用来控制步进电机的方向
    sbit ENA=P1^1; //位定义ENA为P1.1口,用来控制步进电机的使能
    sbit PWM=P1^2; //位定义PWM为P1.1口,用来输出PWM波
    
    TMOD = 0x11; 
    //这一句代码比较费解,因为对单片机的控制字不熟悉,仔细翻看了单片机的手册,原来这是控制定时器的,共有两位,前一位控制定时器1,后一位控制定时器0。因为控制只使用了一个定时器1,所以其实定时器0所在的位其实无关紧要。控制位的定义如下图所示,共4位,组成一个16进制数,所以代码中的1其实铺开了二进制应该是0001,对应下面的16位定时器,TL1、TH1全用。

    这里写图片描述

    TH1 = 0xfe; //11.0592MHz 0.5ms定时
    TL1 = 0x33;
    //这句代码非常的费解,刚开始的时候完全不懂这两个数索要表示的意思是什么,旁边还有个注释,也是没看懂。好在实验室有一位大神,分分钟帮我讲懂了。先看芯片手册上给出的例子:

    这里写图片描述
    这里写图片描述

    //也就是说初始时我的计数是从0xfe33开始的,定时器是16位的,所以实际计数值化为十进制为:

    216(15×163+14×162+3×161+3×160)=461
    //也就是说实际上计数为461,而实际上我查得我的晶振频率为11.907MHz,所以实际的时间长度为:

    Tc=461×1211.907×106=0.4646
    //也就是说实际的定时器定时464.6ms,这里终于解释清楚了为什么上面的定时器数据应该那么写
    
    
    TR1 = 1; //启动T1定时,这里比较好理解
    
    IE =0x8A; //开T0,T1中断,开总中断
    //这里继续翻出芯片的技术手册来解释,有了前面的基础,后面看起来自然一目了然,必须允许定时器溢出中断,定时器每溢出一次就产生一次中断,总中断是必须打开的,用了定时器1,因此定时器1的中断也需要打开,而定时器0的中断其实开不开无所谓的,因为根本就没有用定时器0。

    这里写图片描述

    main()
    {
        system_Ini(); //调用子函数,初始化定时器T1
        while(1) //无限循环
        { 
            if(timer1>100)
            {
                timer1=0; //输出占空比0.7的PWM脉冲
            }
            if(timer1<30)
            {
                PWM=0;
            }
            else 
            {
                PWM=1;
            }
        }
    }
    
    
    /*************************************
    [ t1 (0.5ms)中断] 中断中做 PWM 输出 1000/(0.02ms*250)=200Hz
    *************************************/
    
    void T1zd(void) interrupt 3 //3为定时器1的中断号; 1为定时器0的中断号; 0为外部中断1的中断号; 2为外部中断2的中断号; 4为串口中断的中断号,这是芯片规定的
    
    {
        TH1 = 0xfe; //11.0592 初始化定时器,让定时器复位继续定时
        TL1 = 0x33;
        timer1++; //计数+1
    }
    展开全文
  • 51单片机控制舵机

    2018-08-04 08:14:19
    舵机简介 舵机一般由舵盘、减速齿轮组、位置反馈电位计5k、直流电机、控制电路板等。一般情况下舵机的信号线为黄色或白色,电源分4.8V和6V,分别对应不同...对于t = 0.5ms~2.5ms 的产生,写程序时我们可以采用全局...
  • 采用单片机系统来实现运动控制,成本较低,但开发难度较大,周期长。这种方案适应于产品批量较大、控制系统功能简单、有单片机开发经验的用户。 2.专业运动控制PLC 许多品牌的PLC都可选配定位控制模块,有些PLC的...
  • 前面笔者分享过基于51单片机的两种小车制作,我们利用的是L298N驱动控制电机转动,那么接下来,笔者给大家介绍两种利用51单片机控制步进电机的小程序。 首先我们要如何使电机转动呢,源程序如下: #include &...
  • 单片机控制双步进电机运动控制系统 ,朱雷平,,采用单片机AT89C55作为控制系统的核心,控制双步进电机带小负载做运动。 单片机接收相应的信号执行显示程序和轨迹控制程序,向LCD显�
  • 单片机(STC89C52RC)控制两个直流电机,从而实现各种运动形式。 本例中实现功能为:前进 后退 右转 左转。 C语言程序如下: /*------------------------------------ FileName: main.c Function: MCU控制两个直流...
  • 采用STM系列开发板,实现智能运动控制的插补运算、加减速控制,要求结合开发板模块,使用相关算法,可靠实现电机的控制 最后的结果应该是能通过stm32控制电机,实现目标按s型轨迹运动和加减速,正反转
  • 基于单片机的智能轮椅控制系统设计 智能轮椅的设计,用的到的就下八
  • P1是用来控制电机的端口,IN~控制前进后退,EN~控制小车能不能走,P0是红外接收的口,为1时表示探测到黑线 zkb为占空比,通过zkb来控制小车的速度,t为相当于总时间,zkb是在t时间内电机工作的时间。 下面是我写
  • 实验室的运动平台控制器坏了,使用51单片机对平台进行控制,包含步进电机,零位开关,限位开关和串口通信
1 2 3 4 5 ... 20
收藏数 2,967
精华内容 1,186
关键字:

单片机程序 运动控制