1. ATMega8A
https://www.google.com/search?q=AVR+OS+DIY 轻量级多任务OS https://www.xpstem.com/tutorials/detail/10007 深入了解
TB价1元-QFP32。与别的成员相差在程序/RAM/EE的大小,本片是8K/1K/0.5K。5V,DIP28价约1刀,TQFP32稍便宜。6个10bit A/D(2个与I2C共线,32脚芯片有8个,另有2个模拟输入可做比较器),时钟200K变换需时125us,有内置2.56Vref也可外加,内置的稳定但总绝对误差在-40~80C为1.75LSB,供电为AVcc。典型时钟16M,因库的兼容性不建议更换,内置RC震荡器8M,25C时误差2%,整个温度范围误差可达14%。BootLoader不过1KB,也有512B的版本https://github.com/Optiboot/optiboot,均需与时钟频率相配,因其使用串口。串口可达1M,有2X模式。厂家的触摸库QTouch®可下载。以下28DIP即国内所称M8为例。
ATmega8A:8K字节的系统内可编程闪存,具有读-写功能,写入功能,512字节EEPROM,1K字节SRAM,23条通用I / O线,32条通用工作寄存器,三个具有比较模式的灵活定时器/计数器,内部和外部中断,一个串行可编程USART,面向字节的两线串行接口,6通道ADC(TQFP和VQFN封装8个),精度为10位,带有内部振荡器的可编程看门狗定时器,SPI串行端口和五个软件可选的省电模式。空闲模式会在允许SRAM的同时停止CPU,定时器/计数器,SPI端口和中断系统继续运行。掉电模式保存寄存器内容,但冻结振荡器,禁用所有其他芯片功能,直到下一次中断或硬件复位为止。在省电模式下,异步计时器继续运行,允许用户在设备的其余部分正在休眠。 ADC降噪模式可停止CPU和除异步以外的所有I / O模块定时器和ADC,以最小化ADC转换期间的开关噪声。在待机模式下,晶体/谐振器振荡器在器件的其余部分处于睡眠状态时运行。这样可以非常快速地启动低功耗。
XT1/2为时钟脚,接22p到地,再并晶体或陶瓷片,不用的脚可做I/O。I/O脚均可选上拉电阻,作输入时有下拉电阻。由上图可见I2C与ADC4/5共用,速率率可达400K。SPI支持主从模式。有WDT。模拟比较器输入OC1A/1B,输出可驱动中断或T/C1。T/C0和T/C2为8bit后者支持多个PWM模式-没去细看,T/C1为16bit。中断优先级不清楚,中断源有内/外、T/Cx、A/D等没啥限制。缺328P的debug硬件。
AVR系列比较:https://www.futurlec.com/ICAtmel_ATMega_Comparison.shtml
1.1 PWM
https://sites.google.com/site/qeewiki/books/avr-guide/pwm-atmega8
ATmega8具有3个PWM输出,2个在T/C1上16bit,1个在T/C2上8bit。
1.1.1 T/C2 8bit PWM
有快速PWM和相位校正PWM两种模式,输出OC2可以是同相或反相。
快速PWM模式:与普通计数器相同。控制逻辑接收信号并递增TCNT2寄存器。当检测到匹配时,将设置OCF0x标志,并将信号发送到波形发生器。波形发生器随即更改OC0x引脚的状态(该状态由所选模式确定)。当TCNT2寄存器超过TOP值(0xFF或255)时,它只是溢出回到0,同时设置OCF2标志。可以软件清除OCF2标志,或将其用于触发中断。一但触发中断请求,该标志将自动清除。同相模式下,若TCNT2小于OCR2,则OC2引脚为HIGH(VCC),否则OC2引脚为LOW(GND)。反向模式下,若TCNT2小于OCR2,则OC2引脚为LOW(GND),否则OC2引脚为HIGH(VCC)。由于此模式的频率很高,因此最适合用于DAC,LED衰落,整流和功率调节。频率可以通过以下公式计算:PWM_fequency =时钟速度/(预分频器值* 256)
相位校正PWM:它有点奇怪,递增计数直到达到TOP值(0xFF或255),然后开始递减计数直到达到下限0。控制逻辑接收信号并递增TCNT2寄存器。检测到匹配时将设置OCF2标志,并将信号发送到波形发生器。波形发生器随即更改OC2引脚的状态(该状态由所选模式确定)。当TCNT2寄存器达到TOP值(0xFF)时,将设置OCF2标志,用法与前相同。同相模式下,向上计数时,TCNT2和OCR2之间的比较匹配时,OC2引脚为LOW(GND);向下计数时,比较匹配中的OC2引脚为HIGH(VCC)。反相模式下,向上计数时,TCNT2和OCR2之间的比较匹配时,OC2引脚为HIGH(VCC);向下计数时,比较匹配中的OC2引脚为LOW(GND)。
1.1.2 T/C1 16bit PWM
有两个输出OC1A和OC1B。由于这两个输出都在同一个计时器上运行,并且OC1A和OC1B都同步了波形发生器,因此这使得该计时器非常适合制造坦克机器人。
T/C1的工作方式与T/C2相同。将OCR1A / OCR1B与TCNT1寄存器进行比较,当检测到匹配时,将设置OCF1A / OCF1B标志并将信号发送到波形发生器。波形发生器随即更改OC1A / OC1B引脚的状态(该状态由所选模式确定)。OCF1A / OCF1B标志可以由软件清除,也可将其配置为触发中断。后者在触发中断请求时会自动清除,A和B具有单独的向量,其中A优先。
T/C1能够在3种模式下运行:快速PWM模式,相位校正PWM模式以及相位和频率校正模式。输出均可反转或不反转。与T/ C2不同的是它有几个选项可用于控制PWM的最大值。有的模式例如模式1,TOP固定为0x00FF;其它的如模式8至15则用存储在ICR1或OCR1A寄存器中的TOP值。
快速PWM模式:T/C1上的快速PWM的工作方式与T/C2上的一样。它一直计数到到达顶部,然后溢出回到0。最大的不同是,我们有几种具有不同TOP值的Fast PWM模式。需要注意的是,如果将ICR1或OCR1A用作TOP值,则MINIMUM有效值为3(0x0003)。由于此模式的频率很高,因此最适合用于DAC,LED衰落,整流和功率调节。快速PWM的频率可以通过以下公式计算:PWM_fequency =时钟速度/ [Prescaller_value *(1 + TOP_Value)]
相位校正PWM模式:T/C1上的相位校正模式与定时器/计数器2上的相位校正模式一样工作(有关详细信息,请参见上文)。不同的是我们可以将ICR1或OCR1A的值用作TOP值。输出可以反转或不反转。在同相模式下,向上计数时,TCNT1和OCR1A / OCR1B之间的比较匹配时,OC1引脚为LOW(GND);向下计数时,比较匹配中的OC1引脚为HIGH(VCC)。在反相模式下,向上计数时,在TCNT1和OCR1A / OCR1B之间的比较匹配时,OC2引脚为HIGH(VCC);在向下计数时,在比较匹配中,OC2引脚为LOW(GND)。建议将此模式用于电动机控制。相位校正PWM的频率可以通过以下公式计算:PWM_frequency =时钟速度/(2 *预分频器值* TOP_value)
相位和频率校正PWM模式:如果我们不打算在PWM模式启动后改变TOP值,则相位校正和相位和频率校正PWM模式的功能相同。我可以在数据表上看到的唯一区别是,相位和频率校正模式在击中底部时会更新其TOP值,而相位校正模式在击中TOP时会更新其TOP值。建议将此模式用于电动机控制。相位和频率校正PWM的频率可以通过以下公式计算。
ATmeg8A可用16M驱动PWM,12bit时频率3.9故K需多阶滤波。外加DAC122S085是廉价2CH 12bit DAC,内部非线性+-8bit;DAC7562的非线性可忽略。
QFP32有24端口:晶振2/串口2/DA2/AD3/旋转3/触摸4/LCD4+6,共23;只好用串口LCD,余下线可做键盘/蜂鸣/风扇。复用的方法见下节。
引出脚在44页,SFR 115页。系列:https://en.wikipedia.org/wiki/C8051 https://www.silabs.com/development-tools/mcu/8-bit/8-bit-usb-debug-adapter Keil: https://www.keil.com/dd/chip/4111.htm KEIL5注册机2032.平民链接:https://pan.baidu.com/s/1FyWCAWoRQ4ZEtFOCchABKA 提取码:bqlg 官网免费开发包无debug:https://www.silabs.com/community/mcu/8-bit/forum.topic.html/free_unlimited_keil-27dh
8051 multi task core 利用了KEIL编译器的智能,不保留寄存器。通常不能超过7个任务。https://www.amobbs.com/thread-1398508-1-1.html 这个需要用户在多点插入task_switch()做手动调度,例如LCD更新函数执行时间长可插入多次。https://cloud.tencent.com/developer/article/1692862 这个定时调度。每个任务执行后重装延时tick,task0有最高优先级。当然也可以用KEIL RTX51 Tiny,开源的在KEILC51RTXTINY2下。
TB价3.5元。LQFP32封装,F410/2-GQ分别为32K/16KROM,均有2K+64BRT时钟存贮器。2CH ADA,A/D为200K,D/A为电流输出型0.25/0.5/1/2mA。内置基准2.2V精度不错,内置稳压REG0可输出2.1/2.5V并为内核供电,VIO接相应外设的电压3.3V或5V。内置温度传感(+-3C),开发有Silicon Lab的UDA使用JTAG。只有一脚地线,手册最小SNR为 66dB,有效位ENOB = (SNR-1.76)/6.02 = (66-1.76)/6.02 = 10.67bit。
* 高速、流水线结构的8051兼容的微控制器核(50M时钟可达50MIPS)* 全速片内系统调试接口 * 真12位200 ksps的24通道ADC * 两个12位电流输出DAC * 2%精度可编程的24.5MHz内部振荡器 * 16/32KB的片内FLASH存储器* 2304字节片内RAM * 硬件实现的SMBus/ I2C、增强型UART和增强型SPI串行接口 * 4个通用的16位定时器 * 具有6个捕捉/比较模块和看门狗定时器功能的可编程计数器/定时器阵列(PCA)* 硬件实时时钟(smaRTClock),工作电压可低至1V,带64字节电池后备RAM和后备稳压器 * 硬件CRC引擎 * 片内上电复位、VDD监视器和温度传感器 * 片内电压比较器 * 多达24个端口I/O
FLASH存储器可现场按512B分片编程,用于数据存储或固件更新。软件可以关断任一或所有外设以节省功耗。C2开发接口允许使用安装在最终应用系统上的产品MCU进行全速在系统调试,不占用片内资源。调试逻辑支持观察和修改存储器和寄存器,支持断点、单步、运行和停机命令。MCU暂停期间,所有外设(ADC和SMBus除外)均处于停止状态
步进或在断点处保持同步。两个C2引脚可以与用户功能共享,使在系统调试功能不占用封装引脚。每种器件都可在工业温度范围(-40℃到+85℃)内用2.0V ~ 2.75V的电压工作。C8051F41x-GQ为LQFP32封装。
同于8051程序和数据地址配置:256B RAM,低128B可直接/间接寻址,其中LSB32是四套GPR通用寄存器,次16B可位寻址。高128 B地址为两块RAM共享,SFR特殊功能寄存器是直接访问,128B RAM则间接寻址。 剩下的2KB XRAM用movx指令访问。程序存储器包含32/16kB Flash可以512B扇区重新编程,且不需要片外编程电压。
用它的唯一理由是片内ADA。Vref可选内/外基准或Vdd,可选输出(200uA)。A/D可由软件,C/T2-3或外部触发,通道包括Vdd/Gnd/片内温度探头。ADC的时钟FCLK最大为25M,而变换时钟SAR clock为3M,最大频率为200K,每次变换前需等待的时间称为Tracking,有3种模式,以post tracking后硬件定时较为方便。突发模式做1/4/8/16次转换,前后都是低功耗。输出12bit可选左或右对齐,突发>1时必须选右对齐,因为输出的是和数。 转换结束时AD0INT置1,可产生中断或查询它。窗口检测可用于只在需要时才介入调整,避免可控电源输出振荡的现象。ADC需偏置/满度校准。D/A用内部基准源,允许无缝的满量程更改并支持波形生成的无抖动更新; 更新在定时器溢出时或与外部信号同步;输出分别由IDA?EN控制,IDAMRG置位可将IDA1合并到IDA0;内部非线性可达10bit。两个带有多路开关的电压比较器,均可提供可编程的响应时间和迟滞(+-18mV),可选同步锁存CP0/1或异步CP0/1A输出;可用CNVSTR的上升/下降或双沿中断来更新,可唤醒处理器或将其复位(CP0),数据可选左右对齐,注意外接脚需配置为模拟输入。CRC0支持CRC-16/32有硬件位反。REG0接受VREGIN引脚最高5.25V的输入,输出可选2.1/2.5V(Vref=1.5/2.2V也可以输出)并驱动VDD引脚,电流最多50mA。smaRTClock的32 kHz振荡器可选用晶体,警报和时钟丢失会中断CIP-51,可唤醒处理器或由其定时器或停振产生复位。备用电源VRTC-BACKUP需1V以上。
三个8bit端口,每bit均可配置为DIO/AIO,DIO可为推挽或漏极开路操,可配置全局的弱上拉,DO可输出/吸收100mA或总共500mA。有一个矩阵开关Crossbar可将内部资源入C/T、串口、中断源、PCA0等映射到端口I / O引脚。内部振荡器校准为24.5 MHz±2%,外部可接时钟源/晶体/陶瓷/电容或RC。系统时钟SYSCLK最高50M,可由内外部或smaRTClock通过x4和除2^n(n=0~6)的倍频器产生,见P175,内部振荡最大频率25M,外接不能超出此值。2.5V时核心耗电最大10/15mA(25/50M)。
堆栈指针SP初始化时指向RAM 0x07,压栈时(++SP)将使第一个数据存在0x08,这也是寄存器组1的R0。因此需要初始化SP指向256B RAM中的空余位置。 MOVC和MOVX可读取闪存,使其用于数据存储,也可在线更新程序;也可C2接口编程。闪存重新编程之前通常会被擦除(复原为0xFF),擦除和写入操作由硬件自动定时,不需要查询,但在此期间暂停代码执行,且片上VDD监视器需设置为最高(VDMLVL=1),同时启用VDD监视器并作为复位源。闪存的写入和擦除受到锁钥的保护,必须按顺序正确写入密钥寄存器FLKEY的关键代码0xA5、0xF1。闪存的读出按最大25M时钟设计。详见第16章。
2KB XRAM的访问可用MOVX指令及@DPTR指针,此时高5位地址无关,故不用担心地址溢出;或MOVX间接寻址模式例如@ R1,此时EMI0CN给出高八位地址。存储器类型:
code-MOVC @A+DPTR 8~32KB Flash;data-直接访问的128B;idata-间接访问的256B; bdata-可按位访问的16B;pdata-MOVX @Rn访问的XRAM的低256B;xdata-MOVX @DPTR访问的1~2KB; far-64KB地址外的外接存储器。
端口电源电压经VIO加入,P1/P2端口电压不可超过VIO,P0可以超过但以5 V为限。 I/O配置有优先级的。
有4个C/T:2个标准8051 16bitC/T0-1,2个16bit 16位自动重载定时器T2-3。C/T0-1的模式0/1是13/16bit,2/3是双8bit,但模式2有自动装载,C/T1无模式3。T2-3是16bit或双8bit自动装载。C/T0-1可由系统时钟除4/12/48或外部时钟/8提供。C/T2-3可由系统时钟除1/12或外部时钟/8提供。C/T0-1用作计数器时在T0/T1的下降沿递增,输入可达SYSCLK/4,必须保持两个SYSCLK周期。
可编程计数器阵列(PCA0)提供了增强的计时器功能,其中的16bitC/T可选7个时钟源:系统时钟或除以4/12、外部源或实时时钟源除以8,定时器0溢出或ECI引脚。C/T内容与6个16位捕获/比较器C/C作用后,经交叉开关Crossbar去I/O端口。C/C有6个模式:EdgeTrigger捕获到PCA0CPxn中并设置CCFn;软件定时器则是与PCA0CPxn比较并设置CCFn;高速输出则是再上述比较匹配时将CEXn脚反转;频率输出产生可编频率的方波;8位PWM或16位PWM,模块5可做WDT。6个C/C各自的溢出位CF均可触发PCAINT,但无论中断与否需由软件清除。
8bit PWM每个模块均可独立使用,占空比由PCA0CPHn改变。 当PCAPCA0L等于PCA0CPLn时, CEXn脚被置位;PCA0L溢出时将复位,PCA0CPLn会自动加载PCA0CPHn。PCA0CPMn寄存器中的ECOMn和PWMn位置1 使能8位脉冲宽度调制器模式。PCA0CPHn = 0时占空比为100%,0xFF时为 0.39%,ECOMn清零可为0%。
16bi PWM模式下,当PCA计数器匹配时C/C模块内容时,CEXn输出为高;当计数器溢出时为低。将PCA0CPMn中的ECOMn,PWMn和PWM16n位置1使能16位PWM模式。要改变占空比,应启用匹配中断(ECCFn = 1 AND MATn = 1),在中断中写入新值。PCA0CPn = 0占空比为100%,FFFF时为 0.0015%,将ECOMn位清零为0%。48M下12bit PWM约11.7K,滤波相对容易;此时串口可达115.2K:https://www.keil.com/products/c51/baudrate.asp 不过22.1184M更精确。
看门狗定时器在复位时启用,将PCA0MD的WDTE清零可以禁止它。启用时,某些PCA0H/L等寄存器不能写入;当PCA0CPH5与PCA0H匹配时产生复位,当PCA0CPH5被更新时实际的写入值是PCA0H+PCA0CPL5。
QFP32有24端口:晶振2/串口2/DA2/AD3+Vref/旋转3/触摸4/LCD4+6,共23-24;方案1用串口LCD,余下线可做键盘/蜂鸣/风扇。方案2加用LC244片选输入即/LCDCS=InDis后,8线为LCD8输出与旋转3i/触摸2/按键3输入,晶振2/串口2/DA2/AD3+Vref/LCD1+8(RD不用)/触摸2=20-21,再加蜂鸣/风扇。可用A/D检测多个输入。
编程可借鉴带LCD12864和旋转编码器的8051源码:https://www.dianyuan.com/bbs/2445390.html
官网IDE:https://www.silabs.com/developers/8-bit-8051-microcontroller-software-studio 开发板50刀https://www.silabs.com/documents/public/user-guides/C8051F41x-DK.pdf,USB盒35刀,可用Keil:https://www.silabs.com/documents/public/application-notes/an104.pdf 及用官网烧写软件:https://www.silabs.com/developers/8-bit-8051-microcontroller-software-studio 另文说点击μVision的"Debug -> Start/Stop Debug Session"即可。
Use Arduino 烧写(只限)AT89S51/2: https://www.instructables.com/How-to-Program-8051-Using-Arduino/ 将Uno的pin10-13接89C51/52的Rst/MOSI/MISO/SCK及电源,Uno插入USB即加电,其+5V接入805x的EA脚;启动Arduino IDE,选Files|Examples|Arduino ISP,选Tools|Board|Arduino Uno,选好串口;下载本链接给的AVR8051.conf文件,在cmd窗口执行下述命令(89s52/1需取其一):"C:Program Files (x86)Arduinohardwaretoolsavrbinavrdude.exe" -C C:/AVR8051.conf -c stk500v1 -P COM5 -p 89s52/1 -b 19200 -U flash:w:"c:mycode.hex"。ISP倒有源码:https://github.com/arduino/ArduinoISP
2.1 C8051F30x
QFN11/SOIC14, 8bit I/O,25M,8bit 带增益可设运放A/D,C/T0-1,T2,PCA0,小板2刀。PCB正反印字指明接脚。
3. 外设
3.1 电阻触摸屏
电阻触摸屏4线是:xp/yp为A/D,xm/ym为DO。测X坐标时,xp-xm分别为Vcc-Gnd,yp三态,由ym A/D读出X向的由笔点下导致的分压Vx;测Y坐标时,yp-ym分别为Vcc-Gnd,xp三态,由xm A/D读出X向的由笔点下导致的分压Vy。测Z时,ym-xp为Vcc-Gnd,z=f(yp,xm,x) 算法详见Arduino库及https://www.ti.com/lit/ds/symlink/tsc2046.pdf的公式3。初次使用前需校准,先点击读出左上脚,再右下角,将相应Xmin/Xmax/Ymin/Ymax改变驱动程序中的值。例如10bit A/D得到的实际范围值可能是110-910。
https://blog.csdn.net/Linux_ARM9/article/details/104830868 http://www.51touch.com/technology/multitouch/2012/0224/14091.html
3.2 显示屏
3.2.1 LCD1602/2004
HD44780 https://www.arduino.cc/en/Tutorial/LibraryExamples/LiquidCrystalDisplay? 6线,R/W接地。https://create.arduino.cc/projecthub/electropeak/using-1602-lcd-keypad-shield-w-arduino-w-examples-e02d95 带Sel,上下左右及Rst键。有I2C版或加PCF8574x即得。
3.2.2 LCD 196x64 LM6071/2
https://www.topwaydisplay.com/product/mono/LM6071CFW 100x60x10.8mm 4/12线接口。
2.3.2 2.4"TFT触摸屏
常见两种芯片:ILI9341和SPFD5408,可用4线串口或4+8线并口。
SPFD5408a: Ali上最便宜的,库:https://www.instructables.com/How-to-use-24-inch-TFT-LCD-SPFD5408-with-Arduino-U/
ILI9341: https://create.arduino.cc/projecthub/calogerus/arduino-uno-2-4-tft-lcd-display-shield-touch-panel-ili9341-576b1b https://create.arduino.cc/projecthub/electropeak/arduino-2-4-touch-screen-lcd-shield-tutorial-fe6f05 D0-7 to Arduino Pin2-8, RST/CS/RS(D/C)/WR/RD to pin A4-A0. RST线可选。先写命令(RS=0)再读写数据。触摸屏用pin8/9/A2/A3(YM/XP/YP/XM),因此不能同时访问。该片也支持3-4线串口SS/SDI/SDO/SCK:https://create.arduino.cc/projecthub/techarea98/graphics-test-ili9341-tft-lcd-spi-display-78e1c3
2.4" touch: https://www.ebay.com/itm/2-4-TFT-LCD-Display-Shield-Touch-Panel-ILI9341-240X320-for-Arduino-UNO-R3-C/233591453475 软件:https://create.arduino.cc/projecthub/electropeak/arduino-2-4-touch-screen-lcd-shield-tutorial-fe6f05
3.4 旋转编码器
一排5脚的依次是Gn'd/Vcc/开关/ondutB/outA。国产EC11为A/G/B及开关,寿命8万次;消抖不小于5ms,可上拉10K//10n;脉冲数有15/20两种。顺时钟AB=01-00-10-11,逆时钟是01-11-10-00。半译码可以用下沿中断A,若B为1是顺时钟。全译码可再加下沿中断B,若A为0是顺时钟;或上下沿中断A,若A!=B为顺时钟;或四状态机如下。
int counter;
bool prevA = 1, prevB = 1;
void loop() {
bool A = digitalRead(pin_rotaryA), B = digitalRead(pin_rotaryB);
if (B != prevB)
counter += (B - prevB) * (A ? +1 : -1);
else if (A != prevA)
counter += (A - prevA) * (B ? -1 : +1);
else
return; //nothing changed: exit
prevA = A;
prevB = B;
Serial.println(counter);
}
3.5 数字电位器/模拟开关
MCP44* lib: https://github.com/sapher/MCP42xxx-Arduino-Library 注意42xx不支持菊花链但价格减半,42xxx也不能直接用库函数。每片数据+命令为16bit,因加电后初始化0,SO先输出的16bit总是0。若菊花链有3片,需先写入最远一片的16bit,总计48bit后将/cs拉起。如果只需要编程第2片,可以只写32bit并将第1片的C1C0写0即命令无效。AD5204/6内封4/6个pot电流可达+-11mA,MCP仅1mA。I2C接口的多片不是问题,但在M8上要占用A/D线,暂且忽略。
https://category.alldatasheet.com/index.jsp?components=SINGLE-POLE,DOUBLE-THROW 不超过5V,低阻典型0.5ohm不大于1ohm。https://www.kynix.com/Detail/785281/74LVC1G3157DBVR.html
4. 编程
Arduino创建项目:https://blog.csdn.net/u010918541/article/details/50496242
Arduino用于STM32:https://blog.csdn.net/qq_36338040/article/details/79201281
The base source are in the Arduino installation, under cores/arduino/.
Source for additional libraries included are in libraries/.
4.1 Arduino下的多任务
RTOS https://www.arduino.cc/reference/en/libraries/freertos/
4.1.1 使用millis():这是非堵塞的50天后才溢出的计数器,即1ms定时中断来更新U32。程序读出更新值并与旧存贮值比较来执行某功能:
unsigned long previousMillis1 = 0;
void loop() {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis1 >= OnTime1) {
previousMillis1 = currentMillis;
//do sth
}
可以用许多if{}来完成不同任务。也可用定时中断扩展成不同时间片,时间片内既可完成开销小的任务,也可设置标志让在主循环中检测执行。
4.1.2 使用库函数 Scheduler
https://github.com/arduino-libraries/Scheduler 限于Arduino SAM Boards (32-bit ARM Cortex-M3) 或 SAMD
#include
int counter = 0;
int counter1 = 0;
void setup()
{
Serial.begin(9600);
Scheduler.startLoop(loop1);
}
void loop () {
analogWrite(9, counter);
counter++;
if (counter > 255){
counter = 0;
}
delay(33);
}
void loop1 () {
if (Serial.available()) {
char c = Serial.read();
if (c=='0') {
digitalWrite(2, LOW);
Serial.println("Led turned off!");
}
if (c=='1') {
digitalWrite(2, HIGH);
Serial.println("Led turned on!");
}
}
yield();
}
4.2 80x51 KEIL下的多任务
无需保护R0-7。TCB含任务入口、SP和(等待)状态。main()初始化所有任务,然后跳转到task0。 每个任务都是死循环,在结束时调用os_delay。os_delay更新任务状态然后跳至os_idle。 os_idle检查任务状态以决定运行新任务与否。定时中断更新各任务状态。因80x52内存小,任务总数建议4~6个,用私有栈。
Michael J.Pond 2009: 书中有一个合作式的多任务核,堆栈是共享的。定时中断更新任务等待时间,主循环中的调度器通过函数指针调用任务或休眠等待中断。运行的任务不能被调度,需要自己让步不至超时。
5. 扩展
I2C 16bit I/O:PI4IOE5V6416LEX
8CH12bit A/D:TLA2518(SPI 1M)/28(I2C 140K)
4CH12bit D/A: MCP4728线性差
6. DIY计算器
http://www.51hei.com/bbs/dpj-183859-1.html http://www.51hei.com/bbs/dpj-48762-1.html
7. 电子秤
最全含仿真:https://blog.csdn.net/weixin_39553705/article/details/110235062? https://download.csdn.net/download/qq_45658684/15311497?spm=1001.2101.3001.5697
https://item.taobao.com/item.htm?id=646522090761 仿真:https://blog.csdn.net/a_huan258147/article/details/113570283? https://blog.csdn.net/weixin_39553705/article/details/110235062? 布线:https://blog.csdn.net/weixin_44830487/article/details/115792671? https://blog.csdn.net/x1131230123/article/details/116357658