採用msp430f249單片機, 控制直流電機並測速
模擬及效果圖
#include
#include "LCD_12864.h"
#include "Measuring.h"
#define key1 0x01
#define key2 0x02
#define key3 0x03
#define key4 0x04
#define key5 0x05
#define key6 0x06
#define M1 10//測速10次取平均值
unsigned int cap1,N1;
long width[10]={0,0,0,0,0,0,0,0,0,0};
char m,k1,i=0;
long data,zhuansu=0;
void Show_shuzi(void); //顯示數位
void Clear_shuzi(void);//清除數字顯示
#define port P5OUT
#define bflag (P5OUT&BIT7)
void key_check (void);
void Disp_N(void);//顯示逆時針
void Disp_S(void);//顯示順時針
void Init_PWM();
void key_process_1(void); //啟
void key_process_2(void); //停止
void key_process_3(void); //加速
void key_process_4(void); //減速
void key_process_5(void); //正轉
void Key_process_6(void);//測速
unsigned char key_value; //定義鍵值全域變是
unsigned int a=30000;
unsigned char number[];
unsigned char digit=0;
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; //停止看門狗
Init_PWM();
Init_Measuring();
P2IE = 0x77; // P2.0-P2.3 IO口中斷使能
P2IES = 0x77; // P2.0-P2.3 IO口下降沿觸發中斷方式
P2IFG = 0x0; // P2.0-P2.2 IO口中斷標誌位元清除
_EINT(); //中斷允許
//LPM0; //進入低功耗LPM0
P1OUT &=~(BIT4+BIT7); //正轉
P1OUT |=BIT0+BIT5;
P5DIR|=0XFF;
P6DIR|=BIT0+BIT1+BIT2+BIT3+BIT4;
ready_12864();//清屏
left();
display(num1,0x00,32);
display(num1+32,0x00,48);
display(num,0x02,0);
display(num+32,0x02,16);
display(num+64,0x02,32);
display(num+96,0x02,48);
display(num2,0x04,0);
display(num2+32,0x04,16);
display(num2+64,0x04,32);
display(num3,0x06,0);
display(num3+32,0x06,16);
display(num3+64,0x06,32);
right();
display(num1+64,0x00,64);
display(num1+96,0x00,80);
display(num+128,0x02,64);
display(num+160,0x02,80);
display(num+192,0x02,96);
display(num+224,0x02,112);
//數字顯示
// display_sz(shuzi,0x04,0);
// display_sz(shuzi+16,0x04,8);
while(1)
{
CCR1=a;
key_check ();
// Show_shuzi();
switch (key_value) //對鍵值進行處理.采switch語法結構查詢
{
case key1: //啟動/停止
{
static char k=0;
if(k==0)
{
key_process_1(); //調用鍵處理常式1
Disp_S(); //順時針顯示
k++;
}
else
{
key_process_2();
k=0;
}
}
break;
case key2:
{
P1OUT &=~(BIT0+BIT5); //反轉
P1OUT |=BIT4+BIT7;
Disp_N();
}
break;
case key3: key_process_3(); //調用鍵處理常式3
break;
case key4: key_process_4(); //調用鍵處理常式3
break;
case key5:// key_process_5();
{
P1OUT |= BIT1;
P1OUT &=~(BIT4+BIT7); //正轉
P1OUT |=BIT0+BIT5;
Disp_S();
}
break;
case key6: Key_process_6();//測速
break;
default: break;
}
key_value=0x00; //鍵值清除
P2IE = 0x77; // P2.0-P2.2 IO口中斷使能
P2IFG = 0x0; // P2.0-P2.2 IO口中斷標誌位元清除
// LPM0;
}
}
//P2中斷服務程式
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
switch (P2IFG)
{
case 0x01: key_value=0x01;
break;
case 0x02: key_value=0x02;
break;
case 0x04: key_value=0x03;
break;
case 0x20: key_value=0x04;
break;
case 0x10: key_value=0x05;
break;
case 0x40: key_value=0x06;
break;
default: P2IFG = 0x0; // P2.0-P2.2 IO口中斷標誌位元清除
break;
}
P2IFG = 0x0; // P2.0-P2.2 IO口中斷標誌位元清除
// LPM0_EXIT;
}
//計時器B中斷服務程式,計一個脈衝週期
#pragma vector=TIMERB0_VECTOR
__interrupt void TimerB0(void)//計時器TB的CCR0的中斷:用於檢測脈衝上升與下降沿
{
if(TBCCTL0&CM1) //捕獲到下降沿
{
width[m++]=65536*N1+TBCCR0-cap1; //記錄下結束時間
N1=0;
TBCCTL0=CM_1+SCS+CAP+CCIE;//+TBCLR; //改為上升沿捕獲:CM1置0,CM0置1
if(m==M1) m=0;
}
else if(TBCCTL0&CM0) //捕獲到上升沿
{ cap1=TBCCR0;
N1=0;
TBCCTL0=CM_2+SCS+CAP+CCIE;//+TBCLR; //改為下降沿捕獲:CM0置0,CM1置1
}
}
// Timer_B7 Interrupt Vector (TBIV) handler
#pragma vector=TIMERB1_VECTOR
__interrupt void Timer_B(void)
{
switch( TBIV )
{
case 14: N1++; break;
}// 溢出
// Show_shuzi();
}
void key_check (void)
{ unsigned int i;
for(i=0;i
if(0xff !=(P2IN & 0x88)) //是否有鍵存在?
{
while(0xff !=( P2IN | 0x88)); //一直等待按鍵鬆開
}
else
key_value = 0x00; //延時去抖動無鍵按下,則清除鍵變數.
}
void Init_PWM()
{
BCSCTL2=SELS; //SMCLK = XT2
P1DIR = 0xff; // P1輸出
P1OUT &=~BIT2;
CCR0 = 60000; // PWM 週期 7.5ms,實際為2.5ms為好
CCTL1 = OUTMOD_7; // CCR1復位/置位
CCR1 = a; // CCR1 PWM 占空比50%
TACTL = TASSEL_2 + MC_1; // 計時器A時鐘源為SMCLK,增計數模式
}
void key_process_1(void) //啟動
{
P1SEL |=0X04; // P1.2第二功能TA1輸出PWM
TACTL = TASSEL_2 + MC_1; // 計時器A時鐘源為SMCLK,增計數模式
//開顯示
left();
wreg(0x3f);
right();
wreg(0x3f);
}
void key_process_2(void) //停止
{
P1SEL =0X0;
TACTL=MC_0;
P1OUT &=~BIT2;
//關顯示
left();
wreg(0x3e);
right();
wreg(0x3e);
}
void key_process_3(void) //加速
{
a+=5000;
if(a>=60000) a=60000;
Show_shuzi();
}
void key_process_4(void) //減速
{
a-=5000;
if(a
Show_shuzi();
}
void key_process_5(void) //正轉
{
P1OUT &=~(BIT4+BIT7); //正轉
P1OUT |=BIT0+BIT5;
}
void Key_process_6(void)//測速
{
Clear_shuzi();//清屏顯示
Show_shuzi();
if(zhuansu100)//蜂鳴器報警
{
P1OUT |= BIT1;
}
else
P1OUT &=~ BIT1;
}
void Disp_N(void)//顯示逆時針
{
right();
display(DIR_N,0x06,0);
display(DIR_N+32,0x06,16);
display(DIR_N+64,0x06,32);
}
void Disp_S(void)//顯示順時針
{
right();
display(DIR_S,0x06,0);
display(DIR_S+32,0x06,16);
display(DIR_S+64,0x06,32);
}
void Show_shuzi(void)
{
//測速10次
data=0;
for(k1=0;k1
data+=width[k1];
data=data/M1;
data=10000000/data;
zhuansu=data;
while(data>0)
{
number[digit] = data%10;
data=data/10;
digit++;
}
right();
unsigned char g;
g = digit-1;
for(i=0;i
{
display_sz(shuzi+number[g]*16,0x04,8*i);
g--;
}
digit=0;
display_sz(RMP,0x04,24);
display_sz(RMP+16,0x04,32);
display_sz(RMP+32,0x04,40);
display_sz(RMP+48,0x04,48);
display_sz(RMP+64,0x04,56);
}
void Clear_shuzi(void)//清除數字顯示
{
uint i,j;
right();
wreg(0x3f);
right();
for(i=4;i
{
pagefirst(i);
linefirst(0x00);
for(j=0;j
{
wdata(0x00);
}
}
}
本文素材來自電子發燒友論壇
先進PID控制MATLAB模擬(第4版)/電子工程技術叢書 ¥63.04 購買