Есть исходник реализации программного SPI на PIC12F629. Задача стоит получить простенький вариант (минимальных размеров) передатчика SPI. Т.е. по нажатию кнопки передать по SPI массив из N-бит информации.
Основная проблема как сделать легкодоступным изменение тактовой частоты (SCLK) к примеру 8.84кГц
// PIC12F629 Configuration Bit Settings
// 'C' source line config statements
#include <xc.h>
#include <stdint.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG
#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // GP3/MCLR pin function select (GP3/MCLR pin function is MCLR)
#pragma config BOREN = ON // Brown-out Detect Enable bit (BOD enabled)
#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)
//==============================================================
#define _XTAL_FREQ 4000000L
//==============================================================
#define MOSI GP0
#define MISO GP1
#define SCK GP2
#define SS GP5
#define GPIO_Tx GP4
#define TRIS_Tx TRISIObits.TRISIO4
//==============================================================
//
//==============================================================
const uint8_t arr_data[] = {
0x03, 0x00, 0x7E, 0xF8, 0x85, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0xFD, 0x7E, 0x00, 0x00, 0xE1
};
unsigned char flag;
enum {
reset = 0,
in = 1, //приняли байт
};
//==============================================================
//
//==============================================================
void Init_MCU(void);
void SPI_write_LSB (uint8_t);
void SPI_send_arr_data(void);
//==============================================================
//
//==============================================================
void Init_MCU(void) {
GPIO = 0;
CMCON = 7;
TRISIO = 0b00010010; //GP4,GP1 input
GPIF = 0;
GPIE = 1;
IOCB4 = 1; //GP4 interrupt
PEIE = 1;
GIE = 1;
}
//==============================================================
void main(void) {
Init_MCU();
SS=1;
while (1) {
switch(flag) {
case in: SPI_send_arr_data();
break;
}
__delay_ms(100);
}
}
//==============================================================
//
//==============================================================
void SPI_send_arr_data(void) {
SS = 0;
for (uint8_t i = 0; i<sizeof (arr_data); i++) {
SPI_write_LSB(arr_data[i]);
}
SS = 1;
flag = reset;
}
//==============================================================
//
//==============================================================
void SPI_write_LSB (uint8_t data) {
unsigned char mask = 0x01;
while (mask) {
if (data & mask)MOSI = 1;
else MOSI = 0;
SCK = 1;
__delay_us(46);
SCK = 0; //
__delay_us(46);
mask <<= 1;
}
}
//==============================================================
//
//==============================================================
interrupt void IRQ(void) {
flag = GPIO;
if (GPIF && GP4 == 0) {
flag = in;
}
GPIF = 0;
}
//==============================================================
//
//==============================================================