Добрые люди, выручайте. Занимаюсь микроконтроллёрами не долго.
Решил с микроконтроллёра почитать-позаписывать на SD-карту 1Мб, на микроконтроллёре STM32L152R8T6 на отладочной плате стоит по SPI2.
Инициализировать, читать получается. А вот записывать не совсем, записанная информация почему то сдвинута на один бит влево.
То есть у меня либо пропадает один тактовый импульс(либо лишний

) или пропускает один импульс SD-карта.
Мои действия я попытался вручную его добавить или покрутил фазирвки у SPI.
Подскажите что можно ещё покрутить.
#include "stm32l1xx.h"
uint8_t logi=0, temp, send_data = 0x01;
uint32_t ii, nom_baita;
uint8_t simvol[0x250];
void uart_send(uint8_t data);
void impuls_sclk() //попытка корректирующего импульса для SPI(не задействовано)
{
SPI2->CR1 &=~ SPI_CR1_SPE;
GPIOB->MODER&=~(1<<27);
GPIOB->MODER|=(1<<26);
GPIOB->ODR|=(1<<13);
for(ii=0; ii<=2; ii++);
GPIOB->ODR&=~(1<<13);
GPIOB->MODER&=~(1<<26);
GPIOB->MODER|=(1<<27);
SPI2->CR1 |= SPI_CR1_SPE;
}
void massiv()// массив для записи блока на 512 байт
{for (ii=0; ii<0x200; ii++){simvol[ii]=0x88;}//if (ii<0x100){simvol[ii]=ii;}else{simvol[ii]=(ii-0x100);}
simvol[0]=0x00;
simvol[1]=0x01;
simvol[2]=0x02;
simvol[3]=0x03;
simvol[4]=0x04;
simvol[5]=0x05;
simvol[6]=0x06;
simvol[7]=0x07;
simvol[8]=0x08;
simvol[9]=0x09;
}
//Инициализация GPIO
void gpio_init()
{ RCC->AHBENR |= RCC_AHBENR_GPIOBEN; //Тактирование портов A, B
//Линии SPI2 (Slave)
//PB15(MOSI), PB14(MISO), PB13(SCK), PB12(NSS) - AF, Push-Pull, AF5(SPI1)
GPIOB->MODER |=0xA9000000;
GPIOB->OSPEEDR |=0xFF000000;
GPIOB->AFR[1] |= (5<<28 | 5<<24 | 5<<20 ); //PB15, PB14, P13, PB12 = AF5 "| 5<<16"
//LED
GPIOB->MODER |= GPIO_MODER_MODER6_0 | GPIO_MODER_MODER7_0; //PB6, PB7 - GP Output
GPIOB->OTYPER &= ~(GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7); //PB6, PB7 - Push-Pull
GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7; //40 MHz
GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPDR6 | GPIO_PUPDR_PUPDR7); //No pull
}
void init_uart()// инициализация UART только для передачи в теминал
{
//RCC
RCC->CR |= RCC_CR_HSION; //Включаем тактовый генератор HSI
while(!(RCC_CR_HSIRDY)); //Ждем его стабилизации
RCC->CFGR |= RCC_CFGR_SW_HSI; //Выбираем источником тактовой частоты SYSCLK генератор HSI
RCC->CR &= ~RCC_CR_MSION; //Отключаем генератор MSI.
//GPIO
RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //Включаем тактирование порта А
GPIOA->MODER |= GPIO_MODER_MODER9_1; //PA9 - выход AF
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_9; //PA9 - выход push-pull
GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR9); //PA9 - без подтяжки
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR9; //PA9 - скорость 40 МГц
/*Далее в разряды AFRH9[3:0] регистра альтернативных функций GPIOA_AFRH записываем
значение 0111, тем самым для вывода PA9 задаем значение
альтернативной функции - AF7, что соответствует USART1_TX*/
GPIOA->AFR[1] |= (0x7<<4);
//USART1
RCC->APB2ENR |= RCC_APB2ENR_USART1EN; //Включаем тактирование модуля USART1
USART1->CR1 |= USART_CR1_UE; //Включаем USART1
USART1->CR1 &= ~USART_CR1_M; //Длина слова - 8 бит
USART1->CR2 &= ~USART_CR2_STOP; //1 стоп-бит
USART1->BRR = (0x683); //baud rate 9600 при частоте HSI = 16 МГц
USART1->CR1 |= USART_CR1_TE; //Разрешаем передачу данных
}
//Функци передачи символа через USART
void uart_send(uint8_t data)
{
GPIOB->ODR |= (1<<6);
while(!(USART1->SR & USART_SR_TC)); //Ждем установки флага TC - завершения передачи
USART1->DR = data;
GPIOB->ODR &=~(1<<6);
}
//Инициализация SPI2
void spi_init()
{
/*Настройка SPI2 (Master)
8 бит данных, MSB передается первым, программный режим управления NSS,
вывод NSS (PA4) разрешено использовать в качестве выхода*/
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; //Тактирование модуля SPI2
SPI2->CR1 |= SPI_CR1_BR; //Baud rate = Fpclk/256
SPI2->CR1 &=~ SPI_CR1_CPOL; //Полярность тактового сигнала
SPI2->CR1 &=~ SPI_CR1_CPHA; //Фаза тактового сигнала
SPI2->CR1 &=~ SPI_CR1_DFF; //8 бит данных
SPI2->CR1 &=~ SPI_CR1_LSBFIRST; //MSB передается первым
SPI2->CR1 |= SPI_CR1_SSM; //Программный режим NSS
SPI2->CR1 |= SPI_CR1_SSI; //Аналогично состоянию, когда на входе NSS высокий уровень
SPI1->CR2 |= SPI_CR2_SSOE; //Вывод NSS - выход управления slave select
SPI2->CR1 |= SPI_CR1_MSTR; //Режим Master
SPI2->CR1 |= SPI_CR1_SPE; //Включаем SPI1
}
void spi_exchange(uint8_t send_data)// функция для отправки байта в SD-карту
{uint32_t iii;
GPIOB->ODR |= (1<<7);
//for(iii=0; iii<100; iii++);
SPI2->DR = send_data; //Пишем в буфер передатчика SPI2
while(!(SPI2->SR & SPI_SR_RXNE)); //Ожидаем окончания приема данных модулем SPI1 (RXNE =1 - приемный буфер содержит данные)
temp = SPI2->DR;//Считываем данные из приемного буфера SPI1. При этой операции происходит очистка буфера и сброс флага RXNE
if (logi==1){ uart_send(temp);}//uart_send(send_data); //переменная logi для включения выключения ведения лога, т.е. отправки в терминал
GPIOB->ODR &=~(1<<7);
}
void comanda(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5)//функция для отправки команды
{
spi_exchange(b0);
spi_exchange(b1);
spi_exchange(b2);
spi_exchange(b3);
spi_exchange(b4);
spi_exchange(b5);
}
void start_card()//старт карты
{
for(ii=0; ii<1000; ii++);
GPIOB->ODR |= (1<<12);
for (ii=0; ii<=10; ii++) { spi_exchange(0xFF); };
GPIOB->ODR &=~ (1<<12);
comanda(0x40,0,0,0,0,0x95);
nom_baita=0;
while(1){if (temp==0x01){break;}; spi_exchange(0xFF); nom_baita++; if (nom_baita>20){break;};}
for(ii=0; ii<=100000; ii++);
}
void init_card()//инициализация
{
metka:
comanda(0x41,0,0,0,0,0x95);
spi_exchange(0xFF);
spi_exchange(0xFF);
if (temp!=0)goto metka;
}
void wrait_card()
{
//записать блок
comanda(0x58,0,0,0,0,0x95);
while (1){if(temp==0x00)break; spi_exchange(0xFF);}
for (ii=0; ii<517; ii++){spi_exchange(simvol[ii]); uart_send(simvol[ii]);}
}
void read_card()// чтение блока
{
comanda(0x51,0,0,0,0,0x95);
while (1){if(temp==0xFE)break; spi_exchange(0xFF);}
logi=1;
for (ii=0; ii<512; ii++){spi_exchange(0xFF); }//uart_send(simvol[ii]);
}
//Основной цикл программы
int main()
{ massiv();
init_uart();
gpio_init(); //Вызов функции инициализации портов
spi_init(); //Вызов функции инициализации модулей SPI
start_card();
init_card();
//wrait_card();
read_card();
while(1);
}