BASIC4MCU | 질문게시판 | SPI 통신으로 ISD4002 제어하기
페이지 정보
작성자 T800 작성일2018-06-11 18:19 조회12,082회 댓글1건첨부파일
본문
● 디 바 이 스 : PIC16F884
● 컴 파 일 러 : XC-8
PIC의 SPI 통신을 이용하여 ISD4002 칩에 저장된 음성 신호를 플레이 하고자 합니다.
기존에 ATMEGA를 이용해 성공하셨다는 분의 소스를 참고하여 고쳐봤는데 아웃풋 신호가 나오지를 않네요.
어느부분이 잘못된건지 검토 부탁드리겠습니다.
// CONFIG1
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR enabled)
#pragma config IESO = ON // Internal External Switchover bit (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3/PGM pin has PGM function, low voltage programming enabled)
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)
#include <xc.h>
#define led1 PORTBbits.RB1
#define led2 PORTBbits.RB0
#define led3 PORTDbits.RD6
#define led4 PORTDbits.RD7
#define led5 PORTDbits.RD4
#define led6 PORTDbits.RD5
#define led7 PORTCbits.RC6
#define led8 PORTCbits.RC7
#define led1_DIR TRISBbits.TRISB1
#define led2_DIR TRISBbits.TRISB0
#define led3_DIR TRISDbits.TRISD6
#define led4_DIR TRISDbits.TRISD7
#define led5_DIR TRISDbits.TRISD4
#define led6_DIR TRISDbits.TRISD5
#define led7_DIR TRISCbits.TRISC6
#define led8_DIR TRISCbits.TRISC7
#define SCK PORTCbits.RC3
#define SCK_DIR TRISCbits.TRISC3
#define SDI PORTCbits.RC4
#define SDI_DIR TRISCbits.TRISC4
#define SDO PORTCbits.RC5
#define SDO_DIR TRISCbits.TRISC5
#define SC PORTAbits.RA0
#define SC_DIR TRISAbits.TRISA0
#define SC_DCU PORTAbits.RA2
#define SC_DCU_DIR TRISAbits.TRISA2
#define WP PORTDbits.RD1
#define WP_DIR TRISDbits.TRISD1
#define ARAC PORTBbits.RB2
#define ARAC_DIR TRISBbits.TRISB2
#define AEOM PORTDbits.RD3
#define AEOM_DIR TRISDbits.TRISD3
#define POWER_UP 0b00100000
#define SET_PLAY 0b11100000
#define PLAY 0b11110000
#define STOP 0b00110000
#define STOP_PWRDN 0b00010000
#define VOICE_OPEN 0x0018 // "문이 열립니다"
#define VOICE_CLOSE 0x0024 // "문이 닫힙니다"
#define VOICE_BEEP1 0x0032
#define VOICE_BEEP2 0x004D
#define VOICE_CARE 0x0065
#define _XTAL_FREQ 20000000
#include <xc.h>
void write_cmd(unsigned char cmd);
void write_cmd_add(unsigned char cmd, unsigned int address);
//1바이트 SPI 전송함수
void spi_transmit_byte(unsigned char x)
{
SSPBUF = x;
while(!PIR1bits.SSPIF);
PIR1bits.SSPIF = 0;
}
void write_cmd(unsigned char cmd)
{
SC_DCU = 0; //ISD4002를 슬레이브로 선택
spi_transmit_byte(cmd); //cmd 8bit 전송
SC_DCU = 1; //ISD4002를 슬레이브로 선택해제
__delay_ms(10);
}
void write_cmd_add(unsigned char cmd, unsigned int address)
{
//LowAddress는 A7~A0, opcode는 C4~C0,0,A9,A8 의 구성
unsigned char LowAddress, opcode = 0;
LowAddress = (unsigned char)((address >> 8) & 0x00003); //A9 A8 추출
opcode = cmd | LowAddress; //cmd와 A9,A8 결합
LowAddress = (unsigned char)(address & 0x00FF); //하위 어드레서 추출
SC_DCU = 0;
spi_transmit_byte(LowAddress); //LSB opcode 전송
spi_transmit_byte(opcode); //MSB opcode 전송
SC_DCU = 1;
__delay_ms(10);
}
void SPI_Init(void)
{
SSPCON = 0b00100010; //SSPEN:1, CKP:0, SSPM:0010(312.5khz)
//SSPEN: Synchronous Serial Port Enable bit
//양 모드 에서, 활성화될 때, 이러한 핀들은 적절하게 입력 또는 출력으로 구성되어야 한다
//1 = 시리얼 포트를 활성화하고 SCK, SDO, SDI, 와 SS를 시리얼 포트 핀의 소스로서 구성해야 한다.
//0 = 시리얼 포트를 비활성화하고 이러한 핀들을 I/O 포트 핀으로 구성해야 한다.
//SSPM3:SSPM0: Synchronous Serial Port Mode Select bits
//0000= SPI master mode, clock = FOSC/4
//0001= SPI master mode, clock = FOSC/16
//0010= SPI master mode, clock = FOSC/64
//0011= SPI master mode, clock = TMR2 output/2
//0100= SPI slave mode, clock = SCK pin. SS 핀 제어 활성화..
//0101= SPI slave mode, clock=SCK pin. SS 핀 제어는 비활성화. SS는 I/O 핀으로 사용가능
//0110= slave mode, 7-bit address
//0111= slave mode, 10-bit address
//1000= master mode, clock = FOSC/ (4 * (SSPADD+1))
//1xx1= Reserved
//1x1x= Reserved
NOP();
NOP();
SSPSTAT = 0b01000000; // SMP:0(bit7), CKE:1(bit6),SPI 마스터 모드
//SMP
//1 = 데이터 출력시간의 끝에 입력 데이터 샘플
//0 = 데이터 출력시간의 중간에 입력 데이터 샘플
//CKE : SPI Clock Edge Select
//1 = SCK의 상승하는 에지에서 데이터를 전송한다.
//0 = SCK의 하강하는 에지에서 데이터를 전송한다.
NOP();
NOP();
SSPIF = 0;
}
void led_onoff()
{
led1_DIR = 0; led2_DIR = 0; led3_DIR = 0; led4_DIR = 0;
led5_DIR = 0; led6_DIR = 0; led7_DIR = 0; led8_DIR = 0;
led1 = 0; led2 = 0; led3 = 0; led4 = 0;
led5 = 1; led6 = 1; led7 = 0; led8 = 1;
}
int main(void)
{
ANSELH=0x00;
INTCON = 1;
SCK_DIR = 0;
SDI_DIR = 1;
SDO_DIR = 0;
SC_DIR = 0;
SC_DCU_DIR = 0;
WP_DIR = 0;
WP = 1;
ARAC_DIR = 0;
AEOM_DIR = 0;
ARAC = 1;
AEOM = 1;
SPI_Init();
unsigned int a = VOICE_OPEN;
while(1)
{
write_cmd_add(POWER_UP, 0); //1. power up
__delay_ms(2000); //2. wait Tstop
write_cmd_add(SET_PLAY, a); //3. PLAY from address a
__delay_ms(2000);
write_cmd(PLAY); //SET_PLAY와 연결해서 address a이후 current 에서 PLAY
__delay_ms(5000);
write_cmd_add(STOP, 0); // STOP
__delay_ms(2000);
}
}
댓글 1
조회수 12,082master님의 댓글
master 작성일통신은 오실로스코프나 로직아날라이저 등의 계측기를 사용해서 디버깅 해야지 수월합니다.