avr汇编百例 晋级篇 参考程序
- 格式:docx
- 大小:81.76 KB
- 文档页数:30
(-2K 28KB)(-2K 28KB) 执行同功能的程序 8MHzAVR 224MHz C5不再有作废的产品; 不需要5分钟的紫外线擦除时间;再也用不着因为掩模而无法入睡了;没有10周订货交货时间; 添加新特性易如反掌;容易调试;容易在线升级,几秒钟搞定;AVR指令表2000/5耿德根编数据传送指令位指令和位测试指令MOV Rd,Rr寄存器拷贝LSL Rd逻辑左移LDI Rd,K装入立即数LSR Rd逻辑右移LDS Rd,K直接从SRAM装入ROL Rd通过进位左循环LD Rd,X X变址间接装入R ROR Rd通过进位右循环LD Rd,X+X变址ASR Rd算术右移LD Rd,-X X变址SWAP s半字节交换LD Rd,Y Y变址BSET s置状态寄存器的位LD Rd,Y+Y变址BCLR s SREG中的位清除LD Rd,-Y Y变址SBI P,b置I/O寄存器的位LDD Rd,Y+q Y变址间接装入R CBI P,b清I/O寄存器的位LD Rd,Z Z变址BST Rr,b R中位到SREG中T标志LD Rd,Z+Z变址BLD Rd,b SREG中T标志到R某位LD Rd,-Z Z变址SEC置位进位标志LDD Rd,Z+q Z变址CLC清除进位标志STS K,Rr R数据直接送SRAM SEN置位负数标志ST X,Rr X变址间接装入SRAM CLN清除负数标志ST X+,Rr X变址SEZ置位零标志ST-X,Rr X变址CLZ清零标志位ST Y,Rr Y变址SEI置位全局中断标志ST Y+,Rr Y变址CLI清除全局中断标志ST-Y,Rr Y变址SES置位符号标志STD Y+q,Rr变址间接装入SRAM CLS清除符号标志ST Z,Rr Z变址SEV置位溢出标志位ST Z+,Rr Z变址CLV清除溢出标志ST-Z,Rr Z变址SET置位T标志STD Z+q,Rr Z变址CLT清除T标志LPM装入程序存储器SEH置位半进位标志IN Rd,P I/O口数据装入到R CLH清除半进位标志OUT P,Rr寄存器数据送I/O口NOP空操作PUSH Rr压寄存器到堆栈SLEEP休眠POP Rd堆栈弹出到寄存器WDR看门狗复位汇编器伪指令(伪指令前必须加“ ..” ).BYTE-- 保存寄节到变量.CSEG-- 代码段.DB-- 字节常数.EXIT-- 退出文件.DEF-- 设置寄存器的符号名.INCLUDE--包括号外的文件.DEVICE--定义被汇编的器件.LIST-- 打开列表文件生成器.DSEG-- 数据段.LISTMAC--打开宏表达式.DW-- 字常数.MACR O-- 宏开始.ENDMACRO--宏结束.NOLIST-- 关闭列表文件生成器.EQU-- 设置符号相等于一个表达式.ORG-- 设置程序起始位置.ESEG-- EPROM段.SET-- 设置一个与表达式相等的符号A VR ICE200在线仿真器双龙电子为中国大陆总代理ICE200可仿真的器件为A T90S1200/2313/2333/4433/4414/8515/4434/8535及A Ttiny10/11/12由于仿真器的电源不对外所以ICE200也支持低电压器件A T90S I/O空间定义十六进制地址名称AT90SMEG103名称AT90S1200名称AT90S8515功能(对应8515名称,*为对应MEG103)$3F($5F)SREG SREG SREG状态寄存器$3E($5E)SPH SPH堆栈指针高$3D($5D)SPL SPL堆栈指针低$3C($5C)XDIV XTAL分频控制器 *$3B($5B)RAMPZ GIMSK GIMSK通用中断屏蔽寄存器$3A($5A)EICR GIFR通用中断标态寄存器$39($59)EIMSK TIMSK TIMSK定时器/计数器中断屏敝寄存器$38($58)EIFR TIFR TIFR定时器/计数器中断标志寄存器$37($57)TIMSK定时器/计数器中断屏敝寄存器 * $36($56)TIFR定时器/计数器中断标志寄存器 * $35($55)MCUCR MCUCR MCUCR MCU通用控制寄存器$34($54)MCUSR MCU通用控制寄存器 *$33($53)TCCR0TCCR0TCCR0定时器/计数器0控制寄存器$32($52)TCNT0TCNT0TCNT0定时器/计数器0(8位)$31($51)OCR0定时器/计数器0输出比较寄存器 * $30($50)ASSR异步方式状态寄存器 *$2F($4F)TCCR1A TCCR1A定时器/计数器1控制寄存器A$2E($4E)TCCR1B TCCR1B定时器/计数器1控制寄存器B$2D($4D)TCNT1H TCNT1H定时器/计数器1高字节$2C($4C)TCNT1L TCNT1L定时器/计数器1低字节$2B($4B)OCR1AH OCR1AH定时器/计数器1输出比较寄存器A高字节$2A($4A)OCR1AL OCR1AL定时器/计数器1输出比较寄存器A低字节$29($49)OCR1BH OCR1BH定时器/计数器1输出比较寄存器B高字节$28($48)OCR1BL OCR1BL定时器/计数器1输出比较寄存器B低字节$27($47)ICR1H定时器/计数器1输入捕获寄存器高字节 * $26($46)ICR1L定时器/计数器1输入捕获寄存器低字节 * $25($45)TCCR2ICR1H T/C1输入捕获寄存器高字节$24($44)TCNT2ICR1L T/C1输入捕获寄存器低字节$23($43)OCR2定时器/计数器2输出比较寄存器 * $22($42)$21($41)WDTCR WDTCR WDTCR看门狗定时控制寄存器$20($40)$1F($3F)EEARH EEARH EPROM地址寄存器高字节$1E($3E)EEARL EEAR EEARL EPROM地址寄存器低字节$1D($3D)EEDR EEDR EEDR EPROM数据寄存器$1C($3C)EECR EECR EECR EPROM控制寄存器$1B($3B)PORTA PORTA A口数据寄存器$1A($3A)DDRA DDRA A口数据方向寄存器$19($39)PINA PINA A口输入脚$18($38)PORTB PORTB PORTB B口数据寄存器$17($37)DDRB DDRB DDRB B口数据方向寄存器$16($36)PINB PINB PINB B口输入脚$15($35)PORTC PORTC C口数据寄存器$14($34)ODRC C口数据方向寄存器$13($33)PINC C口输入脚$12($32)P0RTD PORTD PORTD D口数据寄存器$11($31)DDRD DDRD DDRD D口数据方向寄存器$10($30)PIND PIND PIND D口输入脚$0F($2F)SPOR SPOR SPI I/O数据寄存器$0E($2E)SPSR SPSR SPI状态寄存器$0D($2D)SPCR SPCR SPI控制寄存器$0C($2C)UDR UDR UART I/O数据寄存器$0B($2B)USR USR UART状态寄存器$0A($2A)UCR UCR UART控制寄存器$09($29)UBRR UBRR UART波特率寄存器$08($28)ACSR ACSR ACSR模拟比较控制和状态寄存器$07($27)ADMUX ADC多路选择寄存器 *$06($26)ADCSR ADC状态和控制寄存器 *$05($25)ADCH ADC数据寄存器高 *$04($24)ADCL ADC数据寄存器低 *$03($23)PORIE E口数据寄存器 *$02($22)DDRE E口数据方向寄存器 *$01($21)PINE E口输入脚 *$00($20)PINF F口输入脚 *复位和中断向量向量号程序地址源源中断定义1$000/RESET/RESET硬件脚和看门狗复位2$001INT0INT0外部中断请求03$002INT1INT1外部中断请求14$003TIMER1 CAPT TIMER1 CAPT定时器/计数器1捕获事件5$004TIMER1 COMPA TIMER1 COMPA定时器/计数器1比较匹配A6$005TIMER1 COMPB TIMER1 COMPB定时器/计数器1比较匹配B7$006TIMER1 OVF TIMER1 OVF定时器/计数器1溢出8$007TIMER0 OVF TIMER0 OVF定时器/计数器0溢出9$008SPI,STC SPI,STC串行传送完成10$009UART,RX UART,RX UART,RX完成11$00A UART,UDRE UART,UDRE UART数据寄存器空12$00B UART,TX UART,TX UART,TX完成13$00C ANA_COMP ANA_COMP模拟比较器OK-AVR万用串行下载开发实验板OK-AVR万用串行下载开发实验板,采用双龙电子公司的专利技术(专利号:98226094.6),是为ATMEL公司的AVR单片机特别研制的廉价的万用串行下载开发实验工具该板适用于ATMEL公司所有具有串行下载功能的AVR单片机,同时还可做AVR单片机的I/O口A/D D/A音频输出等实验本公司随机提供了ATMEL的集成模拟仿真调试软件,对初学AVR 单片机的设计者,可暂时节省购买较昂贵的实时仿真器及万用编程器的费用; OK-AVR万用串行下载开发实验板有CZ1电源及通讯下载用插座,LED电源指示,下载通讯工作指示;附AVR单片机8根下载信号线; AVR单片机四种DIP封装器件下载锁紧插座;WR划线电位器可作为模拟信号输入用,有音响器,另有用户器件扩展区,焊接你实验需要的器件;AVR集成软件包包括: AVR Assembler 1.30编译器; AVR Studio 3.00; AVR Prog;送一片AT90S1200单片机及集成软件AVR单片机数据资料OK-AVR下载开发实验板使用说明等光盘AVR单片机可下载器件:90S120090S231390S2323/90LS232390S2343/90LS234390S2333/90LS233390S4433/90LS443390S441490LS851590S4434/90LS443490S8535/90LS853590S8555ATtiny10/11/12/15MEGA103/603/161/163(适用所有串行下载信号线的AVR单片机)。
;范例19 ;等步距线性内插计算子程序.EQU TBLGTH=10CHETA: LDI R16,TBLGTH-1 ;r16<--表长(即字数)-1LDI R31,HIGH(chtbl*2);y0(函数初值)在r14r15,STEP(步长)在r10r11,自变量X 在r12r13LDI R30,LOW(chtbl*2+1);查表指针,首指数据表第1字之高位字节!RCALL CPMR1 ;X与表中第一个字型数据(X0)比较BRCC CHRET ;X<X0 查表结束,Y=Y0CHET1: RCALL CMPR1 ;X与表中下一个数据比较BRCC NX33 ;X<X(i+1) 找到插值区间ADD R15,R11 ;否则Y0中加入一个STEP:Yk=Y0+k*step(步距为负时则;减去|STEP|)ADC R14,R10DEC R16BRNE CHET1 ;未查到表格终值,循环;否则结束,Y取得最大值Yn CHRET: RETNX33: SBIW R30,5 ;指针退回(-5),指向XiMOV R8,R14MOV R9,R15 ;保存Y0+i*STEPRCALL SUBS ;(X-Xi)-->r16r17MOV R15,R17MOV R14,R16 ;转入r14r15RCALL MUL16 ;(X-Xi)*STEP-->r12r13r14r15MOV R10,R12MOV R11,R13 ;保存乘积高位字LPM ;X(i+1)低位字节MOV R13,R0ADIW R30,1LPM ;X(i+1)高位字节MOV R12,R0SBIW R30,3 ;指针指向XiRCALL SUBS ;X(i+1)-Xi-->r16r17MOV R12,R10MOV R13,R11 ;取回乘积高位字MOV R10,R16MOV R11,R17 ;X(i+1)-Xi-->r10r11RCALL DIV165 ;(X-Xi)*STEP/[X(i+1)-Xi]-->r14r15ADD R15,R9ADC R14,R8 ;Y0+i*STEP+(X-Xi)*STEP/[X(i+1)-Xi]-->r14r15RET ;若STEP为负值则改为计算(r8r9)减去(r14r15)之值CMPR1: LPM ;取数据高位字节ADIW R30,2 ;指向下一数据的高位字节CP R0,R12 ;与X高位字节相比较BRNE CPRT1 ;不相等即转出SBIW R30,3 ;否则调整指针LPM ;取数据低位字节ADIW R30,3 ;指向下一数据的高位字节CP R0,R13 ;与X低位字节相比较CPRT1: RET ;以进位C带回比较结果SUBS: LPM ;计算(X-Xi)或[X(i+1)-Xi]并送入r16r17MOV R5,R0 ;取Xi低位字节ADIW R30,1LPM ;取Xi高位字节SBIW R30,1 ;仍指向Xi低位字节SUB R13,R5MOV R17,R13SBC R12,R0MOV R16,R12 ;计算差并将其转入R16R17RET;自变量x表长为12字CHTBL:DW 19214,23404,27600,32799,37009,40211,45414,48618,51821,55029,57787,60070 ;步距表长为11字STEPT: DW 356,366,379,395,415,440,471,509,555,603,657;不等步距线性内插计算子程序,步距表首址在R6R7中;自变量X在R12R13之中,函数初值Y0在R14R15中;范例20 ;表长(字个数)-1在R16中CHTSTP: LDI R31,HIGH(chtbl*2)LDI R30,LOW(chtbl*2+1);查表指针LDI R16,LOW(stept*2)MOV R7,R16LDI R16,HIGH(stept*2)MOV R6,R16 ;步距表指针LDI R16,TBLGTH-1 ;r16<--表长(字个数)-1RCALL CMPR1 ;X与表首数据比较BRCC CHSTPT ;X<X0 查表结束,有Y=Y0CHSTP1: RCALL CMPR1 ;否则与表中下一数据比较BRCC CHSTP3 ;X<X(i+1),找到插值区间!RCALL GTSTP ;查表取STEP字型变量ADD R15,R11 ;Y0<--Y0+STEPkADC R14,R10DEC R16BRNE CHSTP1 ;未查到表格终值循环;否则结束,Y取得最大值Yn CHSTPT: RETCHSTP3: SBIW R30,5 ;指针退回,指向Xi低位字节MOV R8,R14MOV R9,R15 ;Y0+∑STEPk送入r14 r15RCALL SUBS ;(X-Xi)->r16r17MOV R14,R16 ;(X-Xi)转入R14R15RCALL GTSTP ;查表取STEPi-->R10R11RCALL MUL16 ;(X-Xi)*STEPi-->R12R13R14R15MOV R10,R12MOV R11,R13 ;保存积高位字LPMMOV R13,R0ADIW R30,1LPMMOV R12,R0SBIW R30,3RCALL SUBS ;(X(i+1)-Xi)-->r16 r17MOV R12,R10MOV R13,R11MOV R10,R16MOV R11,R17 ;取回积高位字&(X(i+1)-Xi)-->r10r11RCALL DIV165 ;(X-Xi)*STEPi/[X(i+1)-Xi]-->r14r15ADD R15,R9 ;ADC R14,R8 ;Y0+∑STEPk+(X-Xi)*STEPi/[X(i+1)-Xi]-->r14r15 RETGTSTP: MOV R5,R6 ;查取STEP字型变量/POINTER in r6r7!MOV R6,R30MOV R30,R5MOV R5,R7MOV R7,R31MOV R31,R5 ;(r6r7)<-->ZLPMMOV R11,R0ADIW R30,1LPMMOV R10,R0 ;STEPk取到r10r11ADIW R30,1MOV R5,R6MOV R6,R30MOV R30,R5MOV R5,R7MOV R7,R31MOV R31,R5 ;指针增2后送回r6r7RET;范例21 ;功能表程序FUNC2: LDS R16,$A3 ;use r0,r8,r9,r10,r11,r16&r17/& subprogram dspa SBR R16,$80 ;功能表程序标志LDI YH,2LDI YL,0 ;功能内容表SRAM地址RCALL FLFUNC ;CLR r27!LDI R16,2ST X,R16 ;显示'FUNC.2'RCALL DL2SCLR R9 ;功能内容寻址偏移量R9!CLR R8 ;功能名称寻址偏移量(R8)=(r9)*3FFUNC0: RCALL DSF_ ;显示'F- 'FF0: RCALL DSPA ;in subprogram dspy clr. r27!CPI R16,11 ;回车键按下?BRNE FF2PFF0C: RCALL COMBNO ;合成功能名称送入r16 CPI R16,20 ;是最后一个功能名称?BRNE FF1CLR R9 ;是,两偏移量初始化!CLR R8FF1: LDI ZH,HIGH(FTABL*2)LDI ZL,LOW(FTABL*2);功能名称表指针ADD ZL,R8ADC ZH,R27 ;(r27)=0 ALWAYSLPMMOV R16,R0RCALL BRA3A ;分解新功能名称到$6E/$6FFF0G: LDI R28,0ADD R28,R9 ;功能内容指针加偏移量LD R16,YLDI R26,$72RCALL BRAX ;将新功能内容分解到$72/$73FF0A: RCALL DSPA ;显示新功能名称/内容CPI R16,11BRNE FF0B ;回车键按下?INC R8INC R8INC R8 ;是,功能名称寻址偏移量加3INC R9 ;功能内容寻址偏移量加1RJMP FF0C ;转回FF2P: RJMP FF2FF0B: CPI R16,10BRNE FF0DRCALL DSF_ ;清除键按下,清除显示区后,显示‘F-’FF1B: RCALL DSPACPI R16,11BREQ FF1 ;转恢复当前显示CPI R16,10BRCC FF1BRJMP FF2D ;只有数字键按下才转出去处理FF0D: CPI R16,10BRCC FF0AFF1D: LDI R17,$24 ;STS $73,R17 ;数字键处理,先在缓存区内放一空白FF0E: LDS R17,$73STS $72,R17 ;键入数字左移STS $73,R16 ;存入新数字FF0F: RCALL DSPACPI R16,10BREQ FF0G ;清除键按下,恢复显示旧功能内容BRCS FF0E ;键入数字左移更新CPI R16,11BRNE FF0FLDS R26,$72 ;回车键按下RCALL COMBA ;合成新功能内容(combin $72&$73 into binary(r16)) MOV R17,R8INC R17LDI ZH,HIGH(FTABL*2)LDI ZL,LOW(FTABL*2)ADD ZL,R17 ;取当前功能内容下限ADC ZH,R27FF1F: LPMCP R16,R0BRCS DSER2 ;新功能内容小于下限,错误INC R17LDI ZH,HIGH(FTABL*2)LDI ZL,LOW(FTABL*2)ADD ZL,R17 ;取当前功能内容上限ADC ZH,R27LPMCP R0,R16BRCS DSER3 ;新功能内容大于上限,错误FF7: LDI R28,0ADD R28,R9 ;功能内容表首地址为$200!ST Y,R16 ;合法的新功能内容进入功能内容表INC R9INC R8INC R8INC R8 ;调整偏移量,进入下一个功能显示RJMP FF0CFF1P: RJMP FF1DSER2: RCALL FERR2 ;显示'F Err.2'2秒RCALL EXCH0RJMP FF0G ;恢复原数据显示DSER3: RCALL FERR3 ;显示'F Err.3'2秒RCALL EXCH0RJMP FF0G ;恢复原数据显示FF2: CPI R16,10BRCS FF2D ;功能键按下,转初始RJMP FF0FF2D: LDI R17,$24 ;数字键按下,在显示缓存区内左移STS $6F,R17 ;FF3: LDS R17,$6FSTS $6E,R17STS $6F,R16FF4: RCALL DSPACPI R16,10BRNE FF41RCALL DSF_ ;清除数字,显示‘F-’FF40: RCALL DSPACPI R16,11BREQ FF1P ;转回显示当前功能名称及内容CPI R16,10BRCC FF40 ;无效键按下,转回RJMP FF2D ;否则转数字处理FF41: BRCS FF3CPI R16,11BRNE FF4RCALL COMBNO ;合成新功能名称CLR R10 ;功能名称偏移量计数器清除CLR R11 ;功能内容偏移量计数器清除SFFLP: LDI ZH,HIGH(FTABL*2)LDI ZL,LOW(FTABL*2)ADD ZL,R10ADC ZH,R27LPMCP R0,R16 ;BREQ SFFND ;在功能名称表中找到新名称INC R11 ;INC R10INC R10INC R10 ;调整偏移量LDI R17,60CP R10,R17 ;功能名称指针偏移量超过59?BRCS SFFLP ;否,继续查功能名称表RCALL FERR1 ;查完功能名称表未查到键入功能名称!RJMP FFUNC0 ;转回恢复原显示SFFND: MOV R9,R11 ;得到功能内容指针偏移量MOV R8,R10 ;得到功能名称指针偏移量RJMP FF0G ;转显示新功能名称及内容FTABL: .DB 1,0,1,2,1,8,3,0,2,4,0,1 5,1,2,6,0,4,7,1,4,8,1,2,9,2,7,10,1,5,11,1 .DB 5,12,0,5,13,1,2,14,1,7,15,1,10,16,1,4,17,2,4,18,2,5,19,1,2,20,1,3 COMBNO: LDI XL,$6E ;取$6E$6F中的BCD码,合成新功能名称子程序COMBA: LD R16,X+CPI R16,$24BRNE CMBACLR R16CMBA: MOV R0,R16LSL R16LSL R16ADD R16,R0LSL R16 ;高位BCD乘10LD R0,XADD R16,R0 ;加低位BCDRETDSF_: RCALL FIL8 ;准备显示'F- 'LDI R16,$0FSTS $6C,R16LDI R16,$14STS $6D,R16RETBRA3A: LDI XL,$6E ;二进制数转换为两位BCD码并显示BRAX: LDI R17,$24 ;十位为0时显示空白ST X,R17BRHOUR: CLR R0 ;BRX0: SUBI R16,10 ;减10BRCS BRX2INC R0RJMP BRX0BRX2: SUBI R16,-10 ;不够减恢复出十位BCDTST R0BREQ BRX1ST X,R0 ;放入显示区BRX1: INC R26ST X,R16BRART: RETFERR1: LDI XL,$71 ;显示'F Err.1'LDI R16,1ST X,R16RJMP FER123FERR2: RCALL MOVE1 ;显示'F Err.2' LDI R16,2STS $71,R16RJMP FER123FERR3: RCALL MOVE1 ;显示'F Err.3' LDI R16,3STS $71,R16FER123: LDI XL,$6CLDI R16,$0FST X+,R16LDI R16,$24ST X+,R16LDI R16,$0EST X+,R16LDI R16,$1BST X+,R16LDI R16,$3BST X+,R16 ;显示'F Err.1/2/3'LDI R16,$24 ;2秒STS $72,R16STS $73,R16RCALL DL2SRETFIL8: LDI R26,8 ;将显示缓存区充空白MOV R10,R26LDI R26,$6CCLR R27LDI R16,$24FILP: ST X+,R16DEC R10BRNE FILPRETFLFUNC: RCALL FIL8 ;准备显示'Func.' LDS R26,$6CLDI R16,$0F ;'F'ST X+,R16LDI R16,$1E ;'u'ST X+,R16LDI R16,$17 ;'n'ST X+,R16LDI R16,$40 ;'c.'ST X+,R16RETEXCH0: LDI ZL,$14 ;将显示缓存区内容转移$6C-$73<-->$214-$21B LDI ZH,2LDI XL,$6CEXL: LD R16,XLD R17,ZST X+,R17ST Z+,R16CPI R26,$74BRNE EXLRETMOVE1: LDI ZL,$14 ;将显示缓存区内容传送到$214-$21BLDI ZH,2LDI XL,$6CMV1: LD R16,X+ST Z+,R16CPI R26,$74BRNE MV1RET;范例22 ;读出EEPROM子程序REEP: LDI YH,1LDI YL 0 ;EEPROM 读出首地址:$100LDI XL,$60 ;读出数据存放首地址:$60CLR XHREEP1: SBIC $1C,1 ;查EEWE位,EEWE=1为当前尚有写入操作未结束RJMP REEP1 ;等待EEWE=0OUT $1F,YHOUT $1E,YL ;读出地址写入EEPRO地址寄存器SBI $1C,0 ;设置读出使能位(EERE)IN R16,$1D ;从EEPROM数据寄存器中读出数据ST X+R16 ;存入缓存区INC YLBRNE REEP1 ;INC YHCPI YH,2 ;EEPROM最末数据(地址为$1FF)读完?BRNE REEP1RET;范例23 ;写入EEPROM子程序WEEP: LDI YH,1LDI YL 0 ;EEPROM 写入之首地址:$100LDI XL,$60 ;写入数据存储区首地址:$60CLR XHWEEP1: SBIC $1C,1 ;查EEWE位,EEWE=1为当前尚有写入操作未结束RJMP WEEP1 ;等待EEWE=0OUT $1F,YHOUT $1E,YL ;送写入地址到EEPRO地址寄存器LD R16,X+ ;取写入数据并调整数据指针OUT $1D,R16 ;送到EEPROM数据寄存器SBI $1C,2 ;设置EEPROM写入总使能位EEMWESBI $1C,1 ;设置EEPROM写入使能位EEWEINC YLBRNE WEEP1INC YHCPI YH,2 ;EEPROM最末写入单元地址为$1FFBRNE WEEP1RET。
; 以下提供几个补充参考程序,都带有详细说明和指令注释.它们是主从多机通讯程序,采;用中断方式写入EEPROM,直接对晶振分频产生0.1秒和秒号的精确定时程序,以及RS-232/ ;RS-485标准转换程序,A VR频率计程序,串行时锺日历芯片DS1302读写,共享时基的PWM 输出、;输入捕获测周期程序和定时信号获取,以及DS18B20测温等程序.多机通讯主要用8和9位数;据模式区分被选分机(9位)和其它分机(8位),达到主机只与被选分机交换数据之目的.以中;断方式写EEPROM的优点是可与系统运行同时进行(即在线写入),占用很少机时.;精确定时用定时/计数器1(或0)直接对MCU主频(不设分频)设定时间常数,分频精度可达到;1HZ.RS-232/RS-485标准转换程序中AVR不作中转,使两种器件相关脚位直接连接.以TT0 ;定时,以T0引脚接收RS-232数据.以收到RS-232字符起始位下跳沿或结束符($03)为依据, ;控制切换RS-485的收发使能.(系统中的主A VR可兼做对通信标准之监控转换,即只是在完成;主要工作任务的同时'附带'进行).具体过程不再细述.串行时锺日历芯片DS1302具体积小, ;可靠性高,与单片机连接方便等优点.; 以下程序请参看有关章节或程序中的注释。
;范例91 ;多机通讯主机程序/晶振4MHZ.ORG 0 ;以8/9位数据模式区分被选/未被选分机通讯.EQU DTPINT=$180 ;UBRR=12 波特率19200(REL.ERR.=0.16%).EQU DRPINT=$1C0 ;主机对1#,2#,3#,4#分机发送数据块在$180-18F,$190-19F,$1A0-1AF)和$1B0-1BFSTRT38: RJMP RST38 ;主机从1#,2#,3#,4#分机接收数据块在$1C0-1CF,$1D0-1DF,$1E0-1EF)和$1F0-1FF.ORG $00B ;RJMP STRT38.ORG $00CRJMP STRT38 ;主机不设串口中断,只以查询接收.ORG $011RST38: LDI R16,12OUT UBRR,R16 ;设波特率:[BAUD RATE=FCP/16(UBRR+1)]CLR R15 ;初始化分机号LDI R27,HIGH(DTPINT)LDI R26,LOW(DTPINT);发送数据指针(首指$180)LDI R29,HIGH(DRPINT)LDI R28,LOW(DRPINT);接收数据指针(首指$1C0)NEXTNO: LDI R16,$18OUT UCR,R16 ;允许UART接收和发送,8位数据模式INC R15 ;指向1#分机OUTLP: OUT UDR,R15 ;呼分机号,1:1#/2:2#/03:3#/04:4#...TSLOP: IN R16,USRSBRS R16,7RJMP TSLOP ;分机返回机号?IN R16,UDRCP R16,R15 ;分机号正确返回?BRNE OUTLPLDI R16,$1C ;改为9位数据模式TXB8=0OUT UCR,R16 ;TXLOP: LD R16,X+OUT UDR,R16 ;向分机发送数据块TESTL: IN R17,USRSBRS R17,5RJMP TESTL ;等待发送完成CPI R16,$0ABRNE TXLOP ;RXTST: IN R17,USRSBRS R17,7 ;RXC=1 收到数据RJMP RXTST ;等待接收分机返回数据块IN R16,UDRST Y+,R16 ;存储接收数据CPI R16,$0A ;分机数据块发完?BRNE RXTSTMOV R16,R15CPI R16,4 ;与分机轮询通讯完毕?BRNE NEXTNO ;未完转对下一分机通信HH38: RJMP HH38 ;否则踏步(可改为处理分机返回的数据,之后再进行下一个轮询).DSEG.ORG $180DTPINT:.BYTE $40;$41 $45 $65 $73 $46 $42 $40 $6F $33 $44 $66 $5C $4D $4B $0D $0A;$42 $4F $66 $78 $47 $45 $44 $63 $32 $48 $60 $7C $6D $45 $0D $0A;$43 $56 $55 $53 $4D $4F $40 $2E $31 $42 $67 $4C $47 $4A $0D $0A;$45 $54 $59 $63 $3D $4B $48 $2F $35 $48 $69 $3C $77 $43 $0D $0A.ORG $1C0DRPINT:.BYTE $40;范例92.ORG 0 ;多机通讯1#分机程序/晶振4MHZ.EQU DTPIT1=$180 ;(UBRR)=12 波特率为19200(REL.ERR.=0.16%).EQU DRPNT1=$1C0STRT39: RJMP RST39.ORG $00BRJMP UARXC ;8535UART接收完成中断.ORG $00CRJMP UATXC ;UART发送完成中断.ORG $011RST39: CLR R18 ;清除分机被选中(R18,6)和主机数据块接收完毕标志(R18,7) LDI R16,12OUT UBRR,R16 ;设波特率[BAUD RATE=4000000/16*(12+1)=19200]LDI R16,HIGH(DRPNT1)MOV R8,R16LDI R16,LOW(DRPNT1)MOV R9,R16 ;r8,r9:接收数据指针(FIRST POINT TO $1C0)LDI R16,$98 ;允许UART中断接收,8位数据模式OUT UCR,R16SEIRXDTS: SBRS R18,6 ;主机呼号已收到(若收到,在R17中)?RJMP RXDTSOUT UDR,R17 ;返还该机号TXDON: IN R16,USRSBRS R16,5RJMP TXDON ;该机号发送完成?LDI R16,$9C ; 允许UART中断接收,9位数据模式,TXB8=0OUT UCR,R16RCVBLK: SBRS R18,7RJMP RCVBLK ;主机发来数据块已接收完毕?LDI R16,HIGH(DTPIT1)MOV R6,R16LDI R16,LOW(DTPIT1)MOV R7,R16 ;设发送数据指针r6r7,首指$180LDI R16,$3C ;允许UART中断发送,9位数据模式,TXB8=0OUT UCR,R16TXDN: SBIC UCR,5RJMP TXDN ;发送完毕?RJMP RST39 ;:UART中断接收程序UARXC: SBIC USR,4RETI ;祯错误(主机正与其它分机进行9位数据模式通信),不予接收IN R14,SREG ;保存当前状态TST R18BREQ NUMB ;(R18)=0时收到数据,只可能是机号,转去核实PUSH R16 ;否则为主机向本分机发来数据块(9位模式,机号已符合)PUSH R26PUSH R27IN R17,UDR ;接收数据MOV XH,R8MOV XL,R9 ;取接收数据指针ST X+,R17 ;转入RAMMOV R8,XHMOV R9,XL ;存数据指针CPI R17,$0A ;是数据块结束符LF?BRNE RS1SBR R18,$80 ;收到完整数据块标志RS1: POP R27POP R26POP R16DRETI: OUT SREG,R14RETINUMB: IN R17,UDR ;取出数据CPI R17,1 ;是1#分机?2#分机与$02比较/3#分机与$03比较...BRNE DRETI ;机号不符合,转!SBR R18,$40 ;建机号符合标志RJMP DRETI; UART中断发送程序UA TXC: PUSH R16 ;r6 r7:发送数据指针,首指$180IN R16,SREGPUSH R16PUSH R26PUSH R27MOV XH,R6MOV XL,R7 ;取出发送指针LD R16,X+ ;取数据,调指针MOV R6,XHMOV R7,XLOUT UDR,R16 ;送入发送寄存器CPI R16,$0ABRNE SDCBI UCR,5 ;发送最后1个字符后,禁止发送寄存器空中断(CLR UDRIE) LDI R16,HIGH(DRPINT)MOV R8,R16LDI R16,LOW(DRPINT)MOV R9,R16 ;接收数据指针初始化(POINT TO $1C0)SD: POP R27POP R26POP R16OUT SREG,R16POP R16RETI.DSEG.ORG $180DTPIT1:.BYTE $40.ORG $1C0DRPNT1:.BYTE $10;$41 $45 $65 $73 $46 $42 $40 $6F $33 $44 $66 $5C $4D $4B $0D $0A;范例93;以中断方式写入EEPROM(仅对8535,8515无此功能),克服查询方式占用过多机时的缺点,;并可在线写入;运作过程特点如下:;(1)主程序初始化时设置EEPROM就绪(ready)中断使能位和中断总使能位;(2)在主程序中写入第一个字节,写入完成后引起就绪中断,其他写入在中断服务中完成;(3)本程序为一写入特例,写入地址为$100--$1FF,可作适当修改(如设块长计数器等);(4)为防止高优先级中断破坏写入过程,中断服务中不允许中断嵌套;(5)本例为简化程序只以查询写入地址循环作为背景程序,实用时可改为具体的背景序;(6)如能确信当前系统没有EEPROM正在写入,可删除对其进行查询部分. STWEEP: LDI R16,HIGH(ramend)OUT SPH,R16LDI R16,LOW(ramend)OUT SPL,R16SBI EECR,3 ;设置EEPROM就绪(ready)中断使能位SEI ;中断总使能RJMP SRTW.ORG $00FRJMP EEPRDY ;8535 EEPROM就绪(ready)中断向量SRTW: LDI YH,1LDI YL 0 ;EEPROM 写入首地址:$100LDI XL,$60 ;欲写入数据块首地址:$60CLR XHWEEP0: SBIC EECR,1 ;当前有EEPROM写入操作,有则等待写入完成RJMP WEEP0RCALL WREEP ;写入第一个字节,($60)->$100,写入完成后,EEWE=0时引发EEPROM就绪中断INC YL ;调整写入地址指针HHWEEP: TST YLBRNE HHWEEPCPI YH,2 ;写入地址达到$200后,写入完成BRNE HHWEEPCBI EECR,3 ;禁止EEPROM就绪(ready)中断WDON: RJMP WDON ;踏步EEPRDY: IN R6,SREGPUSH R16RCALL WREEP ;写入一个字节INC YLBRNE WRETIINC YH ;EEPROM末地址为$1FFWRETI: POP R16OUT SREG,R6RETIWREEP: OUT EEARH,YH ;OUT EEARL,YL ;写入地址送入EEARLD R16,X+ ;取数据,调指针OUT EEDR,R16 ;数据写入EEPROM数据寄存器SBI EECR,2 ;设置EEPROM写入总使能位EEMWESBI EECR,1 ;设置EEPROM写入使能位EEWERET;范例94 ;精确定时产生0.1秒信号;用定时/计数器1定时,不分頻定出0.1秒信号,由PC5脚输出正脉冲。
20个简单汇编语言程序-回复简明了解汇编语言,让我们先了解一下汇编语言的基本概念和特点。
汇编语言是一种低级语言,用于与计算机硬件进行沟通和交互,它是由一系列指令组成的。
与高级语言相比,汇编语言更加接近计算机的硬件和操作,因此它的指令更直观,更加底层。
下面我们来看一下20个简单的汇编语言程序:1. [将两个数相加并存储到一个寄存器中]2. [将两个数相加并存储到内存中]3. [将一个寄存器的值存储到内存中]4. [从键盘输入一个数并存储到内存中]5. [从内存中读取一个数并输出到屏幕上]6. [将两个寄存器的值进行逻辑与操作]7. [将两个寄存器的值进行逻辑或操作]8. [将两个寄存器的值进行逻辑非操作]9. [将一个寄存器的值左移一位]10. [将一个寄存器的值右移一位]11. [将一个寄存器的值加一]12. [将一个寄存器的值减一]13. [将一个寄存器的值与一个常数相加]14. [将一个寄存器的值与一个常数进行逻辑与操作]15. [将一个寄存器的值与一个常数进行逻辑或操作]16. [将一个寄存器的值与一个常数进行逻辑非操作]17. [将一个寄存器的值与一个常数左移一位]18. [将一个寄存器的值与一个常数右移一位]19. [将一个寄存器的值与一个常数进行加一]20. [将一个寄存器的值与一个常数进行减一]现在,我们将一步一步地回答这个问题,写一篇1500-2000字的文章,帮助读者更好地理解这些汇编语言程序。
第一步:介绍汇编语言在这一步,我们将介绍汇编语言的基本概念、应用领域和优缺点。
我们将解释汇编语言与高级语言之间的区别,并讨论为什么学习汇编语言对于理解计算机系统和进行底层开发非常重要。
第二步:汇编语言基础知识在这一步,我们将介绍汇编语言的基本知识和概念。
我们将解释什么是指令、寄存器、内存等,并讨论它们在汇编语言中的作用和用法。
第三步:编写简单的汇编语言程序在这一步,我们将逐个介绍这20个简单的汇编语言程序,并提供详细的说明和示例代码。
AVR汇编指令AVR指令算术指令:加法(4)ADD Rd,Rr (Rd)<- (Rd)+(Rr);d,r =【0-31】ADC Rd,Rr (Rd)<- (Rd)+ (Rr)+ C ;d,r =【0-31】ADIW Rdl,K (Rdh:Rdl)<- (Rdh:Rdl)+K ;d =【24,26,28,30】K =【0-63】INC Rd (Rd)<- (Rr)+ 1 ;d =【0-31】减法(6)SUB Rd,Rr (Rd)<- (Rd)- (Rr);d,r =【0-31】SUBI Rd,K (Rd)<- (Rd)- K ;d =【16-31】K =【0-255】SBC Rd,Rr (Rd)<- (Rd)- (Rr)- C ;d,r =【0-31】SBCI Rd,K (Rd)<- (Rd)- K - C ;d =【16-31】K =【0-255】 SBIW Rdl,K (Rdh:Rdl)<- (Rdh:Rdl)- K ;d=【24,26,28,30】 K =【0-63】DEC Rd (Rd)<- (Rr)- 1 ;d =【0-31】乘法(1)MUL Rd,Rr (R1)<-H(Rd*Rr)(R0)<-L(Rd*Rr);d,r =【2-31】逻辑运算与(4)AND Rd,Rr (Rd)<- (Rd)&(Rr);d,r =【0-31】ANDI Rd,K (Rd)<- (Rd)& K ;d =【16-31】K =【0-255】CBR Rd,K (Rd)<- (Rd)& (FF- K);d =【16-31】K=【0-255】 TST Rd (Rd)<- (Rd)&(Rr);d =【16-31】Z标记位或(4)OR Rd,Rr (Rd)<- (Rd)|(Rr);d,r =【0-31】ORI Rd,K (Rd)<- (Rd)| K ;d =【16-31】K =【0-255】SBR Rd,K (Rd)<- (Rd)| K ;d =【16-31】K =【0-255】SER Rd (Rd)<- FF ;d =【16-31】异或(2)EOR Rd,Rr (Rd)<- (Rd)⊕(Rr);d,r =【0-31】CLR Rd (Rd)<- 00 ;d =【0-31】⽐较(3)CP Rd,Rr (Rd)- (Rr);d,r =【0-31】CPI Rd,K (Rd)- K ;d =【16-31】K =【0-255】CPC Rd,Rr (Rd)- (Rr)- C ;d,r =【0-31】取反(1)COM Rd (Rd)<- FF -(Rd);d =【0-31】取补(1)NEG Rd (Rd)<- 00 -(Rd);d =【0-31】⽆条件跳转(3)RJMP K (PC)<- (PC)+1+K ;K =【-2k - 2k】IJMP (PC)<- (Z);Z : 16BITJMP K (PC)<- K ;K =【0-4M】条件跳转(20)BRBS S , K BRBC S , K 状态寄存器判断位;S =【0-7】K =【-64,63】BREQ K BRNE K 为零标记不为零BRIE K BRID K 全局中断开关BRTS K BRTC K 标记位为零BRHS K BRHC K 半进位置位为零BRGM K BRLT K 带符号⼤于等于⼩于BRSH K BRLO K ⽆符号⼤于等于⼩于BRCS K BRCC K 进位置位为零BRVS K BRVC K 补码溢出置位为零BRMI K BRPL K 负数正数条件跳⾏(5)CPSE Rd,Rr 相等时跳⾏;d,r =【0-31】SBRS Rd,b 该为置位时跳⾏;d =【0-31】S =【0-7】 SBRC Rd,b 该为零时跳⾏;d =【0-31】S =【0-7】SBIC P,b 该为零时跳⾏;P =【0-31】S =【0-7】 SBIS P,b 该为置位时跳⾏;P =【0-31】 S =【0-7】调⽤(5)RCALL K (PC)<- (PC)+1+K ;K =【-2k - 2k】ICALL 跳转到Z指向地址;16 bitCALL K 0-4MRET ⼦程序返回RETI 中断返回栈(2)PUSH Rd 进⼊堆栈;d =【0-31】POP Rd 出栈;d =【0-31】直接数据传送(4)MOV Rd,Rr (Rd)<-(Rr);d,r =【0-31】LDS Rd,K (Rd)<-(K);d =【0-31】STS K,Rd (K)<-(Rd);d =【0-31】LDI Rd,K (Rd)<- K ;d =【16-31】K =【0-255】间接数据传送(22)X寄存器:LD Rd,X (Rd)<-((X));d =【0-31】LD Rd,X+ (Rd)<-((X)),(X)+=1 ;d =【0-31】LD Rd,-X (X)- =1,(Rd)<-((X));d =【0-31】ST X,Rd ((X))<-(Rd);d =【0-31】ST X+,Rd ((X))<-(Rd),(X)+=1 ;d =【0-31】ST -X,Rd (X)- =1,((X))<-(Rd);d =【0-31】Y寄存器:LD Rd,YLD Rd,Y+LD Rd,-YLDD Rd,Y+Q (Rd)<-((Y+Q));d =【0-31】Q =【0-63】 ST Y,RdST Y+,RdST -Y,RdSTD Y+Q,RdZ寄存器:LD Rd,ZLD Rd,Z+LD Rd,-ZLDD Rd,Z+QST Z,RdST Z+,RdST -Z,RdSTD Z+Q,Rd寻址(1)LMP 利⽤Z寄存的地址寻址(注意lsb位要为0读低8位数1读⾼8位数)I/O⼝(2)IN Rd,P (Rd)<- (P);d =【0-31】 P =【0-63】 OUT P,Rd (P)<- (Rd);d =【0-31】 P =【0-63】移位(6)LSL Rd (Rd)<<1, C<-MSB ,LSB<-0 ;d =【0-31】LSR Rd (Rd)>>1, C<-LSB ,MSB<-0 ;d =【0-31】ROL Rd (Rd)<<1 ,LSB<-C , C<-MSB ;d =【0-31】ROR Rd (Rd)>>1 ,MSB<-C , C<-LSB ;d =【0-31】SWAP Rd 半字节交换;d =【0-31】ASR Rd 7位不变,其余右移 , C<-LSB ;d =【0-31】T标记位(2)BLD Rd,b 将位读⼊T标记;d =【0-31】 b =【0-7】BST Rd,b 将T标记写⼊位;d =【0-31】 b =【0-7】状态位设置(20)BSET S BCLR S 设置状态寄存器指定位; S =【0-7】SEI CLI 状态标记设置或清除SEH CLHSET CLTSES CLSSEN CLNSEV CLVSEZ CLZSEC CLCSBI P,b CBI P,b 32IO⼝指定位设置清楚;P =【0-31】 b =【0-7】其他WDR 看门狗复位SLEEP 休眠NOP 空指令。
写在前面的话大家好!初次见面请多关照。
欢迎大家来到羽良,这是一个充满阳光,聚集智慧,共享求职经验的平台。
感谢您的参与,在这里,您可以认识更多新的朋友,衷心祝愿大家能够和我们共同度过一段美好的学习时光。
在这个嵌入式产业群雄争霸的今天,不懂单片机对于一个工科学生来说无疑是一场输在起跑线上的比赛。
我们希望的是每个工科生都可以熟练掌握它,这样可以给成功天平的一侧添加厚重的砝码。
但是我们不赞成趋之若鹜,一切以兴趣为出发点。
首先,我觉得有必要介绍羽良,这样便于大家了解自己学习环境,以及自己所处的高度。
2007年——在摧残式教育和掠夺式启发依然横行的年份,本着自由呼吸大学空气的念头,李雨轩,梁冲,程戎翰,刘培勋童鞋“究天人之际,通古今之变”,创立了羽良。
作为羽良的鼻祖,他们经历了创业之苦。
没有空间,他们与学校争取,经过多次的唾沫横飞,争取到了大家现在看到的实验室(江湖传言程童鞋打开门的一刻留下了一克拉的眼泪,hold不住了)。
经费不足,大家共同解决,从一穷二白到现在的物质比较丰富。
代代羽良人秉承“坚持不懈,自力更生”的理念,锻炼自己,建设团队。
从这里走出了一批又一批优秀的职场达人。
这就是平台的力量!!!接着,大家看到的学习板是一个叫刘宇龙的大童鞋,在一个蛋疼的中午绘制的学习图,并联系工厂制版的结果。
它以ATmega16为基础,外设了N多个设备(相当给力啊),便于大家的学习与进一步深入。
让大家在自主学习的同时巩固自己的课本知识,一举两得。
这样学习有高屋建瓴的感觉。
进而,大家看到的资料是三个牺牲国庆陪mm时间的大二孩纸(伤不起)钻在工作室里纠结反应后的结果。
资料里有各位同学需要学习的课程以及对这款单片机的详细介绍,还有一些内部程序资料(谢绝外传)。
资料是为了广大学员在寝宫里便可以学习,一方面便于复习和预习,另一方面便于学员的自主深入学习。
我们坚信实践才是对理论的升华,以及对能力的提高的唯一途径。
所以我们大家只要是有时间就练习,这样进步的很快(谦孩纸的经验)。
AVR单片机汇编语言编程实验学院:自动化专业:测控技术与仪器一、实验名称:AVR单片机汇编语言编程实验二、实验目的:熟悉并掌握AVR单片机指令系统、汇编语言常用伪指令,掌握单片机汇编语言编程技术,编程实现指定功能,加深对计算机汇编指令的理解。
三、实验仪器:计算机,VMware,Windows7虚拟机,AtmelStudio开发环境,Proteus仿真开发环境四、实验内容、实验过程及结果分析:1. Flash 单元赋值创建汇编语言工程,目标机型选为Mega128。
使用汇编语言伪指令进行编程,将下述32 字节的常数数据存入首地址为$0160 的连续flash 存储单元照片中。
数据如下:0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x070x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x7;0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf80x80,0x90,0x88,0x83,0xc6,0xa,0x86,0x8e;前后16 字节分别是字符0-F 对应的共阴极和共阳极LED 数码管的字形显示段码。
随后使用IDE 自带的调试工具,进入debug 调试。
在调试过程中,在Flash 存储器映像中查找上述存入的数据块所对应的地址,记录Flash 存储器映像。
图1.1.0如图1所示,数据3f的首地址为$002C0的内存单元中,为$的二倍,因此说明数据成功存入该段存储单元2. DATA RAM 内存块赋值使用汇编语言指令,将上述存储在 Flash 中的 32 个字节单元的数据块依次赋值给起始地址为$0230 的 SRAM 内存块的相应内存单元,流程如图2.1.0 所示。
图2.1.0寄存器初始状态如图2.2.0所示。
将Z指针指向先前第一位数据的首地址,并进行一个次数为16的循环,通过LPM指令将储存在Flash中16字节的数据拷贝至起始地址为$0230的内存单元中,如图2.2.1所示,数据存储状态如2.2.3 所示。
; 以下提供几个补充参考程序,都带有详细说明和指令注释.它们是主从多机通讯程序, 采;用中断方式写入EEPROM,直接对晶振分频产生0.1秒和秒号的精确定时程序,以及RS-232/ ;RS-485 标准转换程序,AVR 频率计程序,串行时锺日历芯片DS1302 读写,共享时基的PWM 输出、;输入捕获测周期程序和定时信号获取,以及DS18B20 测温等程序.多机通讯主要用8 和9位数;据模式区分被选分机(9 位)和其它分机(8 位),达到主机只与被选分机交换数据之目的.以中;断方式写EEPROM 的优点是可与系统运行同时进行(即在线写入),占用很少机时.;精确定时用定时/计数器1(或0)直接对MCU 主频(不设分频)设定时间常数,分频精度可达到;1HZ.RS-232/RS-485 标准转换程序中AVR 不作中转,使两种器件相关脚位直接连接.以TCNT0 淀时,以T0引脚接收RS-232数据•以收到RS-232字符起始位下跳沿或结束符($03)为依据, ;控制切换RS-485 的收发使能.(系统中的主AVR 可兼做对通信标准之监控转换,即只是在完成;主要工作任务的同时'附带'进行).具体过程不再细述.串行时锺日历芯片DS1302 具体积小, ;可靠性高,与单片机连接方便等优点.; 以下程序请参看有关章节或程序中的注释。
;范例91 ;多机通讯主机程序/晶振4MHZ.ORG 0 ;以8/9 位数据模式区分被选/未被选分机通讯.EQU DTPINT=$180 ;UBRR=12 波特率19200(REL.ERR.=0.16%).EQU DRPINT=$1C0 ; 主机对1#,2#,3#,4# 分机发送数据块在$180-18F,$190-19F,$1A0-1AF)和$1B0-1BFSTRT38: RJMP RST38 ; 主机从1#,2#,3#,4# 分机接收数据块在$1C0-1CF,$1D0-1DF,$1E0-1EF)和$1F0-1FF.ORG $00B ;RJMP STRT38.ORG $00CRJMP STRT38 ;主机不设串口中断,只以查询接收.ORG $011RST38: LDI R16,12OUT UBRR,R16 ;设波特率:[BAUD RATE=FCP/16(UBRR+1)]CLR R15 ; 初始化分机号LDI R27,HIGH(DTPINT)LDI R26,LOW(DTPINT); 发送数据指针(首指$180)LDI R29,HIGH(DRPINT)LDI R28,LOW(DRPINT);接收数据指针(首指$1C0)NEXTNO: LDI R16,$18OUT UCR,R16 ;允许UART 接收和发送,8 位数据模式INC R15 ; 指向1#分机OUTLP: OUT UDR,R15 ;呼分机号,1:1#/2:2#/03:3#/04:4#...TSLOP: IN R16,USRSBRS R16,7RJMP TSLOP ; 分机返回机号?IN R16,UDR CP R16,R15;分机号正确返回? BRNE OUTLPLDI R16,$1C ;改为 9 位数据模式 TXB8=0 OUT UCR,R16JTXLOP: LDR16,X+OUT UDR,R16;向分机发送数据块TESTL: INR17,USRSBRS R17,5RJMP TESTL ; 等待发送完成CPI R16,$0ABRNE TXLOPJRXTST: INR17,USRSBRS R17,7 ;RXC=1 收到数据RJMP RXTST ;等待接收分机返回数据块IN R16,UDRST Y+,R16 ;存储接收数据 CPI R16,$0A ;分机数据块发完?BRNE RXTSTMOVR16,R15CPI R16,4 ;与分机轮询通讯完毕? BRNE NEXTNO ;未完转对下一分机通信 HH38: RJMP HH38;否则踏步(可改为处理分机返回的数据,之后再进行下一个轮询).DSEG.ORG $180DTPINT:.BYTE $40;$41 $45 $65 $73 $46 $42 $40 $6F $33 $44 $66 $5C $4D $4B $0D $0A ;$42 $4F $66 $78 $47 $45 $44 $63 $32 $48 $60 $7C $6D $45 $0D $0A;$43 $56 $55 $53 $4D $4F $40 $2E $31 $42 $67 $4C $47 $4A $0D $0A ;$45 $54 $59 $63 $3D $4B $48 $2F $35 $48 $69 $3C $77 $43 $0D $0A .ORG $1C0 DRPINT:.BYTE $40;范例 92.ORG 0 ;多机通讯 1#分机程序 /晶振 4MHZ.EQU DTPIT1=$180 ;(UBRR )=12 波特率为 19200(REL.ERR.=0.16%).EQU DRPNT1=$1C0 STRT39: RJMP RST39;8535UART 接收完成中断 ;UART 发送完成中断.ORG $00B RJMP UARXC .ORG $00C RJMPUATXCOUT UCR,R16RCVBLK: SBRS R18,7RJMP RCVBLK ;主机发来数据块已接收完毕? LDI R16,HIGH(DTPIT1) MOV R6,R16 LDI R16,LOW(DTPIT1)MOV R7,R16 ;设发送数据指针r6r7,首指$180LDI R16,$3C;允许 UART 中断发送, 9位数据模式, TXB8=0OUT UCR,R16 TXDN: SBIC UCR,5RJMP RJMPTXDN RST39; 发送完毕? J:UART 中断接收程序UARXC: SBICUSR,4RETI; 祯错误(主机正与其它分机进行 9 位数据模式通信) ,不予接收IN R14,SREG ; 保存当前状态TST R18BREQ NUMB ;(R18)=0 时收到数据,只可能是机号,转去核实PUSH R16 ; 否则为主机向本分机发来数据块( 9 位模式,机号已符合)PUSH R26 PUSH R27IN R17,UDR ;接收数据MOV XH,R8MOVXL,R9 ;取接收数据指针 STX+,R17; 转入 RAMLDI R16,12 OUT UBRR,R16 ;设波特率 [BAUD RATE=4000000/16* ( 12+1)=19200]LDI R16,HIGH(DRPNT1)MOV R8,R16LDI R16,LOW(DRPNT1) MOV R9,R16 丁8,r9:接收数据指针(FIRST POINT TO $1C0)LDI R16,$98;允许 UART 中断接收, 8位数据模式OUTUCR,R16SEIRXDTS: SBRS R18,6; 主机呼号已收到(若收到,在 R17 中)?RJMP RXDTSOUT UDR,R17; 返还该机号TXDON: INR16,USRSBRSR16,5RJMP TXDON ; 该机号发送完成?LDI R16,$9C ; 允许 UART 中断接收, 9 位数据模式, TXB8=0;清除分机被选中( R18, 6)和主机数据块接收完毕标志 (R18,7).ORG $011 RST39:CLR R18SDCOM: POP R27POP R26POP R16 OUT SREG,R16 POP R16RETI.DSEG .ORG$180DTPIT1:.BYTE $40 .ORG $1C0 DRPNT1:.BYTE $10;$41 $45 $65 $73 $46 $42 $40 $6F $33 $44 $66 $5C $4D $4B $0D $0AMOV R8,XH MOV R9,XL; 存数据指针 CPI R17,$0A ;是数据块结束符 LF? BRNE RSCOM1SBR R18,$80 ; 收到完整数据块标志RSCOM1: POP R27POP R26 POP R16DRETI: OUT SREG,R14 RETI NUMB: IN R17,UDR ; 取出数据CPI R17,1 ;是 1#分机? 2#分机与 $02比较/3#分机与$03比较 BRNEDRETI; 机号不符合,转 ! SBR R18,$40 ; 建机号符合标志RJMP DRETI; UART 中断发送程序 UA TXC : PUSHR16;r6 r7:发送数据指针,首指$180IN R16,SREG PUSH R16PUSH R26PUSH R27MOV XH,R6MOV XL,R7 ;取出发送指针 LD R16,X+ ; 取数据,调指针MOV R6,XH MOV R7,XLOUTUDR,R16; 送入发送寄存器CPI R16,$0A BRNE SDCOMCBI UCR,5; 发送最后 1 个字符后,LDI R16,HIGH(DRPINT) MOVR8,R16LDI R16,LOW(DRPINT)MOV R9,R16 ; 接收数据指针初始化 禁止发送寄存器空中断 (CLR UDRIE)POINT TO $1C0);范例93;以中断方式写入EEPROM (仅对8535,8515 无此功能) ,克服查询方式占用过多机时的缺点,;并可在线写入;运作过程特点如下:;(1)主程序初始化时设置EEPROM就绪(ready)中断使能位和中断总使能位;(2)在主程序中写入第一个字节,写入完成后引起就绪中断,其他写入在中断服务中完成;(3)本程序为一写入特例,写入地址为$100--$仆F,可作适当修改(如设块长计数器等) ;(4)为防止高优先级中断破坏写入过程,中断服务中不允许中断嵌套;(5)本例为简化程序只以查询写入地址循环作为背景程序,实用时可改为具体的背景序;(6)如能确信当前系统没有EEPROM 正在写入,可删除对其进行查询部分.STWEEP: LDI R16,HIGH(ramend)OUT SPH,R16LDI R16,LOW(ramend)OUT SPL,R16SBI EECR,3 设置EEPROM就绪(ready)中断使能位SEI ;中断总使能RJMP SRTW.ORG $00FRJMP EEPRDY ;8535 EEPROM就绪(ready)中断向量SRTW: LDI YH,1LDI YL 0 ;EEPROM 写入首地址:$100LDI XL,$60 ;欲写入数据块首地址:$60CLR XHWEEP0: SBIC EECR,1 ;当前有EEPROM 写入操作,有则等待写入完成RJMP WEEP0RCALL WREEP ;写入第一个字节,($60)->$100 ,写入完成后,EEWE=0 时引发EEPROM 就绪中断INC YL ;调整写入地址指针HHWEEP: TST YLBRNE HHWEEPCPI YH,2 ;写入地址达到$200后,写入完成BRNE HHWEEPCBI EECR,3 ;禁止EEPROM 就绪(ready)中断WDON: RJMP WDON ;踏步EEPRDY: IN R6,SREGPUSH R16RCALL WREEP ;写入一个字节INC YLBRNE WRETIINC YH ;EEPROM 末地址为$1FF WRETI: POP R16OUT SREG,R6RETIWREEP: OUT EEARH,YH ;OUT EEARL,YL ;写入地址送入EEARLD R16,X+ ;取数据,调指针OUT EEDR,R16 ;数据写入EEPROM 数据寄存器SBI EECR,2 ;设置EEPROM 写入总使能位EEMWESBI EECR,1 ;设置EEPROM 写入使能位EEWERET;范例94 ;精确定时产生0.1 秒信号;用定时/计数器1定时,不分頻定出0.1秒信号,由PC5 脚输出正脉冲。