最便宜的单片机能便宜到什么程度?最的单片机?
最便宜的单片机能便宜到什么程度?
STC单片机,最便宜的不到1元钱,还不够买个雪糕呢,你说便宜到什么程度了。
我用过最便宜的单片机是台湾芯睿的处理器MK6A12A。
SOP-8封装,1k OTP ROM, 48 RAM,不带A/D。
用来做一些低端的小家电,比如实现某个产品的功能,
检测到振动以及有太阳光输入之后,输出控制马达,间歇或者持续工作。
比较麻烦的是,该处理器只支持汇编语言编程。
淘宝上的售价大概是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 B10000110 ;看门狗时间约为1.28S
MOVAM WDT_CTL
CLRWDT ;清WDT
;------------------------------------------------
CLR IRQF
MOVLA B00000000 ;开总中断 开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 B11111101
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 B00000000
MOVAM PA_DAT ;PA口数据寄存器 PB2输入
MOVLA B00000000
MOVAM PA_DIR ;PA口方向寄存器 0输出 1输入
MOVLA B00000000
MOVAM PA_PLU ;I/O口上拉控制 0禁止 1开启
;PB
MOVLA B00000000
MOVAM PB_DAT ;PB口数据寄存器
MOVLA B00000001
MOVAM PB_DIR ;PB口方向寄存器 0输出 1输入
MOVLA B00000000
MOVAM PB_PLU ;I/O口上拉控制 0禁止 1开启
;PC
MOVLA B00000000
MOVAM PC_DAT ;PC口数据寄存器
MOVLA B00000000
MOVAM PC_DIR ;PC口方向寄存器 0输出 1输入
MOVLA B00000000
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 B01100010 ;设置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: tt;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
rlctR_Data0,m
rlctR_Data1,m
rlctR_To2,m
rlctR_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语言和汇编混编程。
最便宜的单片机?
国产STM32还便宜?10块人民币一片!r 国产STM8只要2块钱一片……r 当然,STM8也并不算便宜,因为宏晶最贵的8051只要3块钱,最便宜的只要5毛钱……r 为什么这么便宜?因为作为银河系最大的51单片机厂商,宏晶每年卖出几亿片单片机,连起来可以绕地球3圈,研发成本稀释到每片近乎为零……r