Удалось прочитать хоть что-то, но полностью он не работает. Проблема кроется в линии MOSI, при записи она работает, а вот при вызове процедуры чтения - молчит (а должна вначале переслать адрес регистра, и уже потом молчать). Может, я что-то не так делаю? Код ниже.
Код: Выделить всё
#define CE PORTD.F0
#define CSN PORTD.F1
#define SCK PORTD.F2
#define MOSI PORTB.F0
#define MISO PORTD.F4
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
int tmp;
short flag=0;
unsigned char stat=0;
unsigned char buf=0;
char t=0;
bit b;
char *txt="abcdef";
unsigned char R_Register(unsigned char addr);
unsigned char DummyRead();
unsigned char W_Register(unsigned char addr);
void DummyWrite(unsigned char s1);
void main() {
TRISB=0;
PORTB=0;
TRISD=0b00010000;
PORTD=0;
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
CE=0;
CSN=1;
SCK=0;
Lcd_out(1,1,"Ready");
delay_ms(2000);
Lcd_Cmd(_LCD_CLEAR);
CSN=0;
MOSI=1;
buf=DummyRead();
CSN=1;
CSN=0;
R_Register(0x04);
buf=DummyRead();
CSN=1;
inttostr(buf,txt);
lcd_out(1,10,txt);
lcd_out(1,1,"SETUP_RETR");
inttostr(stat,txt);
lcd_out(2,10,txt);
lcd_out(2,1,"STATUS");
delay_ms(2000);
Lcd_Cmd(_LCD_CLEAR);
lcd_out(1,1,"Writing...");
CSN=0;
W_Register(0x04);
DummyWrite(0xFF);
CSN=1;
Lcd_Cmd(_LCD_CLEAR);
lcd_out(1,1,"Reading...");
CSN=0;
R_Register(0x04);
buf=DummyRead();
CSN=1;
inttostr(buf,txt);
lcd_out(1,10,txt);
lcd_out(1,1,"SETUP_RETR");
inttostr(stat,txt);
lcd_out(2,10,txt);
lcd_out(2,1,"STATUS");
}
unsigned char DummyRead() {
for (t=1; t<=8; t++) {
SCK=1;
switch (t) {
case 1: buf.F7=MISO; break;
case 2: buf.F6=MISO; break;
case 3: buf.F5=MISO; break;
case 4: buf.F4=MISO; break;
case 5: buf.F3=MISO; break;
case 6: buf.F2=MISO; break;
case 7: buf.F1=MISO; break;
case 8: buf.F0=MISO; break;
};
delay_ms(100);
SCK=0;
delay_ms(100);
};
return buf;
}
void DummyWrite(unsigned char s1) {
for (t=1; t<=8; t++) {
SCK=1;
switch (t) {
case 1: MOSI=s1.F0; break;
case 2: MOSI=s1.F1; break;
case 3: MOSI=s1.F2; break;
case 4: MOSI=s1.F3; break;
case 5: MOSI=s1.F4; break;
case 6: MOSI=s1.F5; break;
case 7: MOSI=s1.F6; break;
case 8: MOSI=s1.F7; break;
};
delay_ms(100);
SCK=0;
delay_ms(100);
};
}
unsigned char R_Register(unsigned char addr) {
MOSI=0;
SCK=0;
for (t=1; t<=8; t++) {
SCK=1;
switch (t) {
case 1: stat.F7=MISO; break;
case 2: stat.F6=MISO; break;
case 3: stat.F5=MISO; break;
case 4: MOSI=addr.B4; stat.F4=MISO; break;
case 5: MOSI=addr.B3; stat.F3=MISO; break;
case 6: MOSI=addr.B2; stat.F2=MISO; break;
case 7: MOSI=addr.B1; stat.F1=MISO; break;
case 8: MOSI=addr.B0; stat.F0=MISO; break;
};
delay_ms(100);
SCK=0;
delay_ms(100);
return stat;
};
}
unsigned char W_Register(unsigned char addr) {
MOSI=0;
SCK=0;
for (t=1; t<=8; t++) {
SCK=1;
switch (t) {
case 1: stat.F7=MISO; break;
case 2: stat.F6=MISO; break;
case 3: MOSI=1; stat.F5=MISO; break;
case 4: MOSI=addr.F4; stat.F4=MISO; break;
case 5: MOSI=addr.F3; stat.F3=MISO; break;
case 6: MOSI=addr.F2; stat.F2=MISO; break;
case 7: MOSI=addr.F1; stat.F1=MISO; break;
case 8: MOSI=addr.F0; stat.F0=MISO; break;
};
delay_ms(100);
SCK=0;
delay_ms(100);
};
return stat;
}
Задержек везде понатыкано для того, чтобы успевать следить за светодиодами, которыми и проверяется работоспособность.
Все линии работают нормально, кроме MOSI (данные, идущие к модулю). Начальный вариант был без конструкций switch, с побайтовым сдвигом приёмной переменной, но сдвиг этот работает как-то странно, и результат получается неожиданный. В данном варианте программы после первого прочтения получаются данные на экране SETUP_RETR = 28, STATUS = 0. После запси и повторного чтения SETUP_RETR = 28, STATUS = 14, хотя я хотел записать 0xFF в SETUP_RETR. Интересно, что 14 должно содержаться в регистре STATUS с самого начала.
Я уже по-всякому этот код крутил, в разных местах менял, но правильно модуль работать так и не захотел. В чём может быть проблема?
P.S. Программа на mikroC.