Вот, понадобилось термометр к PIC'у приделать, и как не бьюсь, что-то у меня не выходит ничего, может, кто подскажет, как это правильно делается.
А вот собственно программа:
radix DEC LIST P=18F252 #include "p18f252.inc" cblock 0x10 ADDR DATA t0 t1 t2 endc Fosc equ 20000000 SBaud equ 9600 IBaud equ 100000
org 0x00000 goto start org 0x00020
start: movlw b'00100100' movwf TXSTA movlw (Fosc / (16 * SBaud)) movwf SPBRG movlw b'10010000' movwf RCSTA
bcf TRISC, 3 bcf TRISC, 4 movlw 0x38 movwf SSPCON1 clrf SSPCON2 movlw ((Fosc / (4 * IBaud)) - 1) movwf SSPADD bsf SSPSTAT, CKE bsf SSPSTAT, SMP bcf PIR1, SSPIF bcf PIR2, BCLIF movlw 0x9F movwf ADDR
movlw 'R' movwf TXREG main: call i2c_start call i2c_write_addr call i2c_read_byte ; call i2c_read_byte call i2c_stop movff DATA, TXREG call delay_100ms goto main
i2c_start: bsf SSPCON2,SEN ; Send start bit btfsc SSPCON2,SEN ; Has SEN cleared yet? goto $-2 ; No, loop back to test. return
i2c_write_addr: bcf PIR1,SSPIF ; clear interrupt flag movff ADDR,SSPBUF btfss PIR1,SSPIF ; has SSP completed sending SLAVE Address? goto $-2 ; no, loop back to test btfss SSPCON2,ACKSTAT ; was ACK received from slave? return ; yes, return to calling routine bsf SSPCON2,RSEN ; send repeated start bit btfsc SSPCON2,RSEN ; has repeated start been sent yet? goto $-2 ; no, loop back to test bra i2c_write_addr ; send slave address again
i2c_read_byte: bcf PIR1,SSPIF ; clear interrupt flag bsf SSPCON2,RCEN ; enable receive mode btfss PIR1,SSPIF ; has SSP received a data byte? goto $-2 ; no, loop back to test movff SSPBUF, DATA ; send data to serial bsf SSPCON2,ACKDT ; no ACK bsf SSPCON2,ACKEN ; send ACKDT bit btfsc SSPCON2,ACKEN ; has ACKDT bit been sent yet? goto $-2 ; no, loop back to test bcf SSPCON2,RCEN ; disable receive mode return
i2c_stop: bsf SSPCON2,PEN ; send stop bit btfsc SSPCON2,PEN ; has stop bit been sent? goto $-2 ; no, loop back to test return
delay_100ms movlw d'10' movwf t2 ; 10 ms d0: movlw (Fosc / 100000) movwf t1 d1: movlw d'62' movwf t0 d2: decf t0,0 btfss STATUS,Z goto d2 decfsz t1,0 goto d1 decfsz t2,0 goto d0 return END
Ну и фигнюшка, чтобы из сериала дампить:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include <errno.h>
#include <time.h>
int main(int argc, char **argv) { int fd; struct termios tios; unsigned char c;
if ((fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY)) < 0) { perror(""); exit(2); }
tcgetattr(fd, &tios); tcflush(fd, TCIFLUSH); tios.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS); /* no parity or flow control */ tios.c_iflag &= ~(IXON | IXOFF | IXANY | INLCR | ICRNL); tios.c_cflag |= CLOCAL | CREAD | CS8; /* 8 data bits, two way communication */ tios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* get raw data from port */ tios.c_oflag &= ~ OPOST; /* send raw data */ cfsetospeed(&tios, B9600); tcsetattr(fd, TCSANOW, &tios); for(;;) { if (read(fd, &c, 1) == 1) { printf("%02x (%c)\n", c, c); fflush(stdout);
} } }