可能很多人都用软件模拟过不少东西,比如IIC,SPI,UART等.
但我相信用软件模拟PWM的人应该还不多,因为一般的PWM都要求不断的输出.
这样就非常占用CPU的资源. 然而,当你利用我们的多核MCU时,你就会不再吝啬
CPU的资源了,因为即使你用掉一个,都还有7个任你使用呢,这样的效果我想传统的
MCU还没有那家的可以灵活. 一个14PIN的MCU就可以方便完成你想要的I/O操作了哟
看看我模拟的PWM原程序,是不是还有7个CPU在等待任务呢
/p>
欢迎点击下载阅读
img alt="图片点击可在新窗口打开查看" src="http://blog.gkong.com/images/file/zip.gif" border="0" style="CURSOR: pointer;"/>PWM_generator.rar
//***************************************************************************
//***** PDK80Cxx Peocessor Application Example Project *****
//***************************************************************************
// Example Name :: PWM_Generator( ) Version 1.00
// Module Name :: PWM.asm
// MCU TYPE :: PDK80C02
// OSC :: External (HT) 8MHz
// Abstract
br/>// Module related to PWM generator
// Environment
br/>// PADAUK FPPA(TM) IDE Tool Version : 0.12 Beta
//
// Revision History
br/>// Sep. 19, 2006 Raker.Yang Created
/////////////////////////////////////////////////////////////////////////
// Copyright (C) 2006 by ChangKe Electronic Technology Co. Ltd. All rights reserved.
;
;--------special register define---------------------
flag.z equ flag.0
flag.c equ flag.1
flag.ac equ flag.2
flag.ov equ flag.3
;--------special register define end-----------------
;
;---------constant define-----------------------------
;FPPA0~FPPA7 stack bottom define-------
STACK_BOTTOM0 equ 0x7F
STACK_BOTTOM1 equ 0x79
STACK_BOTTOM2 equ 0x73
STACK_BOTTOM3 equ 0x6D
STACK_BOTTOM4 equ 0x69
STACK_BOTTOM5 equ 0x65
STACK_BOTTOM6 equ 0x61
STACK_BOTTOM7 equ 0x5D
;--------------------------------------
;
;---------PWM VAL defien-----------------------------
PWM_FREQH0 equ 0x05
PWM_FREQL0 equ 0x04
PWM_DUTYH0 equ 0x02
PWM_DUTYL0 equ 0x02
;--------I/O PORT define-----------------------------
PWMOUT0 equ pa.2
PWMOUT1 equ pa.3
PWMOUT2 equ pa.4
RX0 equ pb.6
;--------I/O PORT defien end-------------------------
;----------PROGRAM FOLLOWING------------------------------------
;
.include "pwm_generator.inc"
.ramadr 0x00
; int freqH0
int freqL0
int freqL0buf
; int freqHbuf0
; int dutyH0
int dutyL0
; int dutyHbuf0
int dutyL0buf
;.romadr 0
//=====================================================
//---
//--- Program Begin
goto reset ; //fpp0boot ;// Processor #0 entry vector
goto fpp1boot ; // Processor #1 entry vector
goto fpp2boot ; // Processor #2 entry vector
goto fpp3boot ; // Processor #3 entry vector
goto fpp4boot ; // Processor #4 entry vector
goto fpp5boot ; // Processor #5 entry vector
goto fpp6boot ; // Processor #6 entry vector
goto fpp7boot ; // Processor #7 entry vector
//------------------------------------------------------------------------
; .include "reset.asm"
//--- Boot-up the chip use Processor-0 here!
reset:
mov a, STACK_BOTTOM0
mov sp, a
call clkModeSelect
call ioInit
call ramClear
pmode 0x01
;----------FPP0 program----------------------------------
;PWM generator
;argument: T = (11 + 11*(freqL0)) * t = 11*(1 + (freqL0)) * t
; Duty = (11 + 11*(dutyL0)) * t = 11*(1 + (dutyL0)) * t
; IF (dutyL0) = 0, THEN Output low level constantly
; IF (dutyL0) >= (freqL0) + 1, THEN Output High level constantly
; Note: t is fpp0's system clock,duty value must be less than T value.
;------------------------------------
fpp0boot:
mov a, PWM_FREQL0
mov freqL0, a
mov a, PWM_DUTYL0
mov dutyL0, a
mov a, 0xff
mov fppen, a
fpp0Loop:
pwm0Init:
mov a, freqL0 ;trace1_7
mov freqL0buf, a ;trace1_8
mov a, dutyL0 ;trace1_9
mov dutyL0buf, a ;trace1_10
pwm0start:
mov a, dutyL0buf ;trace1_11
t1sn flag.z ;trace0_0
goto dec_duty0_reg ;trace0_1
set0 PWMOUT0 ;trace1_1
nop ;trace1_2
goto check_pwm0_freq ;trace1_3
dec_duty0_reg:
set1 PWMOUT0 ;trace0_2
dec dutyL0buf ;trace0_3
check_pwm0_freq:
mov a, freqL0buf ;trace0_4
t0sn flag.z ;trace0_5
goto pwm0Init ;trace1_6
;dec frequnce reg
nop ;trace0_6
nop
nop
dec freqL0buf ;trace0_9
goto pwm0start ;trace0_10
;--------the end of fppa 0------------------
;
;--------fppa 1 program---------------------
fpp1boot:
mov a, STACK_BOTTOM1
mov sp, a
fpp1loop:
nop
goto fpp1loop
;--------the end of fppa 1------------------
;
;
;--------fppa 2 program---------------------
fpp2boot:
mov a, STACK_BOTTOM3
mov sp, a
fpp2loop:
nop
goto fpp2loop
;--------the end of fppa 2------------------
;
;--------fppa 3 program---------------------
fpp3boot:
mov a, STACK_BOTTOM3
mov sp, a
fpp3loop:
nop
goto fpp3loop
;--------the end of fppa 3------------------
;
;--------fppa 4 program---------------------
fpp4boot:
mov a, STACK_BOTTOM4
mov sp, a
fpp4loop:
nop
goto fpp4loop
;--------the end of fppa 4------------------
;
;--------fppa 5 program---------------------
fpp5boot:
mov a, STACK_BOTTOM5
mov sp, a
fpp5loop:
nop
goto fpp5loop
;--------the end of fppa 5------------------
;
;--------fppa 6 program---------------------
fpp6boot:
mov a, STACK_BOTTOM6
mov sp, a
fpp6loop:
nop
goto fpp6loop
;--------the end of fppa 6------------------
;
;--------fppa 7 program---------------------
fpp7boot:
mov a, STACK_BOTTOM7
mov sp, a
fpp7loop:
nop
goto fpp7loop
;--------the end of fppa 7------------------
;
;-------------------------------------------------------------------
;Name :clkModeSelect
;Input :void
;Output :
;Temp reg :void
;Function :select system clock: exteral OSC,
;Argument :
;--------------------------------------------------------------
clkModeSelect:
set0 clkmd.1; // turn-off watchdog
//------Low clock switch to High clock---------------------------------------
mov a, 0x00;
mov eoscr, a; //External OSCillator Register
// bit-0: 1=Enable XTAL Smith trigger strong mode
// 0=Disable XTAL Smith trigger strong mode
// bit-1: 1=Enable XTAL Smith trigger
// 0=Disable XTAL Smith trigger
// bit4-2: Option of driving strength in crystal oscillator
// bit6-5: 00=External RC oscillator
// 01=32KHz crystal oscillator
// 10=4Mhz crystal oscillator
// 11=20MHz crystal oscillator
// bit7: 1=Enable external RC oscillator or crystal oscillator
// 0=Disable external RC oscillator or crystal oscillator
// delay 0xff; // internal 32KHz need delay 30m/S
// external 20MHz need delay 1m/S
mov a, 0x00 ;
mov ihrcrh, a; //bit-0:Internal high RC
mov a, 0xCA;
mov ihrcrl, a; // 12MHz/clkmd bit7~5/Pmode/instruction=real clock
delay 255 ; // 1T=12MHz/4/8=375KHz (2.6uS)
// mov a, r01;
// set1 pa, led1;
// set1 pa.1;
mov a, 0x14 //;0x64 ;0x14; //14; //e4 //54
mov clkmd, a; // Internal Low RC, Watch Dog disable,
// bit-0: Reset Function
// bit-1: 1=Enable Watch Dog (default)
// 0=Disable Watch Dog
// bit-2: 1=Enable Internal Low RC (default)
// 0=Disable Internal Low RC
// bit-3: No used
// bit-4: 1=Enable Internal High RC (default)
// 0=Disable Internal High RC
// bit-7~5: 000=internal high RC/4
// 001=internal high RC/2
// 010=internal high RC
// 011=external OSC/4
// 100=external OSC/2
// 101=external OSC
// 110=internal low RC/4
// 111=internal low RC (default)
ret
;---------------------------------------------------------------------------------------------
;
;-----------IO initial------------------------------------------------------------------------
;Input :void
;Output :void
;Temp reg :void
;Function :I/O direction initial
;Argument :0--->input; 1--->output
;------------------------------------------------------
ioInit:
//---Assign PA.0 is IR_Input
mov a, 0x1c ; // PA.0:IR
mov pac, a ; //
mov a, 0x00 ;
mov pa, a ;
//---- ALL of PORT B assign as LCM Data Bus port
mov a, 0x00 ; // define the PB control property
mov pbc, a ; // PB input
mov a, 0xff ; // assign PB.6 port UART RX
mov pb, a ; //
ret
;------------IO initial end--------------------------------------------------
;
;------------Ram clear-------------------------------------------------------
;Name :ramClear
;Input :const(reset stack bottom)
;Output :void
;Temp reg :void
;Function :
;Argument :
;------------------------------------------------------
ramClear:
; mov a, STACK_BOTTOM - 4;
; mov lb@RAMindex, a;
; mov a, 0x00;
; mov hb@RAMindex, a;
;ClearRAMLoop:
; wdreset;
; idxm RAMindex, a;
; dzsn lb@RAMindex;
; goto ClearRAMLoop;
ret