Anbei der VHDL-Code für einen PWM-Generator, den ich in einem XC9572
untergebracht habe. Der Code beruht zum größten Teil auf der Atmel
AppNote 2324.pdf
http://www.atmel.com/dyn/resources/prod_documents/DOC2324.PDF
Hintergrund:
Als hartgesottener 8051-Fan will ich eine PWM_Motoransteuerung mit einem
8051-Derivat aufbauen. Da der einfache 8051 bekanntermaßen über keine
PWM-Eiheit verfügt und auch sonst nicht gerade der schnellste ist, habe
ich mich nach einer Hardwarelösung sowohl im Netz als auch hier im Forum
umgeschaut und bin auf besagtes Papier von Atmel gestossen. Dort ist der
VHDL-Code für einen PWM-Generator beschrieben, dessen Auflösung durch
einige marginale Änderungen am Quelltext offensichtlich beliebig
angepasst werden kann.
Folgendes ist am originalen Quelltext geändert( das zugehörige
User-Package bleibt !!unverändert!! und muß für die Entwicklungsumgebung
erreichbar sein):
- Erweiterung der Auflösung auf 16 Bit, wovon zZt 11 Bit genutzt werden
- PWM-Daten werden seriell statt parallel eingelesen
- Chip-Select zur Bausteinauswahl eingeführt
- einige Konstanten wegen besserer Übersicht eingeführt
Den Code habe ich mit der ISE, Version 8 Servicepack 3, compiliert. Das
JED-File passt geradeso in einen XC9536, in einem XC9572 könnte man
vermutlich 2 PWM-Module unterbringen.
Wie bereits erwähnt wird der CPLD von einem 8051, in diesem speziellen
Fall von einem DS89C450, angesteuert. Der Baustein ist mit der zweiten
seriellen Schnittstelle des Prozessors verbunden, die im Modus
0(=sysnchrone 8 Bit Datenübertragung, Standartkonfiguration nach Reset),
arbeitet.
Um die Arbeit mit dem PWM-Generator zu verdeutlichen, hier noch ein
Code-Schipsel(Flag- und Registerbezeichnungen aus Prozessordatenblatt):
1 | #define LSB 0
|
2 | #define MSB 1
|
3 | #define AKTIV 0
|
4 | #define NICHT_AKTIV 1
|
5 | #define PWM_SELECT(x) P.n=x
|
6 |
|
7 | union u{ unsigned pwm;
|
8 | unsigned char p[2];}pwm; /*wg 8 bit senderegisterbreite*/
|
9 |
|
10 | void pwm_out(void);
|
11 |
|
12 | void main(void)
|
13 | { .
|
14 | .
|
15 | pwm.pwm=2048; /*maximalwert bei bei 11 bit auflösung*/
|
16 | pwm_out();
|
17 | while(1);
|
18 | }
|
19 |
|
20 | void pwm_out(void)
|
21 | { PWM_SELECT(AKTIV);
|
22 | TI_1=0; /*tx-flag immer löschen*/
|
23 | SBUF1=pwm.p[LSB]; /*lsb senden*/
|
24 | while(!TI_1); /*auf tx warten*/
|
25 | TI_1=0;
|
26 | SBUF1=pwm.p[MSB]; /*msb senden*/
|
27 | while(!TI_1); /*wieder auf tx warten*/
|
28 | PWM_SELECT(NICHT_AKTIV); /*16 bit gesendet-> fertig*/
|
29 | }
|
mfg