C语言实现控制电机加减速正反转(飞思卡尔C代码)

更新时间:2024-01-20 09:08:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

用单片机控制直流电动机的正反转、加减速的程序如何用C语言写

参考一下这个例子吧。 #include

#define uchar unsigned char #define uint unsigned int

sbit PW1=P2^0 ;

sbit PW2=P2^1 ; //控制电机的两个输入 sbit accelerate=P2^2 ; //调速按键 sbit stop=P2^3 ; //停止按键 sbit left=P2^4 ; //左转按键 sbit right=P2^5 ; //右转按键

#define right_turn PW1=0;PW2=1 //顺时针转动 #define left_turn PW1=1;PW2=0 //逆向转动 #define end_turn PW1=1;PW2=1 //停转

uint t0=25000,t1=25000; //初始时占空比为50%

uint a=25000; // 设置定时器装载初值 25ms 设定频率为20Hz uchar flag=1; //此标志用于选择不同的装载初值 uchardflag; //左右转标志

uchar count; //用来标志速度档位

void keyscan(); //键盘扫描 void delay(uchar z);

void time_init(); //定时器的初始化

void adjust_speed(); //通过 调整占空比来调整速度 //**********************************// void main() {

time_init(); //定时器的初始化 while(1) {

keyscan(); //不断扫描键盘程序,以便及时作出相应的响应 } }

//*************************************// void timer0() interrupt 1 using 0 {

if(flag) { flag=0; end_turn;

a=t0; //t0的大小决定着低电平延续时间 TH0=(65536-a)/256;

TL0=(65536-a)%6; //重装载初值 } else {

flag=1; //这个标志起到交替输出高低电平的作用 if(dflag==0) {

right_turn; //右转 } else

{

left_turn; //左转 }

a=t1; //t1的大小决定着高电平延续时间 TH0=(65536-a)/256;

TL0=(65536-a)%6; //重装载初值 } }

voidtime_init() {

TMOD=0x01; //工作方式寄存器 软件起动定时器 定时器功能 方式1 定时器0

TH0=(65536-a)/256;

TL0=(65536-a)%6; //装载初值 ET0=1; //开启定时器中断使能 EA=1; // 开启总中断 TR0=0; }

//****************************************// void delay(uchar z) //在12M下延时z毫秒 {

uintx,y;

for(x=z;x>0;x--) for(y=110;y>0;y--); }

//******************************// voidkeyscan() {

if(stop==0) {

TR0=0; //关闭定时器0 即可停止转动 end_turn; }

if(left==0) {

TR0=1;

dflag=1; //转向标志置位则左转 }

if(right==0) {

TR0=1;

dflag=0; //转向标志复位则右转 }

if(accelerate==0) {

delay(5) ; //延时消抖 if(accelerate==0) {

while(accelerate==0) ; //等待松手 count++;

if(count==1) {

t0=20000;

t1=30000; //占空比为百分之60 }

if(count==2) {

t0=15000;

t1=35000; //占空比为百分之70 }

if(count==3) {

t0=10000;

t1=40000; //占空比为百分之80 }

if(count==4) {

t0=5000;

t1=45000; //占空比为百分之90 }

if(count==5) { count=0; } } } }

功能特点:

1)总线速度高达40 MHz,CAN总线:3个1Mbps的CAN总线,兼容CAN2.0 A/B; 2)128 KB程序Flash和8 KB DataFlash,用于实现程序和数据存储,均带有错误校正码(ECC);

3)可配置A/D:16通道模数转换器;可选8位10位和12位精度,3μs的转换时间4)内嵌MSCAN模块用于CAN节点应用,内嵌支持LIN协议的增强型SIC模块和SPI模块;

5)4通道16位计数器,CRG时钟和复位发生器:锁相环、看门狗、实时中断;

增强型捕捉定时器;

6)出色的低功耗特性,带有中断唤醒功能的10,实现唤醒休眠系统的功能; 7)通道PWM:8位8通道或16位4通道PWM,易于实现电机控制。 8)存储器:128KB FLASH;2KB EEPROM;8KB RAM;

9)串行口:2个异步串行通讯SCI和2个同步串行设备接口SPI;

写在前面的话->:

单片机要工作的话要具备一些基本条件,其中一条就是要有稳定的同步信号。在飞思卡尔 S12 这款单片机中 这个同步信号像其他单片机一样也是由 外部

晶振来提供的。但与传统 51 单片机不同的是 S12 里面集成了 PLL (锁相环) 倍频电路,它可以把外部晶振的频率超到一定之后再提供给单片机,做为系统时钟。并且这个 PLL 电路是可以软件编程的。所以在对 S12 这款单片机进行软件编程时,首先就要配置系统的时钟。假如没有配置好系统时钟的话就像人没有了心脏一样,接下来单片机具体在干什么事就只有它知道。

配置系统时钟的步骤如下: 1、失能系统 PLL 2、打开 PLL 电路 3、计算频率

要改变频率只要修改 SYNR、REFDV、POSTDIV 这三个寄存器的值即可。具体怎么修改,改成多大可参考

datasheet,MC9S12XS128RMV1.pdf 这个 PDF 文档(文档是英文的),里面有具体的公式。以下给出常用的 配置。

/*----------40M----------*/

SYNR =0xc0 | 0x04; REFDV=0xc0 | 0x01; POSTDIV=0x00; /*----------48M----------*/

SYNR =0xc0 | 0x05; REFDV=0xc0 | 0x01; POSTDIV=0x00; /*----------64M----------*/

SYNR =0xc0 | 0x07; REFDV=0xc0 | 0x01; POSTDIV=0x00; 4、等待 PLL 输出频率稳定 5、使能系统 PLL

实验的目的:学会 MC9S12XS128 这款单片机系统时钟的配置很 GPIO 的使用。

/********************************代码实现*************************************/

#include /* common defines and macros */ #include /* derivative information */ #pragma LINK_INFO DERIVATIVE \

/*--------函数原型声明-------------------------**/ void SetBusCLK_48M(void); void DE_48M_ms(intms);

/*----------------------------------------------*/ /*--------主函数中 8路LED以200ms的间隔闪烁-------*/ void main(void) {

byte i = 0;

DisableInterrupts; SetBusCLK_48M();

DDRB = 0XFF; //PB口设置为输出

PORTB = 0XFF; //PB口初始化输出高电平

for(;;) {

for(i=0;i<8;i++) {

PORTB &= ~(1<

PORTB |= (1<

/*-----------------配置系统时钟------------------*/ void SetBusCLK_48M(void) {

CLKSEL = 0X00; //disengage PLL to system PLLCTL_PLLON = 1; //turn on PLL

SYNR = 0xc0 | 0x05; REFDV = 0xc0 | 0x01; POSTDIV = 0x00; //pllclock=2*osc*(1+SYNR)/(1+REFDV)=80MHz; _asm(nop); //BUS CLOCK=48M _asm(nop);

while(!(CRGFLG_LOCK == 1)); //when pll is steady ,then use it; CLKSEL_PLLSEL = 1; //engage PLL to system; }

/*-----------------ms 级延时---------------------*/ void DE_48M_ms(intms) {

intii,jj;

if (ms<1) ms=1;

for(ii=0;ii

for(jj=0;jj<4006;jj++); //48MHz--1ms }

/*---------------end of file----------------------*/

PORTB = 0XFF; //PB口初始化输出高电平

for(;;) {

for(i=0;i<8;i++) {

PORTB &= ~(1<

PORTB |= (1<

/*-----------------配置系统时钟------------------*/ void SetBusCLK_48M(void) {

CLKSEL = 0X00; //disengage PLL to system PLLCTL_PLLON = 1; //turn on PLL

SYNR = 0xc0 | 0x05; REFDV = 0xc0 | 0x01; POSTDIV = 0x00; //pllclock=2*osc*(1+SYNR)/(1+REFDV)=80MHz; _asm(nop); //BUS CLOCK=48M _asm(nop);

while(!(CRGFLG_LOCK == 1)); //when pll is steady ,then use it; CLKSEL_PLLSEL = 1; //engage PLL to system; }

/*-----------------ms 级延时---------------------*/ void DE_48M_ms(intms) {

intii,jj;

if (ms<1) ms=1;

for(ii=0;ii

for(jj=0;jj<4006;jj++); //48MHz--1ms }

/*---------------end of file----------------------*/

本文来源:https://www.bwwdw.com/article/vmbo.html

Top