PIC12F1840のMSSPを使ってSPIを撃ってみます。MCC使うと簡単という噂ですが、なぜかうまくいかなかったので、自力で行きます。
で、めんどくさいので、いきなり最終コードです。今回はLVP=OFFです。なんか、MCLRピンを専用で確保できるならHVのほうが良いということがどこかに書いてあったので。
MCCでうまくいかなかったのですが、MCCで生成したコードを参考にして作成しました。くだらないところで結構悩みましたが、、、MCCと違って、ペリフェラルの割り込みでバッファを更新するようにしたので、SPI送信中に別のことができます。
- /*
- * File: main.c
- * Author:
- *
- * Created on November 3, 2020, 6:27 PM
- */
- // PIC12F1840 Configuration Bit Settings
- // 'C' source line config statements
- // CONFIG1
- #pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
- #pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
- #pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
- #pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
- #pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
- #pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
- #pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)
- #pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
- #pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
- #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)
- // CONFIG2
- #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
- #pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
- #pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
- #pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
- #pragma config LVP = OFF // Low-Voltage Programming Enable (Low-voltage programming enabled)
- // #pragma config statements should precede project file includes.
- // Use project enums instead of #define for ON and OFF.
- #include <stdint.h>
- #include <xc.h>
- #define _XTAL_FREQ 8000000
- typedef struct {
- uint8_t len;
- uint8_t pos;
- uint8_t ongoing;
- uint8_t txbuf[16];
- uint8_t rxbuf[16];
- }spi_tx_buf_t;
- volatile spi_tx_buf_t stbuf;
- void __interrupt() isr(void){
- if(PIR1&0x08){
- PIR1&=~0x08;
- stbuf.rxbuf[stbuf.pos]=SSP1BUF;
- stbuf.pos=stbuf.pos+1;
- if(stbuf.pos<stbuf.len){
- SSP1BUF=stbuf.txbuf[stbuf.pos];
- }else{
- stbuf.ongoing=0;
- }
- }
- }
- void SPI_master_begin(){
- unsigned char dummy;
- SSPSTAT&= ~(0b01000000);
- SSP1CON1= (0b00001010);
- SSP1CON2= (0b00000000);
- SSP1CON3= (0b00000000);
- SSP1ADD = (0b00000001);
- PIE1 |= (0b00001000);
- INTCON |= (0b11000000);
- dummy=SSP1BUF;
- SSP1CON1|= (0b00100000);
- }
- void SPI_master_end(){
- SSP1CON1&= ~(0b00100000);
- }
- void SPI_ExchangeBlock(uint8_t* data,uint8_t len){
- uint8_t i;
- for(i=0;i<len;i++){
- stbuf.txbuf[i]=data[i];
- stbuf.rxbuf[i]=0;
- }
- stbuf.len=len;
- stbuf.pos=0;
- stbuf.ongoing=1;
- SSP1BUF=stbuf.txbuf[stbuf.pos];
- }
- void setup(void){
- OSCCON = (0b01110000);// 8MHz
- WPUA = (0b00000000);
- OPTION_REG=(0b00011111);
- APFCON = (0b01100000);// set RA4 as SDO, RA0 as nSS
- ANSELA = (0b00000000);// set all pin as digital
- TRISA &= ~(0b00010010);// set RA4,1 as output
- PORTA &= ~(0b00010010);// output Low on RA4,1
- SPI_master_begin();
- }
- #define MULTI_BYTE
- void loop(void){
- #ifdef MULTI_BYTE
- uint8_t data[]={0x00,0x01,0x02,0x03,0x04,0x05,0x11,0x22,0xAA};
- SPI_ExchangeBlock(data,9);
- __delay_ms(200);
- #else
- uint8_t i;
- for(i=0;i<255;i++){
- if(stbuf.ongoing==0){
- SPI_ExchangeBlock(&i,1);
- __delay_ms(200);
- }
- }
- #endif
- }
- void main(void) {
- setup();
- while(1){
- loop();
- }
- return;
- }
MULTI_BYTEでやってみた。よさそう。
1バイトずつやってみた。よさそう。
コメントをお書きください