Jiadong Yao
Member level 1
- Joined
- Mar 19, 2014
- Messages
- 40
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 6
- Activity points
- 278
#include <p18F2550.inc>
counter equ 0x21
delay equ 0x22
delay1 equ 0x23
delay2 equ 0x24
delay3 equ 0x25
;***********************************************************
; Reset Vector
;***********************************************************
ORG 0x800 ; Reset Vector
; When debugging:0x000; when loading: 0x800
GOTO START
;***********************************************************
; Interrupt Vector
;***********************************************************
ORG 0x808 ; Interrupt Vector HIGH priority
GOTO inter ; When debugging:0x008; when loading: 0x808
; 808high 818low
;***********************************************************
; Program Code Starts Here
;***********************************************************
ORG 0x820 ;When debugging:0x020; when loading: 0x820
START
clrf PORTA ; Initialize PORTA by clearing output data latches
movlw 0x39 ; Value used to initialize data direction
movwf TRISA ; Set RA0,3,4 as inputs 0001 1001
movlw 0x0F ; Configure A/D for digital inputs 0000 1111
movwf ADCON1 ;
movlw 0x07 ; Configure comparators for digital input
movwf CMCON
clrf PORTB ; Initialize PORTB by clearing output data latches
movlw 0x01 ; Value used to initialize data direction
movwf TRISB ; Set PORTB as output
clrf PORTC ; Initialize PORTC by clearing output data latches
movlw 0x00 ; Value used to initialize data direction
movwf TRISC
bcf UCON,3 ; to be sure to disable USB module p.166 why disable USB module??
bsf UCFG,3 ; disable internal USB transceiver p.168
movlw 0x00
movwf SSPSTAT ;sampled at middle
;transition from Idle to active
;Idle state for clock is a low level
movlw 0x22 ;SPI Master mode, clock = FOSC/64
movwf SSPCON1
clrf counter ; clear registers
movlw 0xff
movwf delay
movwf delay1
movwf delay2
movwf delay3
movlw 0x12 ;125KHz
movwf OSCCON
main
btfsc PORTA,3 ;if RA3=0, skip, go to main
goto select ;if RA3=1, go to select
goto main
select
btfsc PORTA,4 ;check RA4, if it is equal 1, go to up
goto up ; else go to down
goto down
up ; up counter
movlw 0xff ;move the 255 to W
cpfslt counter ; compare counter with W, skip if less than 255
goto up1
goto up2
up1
clrf counter ; clear, counter = 0
movf counter,0 ;show on PORTB
btfsc PORTA,0 ;test RA0
goto main
goto SPIsend
up2
incf counter,1 ;increment
movf counter,0 ;show on PORTB
btfsc PORTA,0 ;test RA0
goto main
goto SPIsend
down ;down counter
movlw 0x00 ; move 0 to the W
cpfsgt counter ;compare counter with W, skip if great than 0
goto down1 ;
goto down2
down1
movlw 0xff ; set counter = 255
movwf counter
movf counter,0 ;show on PORTB
btfsc PORTA,0 ;test RA0
goto main
goto SPIsend
down2
decf counter,1
movf counter,0 ;show on PORTB
btfsc PORTA,0 ;test RA0
goto main
goto SPIsend
delay_loop
Decfsz delay,1
goto $+2
decfsz delay1,1
goto $+2
decfsz delay2,1
goto $+2
decfsz delay3,1
goto delay_loop
return
SPIsend
movwf SSPBUF
goto main
SPIread
bcf PIR1,SSPIF
MOVFF SSPBUF,PORTB
call delay_loop
RETURN
inter ;interrupt doesn't occur
BTFSC PIR1,SSPIF
call SPIread
RETFIE
END
Connecting pins configured as output to ground may damage the device.
When MOSI pin sends the data, MISO pin triggering incoming data. In case of loop it will recieve exaclty what being send.
Where is SSPIE, PEIE and GIE in code ?
Where is your new code. If possible Zip and post the complete MPLAB or MPLABX MPASM project files.
Where is your new code. If possible Zip and post the complete MPLAB or MPLABX MPASM project files.
You need to write a counter program. It doesn't have anything to do with SPI communication.
You need to write a counter program. It doesn't have anything to do with SPI communication.
So, there will be two PICs right? One master and one slave. Master sends counter values to slave PIC and slave PIC displays this data on PORTB. Is that all you want ? Are both PICs 18F2550 ? What clock frequency each PIC is running at ?
Please post your circuit. In your code where is ISR ?
So, there will be two PICs right? One master and one slave. Master sends counter values to slave PIC and slave PIC displays this data on PORTB. Is that all you want ? Are both PICs 18F2550 ? What clock frequency each PIC is running at ?
Please post your circuit. In your code where is ISR ?
There will be only one PIC, that will receivce that what he will send. What circuit do you need? Where MISO connected to MOSI?
Ok. I though it was a PIC to PIC communication. Now I got it. I don't know whether one PIC can do that or not because data will be in SSPBUF register and how can the same register be used to send out data one bit at a time and also receive it because for receiving data also the same SSPBUF is required.
If it is a master to slave communication then it can be done. You copy the value of counter to SSPBUF and then increment the counter and send out this data to slave and slave receives this data in SSPBUF register and this SSPBUF register is assigned to PORTx say PORTB to display the counter value. Then there will be a small delay of say 1 second in the master before incrementing the counter.
I don't know how this can be done using a single PIC. Does 18F2550 has two SPIs ? If yes then it can be done.
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 // Software SPI module connections sbit SPI_MISO at RC0_bit; sbit SPI_MOSI at LATC1_bit; sbit SPI_MISO_Direction at TRISC0_bit; sbit SPI_MOSI_Direction at TRISC1_bit; // End Software SPI module connections unsigned char SPIOutData = 0, SPIInData; char toggleValue = 0; unsigned char SPI_Transfer(unsigned char SPIData) { char SPICount, inByte = 0; for(SPICount = 0; SPICount < 8; SPICount++) { inByte <<= 1; if (SPIData & 0x80) SPI_MOSI = 1; else SPI_MOSI = 0; inByte += SPI_MISO; SPIData <<= 1; } return inByte; } void main() { ADCON1 = 0x0F; CMCON = 0x07; CVRCON = 0x00; TRISA = 0xFF; TRISB = 0x00; TRISC = 0x00; SPI_MISO_Direction = 1; SPI_MOSI_Direction = 0; while(1) { if(!PORTA.F3) { Delay_ms(50); if(!PORTA.F3) { SPIInData = SPI_Transfer(SPIOutData); if(!PORTA.F0) { Delay_ms(50); if(!PORTA.F0) { LATB = SPIInData; } } if(!PORTA.F4) { Delay_ms(50); while(!PORTA.F4); toggleValue = ~toggleValue; } if(!toggleValue)++SPIOutData; else if(toggleValue)--SPIOutData; Delay_ms(1000); } } } }
Code ASM - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 counter equ 0x21 d1 equ 0x22 d2 equ 0x23 d1_2 equ 0x24 org 0x0000 START movlw 0x0F movwf ADCON1 movlw 0x07 movwf CMCON clrf CVRCON movlw 0xFF movwf TRISA movlw 0x01 movwf TRISB clrf TRISC clrf PORTA clrf PORTB clrf PORTC clrf SSPSTAT movlw 0x22 movwf SSPCON1 clrf counter main call SPI_Transfer rlcf W rlcf W movwf PORTB call Delay incf counter goto main SPI_Transfer movwf SSPBUF wait btfss SSPSTAT,BF bra wait movf SSPBUF,W return ;Delay = 1 seconds ;Clock frequency = 4 MHz ; Actual delay = 1 seconds = 1000000 cycles ; Error = 0 % Delay ;999990 cycles movlw 0x07 movwf d1 movlw 0x2F movwf d2 movlw 0x03 movwf d1_2 Delay_0 decfsz d1, f goto $+2 decfsz d2, f goto $+2 decfsz d1_2, f goto Delay_0 ;6 cycles goto $+1 goto $+1 goto $+1 ;4 cycles (including call) return end
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 unsigned char SPIInData = 0, SPIOutData = 0; char toggleValue = 0; unsigned char HW_SPI_Transfer(unsigned char SPIData) { unsigned char inByte = 0; SSPBUF = SPIData; while(!SSPSTAT.BF); SSPSTAT.BF = 0; inByte = SSPBUF; return inByte; } void main() { ADCON1 = 0x0F; CMCON = 0x07; CVRCON = 0x00; TRISA = 0xFF; TRISB = 0x01; TRISC = 0x00; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; SSPSTAT = 0x00; SSPCON1 = 0x22; while(1) { if(!PORTA.F3) { Delay_ms(50); if(!PORTA.F3) { SPIInData = HW_SPI_Transfer(SPIOutData); if(!PORTA.F0) { Delay_ms(50); if(!PORTA.F0) { SPIInData <<= 2; LATB = SPIInData; } } if(!PORTA.F4) { Delay_ms(50); while(!PORTA.F4); toggleValue = ~toggleValue; } if(!toggleValue)++SPIOutData; else if(toggleValue)--SPIOutData; Delay_ms(1000); } } } }
I have implemented what you want in HW SPI C code and it is working fine. PORTB is used to display received SPI data. RB2-RB7 is used to output data and so you can't see 8 bit value on PORTB. SDO is connected to SDI. Code is written in mikroC PRO PIC. Just study the code and implement it in ASM.
Proteus simulation attached.
- - - Updated - - -
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 unsigned char SPIInData = 0, SPIOutData = 0; char toggleValue = 0; unsigned char HW_SPI_Transfer(unsigned char SPIData) { unsigned char inByte = 0; SSPBUF = SPIData; while(!SSPSTAT.BF); SSPSTAT.BF = 0; inByte = SSPBUF; return inByte; } void main() { ADCON1 = 0x0F; CMCON = 0x07; CVRCON = 0x00; TRISA = 0xFF; TRISB = 0x01; TRISC = 0x00; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; SSPSTAT = 0x00; SSPCON1 = 0x22; while(1) { if(!PORTA.F3) { Delay_ms(50); if(!PORTA.F3) { SPIInData = HW_SPI_Transfer(SPIOutData); if(!PORTA.F0) { Delay_ms(50); if(!PORTA.F0) { SPIInData <<= 2; LATB = SPIInData; } } if(!PORTA.F4) { Delay_ms(50); while(!PORTA.F4); toggleValue = ~toggleValue; } if(!toggleValue)++SPIOutData; else if(toggleValue)--SPIOutData; Delay_ms(1000); } } } }
You can see my Proteus simulation. I have used 4 MHz external clock. You can also test in hardware. As soon as data is placed in SSPBUF, data is sent out 1 bit at a time with MSB first. The same data is also read as ADO is connected to SDI. after 8 bit in SSPBUF is shifted out, 8 bits also fill SSPBUF from SDI. I am shifting it twice to left so that the data when written to PORTB doesn't affect the SCK and ADI lines.
#include <xc.h>
void initChip();
//void interrupt ISPread();
unsigned char ISPsend(unsigned char);
void interrupt ISPread(){
if(PIR1bits.SSPIF == 1)
PIR1bits.SSPIF = 0;
while(!SSPSTATbits.BF);
SSPSTATbits.BF =0;
LATB = SSPBUF;
for(int i =0; i<1000;i++){}
}
void initChip(){
PORTA = 0x00; //Initial PORTA
PORTB = 0x00; //Initial PORTB
PORTC = 0x00; //Initial PORTC
TRISA = 0xff; //Define PORTA as input
TRISB = 0x01; //Define PORTB as output
TRISC = 0x00; //Define PORTC as output
ADCON1 = 0x0f; //Turn off ADcon
CMCON = 0x07; //Turn off Comparator
SSPSTAT = 0x00;
SSPCON1 = 0x22;
PIE1bits.SSPIE = 1;
INTCONbits.GIE = 1 ;
INTCONbits.PEIE =1; // enable peripherial when priority is disabled
RCONbits.IPEN =0 ; //disable priority
OSCCON = 0x12; //125KHz
}
unsigned char ISPsend(unsigned char SPIData){
unsigned char inByte = 0;
SSPBUF = SPIData;
while(!SSPSTATbits.BF);
SSPSTATbits.BF=0;
for(int i =0; i<1000;i++){} //delay
inByte = SSPBUF;
return inByte;
}
void main() {
unsigned char counter = 0; // local 8 bit variable
initChip(); // Initial all the PORTs and some configurations
while(1) { // Endless loop : make sure the program runs continuously
if (PORTAbits.RA0 == 1) //Check RA0, if it is equal to value 1
{
if (counter <255) // Up counter
counter = counter + 1;
else
counter = 0;
}
else
{
if (counter > 0) // Down counter
counter = counter -1;
else
counter = 255;
}
PORTB = ISPsend(counter)*4;
// ISPsend(counter);
for(int i =0; i<1000;i++){}
}
}
Code C - [expand] 1 LATB = SSPBUF;
Please Zip and attach your latest XC8 project files. Did you test my .hex in hardware ?
Don't use delays inside ISR. Did you simulate my Proteus designs with my .hex files ?
Don't do this.RB0 is configured as input (SDI). You have to shift SSPBUF values 2 bits to left and then assign it to PORTB.
Code C - [expand] 1 LATB = SSPBUF;
do you mean that we only give values to RB2 to RB7? Because RB0 and RB1 is used in other function. Do i understand correctly?You have to shift SSPBUF values 2 bits to left and then assign it to PORTB.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?