PWM with the 80C517/537
Description
The 80C517/80C537 is a 8051 derivate. It's also a superset of the 515/535.
It offers the following features wich are listed below:- 8 kB ROM (517); no ROM (537)
- 256 Byte on chip RAM
- 64 kByte external program memory
- 64 kByte external data memory
- 8 data pointers
- 8-Bit A/D converter (12 multiplexed inputs)
- 2 16-Bit counters (8051 compatible)
- Captuer Compare Unit based on a 16-Bit timer/counter and a high-speed 16-Bit timer for fast compare
- 8 fast 16-bit compare registers
- arithmetic unit
- Watchdog
- 7 bidirectional 8-Bit ports
- 12 Bit for digital and analog input
- 14 interrupt vectors, 4 priority levels
- PLCC-84 package
Suitable for...
I used the 537 to control a DC/DC motor via a MOSFET based amplifier. I also used it to control a amplifier usualy used for RC models. The CCU is just right for problems like that. It's working interrupt based. You just have to set up the parameters (frequency, pulse width, ...) and the CCU is doing the rest. See example (description/code) below.
Using the CCU
This is a PWM example controlling a RC amp like used for RC models (I did it for the A.R.T. project). I messured the output of the RC receiver. The output had a frequency/period of 40[Hz]/0.025[s]. I found out that the amp stops the motor at a pulse width of about 0.0102[s]. Maximum rpm is reached at a pulse width of 0.0105[s].
Adjusting the Timer
The CCU is based on timer #2. The clock of my 537 is 12M[Hz]. So I adjusted the prescaler to divide the clock input by 12. No we have a time base which is 1M[Hz]. The timer starts with the reloadvalue. If the timer has an overflow (0xffff to 0x0000) the interrupt #5 is triggered. If you select auto reload mode the timer is loaded with the reloadvalue again and you have a periodic signal (which is exactly what we need). What reload value do wee need to reach a period of 0.025[s]? The time is determined by the difference of the reload value to 0xffff. So you get the expression (0xffff - reload) / timebase = period. We know the period and want to know the reload value. So we rearrange the expression and get reload = -(period*timebase - 0xffff). With our values we have reload = -(0.025 * 10^6 - 0xffff) = 0x9e57.
The table is showing the configuration of the 537's special function registers (SFR).
The SFRs are set as follows:
CRC = 0x9e57 - Reloadvalue for timer, determines the period length/frequency
T2CON = 0x11 - Timer #2 autoreload (periodic), compare mode
Adjusting the Pulse Width
The 537's CCU has four channels. We just need two for our differential steering. So we just have to configer the SFRs CC1 and CC2 and enable those two channels (CCEN register).
Each channel is associated with a SFR (CC) and a output port line. If the timer reaches the value in CC (CC1-CC4) the output is going high (1). It is going low (0) again at timer overflow. The pulse width of the high level is given by CC-0xffff.
The interrupt service routine (ISR) is the right place to update the current pulse width. Set the width outside of the ISR. The ISR will make it become valid at the non critical time period.
This is the association between CC register and port: CC1 - P1.1; CC2 - P1.2; CC3 - P1.3 and CC4 - P1-4.
Don't forget: CCEN = 0x28
Example Code
unsigned int pw_left; /* Pulsewidth for left and right motor. */
unsigned int pw_right;
/*
* After the initialization done in main() the CCU produces a periodic
* pulse (width 0,0102s). The current pulse width is adjusted during
* the interrupt service routine.
*/
_interrupt 5 _using 0 void ccu_isr( void )
{
ET2 = 0; /* Disable timer #2 */
CCEN &= 0xd7; /* Compare disabled */
CC1 = pw_left; /* Get pulse width from variables */
CC2 = pw_right; /* Use as the new compare values */
CCEN = 0x28; /* Compare enabled */
TF2 = 0; /* reset the timer #2 Overflow Request */
ET2 = 1; /* enable timer #2 */
}
/*
* Controlling two DC motors by PWM.
*/
void main()
{
/*
* Initial pulsewidth for both motors.
*/
pw_left = 0xfc00;
pw_right = 0xfc00;
/*
* Set the 537's CCU to a periodic signal (40Hz) and set up comparemode
*/
EAL = 0; /* All interrupts disabled. */
CRC = 0x9e57; /* Timer #2 reloadvalue for 40Hz (0,025s) */
CC1 = 0xfc00; /* Adjust pulse width for both channels, so that */
CC2 = 0xfc00; /* initially the motor is turned off (CC = Comparevalue) */
CCEN = 0x28; /* Compare enabel for Chanal 1 and 2 (P1.1, P1.2) */
T2CON = 0x11; /* Timer #2 autoreloadmode, comparemode */
ET2 = 1; /* Activate timer #2 */
EAL = 1; /* All interrupt enabled. */
/*
* Mainprogram
*/
while( 1 )
{
...
/*
* Adjust the pulsewidth for both motors by modifying
* pw_left and pw_right.
*/
...
}
}
Related Sites
Welcome to www.6502.org! - www.6502.org/
Related Literature
Michael Fredershausen: Microcontroller Technik in der Praxis
Siemens: SAB 80C517/537 8-Bit CMOS Single-Chip Microcontroller
Related Docs
Datasheet miniMODUL Docking Board - mmBaseHandbook.pdf (287k bytes)
Datasheet miniMODUL-537 - mm537Handbook.pdf (202k bytes)
Home
this page was updated: 27.05.00 10:18:47
holger@zahnleiter.org
The use of my page's content (programs, wiring diagrams, pictures, documents) is free for non-commercial purposes only.
The information in this document has been carefully reviewed and is believed to be reliable, but I do not assume any liability arising out of the application or use of any documents, programs or circuit described herein.
Furthermore I want to declare that I'm not responsible in any way for the content of other web pages, books and other sources I'm refering to.