-
1 # 順德夫人
-
2 # IT自動化交流
我用過最便宜的微控制器是臺灣芯睿的處理器MK6A12A。
SOP-8封裝,1k OTP ROM, 48 RAM,不帶A/D。
用來做一些低端的小家電,比如實現某個產品的功能,
檢測到振動以及有太Sunny輸入之後,輸出控制馬達,間歇或者持續工作。
比較麻煩的是,該處理器只支援組合語言程式設計。
淘寶上的售價大概是0.5元/片,批次價格在0.3元/片左右。
以下是我們用同系列處理器實現某小家電的彙編程式碼,供參考:#include "MK7A25P.inc"
#define ADC_DURATION .64
#define ADC_POWERON .63
#define POWEUP_DELAY .255
#define KEY_DEBOUNCE .10
#define VARI_DEBOUNCE .4
#define SLEEP_TIME .50
#define PA PA_DAT
#define PB PB_DAT
#define PC PC_DAT
#define PD PD_DAT
#define _VARI_DETECT PB_DAT, 0
#define _MOTOR_OUT PB_DAT, 1
#define UseRegStart 0x40 ;通用暫存器開始地址
#define UseRegEnd 0x80 ;通用暫存器結束地址
#define TIME_HIGH_H 0x00
#define TIME_HIGH_L 0x3B
#define TIME_LOW_H 0x00
#define TIME_LOW_L 0x26
#define TIME_FIRST_H 0x00
#define TIME_FIRST_L 0xA0 ;40s
#define TIME_HIGH_MAX_H 0x00
#define TIME_HIGH_MAX_L 0x3B
#define TIME_HIGH_MIN_H 0x00
#define TIME_HIGH_MIN_L 0x03
#define AD_TEMP_ADVALUE_CHARGEONL 0x7B ;4.00 2.46V
#define AD_TEMP_ADVALUE_CHARGEONH 0x02
#define AD_TEMP_ADVALUE_CHARGEOFFL 0x57
#define AD_TEMP_ADVALUE_CHARGEOFFH 0x02 ; 4.16,2.46V
#define AD_TEMP_ADVALUE_ENABLEL 0xB2
#define AD_TEMP_ADVALUE_ENABLEH 0x02 ;3.66v,2.46V
#define AD_TEMP_ADVALUE_DISABLEL 0xBa
#define AD_TEMP_ADVALUE_DISABLEH 0x02 ; 3.61V,2.46V
#define AD_TEMP_ADVALUE_PROTECTL 0xC3
#define AD_TEMP_ADVALUE_PROTECTH 0x02 ;3.57V,2.46V
#define AD_TEMP_ADVALUE_PROTECTL_SLP 0xBF
#define AD_TEMP_ADVALUE_PROTECTH_SLP 0x02 ;3.57V,2.46V
#define AD_AD_SAMPLES .7
CBLOCK UseRegStart
R_DelayTemp
R_ADSumL
R_ADSumH
R_ADCount
R_uchData
R_uchDataH
R_uchDataL
R_SubeeH
R_SubeeL
R_SuberH
R_SuberL
R_SubResH
R_SubResL
R_ADCDelay
R_ADCFinish
R_key_state
R_key_event
R_key_count
R_vari_state
R_vari_event
R_vari_count
R_uchOutPutEnable
R_uchOutPutLevel
R_uchOutPutTimerH
R_uchOutPutTimerL
R_uchTimer250ms
R_uchTimerCount
R_uchOutPutLogic
R_uchLEDOut
R_uchKeyLevel
R_uchLEDOutLevel
R_uchKeyScanCount
R_uchVariTimer
R_uchFirstTime
R_uchProtect
R_uchCharge
R_uchADDetect
R_Data0
R_Data1
R_Data2
R_Data3
R_Data4
R_Data5
R_To0
R_To1
R_To2
R_To3
R_Count0
R_Com3
R_uchCalTimeH
R_uchCalTimeL
R_uchADFinish
ENDC
ORG 0x0000
LGOTO fmain ;主程式入口
NOP
LGOTO fmain
ORG 0x0004
clr IRQF
RET_INT
ORG 0x0008
fmain:
LCALL finit_io ;IO口初始化
MOVLA POWEUP_DELAY
MOVAM R_uchData
fmain_delay:
nop
nop
nop
nop
DEC R_uchData, m
BTSS Z
lgoto fmain_delay
LCALL finit_regs ;暫存器初始
LCALL finit_io ;IO口初始化
LCALL finit_adc ;ADC初始化
LCALL finit_timer ;timer0初始化
;看門狗
MOVLA B"10000110" ;看門狗時間約為1.28S
MOVAM WDT_CTL
CLRWDT ;清WDT
;------------------------------------------------
CLR IRQF
MOVLA B"00000000" ;開總中斷 開T0 & PWM1
MOVAM IRQM
;1.16ms
lcall fpoweruptimer
;67.6ms
lcall fpcbatest
clr R_ADCDelay
movla TIME_HIGH_H
movam R_uchCalTimeH
movla TIME_HIGH_L
movam R_uchCalTimeL
movla SLEEP_TIME
movam R_uchSleepTimer
fmain_loop:
CLRWDT
BTSS IRQF, tm1f
lgoto fmain_loop_realtime
movla B"11111101"
movam IRQF
inc R_uchTimerCount, m
mov R_uchTimerCount, a
btsc Z
inc R_uchTimer250ms, m
lcall fkey_samp
fmain_loop_realtime:
clr R_key_event
mov R_uchTimer250ms, a
btss Z
lgoto fmain_loop_timer250ms
lgoto fmain_loop_end
fmain_loop_timer250ms
mov R_uchVariTimer,a
btss z
dec R_uchVariTimer,m
lcall fmain_drivemotor
fmain_loop_end
clr R_uchTimer250ms
lcall fmain_getkeylevel
lcall fvari_detect
clrwdt
lcall fmain_sleep
lgoto fmain_loop
ret
fmain_drivemotor:
mov R_uchVariTimer,a
btsc z
lgoto fmain_drivemotor_checkfirst
lgoto fmain_drivemotor_checkad
fmain_drivemotor_checkfirst
mov R_uchFirstTime, a
btss z
lgoto fmain_drivemotor_close
fmain_drivemotor_checkad
mov R_uchOutPutEnable, a
btsc Z
lgoto fmain_drivemotor_close
movla .1
movam R_uchOutPutLogic
add R_uchOutPutTimerL,m
movla .0
addc R_uchOutPutTimerH,m
mov R_uchOutPutLevel, a
btsc Z
lgoto fmain_drivemotor_low
lgoto fmain_drivemotor_high
fmain_drivemotor_low
movla .1
movam R_uchFirstTime
bc _MOTOR_OUT
mov R_uchOutPutTimerL, a
movam R_SuberL
mov R_uchOutPutTimerH, a
movam R_SuberH
movla TIME_LOW_L
movam R_SubeeL
movla TIME_LOW_H
movam R_SubeeH
lcall fvalue_cmp
btsc C
lgoto fmain_drivemotor_next
movla .1
movam R_uchOutPutLevel
clr R_uchOutPutTimerH
clr R_uchOutPutTimerL
lgoto fmain_drivemotor_next
fmain_drivemotor_high
bs _MOTOR_OUT
clr R_uchADDetect
MOVLA AD_AD_SAMPLES
MOVAM R_ADCount
CLR R_ADSumH
CLR R_ADSumL
mov R_uchOutPutTimerL, a
movam R_SuberL
mov R_uchOutPutTimerH, a
movam R_SuberH
mov R_uchFirstTime, a
btsC z
lgoto fmain_drivermoter_high_th_1
mov R_uchCalTimeL, a
movam R_SubeeL
mov R_uchCalTimeH, a
movam R_SubeeH
lgoto fmain_drivermotor_high_next
fmain_drivermoter_high_th_1
movla TIME_FIRST_L
movam R_SubeeL
movla TIME_FIRST_H
movam R_SubeeH
fmain_drivermotor_high_next
lcall fvalue_cmp
btsc C
lgoto fmain_drivemotor_next
movla .0
movam R_uchOutPutLevel
clr R_uchOutPutTimerH
clr R_uchOutPutTimerL
lgoto fmain_drivemotor_next
fmain_drivemotor_next
lgoto fmain_drivemotor_end
fmain_drivemotor_close
movla .1
movam R_uchFirstTime
clr R_uchOutPutLogic
bc _MOTOR_OUT
clr R_uchOutPutTimerH
clr R_uchOutPutTimerL
clr R_uchOutPutLevel
fmain_drivemotor_end
ret
fvalue_cmp:
MOV R_SuberL, a
btss Z
lgoto fvalue_cmp_1
clra
lgoto fvalue_cmp_3
fvalue_cmp_1
MOV R_SuberL,a
SUB R_SubeeL,a
clra
btss C
movla .1
fvalue_cmp_3
add R_SuberH, m
mov R_SuberH, a
btss z
lgoto fvalue_cmp_2
BS C
lgoto fvalue_cmp_end
fvalue_cmp_2:
Sub R_SubeeH, a
fvalue_cmp_end:
ret
;------------------------------------------------
;總初始化
;------------------------------------------------
;------------------------------------------------
;I/O口初始化
;------------------------------------------------
finit_io:
;PA
MOVLA B"00000000"
MOVAM PA_DAT ;PA口資料暫存器 PB2輸入
MOVLA B"00000000"
MOVAM PA_DIR ;PA口方向暫存器 0輸出 1輸入
MOVLA B"00000000"
MOVAM PA_PLU ;I/O口上拉控制 0禁止 1開啟
;PB
MOVLA B"00000000"
MOVAM PB_DAT ;PB口資料暫存器
MOVLA B"00000001"
MOVAM PB_DIR ;PB口方向暫存器 0輸出 1輸入
MOVLA B"00000000"
MOVAM PB_PLU ;I/O口上拉控制 0禁止 1開啟
;PC
MOVLA B"00000000"
MOVAM PC_DAT ;PC口資料暫存器
MOVLA B"00000000"
MOVAM PC_DIR ;PC口方向暫存器 0輸出 1輸入
MOVLA B"00000000"
MOVAM PC_PLU ;I/O口上拉控制 0禁止 1開啟
RET
;------------------------------------------------
;暫存器初始化
;------------------------------------------------
finit_regs:
MOVLA UseRegStart ;通用暫存器開始地址
MOVAM FSR
finit_regs_loop
CLRWDT
CLR INDF
INC FSR,M
MOV FSR,a
XORLA UseRegEnd+.1 ;通用暫存器結束地址
BTSS Z
LGOTO finit_regs_loop
CLR FSR ;清完後要注意bank 的歸位
;--------------------------------------------------------
RET
;------------------------------------------------
;TIMER0初始化
;------------------------------------------------
;------------------------------------------------------ 定時125us
finit_timer:
CLR TM1_CTL2
MOVLA .0 ;256-125=131 ; 注意:1/8Mhz=0.125us 1.024ms
MOVAM TM1L_LA
MOVLA .4
MOVAM TM1H_LA
MOVLA B"01100010" ;設定clk_source=RC
MOVAM TM1_CTL1 ;6(1)鎖存器資料寫到計數器使能,5-4(01)外 4MHZ 模式,2-0(010)預分頻率1:4
BS tm1_ctl1,7
RET
;------------------------------------------------
;AD初始化
;------------------------------------------------
fvari_detect:
btsc _VARI_DETECT
lgoto fvari_high
mov R_vari_state, a
btsc Z
inc R_vari_count, m
lgoto fvari_cal
fvari_high
mov R_vari_state, a
btss Z
inc R_vari_count, m
fvari_cal
movla VARI_DEBOUNCE
sub R_vari_count, a
btss C
lgoto fvari_skip
movla .1
movam R_vari_event
clr R_vari_count
com R_vari_state, m
movla .1
and R_vari_state,m
fvari_skip
mov R_vari_state, a
btsc z
lgoto fvari_end
mov R_uchVariTimer, a
btsc z
bs R_uchOutPutLevel, 0
movla .255
movam R_uchVariTimer
fvari_end
ret
fsub16:
mov R_Data0, a
btsc Z
lgoto fsub16_1
mov R_Data0, a
sub R_Data4, m
clra
btss C
movla .1
add R_Data1,m
fsub16_1
mov R_Data1, a
sub R_Data5, m
ret
fdiv16: ;data1data0/data5data4---->data1data0(to1to0)---to3to2
CLR R_TO0
CLR R_TO1
CLR R_TO2
CLR R_TO3
movla 0x10
movam R_Count0
tmsc R_Data5
lgoto start16
tmsc R_Data4
lgoto start16
lgoto over16
start16
tmsc R_Data1
lgoto div16
tmsc R_Data0
lgoto div16
lgoto dispa16
div16
CLRWDT
bc c
rlc R_Data0,m
rlc R_Data1,m
rlc R_To2,m
rlc R_To3,m
mov R_Data4,a
sub R_To2,a
movam R_Com3
com R_Data5,a
addc R_To3,a
;----------------------------
btss c
lgoto next16
movam R_To3
mov R_Com3,a
movam R_To2
movla 0x01
add R_Data0,m
movla 0x00
addc R_Data1,m
next16
decsz R_Count0,m
lgoto div16
dispa16
mov R_Data0,a
movam R_To0
mov R_Data1,a
movam R_To1
ret
over16
ret
END
回覆列表
我用過的最便宜的微控制器,只要0.16元。臺灣應廣8位OTP微控制器,不帶AD,單核,sot23-6封裝。mini C語言和彙編混程式設計。