📄 pwmdemo.c
字号:
/* PWMDEMO.C */
/****************************************************************************
*
* STK16XSW.PWMDEMO
* ================
*
* Main module for PWM demo.
*
*
* TQ-Systems GmbH
* ---------------
* Customer: TQ-Components
* Project : STK16XSW
* Tools : uVision 2.05
*
* Rev: Date: Name: Modification:
* ----+---------+----------------+------------------------------------------
* 100 16.01.01 A. Lichte Taken over from STK16X.506
*****************************************************************************/
/****************************************************************************
*
* availability summary
*
* available for Starterkit: STK16X STK16XU
* conformed for Starterkit: STK16X STK16XU
* available for Modul : TQM164 TQM165 TQM165U TQM166 TQM167
* TQM167UL TQM167U TQM167LC
*
* conformed for Modul : TQM164 TQM165 TQM165U TQM166 TQM167
* TQM167UL TQM167U TQM167LC
*****************************************************************************/
/*==========================================================================*
* include files (INCLUDE):
*===========================================================================*/
/*--------------------------------------------------------------------------*
* standard include files:
*---------------------------------------------------------------------------*/
#include <ctype.h> /* Typecast functions */
#include <string.h> /* String functions */
#include <setjmp.h> /* Global jump functions */
#include <absacc.h> /* absolute accesss */
#include <intrins.h> /* Intrinsic functions */
#include <reg167.h> /* Special function register */
/*--------------------------------------------------------------------------*
* project specific include files:
*---------------------------------------------------------------------------*/
#include "timer.h"
#include "lcd.h"
/*==========================================================================*
* module internal definitions (DEFINE):
*===========================================================================*/
#define DEMOTIME 2000 /* time interval for each demo [10ms] */
/*==========================================================================*
* module internal type definitions (TYPEDEF):
*===========================================================================*/
/*==========================================================================*
* module internal constants (CONST):
*===========================================================================*/
const vorlage1[][] =
{
{0x10, 1}, {0x40, 1}, {0x80,1}, {0xC0,1}, {0xFF,1}, {0xC0,-1},
{0x80,-1}, {0x40,-1}, {0x10,1}, {0x40,1}, {0x80,1}, {0xC0,1},
{0xFF,1}, {0xC0,-1}, {0x80,-1},{0x40,-1}
};
const sint4[] = {0, 30, 0, -30};
/*==========================================================================*
* extern available constants (CONST):
*===========================================================================*/
/*==========================================================================*
* module internal variables:
*===========================================================================*/
signed int larray[18], rarray[18]; /* original left/right wave forms */
signed int lsarray[18], rsarray[18]; /* interpolated left/right wave forms */
unsigned char lcount, rcount;
/*==========================================================================*
* globale external available variables (EXTERN):
*===========================================================================*/
/*==========================================================================*
* module internal functions:
*===========================================================================*/
/*-------------------------------------------------------------------------*
* void pwm_ini()
*--------------------------------------------------------------------------*
* FT: init timer 1 counter for counting 256 steps
* EP: -
* RW: -
* GP: -
*--------------------------------------------------------------------------*/
void pwm_ini()
{
T1 = 0xFEFF; /* init T1 for counting from FF00 to FFFF (=256 steps) */
T1REL = 0xFEFF;
T01CON = T01CON & 0x00FF | 0x4000; /* init T1 for max. counter frequency */
}
/*-------------------------------------------------------------------------*
* void pwm_off()
*--------------------------------------------------------------------------*
* FT: deactivates PWM
* EP: -
* RW: -
* GP: -
*--------------------------------------------------------------------------*/
void pwm_off()
{
CCM0 = 0;
CCM1 = 0;
CCM2 = 0;
CCM3 = 0;
DP2 = 0;
}
/*-------------------------------------------------------------------------*
* void pwm(char pwm_number, unsigned char pwm_value)
*--------------------------------------------------------------------------*
* FT: PWM control via capture compare (CAPCOM) register of port 2
* EP: pwm_number = signal line of Port 2 (0..15)
* pwm_value = duty cycle (1..255)
* RW: -
* GP: -
*--------------------------------------------------------------------------*/
void pwm(char pwm_number, unsigned char pwm_value)
{
pwm_number &= 0x0F; /* mask for valid addresses */
/* check if initialization is necessary: */
*(&CC0 + pwm_number) = (0xFFFF - pwm_value); /* load COMPARE register */
*(&CCM0+(pwm_number >> 2)) |= (0xF << ((pwm_number % 4) * 4));
/* init CCM register: */
DP2 |= (1 << pwm_number); /* set port bit as output */
}
/*-------------------------------------------------------------------------*
* void wellpwm()
*--------------------------------------------------------------------------*
* FT: load all 16 CAPCOM register with values which result from "left side"
* and "right side" wave
* EP: -
* RW: -
* GP: lsarray, rsarray
*--------------------------------------------------------------------------*/
void wellpwm()
{ int i, zv;
for (i=0; i<16; i++)
{
zv =50 + lsarray[i+1] + rsarray[i+1];
if (zv < 0)
zv = 0;
if (zv > 100)
zv = 100;
if (zv > 50)
zv = 50 + 4 * (zv - 50); /* increase brightness (for better optics) */
pwm(i, (unsigned char) zv);
}
}
/*-------------------------------------------------------------------------*
* void wellinit()
*--------------------------------------------------------------------------*
* FT: init port outputs
* EP: -
* RW: -
* GP: larray, rarray, lcount, rcount
*--------------------------------------------------------------------------*/
void wellinit()
{ int i;
for (i=0; i<18; i++)
{
larray[i] = 0;
rarray[i] = 0;
}
lcount = 0;
rcount = 0;
wellpwm();
}
/*-------------------------------------------------------------------------*
* void lwelle()
*--------------------------------------------------------------------------*
* FT: shift the left moving wave for 1/16 positions to left; for that
* "lsarray" contains the interpolated value of "larray"
* reflection principle: the overflow value on the left side is taken as
* the left-end value of the right moving wave;
* after having been interpolated 15 x, the original wave is shifted
* left by 1
* EP: -
* RW: -
* GP: lsarray, rsarray, larray, rarray, lcount
*--------------------------------------------------------------------------*/
void lwelle()
{ int i;
larray[17] = rarray[16]; /* last element of right wave appears left */
rarray[0] = larray[1]; /* first element of left wave appears right */
for (i=1; i<17; i++)
{ /* interpolate wave: */
lsarray[i]= (int) (larray[i] * (16-lcount) + larray[i+1] * (lcount)) >> 4;
}
lcount = (lcount + 1) & 0x0F;
if (lcount == 0)
{ /* shift original wave: */
for (i=0; i<17; i++)
larray[i] = larray[i+1];
}
}
/*-------------------------------------------------------------------------*
* void rwelle()
*--------------------------------------------------------------------------*
* FT: shift the right moving wave for 1/16 positions to right
* (principle as described in function "lwelle()")
* EP: -
* RW: -
* GP: rsarray, rarray, rcount
*--------------------------------------------------------------------------*/
void rwelle()
{ int i;
for (i=1; i<17; i++)
{ /* interpolate wave: */
rsarray[i] = (int) (rarray[i] * (16-rcount) + rarray[i-1] * (rcount)) >> 4;
}
rcount = (rcount+1)&0x0F;
if (rcount == 0)
{ /* shift original wave: */
for (i=17; i>0; i--)
rarray[i] = rarray[i-1];
}
}
/*-------------------------------------------------------------------------*
* void rinput(char pos, int adval)
*--------------------------------------------------------------------------*
* FT: increase any value within right moving wave by given value;
* this value will be shifted to right
* EP: pos = LED number (0..15) whose brightness has to be changed
* adval = PWM offset value (-50..50) for this LED
* RW: -
* GP: rarray
*--------------------------------------------------------------------------*/
void rinput(char pos, int adval)
{
rarray[pos] += adval;
}
/*-------------------------------------------------------------------------*
* void linput(char pos, int adval)
*--------------------------------------------------------------------------*
* FT: increase any value within left moving wave by given value;
* this value will be shifted to left
* EP: pos = LED number (0..15) whose brightness has to be changed
* adval = PWM offset value (-50..50) for this LED
* RW: -
* GP: larray
*--------------------------------------------------------------------------*/
void linput(char pos, int adval)
{
larray[pos] += adval;
}
/*-------------------------------------------------------------------------*
* void main()
*--------------------------------------------------------------------------*
* FT: main function for PWM demo (3 demos will be performed)
* EP: -
* RW: -
* GP:
*--------------------------------------------------------------------------*/
void main()
{ int i,j;
unsigned char pwmdat[17];
signed char pwmdir[17];
unsigned int wtime;
BOOL errorflag;
DP2 = 0xFFFF; /* set port 2 as output */
pwm_ini();
errorflag=!timer_init(NULL);
lcd_init();
if (errorflag)
{
lcd_center(0,"CHECK TIMER");
timer_delay_10ms(200);
}
wellinit();
timer_delay_10ms(20);
lcd_center(0,"PWM demo");
timer_delay_10ms(200);
/* endless main loop, 3 demos will be performed: */
while(1)
{
/* ** ** ** moving light ** ** ** */
lcd_center(0, "Moving light");
lcd_center(1, " ");
wtime = timer_get_10ms(0);
for (i=0; i<16; i++)
{
pwmdat[i] = vorlage1[i][0];
pwmdir[i] = vorlage1[i][1];
}
do
{
for (i=0; i<16; i++)
{
if (pwmdat[i] == 0xFF) pwmdir[i] = -1;
if (pwmdat[i] <= 0x10) pwmdir[i] = 1;
pwmdat[i] += pwmdir[i];
pwm(i, pwmdat[i]);
}
timer_delay_20us(50);
}
while (timer_get_10ms(wtime) < DEMOTIME);
/* ** ** ** Drop on water ** ** ** */
lcd_center(0, "Drop falling");
lcd_center(1, "on water");
wellinit();
j = 0;
wtime = timer_get_10ms(0);
do
{
if (!rcount)
{
if (!(j%4))
{
for (i=1; i<17; i++) /* damp swing */
{
if (rarray[i]>0) rarray[i]-=1;
if (rarray[i]<0) rarray[i]+=1;
if (larray[i]>0) larray[i]-=1;
if (larray[i]<0) larray[i]+=1;
}
}
if (j == 0) /* drop is falling on water */
{
linput(8, 50);
rinput(9, 50);
}
if (j == 2)
{
linput(8, -50);
rinput(9, -50);
}
if (j == 4)
{
linput(8, 35);
rinput(9, 35);
}
if (j == 6)
{
linput(8, -25);
rinput(9, -25);
}
if (j < 2000) j++;
}
lwelle();
rwelle();
wellpwm();
timer_delay_10ms(2);
}
while (timer_get_10ms(wtime) < DEMOTIME);
/* ** ** ** stationary wave ** ** ** */
lcd_center(0,"Stationary");
lcd_center(1,"wave");
wellinit();
j = 0;
wtime = timer_get_10ms(0);
do
{
if (!rcount)
{
j = (j+1) & 0x03;
rinput(1, sint4[j]);
}
lwelle();
rwelle();
wellpwm();
timer_delay_10ms(2);
}
while (timer_get_10ms(wtime) < DEMOTIME);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -