mcu众多的开发实例

源代码在线查看: 模拟数据采器 usart.txt

软件大小: 97 K
上传用户: stealler
关键词: mcu 开发实例
下载地址: 免注册下载 普通下载 VIP

相关代码

				 
				  
				;Data Acquisition Device 数据采集办法 
				
				;* Module Description组件描述: 
				;* Analog Data Acquisition模拟数据采集器组件使用 EE314 
				;* 设备接口通过RS232串行口serial port到PC,同时提供协议protocol支持最多5个对;* 手方频道 
				;* oscillator clock15.36Mhz ///9600 baud rate/// 16F870
				;************************************************************************
				;* Revision History: 
				;* 06/01/2001(GeneA): created *
				;* 06/06/2001(GeneA); version 1.0 complete *
				;* 06/07/2001(GeneA): A/D conversion bug. Wasn't waiting the required *
				;* Tacq time between selecting the analog channel and beginning *
				;* the A/D conversion. Am now delaying 16 instruction cycles prior *
				;* to starting the conversion. *
				;* 07/12/2001(GeneA): Version 1.1 - Changed command mapping. Read *
				;* analog channel commands are now 'A' - 'E'. Verify status is now *
				;* '@'. Changed the default reporting mode to ASCII. Changed the *
				;* ASCII response string to include a leading character of 'a' - *
				;* 'e' and a terminating character of '@'. This was to improve *
				;* robustness of the protocol. Changed the Verify Status response *
				;* to be a single '!' character. Added conditional assembly *
				;* switches to support clock frequencies of 15.36Mhz and 18.432Mhz.* 
				;************************************************************************
				;
				;SIMDEBUG equ 1
				;DEBUG equ 1
				
				list p=16F870 
				list b=4,n=45,mm=OFF,st=OFF
				
				#include  
				__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC & _DEBUG_OFF & _LVP_OFF
				
				cpuclk equ 18 ; use 15 for 15.36Mhz clock
				; use 16 for 16.00Mhz clock
				; use 18 for 18.432Mhz clock
				
				if (cpuclk != 15) & (cpuclk != 16) & (cpuclk != 18)
				error Invalid CPU CLock Frequency Specified
				endif
				
				fbSerTxInit equ 0x20 ;asynchronous, tx enabled, BRGH=0
				fbSerRxInit equ 0x90 ;使能串行口, 连续发送 8bit
				
				if cpuclk == 15
				cntBaudDiv equ 24
				endif
				
				if cpuclk == 16
				cntBaudDiv equ 25
				endif
				
				if cpuclk == 18
				cntBaudDiv equ 29
				endif
				
				fbTrisAInit equ 0x2F ;B‘00101111’RA4 output 
				fbTrisBInit equ 0x00 ; RB7-0 as output
				fbTrisCInit equ 0x90 ;B‘10010000’TX,RC5 as output
				; RX,RC4 as input
				; RC3-0 as output
				
				fbAdCon0Init equ 0x81 ;AD enabled, Fosc/32 clock, channel 0
				fbAdCon1Init equ 0x80 ;right justified, AN4-0 as analog inputs
				
				if cpuclk == 15
				cntAdDelay equ 16 ;AD延时 
				endif
				
				if cpuclk == 16
				cntAdDelay equ 18
				endif
				
				if cpuclk == 18
				cntAdDelay equ 20
				endif
				
				; 命令处理的字符常数
				cmdReadA0 equ 'A' ; 读模拟通道 0 (read analog channel)
				cmdReadA1 equ 'B' ; 读模拟通道 1
				cmdReadA2 equ 'C' ; 读模拟通道 2
				cmdReadA3 equ 'D' ; 读模拟通道 3
				cmdReadA4 equ 'E' ; 读模拟通道 4
				cmdVerify equ '@' ; 询问状态
				cmdLoopBack equ 'L' ; 进入回送模式命令
				chEsc equ 0x1B ; ESC - 退出回送模式
				chAck equ '@' ; 确认符
				chError equ '#' ; 错误反应符
				chPrompt equ '>' ; > - 回送模式提示
				chStatusOk equ '!' ; status ok. 
				; 送信复位或作为对状态命令的应答
				
				bitModeAnalog equ 0 ;模式控制位 0 is 二进制 read back mode
				; 1 is 十六进制 read back mode
				
				VarRam equ 0x20 ; general purpose variable area
				w_temp equ 0x70 ; variable used for context saving 
				s_temp equ 0x71 ; variable used for context saving
				
				
				cblock VarRam
				bRegA ; temporary working variable
				bRegB ; temporary working variable
				fbMode ; 模式控制位
				chCommand ; 可变的保持电流字符
				achRead ; 读模拟频道数
				bAvalL ; LSB 模拟转变值
				bAvalH ; MSB 模拟转变值
				chSend ; 连续输出魏存器
				endc
				
				;===========================================================
				ORG 0x000 
				goto Main 
				ORG 0x004 
				goto IsrEnter
				IsrEnter
				movwf w_temp 
				swapf STATUS,w 
				movwf s_temp 
				
				IsrExit:
				swapf s_temp,w 
				movwf STATUS 
				swapf w_temp,f
				swapf w_temp,w 
				retfie 
				
				;===========================================================
				Main:
				movlw 0
				movwf INTCON
				movwf PIR1 
				movwf fbMode ; 缺省模式是 ASCII Hex 
				bsf fbMode,bitModeAnalog
				
				call InitConfig
				call Delay
				call Delay
				call VerifyStatus
				
				GetCommand: ; 等待下接收的一个命令字节
				call GetSerialByte ; 从串行口获得下一个字符
				movwf chCommand
				
				movf chCommand,w
				andlw 0xF0
				xorlw 0x40
				btfsc STATUS,Z
				goto DispatchCommand4X
				goto InvalidCommand ; 命令字节 范围是 0x40-0x4F.
				
				DispatchCommand4X:
				movf chCommand,w
				andlw 0x0F
				addwf PCL,f
				
				goto DoCmdVerifyStatus ; 0x40 '@' - Verify status
				goto DoCmdReadAnalog ; 0x41 'A' - read AN0
				goto DoCmdReadAnalog ; 0x42 'B' - read AN1
				goto DoCmdReadAnalog ; 0x43 'C' - read AN2
				goto DoCmdReadAnalog ; 0x44 'D' - read AN3
				goto DoCmdReadAnalog ; 0x45 'E' - read AN4
				goto DoCmdSetBinary ; 0x46 'F' - set binary mode
				goto DoCmdSetAscii ; 0x47 'G' - set ascii mode
				goto DoCmdQueryMode ; 0x48 'H' - query analog mode
				goto DoCmdReset ; 0x49 'I' - reset
				goto InvalidCommand ; 0x4A 'J'
				goto InvalidCommand ; 0x4B 'K'
				goto DoCmdLoopBack ; 0x4C 'L' - enter loopback mode
				goto InvalidCommand ; 0x4D 'M'
				goto InvalidCommand ; 0x4E 'N'
				goto InvalidCommand ; 0x4F 'O'
				
				; 错误命令应答
				InvalidCommand:
				call SendError
				goto GetCommand
				
				;===========================================================
				DoCmdVerifyStatus:
				call VerifyStatus
				goto GetCommand
				
				DoCmdReset:
				goto Main
				
				;测试模式
				DoCmdLoopBack:
				movlw chPrompt
				call PutSerialByte
				call LoopBack
				movlw chAck
				call PutSerialByte
				goto GetCommand
				
				;读模拟频道
				DoCmdReadAnalog:
				movlw cmdReadA0
				subwf chCommand,w 
				movwf achRead ;and store as channel to read
				call ReadAnalogChannel ;get the analog value into bAvalL
				; and bAvalH
				btfss fbMode,bitModeAnalog ;if clear, in binary mode
				call SendAnalogBinary
				btfsc fbMode,bitModeAnalog ;if set, in ASCII mode
				call SendAnalogAscii
				goto GetCommand
				
				;二进制
				DoCmdSetBinary:
				bcf fbMode,bitModeAnalog
				movlw chAck
				call PutSerialByte
				goto GetCommand
				
				;十六进制
				DoCmdSetAscii:
				bsf fbMode,bitModeAnalog
				movlw chAck
				call PutSerialByte
				goto GetCommand
				
				;模拟输出模式询问操作. 应答'A' if in ASCII mode, and a 'B' if in binary mode
				DoCmdQueryMode:
				movlw 0x41 ;ASCII 'A' for ASCII mode
				btfss fbMode,bitModeAnalog ;if clear, we're in binary mode
				movlw 0x42 ;ASCII 'B' for binary mode
				call PutSerialByte ;send the response
				goto GetCommand
				
				clrf PORTA 
				clrf PORTB
				clrf PORTC
				
				bsf STATUS,RP0 ;access alternate file registers
				movlw fbTrisAInit ;0X2F
				movwf TRISA & 0x7F 
				movlw fbTrisBInit
				movwf TRISB & 0x7F 
				movlw fbTrisCInit
				movwf TRISC & 0x7F 
				bcf STATUS,RP0 
				
				movlw fbAdCon0Init ;0X81
				movwf ADCON0
				bsf STATUS,RP0
				movlw fbAdCon1Init ;0X80
				movwf ADCON1 & 0x7F
				bcf STATUS,RP0
				
				; 串行口异步, 波特9600
				bsf STATUS,RP0 
				movlw fbSerTxInit ;0X20
				movwf TXSTA & 0x7F 
				movlw cntBaudDiv ;9600 baud with BRGH=0
				movwf SPBRG & 0x7F
				bcf STATUS,RP0 ;access primary register file
				
				movlw fbSerRxInit ;0X90
				movwf RCSTA
				return
				
				;发送出错
				SendError:
				movlw chError
				call PutSerialByte
				return
				
				;发送应答字符
				VerifyStatus:
				movlw chStatusOk
				call PutSerialByte
				return
				
				LoopBack:
				lpbk10:
				call GetSerialByte ;等待在串行口收到字符
				xorlw chEsc
				btfsc STATUS,Z
				goto lpbk90
				
				xorlw chEsc
				call PutSerialByte
				goto lpbk10
				
				lpbk90: return 
				
				;进行AD,值存bAvalL and bAvalH. 
				ReadAnalogChannel:
				movf achRead,w
				movwf bRegA
				rlf bRegA,f
				rlf bRegA,f
				rlf bRegA,f
				movf bRegA,w
				iorlw fbAdCon0Init
				movwf ADCON0
				movlw cntAdDelay ; 容许样本保留电容变成充电 
				movwf bRegA
				
				rdac20: decfsz bRegA,f
				goto rdac20
				bsf ADCON0,GO_DONE ; Start the conversion
				
				rdac40: btfsc ADCON0,NOT_DONE
				goto rdac40
				
				bsf STATUS,RP0 
				movf ADRESL & 0x7F,w ;get the LSB of the result
				bcf STATUS,RP0 
				movwf bAvalL
				movf ADRESH,w
				movwf bAvalH
				return
				
				
				SendAnalogBinary:
				movf bAvalL,w ;get the LSB
				call PutSerialByte ;and send it
				movf bAvalH,w ;get the MSB
				call PutSerialByte ;and send it
				return
				;
				; -------------------------------------------------------
				; SendAnalogAscii
				;
				; This routine will send the analog value currently
				; stored in bAvalL and bAvalH out the serial port. The
				; data is sent as a packet with a lead character that
				; will be 'a' through 'e' (to indicate which channel the
				; response is for, followed by a 3 digit hex
				; number in ASCII. The value is send MSB first. The 
				; reponse packet is terminated by a '@' character.
				
				SendAnalogAscii:
				movf achRead,w ;get channel number
				addlw 0x61 ;add Ascii 'a'
				call PutSerialByte
				movf bAvalH,w ;get MSB of value to send
				andlw 0x0F ;mask to hex digit
				call ConvertHexDigit ;turn into hex ascii digit
				call PutSerialByte ;send out the serial port
				
				movf bAvalL,w ;get LSB of value
				movwf bRegA ;
				rrf bRegA,f ;shift right by 4 bits to
				rrf bRegA,f ; get the next digit into
				rrf bRegA,f ; the correct bit positions
				rrf bRegA,w
				andlw 0x0F ;isolate the bits for this digit
				call ConvertHexDigit ;turn into hex ascii digit
				call PutSerialByte ;send out the serial port
				
				movf bAvalL,w ;get LSB of value
				andlw 0x0F ;isolate the lower hex digit
				call ConvertHexDigit ;turn into hex ascii digit
				call PutSerialByte ;send out the serial port
				
				movlw chAck ; 送终止符
				call PutSerialByte
				return
				
				
				GetSerialByte:
				ifndef SIMDEBUG
				gtsb10: btfss PIR1,RCIF
				goto gtsb10
				endif
				movf RCREG,w
				return
				
				; -------------------------------------------------------
				; PutSerialByte
				; This routine will send a character out the serial port.
				; It checks the status of the transmit buffer, and waits
				; until it is clear before sending the byte.
				
				PutSerialByte:
				movwf chSend ;save output char temporarily
				ifndef SIMDEBUG
				ptsb10: btfss PIR1,TXIF ;wait until transmitter ready
				goto ptsb10 
				endif 
				
				movf chSend,w ;send the character
				movwf TXREG
				return
				
				; -------------------------------------------------------
				; ConvertHexDigit
				; This routine will convert the 4 bit value in W into
				; an hexadecimal digit in ASCII. The result is returned
				; in W.
				;
				; 0x0A is subtracted from the value to check if it is
				; in the range 0-9 or A-F. If in the range A-F, the 
				; difference between ascii 9 and ascii A is added to
				; bias the result. The value of ASCII '0' is added in
				; (plus the 0x0A that was subtracted in the test) to
				; convert the value to an ASCII numeric digit.
				
				
				ConvertHexDigit:
				movwf bRegA
				movlw 0x0A
				subwf bRegA,w
				btfsc STATUS,C ;if carry set, is in range 0-9
				addlw 0x41-0x39-1 ;bias for difference between '9' and 'A'
				addlw 0x30+0x0A ;convert to ASCII range
				return
				
				Delay:
				movlw 255
				movwf bRegA
				dely20: call BitDelay
				decfsz bRegA,f
				goto dely20
				return
				
				
				; This routine delays for one bit time on the serial
				; port. The delay time is 3*(n-1)+6 clocks.
				
				cntDlyBit equ 169 
				BitDelay:
				movlw cntDlyBit
				movwf bRegB
				btdl20: decfsz bRegB,f
				goto btdl20
				return
				
				;****************************************************************
				
				end 
				
				 
							

相关资源