//=========================
//Project: PWM generation for STEP motor control
//Author: Leo.Tseng
//Date: 2011/12/21
//MCU: W78E054D
//CRYSTAL: 25Mhz
//Description: Use uart for input/output, set boudrate=9600,
// Press "a" to increase PWM high duty, Press "d" to
// decrease PWM high duty.
// PWM will control 3-wire step motor.
//=========================
#include <reg52.h>
#include <stdio.h>
void uart_initinal(int baudrate);
int TIMES=65536; // 16bit counter
int FREQ=10400; // 200HZ = 10400 機械週期
int PWMHIGH=2080; // 高電位佔20%=10400*0.2=2080個機械週期
int PWMLOW=8320; // 低電位佔80%=10400*0.8=8320個機械週期
int PERIOD,n_SCAN;
char ch;
sbit SCAN0 = P1^2;
sbit SCAN1 = P1^3;
sbit SCAN2 = P1^4
//------------------------------------------------
//MAIN C function
//------------------------------------------------
void main (void)
{
uart_initinal(9600); // 起始 UART 設定,baudrate=9600
//PWMOUT = 0;
TMOD = (TMOD & 0xF0) | 0x01; // 設定 T/C0 Mode
PERIOD = TIMES-PWMHIGH;
TH0 = PERIOD/256;
TL0 = PERIOD%256;
ET0 = 1; // 致能 Timer 0 Interrupts
TR0 = 1; // 啟動 Timer 0 計時
EA = 1; // 全部致能始動
SCAN0 = 1;
// PWMOUT1 = 1;
// PWMOUT2 = 1;
printf("按 ""a"" 增加PWM工作週期20%%,按 ""d"" 減少PWM工作週期20%%\n"); // 顯示操作訊息
//printf("Press ""a"" to increase duty cycle, ""d"" to decrease duty cycle\n"); // 顯示操作訊息
while (1)
{
switch (ch=_getkey())
{
// 增加高電位20/%
case 'A': //
case 'a':if(PWMHIGH==300) //
PWMHIGH=2080;
else if(PWMHIGH <= 6240)
PWMHIGH+=2080;
else if(PWMHIGH >= 8320)
PWMHIGH=10100; // 最高duty cycle限制97%
PWMLOW=FREQ-PWMHIGH;
//printf("a_PWMHIGH is %u\n",PWMHIGH);
break;
// 減少高電位20/%
case 'D': //
case 'd':if(PWMHIGH==10100) //
PWMHIGH=8320;
else if(PWMHIGH >= 4160)
PWMHIGH-=2080;
else if(PWMHIGH <= 2080)
PWMHIGH=300; // 最低duty cycle限制97%
PWMLOW=FREQ-PWMHIGH;
//printf("d_PWMHIGH is %u\n",PWMHIGH);
break;
default: break;
}
}
}
//UART副程式使用timer1
void uart_initinal(int baudrate)
{
PCON = 0x00; // PCON: if SMOD=1(b7), Baud Rate is Doubled
SCON = 0x52; // SCON: mode 1, 8-bit UART, enable rcvr
TMOD = (TMOD & 0x0f) | 0x20; // TMOD: timer 1, mode 2, 8-bit reload; keeps timer0 default.
TH1 = 256-(25000000/372/baudrate); // TH1: reload value for baud @ 25MHz, TH=0xF9
//TH1= 256-(11059200/384/baudrate);
TR1 = 1; // TR1: timer 1 run
//TI = 1; // TI: set TI to send first char of UART
}
//計時器0中斷1
void timer0_ISR(void) interrupt 1
{
if((SCAN0==1)&&(SCAN1==1)&&(SCAN2==1)&&(n_SCAN==0))
{
TR0=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
SCAN0=0;
}
else if((SCAN0==0)&&(SCAN1==1)&&(SCAN2==1)&&(n_SCAN==0))
{
TR0=0;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
SCAN0=1;
n_SCAN=1;
}
if((SCAN1==1)&&(SCAN0==1)&&(SCAN2==1)&&(n_SCAN==1))
{
TR0=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
SCAN1=0;
}
else if((SCAN1==0)&&(SCAN0==1)&&(SCAN2==1)&&(n_SCAN==1))
{
TR0=0;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
SCAN1=1;
n_SCAN=2;
}
if((SCAN2==1)&&(SCAN0==1)&&(SCAN1==1)&&(n_SCAN==2))
{
TR0=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
SCAN2=0;
}
else if((SCAN2==0)&&(SCAN0==1)&&(SCAN1==1)&&(n_SCAN==2))
{
TR0=0;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
SCAN2=1;
n_SCAN=0;
}
}
===================================================================
沒有留言:
張貼留言