lbq13
Newbie level 1
code from asm to c
hi everyone,
i'm doing my bachelorproject with rfPIC. but microchip does't offer the democode in C, only in asm.
So i tried to translate the code in C. unluckly the Code does't work. can anyone help me find the errors?
thanks a lot!
the code in asm
the code in C
hi everyone,
i'm doing my bachelorproject with rfPIC. but microchip does't offer the democode in C, only in asm.
So i tried to translate the code in C. unluckly the Code does't work. can anyone help me find the errors?
thanks a lot!
the code in asm
Code:
;----------------------------------------------------------------------
;
; Program Description
;
; This program demonstrates simple command & control and analog
; application demonstrations. To see each demonstration the user must
; load the appropriate receiver code examples:
;
; rcvr_demo.asm
;
; When a push button on the transmitter module is depressed, the
; corresponding LED is lit on the PICkit(tm) 1 FLASH Starter Kit.
; Pressing transmitter module push button GP3 lights LED D0 on the
; PICkit(tm) 1. Pressing push button GP4 lights LED D1.
;
;----------------------------------------------------------------------
list p=12f675 ; list directive to define processor
#include <p12f675.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file
; ---------------------------------------------------------------------
; Configuration Bits (Section 9.1 Configuration Bits)
; ---------------------------------------------------------------------
; ---------------------------------------------------------------------
__CONFIG _CPD_OFF & _CP_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT
;----------------------------------------------------------------------
; Variables (Section 2.2 Data Memory Organization)
;----------------------------------------------------------------------
; Data Memory Organization (Section 2.2)
;
; Register locations 0x20 to 0x5F (64 bytes) are General Purpose
; registers, implemented as static RAM and are mapped across both
; banks.
cblock 0x20
w_temp ; used for context saving
status_temp ; used for context saving
TEMP ; General Purpose Temporary register
CSR0 ; TX buffer shift register
CSR1
CSR2
CSR3
CSR4
CSR5
CSR6
CSR7
CSR8
Count
Count2
BitCount
TimeHi
TimeLo
FuncBits ; Function Bits
endc
;----------------------------------------------------------------------
; Defines
;----------------------------------------------------------------------
; Set up GPIO Port (Section 3.0)
; Function of GPIO pins depend on:
; Configuration Bits (CONFIG) (Section 9.1)
; Weak Pull-up Register (WPU) (Section 3.2.1)
; Interrupt-on-change GPIO Register (IOCB) (Section 3.2.2)
; Option Register (OPTION_REG) (Register 4-1)
; TIMER1 Control Register (T1CON) (Register 5-1)
; Comparator Control Register (CMCON) (Section 6.0)
; A/D Control Register (ADCON0) (Section 7.0) (PIC12F675 Only)
#define POT0 GPIO, 0 ; (Analog Input) Potentiometer GP0
#define POT1 GPIO, 1 ; (Analog Input) Potentiometer GP1
#define TXD GPIO, 2 ; (Output) Transmit Data
#define PB3 GPIO, 3 ; (Input Only) Push button switch GP3
#define PB4 GPIO, 4 ; (Input) Push button switch GP4
#define RFENA GPIO, 5 ; (Output) RF Enable
; Define for TRISIO Register (Section 3.1)
;
; GPIO is an 6-bit wide, bi-directional port. The corresponding data
; direction register is TRISIO. Setting a TRISIO bit (= 1) will make
; the corresponding GPIO pin and input. Clearing a TRISIO bit (= 0)
; will make the corresponding GPIO pin an output. The exception is
; GP3, which is input only and its TRIS bit will always read as a '1'.
; GPIO Pins = xx543210
#define GPTRIS B'00011011'
; delays/timings
#define TGUARD D'46' ; 46 X TE
#define PREAMB D'16' ; Preamble length = 16 pulses
;----------------------------------------------------------------------
; Program Memory
;----------------------------------------------------------------------
; Program Memory Organization (Section 2.1)
ORG 0x000 ; RESET Vector
nop ; for ICD use
goto INITALIZE ; goto INITALIZE
ORG 0x004 ; Interrupt Vector
movwf w_temp ; save W register
swapf STATUS, W ; swap status to be saved into W
bcf STATUS, RP0 ; ---- Select Bank 0 -----
movwf status_temp ; save STATUS register
;----------------------------------------------------------------------
; Subroutine: WaitxTE
;
; Description:
;
; Constants:
;
; Global Variables:
;
; Initialization: W x 400us length of delay required
;
; Output: Count, Count2 as decrementing counters
;
;----------------------------------------------------------------------
WaitxTE
movwf Count2 ; [1]
waitxlp
movlw D'79' ; [1]
movwf Count ; [1]
wait400lp
nop ; [1]
nop ; [1]
decfsz Count,F ; [1]
goto wait400lp ; [2]
; --------
; 79 x 5 = 395us
decfsz Count2,F ; [1]
goto waitxlp ; [2]
retlw 0 ; [2]
; total 2 (call) + W x (395 + 5) + 2 (return)
; w = 1 -> 406us @4MHz
; w = 2 -> 806us @4MHz
;----------------------------------------------------------------------
; Initialize PICmicro (PIC12F675)
;----------------------------------------------------------------------
INITALIZE
; Disable global interrupts during initialization
bcf INTCON, GIE ; disable global interrupts
;----------------------------------------
; Calibrating the Internal Oscillator (Section 9.2.5.1)
; Oscillator Calibration Register (Section 2.2.2.7)
;
; A calibration instruction is programmed into the last location of
; program memory. This instruction is a RETLW XX, where the literal is
; the calibration value. The literal is placed in the OSCCAL register
; to set the calibration of the internal oscillator.
bsf STATUS, RP0 ; ---- Select Bank 1 -----
call 0x3FF ; retrieve factory calibration value
movwf OSCCAL ; update register with factory cal value
bcf STATUS, RP0 ; ---- Select Bank 0 -----
;----------------------------------------
; GPIO Port (Section 3.0)
;
; Store GPTRIS value defined above into the TRISIO direction register
bsf STATUS, RP0 ; ---- Select Bank 1 -----
movlw GPTRIS
movwf TRISIO ; Write to TRISIO register
bcf STATUS, RP0 ; ---- Select Bank 0 -----
;----------------------------------------
; Comparator Module (Section 6.0)
;
; The PIC12F629/675 devices have one analog comparator. The inputs to
; the comparator are multiplexed with the GP0 and GP1 pins. There is
; an on-chip Comparator Voltage Reference that can also be applied to
; an input of the comparator. In addition, GP2 can be configured as
; the comparator output. The Comparator Control Register (CMCON)
; contains bits to control the comparator. The Voltage Reference
; Control Register (VRCON) controls the voltage reference module.
; Comparator Configuration (Figure 6-2)
; bcf CMCON, CINV ; Comparator Output Inversion: not inverted
; bcf CMCON, COUT ; Comparator Output bit: Vin+ < Vin-
; bcf CMCON, CIS ; Comparator Input Switch: Vin- connectos to Cin-
; CM2:CM0 = 111 - Comparator Off (lowest power)
bsf CMCON, CM2 ; Comparator Mode bit 2
bsf CMCON, CM1 ; Comparator Mode bit 1
bsf CMCON, CM0 ; Comparator Mode bit 0
; VRCON (Register 6-2)
bsf STATUS, RP0 ; ---- Select Bank 1 -----
bcf VRCON, VREN ; CVref circuit: powered down, no Idd drain
; bcf VRCON, VRR ; CVref Range Selection: High Range
; bcf VRCON, VR3 ; CVref value selection bit 3
; bcf VRCON, VR2 ; CVref value selection bit 2
; bcf VRCON, VR1 ; CVref value selection bit 1
; bcf VRCON, VR0 ; CVref value selection bit 0
bcf STATUS, RP0 ; ---- Select Bank 0 -----
;----------------------------------------
; Analog-to-Digital Converter (A/D) Module (Section 7.0) (PIC12F675 Only)
;
; The analog-to-digital converter (A/D) allows conversion of an analog
; input signal to a 10-bit binary representation of that signal. The
; PIC12F675 has four analog inputs multiplexed into one sample and hold
; circuit. There are two registers to control the functions of the A/D
; module:
; A/D Control Register (ADCON0)
; Analog Select Register (ANSEL)
;
; Note: When using GPIO pins as analog inputs, ensure the TRISIO register
; bits are set (= 1) for input.
bcf ADCON0, ADFM ; A/D Result Formed: left justified
bcf ADCON0, VCFG ; Voltage Reference: Vdd
bcf ADCON0, ADON ; ADC is shut-off and consumes no operating current
bsf STATUS, RP0 ; ---- Select Bank 1 -----
; select A/D Conversion Clock Source: Fosc/8
bcf ANSEL, ADCS2 ; A/D Conversion Clock Select bit 2
bcf ANSEL, ADCS1 ; A/D Conversion Clock Select bit 1
bsf ANSEL, ADCS0 ; A/D Conversion Clock Select bit 0
; select GPIO pins that will be analog inputs: GP0/AN0, GP1/AN1
bcf ANSEL, ANS3 ; Analog Select GP4/AN3: digital I/O
bcf ANSEL, ANS2 ; Analog Select GP2/AN2: digital I/O
bcf ANSEL, ANS1 ; Analog Select GP1/AN1: analog input
bcf ANSEL, ANS0 ; Analog Select GP0/AN0: analog input
bcf STATUS, RP0 ; ---- Select Bank 0 -----
;----------------------------------------
; TIMER1 Module with Gate Control (Section 5.0)
;
; The TIMER1 Control Register (T1CON) is used to enable/disable TIMER1
; and select various features of the TIMER1 module.
bcf T1CON, TMR1ON ; TIMER1: stopped
bcf T1CON, TMR1CS ; TIMER1 Clock Source Select: Internal Clock (Fosc/4)
bcf T1CON, NOT_T1SYNC ; TIMER1 External Clock Input Sync Control: Syncronize external clock input
; T1OSCEN only if INTOSC without CLKOUT oscillator is active, else ignored
bcf T1CON, T1OSCEN ; LP Oscillator Enable Control: LP oscillator off
; TIMER1 Input Prescale Select: 1:1
bcf T1CON, T1CKPS1 ; TIMER1 Input Clock Prescale Select bit 1
bcf T1CON, T1CKPS0 ; TIMER1 Input Clock Prescale Select bit 0
; TMR1GE only if TMR1ON = 1, else ignored
bcf T1CON, TMR1GE ; TIMER1 Gate Enable: on
;----------------------------------------
; Weak Pull-up Register (WPU) (Section 3.2.1)
;
; Each of the GPIO pins, except GP3, has an individually configurable
; weak internal pull-up. Control bits WPUx enable or disable each
; pull-up. Refer to Register 3-1. Each weak pull-up is automatically
; turned off when the port pin is configured as an output. The pull-ups
; are disabled on a Power-on Reset by the NOT_GPPU bit (see OPTION_REG below).
bsf STATUS, RP0 ; ---- Select Bank 1 -----
; GPIO Pins = xx54x210
movlw B'00010000' ; GP4 pull-up enabled
movwf WPU
bcf STATUS, RP0 ; ---- Select Bank 0 -----
;----------------------------------------
; OPTION Register (OPTION_REG) (Section 2.2.2.2)
; TIMER0 Module (Section 4.0)
;
; The OPTION_REG contains control bits to configure:
; Weak pull-ups on GPIO (see also WPU Register above)
; External GP2/INT interrupt
; TMR0
; TMR0/WDT prescaler
bsf STATUS, RP0 ; ---- Select Bank 1 -----
bcf OPTION_REG, NOT_GPPU ; GPIO pull-ups: enabled
bsf OPTION_REG, INTEDG ; Interrupt Edge: on rising edge of GP2/INT pin
bcf OPTION_REG, T0CS ; TMR0 Clock Source: internal instruction cycle (CLKOUT)
bcf OPTION_REG, T0SE ; TMR0 Source Edge: increment low-to-high transition on GP2/T0CKI pin
bcf OPTION_REG, PSA ; Prescaler Assignment: assigned to TIMER0
; TMR0 Prescaler Rate: 1:2
bcf OPTION_REG, PS2 ; Prescaler Rate Select bit 2
bcf OPTION_REG, PS1 ; Prescaler Rate Select bit 1
bcf OPTION_REG, PS0 ; Prescaler Rate Select bit 0
bcf STATUS, RP0 ; ---- Select Bank 0 -----
;----------------------------------------
; Interrupt-on-Change Register (IOCB) (Section 3.2.2)
;
; Each of the GPIO pins is individually configurable as an interrupt-
; on-change pin. Control bits IOCBx enable or disable the interrupt
; function for each pin. Refer to Register 3-2. The interrupt-on-change
; is disabled on a Power-on Reset.
;
; Note: Global interrupt enables (GIE and GPIE) must be enabled for
; individual interrupts to be recognized.
bsf STATUS, RP0 ; ---- Select Bank 1 -----
; GPIO Pins = xx543210
movlw b'00011000'
movwf IOCB ; Interrupt-on-change enabled: GP3, GP4
bcf STATUS, RP0 ; ---- Select Bank 0 -----
;----------------------------------------
; Peripheral Interrupt Enable Register (PIE1) (Section 2.2.2.4)
;
; The PIE1 register contains peripheral interrupt enable bits.
;
; Note: The PEIE bit (INTCON<6>) must be set to enable any
; peripheral interrupt.
bsf STATUS, RP0 ; ---- Select Bank 1 -----
bcf PIE1, EEIE ; EE Write Complete Interrupt: disabled
bcf PIE1, ADIE ; A/D Converter Interrupt (PIC12F675 Only): disabled
bcf PIE1, CMIE ; Comparator Interrupt: disabled
bcf PIE1, TMR1IE ; TMR1 Overflow Interrupt: disabled
bcf STATUS, RP0 ; ---- Select Bank 0 -----
;----------------------------------------
; Interrupt Control Register (INTCON) (Section 2.2.2.3)
;
; The INTCON register contains enable and disable flag bits for TMR0
; register overflow, GPIO port change and external GP2/INT pin
; interrupts.
bcf INTCON, PEIE ; disable Peripheral Interrupt Enable bit
bcf INTCON, T0IE ; disable TMR0 Overflow Interrupt Enable bit
bcf INTCON, INTE ; disable GP2/INT External Interrupt Enable bit
bsf INTCON, GPIE ; enable Port Change Interrupt Enable bit
; bcf INTCON, GIE ; disable global interrupts
;----------------------------------------------------------------------
;----------------------------------------------------------------------
; Main Program
;----------------------------------------------------------------------
;----------------------------------------------------------------------
MAIN
bcf RFENA ; Disable Transmitter
bsf INTCON, GIE ; enable global interrupts
;----------------------------------
; Scan push buttons
;----------------------------------
SCANPB
movlw 0x00 ; load zero into W
movwf FuncBits ; clear Function Bits register
btfsc PB3 ; Push Button GP3 pressed?
goto SPB1
movlw 0x23 ; Function S0 selected
iorwf FuncBits, F
SPB1
movlw 0xFF
andwf FuncBits, W ; Was any switch depressed?
btfss STATUS, Z
goto XMIT ; Yes, transmit buffer
bcf RFENA ; No, disable Transmitter
sleep ; Put PICmicro to sleep
goto SCANPB ; Upon wake-up on pin change, scan push buttons
;----------------------------------
; fill in transmission buffer
;----------------------------------
XMIT
bsf RFENA ; Enable Transmitter
movlw 0x73 ; send Serial number
movwf CSR0
movfw FuncBits ; send Function Bits
movwf CSR1
; send 16-bit Counter
;
; send analog value (this is modified from the fixed
; KeeLoq(r) protocol; these two fields are normally
; used for 16-bit counter value)
movfw 0x00 ; ADRESL Result
movwf CSR2
movfw 0x00 ; ADRESH Result
movwf CSR3
movlw 0x56 ; send 32-bit serial number 1 (ignored by receiver)
movwf CSR4
movlw 0x34
movwf CSR5
movlw 0x12
movwf CSR6
movlw 0x20
movwf CSR7
movlw 0x55 ; send Flags
movwf CSR8
;----------------------------------
; Transmission Loop
;----------------------------------
TXLoop
; send preamble (50% duty cycle)
Preamble
movlw PREAMB
movwf BitCount ; init number of preamble bits
PreL
bsf TXD ; ON
movlw 1
call WaitxTE ; delay
bcf TXD ; OFF
movlw 1
call WaitxTE ; delay
decfsz BitCount,F ; loop
goto PreL
; sync pause
TXloop
movlw D'10' ; Theader = 10 x Te
call WaitxTE
; send 72 bit pattern
movlw CSR0 ; lsb first
movwf FSR
TXNextByte
movlw D'8'
movwf BitCount
TXNextBit
rrf INDF,W ; 8 bit rotate
rrf INDF,F ; Carry contain lsb
BC ONE
ZERO
movlw 2 ;
movwf TimeHi ; +---+---+ +--
movlw 1 ; | | |
movwf TimeLo ;---+ +---+
goto Trasm_BIT ; | 2Te Te |
ONE
movlw 1 ;
movwf TimeHi ; +---+ +--
movlw 2 ; | | |
movwf TimeLo ;---+ +---+---+
; | Te 2Te |
Trasm_BIT
bsf TXD ; ON
movf TimeHi,W
call WaitxTE
bcf TXD ; OFF
movf TimeLo,W
call WaitxTE
decfsz BitCount,F
goto TXNextBit ; loop on bits
incf FSR,F
movlw CSR8+1 ; check if finished
xorwf FSR,W
andlw 0x1F
BNZ TXNextByte
; guard time
movlw TGUARD
call WaitxTE
goto SCANPB ; go back and scan for push button presses
;----------------------------------------------------------------------
; Data EEPROM Memory (Section 8.0)
;
; PIC12F629/675 devices have 128 bytes of data EEPROM with address
; range 0x00 to 0x7F.
; Initialize Data EEPROM Memory locations
; ORG 0x2100
; DE 0x00, 0x01, 0x02, 0x03
;----------------------------------------------------------------------
; Calibrating the Internal Oscillator (Section 9.2.5.1)
; Oscillator Calibration Register (OSCCAL) (Section 2.2.2.7)
;
; The below statements are placed here so that the program can be
; simulated with MPLAB SIM. The programmer (PICkit or PROMATE II)
; will save the actual OSCCAL value in the device and restore it.
; The value below WILL NOT be programmed into the device.
org 0x3ff
retlw 0x80
;----------------------------------------------------------------------
end ; end of program directive
;----------------------------------------------------------------------
the code in C
Code:
#include <pic.h>
#include <htc.h> // Required to interface with delay routines
#define uchar unsigned char
#define uint unsigned int
//Config: no code or data protect, no brownout detect, ext reset, power-up timer enabled, watchdog, 4MHz int clock
__CONFIG(UNPROTECT & BORDIS & MCLRDIS & PWRTDIS & WDTDIS & INTIO);
#define POT0 GPIO0
#define POT1 GPIO1
#define TXD GPIO2
#define BUTTON3 GPIO3
#define BUTTON4 GPIO4
#define RFENA GPIO5
#define rf_ON RFENA=1;TRISIO=0
#define rf_OFF RFENA=0;TRISIO=0
#define DATA_BYTES 9 // number of bytes in data part of transmission message
#define Serial_number 0x73
#define FuncBits 0x23
#ifndef _XTAL_FREQ
// Unless already defined assume 4MHz system frequency
// This definition is required to calibrate __delay_us() and __delay_ms()
#define _XTAL_FREQ 4000000
#endif
void Init();
void Xmit_One();
void Xmit_Zero();
void Preamble();
void Header();
void TransmitBytes();
void TGuard();
void Transmit_Data();
uchar data_array[DATA_BYTES]; // data for transmission
//*********************** CODE WORD FORMAT ****************************
// _ _ _ _ _ __ _ __ _ _
// | | | | | | | | | | | | | | | | | | |
// | |_| |_| |_| |_____________| |__| |_| |_/ /_| |_| |_________|
// / /
// |--PREAMBLE---|---HEADER----|---------DATA------------|--GUARD--|
// TIME
// *********************************************************************
// *********************** DATA FORMAT *********************************
// //
// bytes | DATA1 | DATA0 |
// bits | 7| 6| 5| 4| 3| 2| 1| 0| 7| 6| 5| 4| 3| 2| 1| 0|
// desc. |S2|S1|S0|S3| 0| 0| SERIAL NUMBER |
//
// bytes | DATA3 | DATA2 |
// bits | 7| 6| 5| 4| 3| 2| 1| 0| 7| 6| 5| 4| 3| 2| 1| 0|
// desc. | Temperature Data |
//
// * S3 Not used
//
// *********************************************************************
//****************************************************************************
// Init
//****************************************************************************
void Init(void)
{
GIE = 0;
OSCCAL=0x3FF;
TRISIO=0b00011011;
CMCON=0b00000111;
VRCON=0x00;
ADCON0=(ADCON0&0b00111110);
ANSEL=0b00010000;
T1CON=0x00;
WPU=0b00010000;
OPTION=0b01000000;
IOC=0b00011000;
PIE1=0x00;
PEIE=0;
T0IE=0;
INTE=0;
GPIE=1;
}
//**************************************************************************
//transmitting a logic one via RF
// +---+ +--
// | | |
//---+ +---+---+
// | Te| 2Te |
//**************************************************************************
void Xmit_One()
{
uchar i;
TXD=1;
__delay_us(400); //Delay 400us;
TXD=0;
__delay_us(800); //Delay 800us;
}
//**************************************************************************
//transmitting a logic zero via RF // +---+---+ +--
// | | |
//---+ +---+
// | 2Te | Te|
//**************************************************************************
void Xmit_Zero()
{ uchar i;
TXD=1;
__delay_us(800); //Delay 800us;
TXD=0;
__delay_us(400); //Delay 400us;
}
//**************************************************************************
// transmit Preamble of transmission message
//**************************************************************************
void Preamble()
{
uchar BitCount;
uchar i;
for (BitCount=0; BitCount<16; BitCount++)
{
TXD=1;
__delay_us(400); //Delay 400us;
TXD=0;
__delay_us(400); //Delay 400us;
}
}
//**************************************************************************
// transmit header bits of transmission message
//Sync Pulse (Wait 10 TE)
//**************************************************************************
void Header()
{
TXD=0;
__delay_ms(4);
}
//**************************************************************************
// transmit 72 bits of data
// for each of 9 bytes of data
//**************************************************************************
void TransmitBytes()
{
uchar x;
uchar i;
for (x=0; x<DATA_BYTES; x++) //DATA_BYTES=9
{
// for each bit in the byte
for (i=0; i<8; i++)
{
if (data_array[x] & 0x80) // (load the data) - mask all but MSB
{
Xmit_One(); //the carry bit = 1, transmit the bit
}
else
{
Xmit_Zero(); //the carry bit = 0, transmit the bit
}
data_array[x] = (data_array[x] << 1); // roll the bits one place to the left.
}
}
}
//**************************************************************************
// Wait 46 TE’s for the Guard Time;transmit no data
// for guard time 46*400us=92*200us=18400us
//**************************************************************************
void TGuard()
{
uchar a;
TXD=0;
__delay_ms(18); //Delay Guardtime=46*Te
}
//**************************************************************************
//
//**************************************************************************
void Transmit_Data()
{
// turn on rf transmitter
rf_ON;
// Format the data string to be transmitted
data_array[0] = 0x73;
data_array[1] = 0x23;
data_array[2] = 0x00;
data_array[3] = 0x00;
data_array[4] = 0x56;
data_array[5] = 0x34;
data_array[6] = 0x12;
data_array[7] = 0x20;
data_array[8] = 0x55;
// transmit Preamble of transmission message
Preamble();
// transmit header bits of transmission message /Sync Pulse (Wait 10 TE)
Header();
// transmit 32 bits of data
// for each of 4 bytes of data
TransmitBytes();
// Wait 46 TE’s for the Guard Time;transmit no data for guard time 46*400us=92*200us=18400us
TGuard();
}
void main()
{
RFENA=0;
GIE=1;
Init();
while(1)
{
if(BUTTON3==0)
{
__delay_ms(10);
if(BUTTON3==0)
{
Transmit_Data();
}
}
// turn off rf transmitter
rf_OFF;
}
}