реклама на сайте
подробности

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Память M95-256, stm32f100+M95-256
Ekka
сообщение Apr 12 2016, 12:23
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 164
Регистрация: 12-04-16
Из: Белгород
Пользователь №: 91 250



Ребята, доброго времени суток) Бьюсь над памятью М95-256. Пишу на Си. МК -stm32f100. Хочу просто считать статусный регистр. Документация мною более-менее изучена. Не могу понять, где ошибка. Почему возвращает 255... иногда 7 возвращается. Может кто-то работал с этой зверь-машиной? Может неверный алгоритм, код, какой-то вообще левый косяк? Я в начинающих пока что. Соображаю медленно.

#include <stm32f10x.h>
#include <stm32f10x_gpio.h>
#include <stm32f10x_rcc.h>
#include <stm32f10x_spi.h>
#include <misc.h>

#define S GPIO_Pin_4
#define Port GPIOA
#define D GPIO_Pin_7
#define Q GPIO_Pin_6
#define C GPIO_Pin_5
#define W GPIO_Pin_2
#define HOLD GPIO_Pin_3

void RDSR()
{
Port->ODR|=W;
Port->ODR&=~S;
SPI_I2S_SendData(SPI1,0b00000101);
Port->ODR|=S;
}

int main(void)
{
SPI_Master_Conf();
RDSR();
while(1);
}


void SPI_Master_Conf()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

GPIO_InitTypeDef port;
port.GPIO_Mode = GPIO_Mode_AF_PP;
port.GPIO_Pin = C|Q|D;
port.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(Port, &port);


GPIO_InitTypeDef port1;
port1.GPIO_Mode = GPIO_Mode_Out_PP;
port1.GPIO_Pin = W|S|HOLD;
port1.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(Port, &port1);

Port->ODR|=S;
Port->ODR&=~(HOLD|W);

SPI_InitTypeDef spi;
SPI_StructInit(&spi);
spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
spi.SPI_Mode = SPI_Mode_Master;
spi.SPI_DataSize = SPI_DataSize_8b;
spi.SPI_CPOL = SPI_CPOL_Low;
spi.SPI_CPHA = SPI_CPHA_2Edge;
spi.SPI_NSS = SPI_NSS_Soft;
spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
spi.SPI_FirstBit = SPI_FirstBit_MSB;
spi.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &spi);
SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);
SPI_I2S_ClearITPendingBit(SPI1,SPI_I2S_IT_RXNE);
NVIC_EnableIRQ(SPI1_IRQn);
SPI_Cmd(SPI1, ENABLE);
}

u32 answer=0;
void SPI1_IRQHandler()
{
if(SPI_I2S_GetITStatus(SPI1,SPI_I2S_IT_RXNE)==1)
{
SPI_I2S_ClearITPendingBit(SPI1,SPI_I2S_IT_RXNE);
answer=(u32)SPI_I2S_ReceiveData(SPI1);
}

}


Сообщение отредактировал Ekka - Apr 12 2016, 12:25
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 12 2016, 15:15
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Не вижу включения тактирования AFIO. Это тактирование альтернативных функций. Нужно почти всегда.
Добавьте в начало что-то вроде
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Ekka
сообщение Apr 13 2016, 06:25
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 164
Регистрация: 12-04-16
Из: Белгород
Пользователь №: 91 250



Цитата(AHTOXA @ Apr 12 2016, 16:15) *
Не вижу включения тактирования AFIO. Это тактирование альтернативных функций. Нужно почти всегда.
Добавьте в начало что-то вроде
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);



Добавила. Но что-то не помогло. Где-то в другом косяк...
Go to the top of the page
 
+Quote Post
Ekka
сообщение Apr 13 2016, 08:08
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 164
Регистрация: 12-04-16
Из: Белгород
Пользователь №: 91 250



Могут ли быть мною опущены какие-то временные задержки? Возвращает то 5, то 255....
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 13 2016, 09:15
Сообщение #5


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Вы вообще неправильно работаете с SPI.
SPI_I2S_SendData(); - просто записывает байт в регистр передатчика. После надо опрашивать статус, чтобы узнать, когда данные отправятся.
(Удобно ждать, когда взведётся бит RXNE).
Перед снятием CS надо подождать ещё немножко, потому что флаг RXNE может взводиться немного раньше, чем завершается передача байта.
Ногу MISO я конфигурирую не как PUSH-PULL, а как INPUT.
Прерывание пока уберите, сделайте просто опросом:

Код
unsigned char SpiRw(unsigned char out)
{
    SPI_I2S_SendData(SPI1,out);
    while (!(SPI_I2S_GetITStatus(SPI1,SPI_I2S_IT_RXNE));
    return SPI_I2S_ReceiveData(SPI1);;
}

void smallDelay()
{
    volatile int i;
    for (i = 0; i < 100; ++i) {}
}

unsigned char RDSR()
{
    unsigned char ret;
    Port->ODR|=W;
    Port->ODR&=~S;
    ret = SpiRw(0b00000101);
    smallDelay();
    Port->ODR|=S;
    return ret;
}



--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Ekka
сообщение Apr 13 2016, 11:28
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 164
Регистрация: 12-04-16
Из: Белгород
Пользователь №: 91 250



Хм... ща попробуем

Спасибо Вам за ответы)))

Вот думаю... может я неправильно подключила.... У меня память М95-256. Есть у нее вход-Q, выход - D, выбор чипа S, С- тактирование. согласно с принципами SPI, MOSI соединяю c Q, MISO - c D, CS - S, NSS - C... HOLD и W - настраиваю как выходы, кидаю на свободные пины.

Хм.... почему же на MISO мк висит единица, просто единица... 255 гонит и все тут. Хотя команда проходит
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 13 2016, 12:03
Сообщение #7


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Ekka @ Apr 13 2016, 16:28) *
Хм.... почему же на MISO мк висит единица, просто единица... 255 гонит и все тут. Хотя команда проходит

Потому что вы её настроили как выход (GPIO_Mode_Out_PP). Настройте как вход.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Ekka
сообщение Apr 13 2016, 12:06
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 164
Регистрация: 12-04-16
Из: Белгород
Пользователь №: 91 250



А так можно написать?

#include <stm32f10x.h>
#include <stm32f10x_gpio.h>
#include <stm32f10x_rcc.h>
#include <stm32f10x_spi.h>
#include <misc.h>

#define Port GPIOA //Основной порт
#define S GPIO_Pin_4 //Выбор чипа
#define D GPIO_Pin_7 //Вход(куда приходят данные)
#define Q GPIO_Pin_6 //Выход(откуда уходят данные)
#define C GPIO_Pin_5 //Сигналы синхронизации (таймер тактирования)
#define W GPIO_Pin_2 //Защита от записи
#define HOLD GPIO_Pin_3 //Удержание устройства (останов без сброса)

void SPI_Master_Conf();
void delay(int volatile ms);
void WRITE(u16 adress, u8 data);
void READ(u16 adress);
void WREN();
void WRDI();
unsigned char RDSR();
u8 answer=0;
int main(void)
{
SPI_Master_Conf();
answer=RDSR();
while(1);
}

unsigned char RDSR()
{
Port->ODR&=~S;
SPI_I2S_SendData(SPI1,0x05);
delay(100);
Port->ODR|=S;
while(!(SPI_I2S_GetITStatus(SPI1,SPI_I2S_IT_RXNE)));
SPI_I2S_ClearITPendingBit(SPI1,SPI_I2S_IT_RXNE);
return SPI_I2S_ReceiveData(SPI1);
}

void SPI_Master_Conf()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

GPIO_InitTypeDef port;
port.GPIO_Mode = GPIO_Mode_AF_PP;
port.GPIO_Pin = C|Q;
port.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(Port, &port);


GPIO_InitTypeDef port1;
port1.GPIO_Mode = GPIO_Mode_Out_PP;
port1.GPIO_Pin =S|W|HOLD;
port1.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(Port, &port1);

GPIO_InitTypeDef port2;
port2.GPIO_Mode = GPIO_Mode_IPU;
port2.GPIO_Pin =D;
port2.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(Port, &port2);

Port->ODR|=S;
Port->ODR&=~(HOLD|W);

SPI_InitTypeDef spi;
SPI_StructInit(&spi);
spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
spi.SPI_Mode = SPI_Mode_Master;
spi.SPI_DataSize = SPI_DataSize_8b;
spi.SPI_CPOL = SPI_CPOL_High;
spi.SPI_CPHA = SPI_CPHA_2Edge;
spi.SPI_NSS = SPI_NSS_Soft;
spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
spi.SPI_FirstBit = SPI_FirstBit_MSB;
spi.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &spi);
SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);
SPI_I2S_ClearITPendingBit(SPI1,SPI_I2S_IT_RXNE);
SPI_Cmd(SPI1, ENABLE);
}
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 13 2016, 12:25
Сообщение #9


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Ekka @ Apr 13 2016, 17:06) *
unsigned char RDSR()
{
Port->ODR&=~S;
SPI_I2S_SendData(SPI1,0x05);
delay(100);
Port->ODR|=S;

Так делать неправильно. Вы же не знаете, успел ли за 100 чего-то приняться ответный байт. Для этого и существуют флаги статуса. Записали, подождали установления статуса RXNE - считали ответ. Потом маленькая задержка (чтобы точно передался последний бит), и можно сбрасывать выбор кристалла.

Цитата(Ekka @ Apr 13 2016, 17:06) *
SPI_I2S_ClearITPendingBit(SPI1,SPI_I2S_IT_RXNE);

Это уже лишнее. Бит RXNE сбрасывается чтением регистра данных (SPI_I2S_ReceiveData(SPI1))

И ещё вы забыли убрать включение прерывания:
Цитата(Ekka @ Apr 13 2016, 17:06) *
SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);
SPI_I2S_ClearITPendingBit(SPI1,SPI_I2S_IT_RXNE);


Кстати, я ещё вот что подумал. Наверное, сначала надо передать команду, а уже только потом микросхема памяти сможет отправить ответ. В этом случае надо для чтения статуса послать второй байт:

Код
unsigned char RDSR()
{
    unsigned char ret;
    Port->ODR|=W;
    Port->ODR&=~S;
    SpiRw(0b00000101);   // передаём команду
    ret = SpiRw(0);     // читаем ответ
    smallDelay();
    Port->ODR|=S;
    return ret;
}


ЗЫ. Для оформления кода пользуйтесь кнопкой код:


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Ekka
сообщение Apr 13 2016, 12:46
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 164
Регистрация: 12-04-16
Из: Белгород
Пользователь №: 91 250



если я убираю это. Цикл WHILE , который ждет, пока установится флаг RXNE виснет.
Код
SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);

Немного не поняла...зачем отправлять ВТОРОЙ байт? Я же отправляю команду - СЧИТАТЬ РЕГИСТР. Разве не должен сразу приходить ответный байт? Что означает второй байт? О_О

и еще вопрос. Почему чип сбрасываем только после того, как примем ответ? Разве выбор чипа не сбрасывают после завершения каждой команды? Или мы его сбрасываем только после окончания вообще работы с микросхемой памяти?

Теперь микросхема отвечает просто нулем. Не могу понять, в документации вроде все так просто. Выбираем чип, отправляем команду считать регистр, сбрасываем чип, считываем ответ. crying.gif
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 13 2016, 13:25
Сообщение #11


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Ekka @ Apr 13 2016, 17:46) *
если я убираю это. Цикл WHILE , который ждет, пока установится флаг RXNE виснет.

Вряд ли это связано. Предполагаю, что вы смотрите регистры отладчиком, отладчик считывает регистр данных, и этим сбрасываете флаг RXNE.
Цитата(Ekka @ Apr 13 2016, 17:46) *
Немного не поняла...зачем отправлять ВТОРОЙ байт? Я же отправляю команду - СЧИТАТЬ РЕГИСТР. Разве не должен сразу приходить ответный байт? Что означает второй байт? О_О

Ну вы же сами вот пишете:
Цитата(Ekka @ Apr 13 2016, 17:46) *
в документации вроде все так просто. Выбираем чип, отправляем команду считать регистр, сбрасываем чип, считываем ответ. crying.gif

Видите, сначала надо отправить команду, и только потом считать ответ. Поскольку контроллер является мастером, для считывания ответа он должен выдавать тактирование (CLK). А для этого надо записать что-то в регистр данных. Вот и появляется второй байт.
Цитата(Ekka @ Apr 13 2016, 17:46) *
и еще вопрос. Почему чип сбрасываем только после того, как примем ответ? Разве выбор чипа не сбрасывают после завершения каждой команды? Или мы его сбрасываем только после окончания вообще работы с микросхемой памяти?

Тут я не могу сказать, я не знаю, что у вас за память. Делайте, как написано в документации.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Ekka
сообщение Apr 14 2016, 08:07
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 164
Регистрация: 12-04-16
Из: Белгород
Пользователь №: 91 250



Спасибо за Ваши ответы))) Микросхема начала отвечать. Присылает байт статуса. НО. Не могу его правильно считать. При установке ожидания флага (цикл while) все глохнет. Без него на осциллографе видно, что ответ приходит. Но считать его отчего-то не получается. В отладке считываю иногда число 12. В реальном времени считывается 255. Хотя осциллограф показывает, что пин входных данных явно не в единице.

вот код, с которым микросхема отвечает.
Код
void RDSR()
{
    Port->ODR&=~S;
    SPI_I2S_SendData(SPI1,0b00000101);
    SPI_I2S_SendData(SPI1,0x0);
    SPI_I2S_SendData(SPI1,0x0);
   // while((SPI_I2S_GetITStatus(SPI1,SPI_I2S_IT_RXNE)==0));
    answer=SPI_I2S_ReceiveData(SPI1);
    Port->ODR|=S;
}


функция просто постоянно крутится в вечном цикле в мэине

Go to the top of the page
 
+Quote Post
Obam
сообщение Apr 14 2016, 08:40
Сообщение #13


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Цитата(Ekka @ Apr 13 2016, 15:28) *
Хм... ща попробуем

Спасибо Вам за ответы)))

Вот думаю... может я неправильно подключила.... У меня память М95-256. Есть у нее вход-Q, выход - D, выбор чипа S, С- тактирование. согласно с принципами SPI, MOSI соединяю c Q, MISO - c D, CS - S, NSS - C... HOLD и W - настраиваю как выходы, кидаю на свободные пины.

Хм.... почему же на MISO мк висит единица, просто единица... 255 гонит и все тут. Хотя команда проходит


Разрешите встрять? Спасибо (:

Так вот: смотрим в datasheet и видим
D - Serial Data Input - Input
Q - Serial Data Output - Output

Попутали, Ekka, вход и выход у памяти - этим и объясняется дикое поведение. Даже чисто мнемонически, на картинке (как по ГОСТу) входы - слева, выход - справа.
В контроллере MISO - настраивать как ВХОД; MOSI - настраивать как PUSH-PULL.


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
Ekka
сообщение Apr 14 2016, 09:20
Сообщение #14


Частый гость
**

Группа: Участник
Сообщений: 164
Регистрация: 12-04-16
Из: Белгород
Пользователь №: 91 250



Цитата(Obam @ Apr 14 2016, 09:40) *
Разрешите встрять? Спасибо (:

Так вот: смотрим в datasheet и видим
D - Serial Data Input - Input
Q - Serial Data Output - Output

Попутали, Ekka, вход и выход у памяти - этим и объясняется дикое поведение. Даже чисто мнемонически, на картинке (как по ГОСТу) входы - слева, выход - справа.
В контроллере MISO - настраивать как ВХОД; MOSI - настраивать как PUSH-PULL.


Код
#include <stm32f10x.h>
#include <stm32f10x_gpio.h>
#include <stm32f10x_rcc.h>
#include <stm32f10x_spi.h>
#include <misc.h>

#define Port GPIOA        //Основной порт
#define S GPIO_Pin_4    //Выбор чипа
#define MISO GPIO_Pin_6    //Вход(куда приходят данные)
#define MOSI GPIO_Pin_7    //Выход(откуда уходят данные)
#define SCK GPIO_Pin_5    //Сигналы синхронизации (таймер тактирования)
#define W GPIO_Pin_2    //Защита от записи
#define HOLD GPIO_Pin_3    //Удержание устройства (останов без сброса)

void SPI_Master_Conf();
void RDSR();
void delay(int ms)
{
    int a=0;
    for(a=0;a<ms;a++);
}

int main(void)
{
    SPI_Master_Conf();

    while(1){
        RDSR();

    }
}

u16 answer=0;
void RDSR()
{
    Port->ODR&=~S;
    SPI_I2S_SendData(SPI1,0b00000101);
    SPI_I2S_SendData(SPI1,0b00000000);
    SPI_I2S_SendData(SPI1,0b00000000);
   // while((SPI_I2S_GetITStatus(SPI1,SPI_I2S_IT_RXNE)==0));
    answer=SPI_I2S_ReceiveData(SPI1);
    Port->ODR|=S;
}

void SPI_Master_Conf()
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

    GPIO_InitTypeDef port;
    port.GPIO_Mode = GPIO_Mode_AF_PP;
    port.GPIO_Pin = SCK|MOSI;
    port.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(Port, &port);


    GPIO_InitTypeDef port1;
    port1.GPIO_Mode = GPIO_Mode_Out_PP;
    port1.GPIO_Pin =S|W|HOLD;
    port1.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(Port, &port1);

    GPIO_InitTypeDef port2;
    port2.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    port2.GPIO_Pin =MISO;
    port2.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(Port, &port2);

    Port->ODR|=(S|HOLD|W);

    SPI_InitTypeDef spi;
    SPI_StructInit(&spi);
    spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    spi.SPI_Mode = SPI_Mode_Master;
    spi.SPI_DataSize = SPI_DataSize_8b;
    spi.SPI_CPOL = SPI_CPOL_Low;
    spi.SPI_CPHA = SPI_CPHA_2Edge;
    spi.SPI_NSS = SPI_NSS_Soft;
    spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
    spi.SPI_FirstBit = SPI_FirstBit_MSB;
    spi.SPI_CRCPolynomial = 7;
    SPI_Init(SPI1, &spi);
    SPI_Cmd(SPI1, ENABLE);
}




так что ли?

Но память один фиг не отвечает. Ну что ж я не так делаю... на осциллографе даже нет признаков жизни. На входе МК же должен быть ответ памяти, да? Там тупо 0. Тогда почему в answer 255... чет я запуталась вкорень


Может, она того.... сгорела sad.gif

Может, я неправильно W и HOLD настроила? Они же должны быть в единицах? Если HOLD опущу - будет пауза. Если W опущу, установлю защиту от записи. Или я опять что-то путаю.


Может, кто делал такую штуку и есть хоть похожий пример?
Go to the top of the page
 
+Quote Post
Obam
сообщение Apr 14 2016, 09:28
Сообщение #15


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Кодом в меня тыкать не надо (:

Смысл моего замечания таков: физически MOSI разведён на Q? физически MISO разведён на D? Если так, то хоть обпереопределяйся - лажа не исправится.

Сообщение отредактировал Obam - Apr 14 2016, 09:30


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 16th June 2025 - 20:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.02339 секунд с 7
ELECTRONIX ©2004-2016