Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
Копченный
0 / 0 / 0
Регистрация: 02.11.2014
Сообщений: 15
1

Реализация Master/Slave SPI

05.04.2015, 12:46. Просмотров 2833. Ответов 17
Метки нет (Все метки)

Всем привет)) парни пмгите найти ошибку) уже голову сломал)) Вообщем есть мастер атмега16 и слэйв атмега8. Пишу в атмелстудио 6. Надо передать 8 байта в слэйв через сипиай =) а слэйв выведит эти байты в виде символа на 8х8 диодную матрицу с помощью индикации.
Тону всего перерыл, вообщем сам не справлюсь) Вот, пожалуйста, посмотрите код

ЭТО СЛЭЙВ:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
 
void init_port (void)
{
DDRB=0b00001000;   //входы от сипиай, РВ4 это МИСО, он выход
 
DDRD=0b11111111; 
PORTD=0b00000000;   //порт для вывлда байта на матрицу от мастера(столбцы)
 
DDRC=0b11111111;
PORTC=0b00000000;   //для минуса для матрицы (вообщем строки)
}
 
char i=0,j=0; 
char simbyl[8];   //массив для хранения байтов
 
void init_timer (void)   //настройка таймера1 для индикации
{
OCR1AH=0b00000000;
OCR1AL=0b00100000;   //число сравнения для режима СТС
TIMSK|=(1<<OCIE1A);   //разрешение прерывания от ТАЙМЕРА1 по совпадению с OCRA1
TCCR1B|=(1<<WGM12)|(1<<CS12);   //режим СТС и предделитель 128
}
 
void init_spi(void)   //настройка сипиай
{
SPCR = (1<<SPE)|(1<<SPIE);   //включаем сипиай, разрешаем от него прерывание, определён как слэйв
}
 
ISR (SPI_STC_vect)   //прерывание по приходу байта 
{
simbyl[j]=SPDR; //сохранение байта в массив
if(j=7)j=0;
else j++;
}
 
/ISR(TIMER1_COMPA_vect)   //прерывание от таймера по совпадению 
{
PORTD=0b00000000;   //очистка порта от старого байта (может это и лишнее)
PORTD=simbyl[i];  //вывод i-ого байта из массива
PORTB=~(1<<i);    //вывод логического нуля на строку i-ого байта
if(i==7)i=0;
else i++;
}
 
int main (void)
{
init_port();
init_timer();
init_spi ();
 
sei();
 
while(1)
{
}
}
ЭТО МАСТЕР:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
 
char i; 
 
char simbyl [8]={   //массив байтов для отправки в слэйв
0b00000000,
0b11000011,
0b00100100,
0b00011000,
0b00011000,
0b00100100,
0b01000010,
0b10000001};
 
void init_port (void)
{
DDRB=0b10111111;    //все выходы сипиай, кроме МИСО выходы
}
 
void init_spi (void)    //настройка сипиай
{
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0);    //включить сипиай, определён как мастер, тактовая частота от  мастера
}
 
char output (void)    //функция вывода i-ого байта в слэйв
{
for (i=0;i<8;i++)
{
   PORTB&=~(1<<4);    //низкий уровень SS
SPDR=simbyl[i];    //отправка  i-ого байта в слэйв
 
while(!(SPSR & (1<<SPIF))){}    //ожидания пока отправится полностью
PORTB|=(1<<4);      //высокий уровень SS
return SPDR;
}
}
 
 
int main(void)
{
init_port();
init_spi();
output();
while(1)
{
}
 
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.04.2015, 12:46
Ответы с готовыми решениями:

Не корректно работает передача Slave-to-Master по SPI
От мастера к слейву данные передаются правильно. В обратном направлении данньіе идут со сдвигом на...

I2C Master/Slave и микроконтроллеры
Возможна ли следующая реализация системы: Микропроцессор задает шину y2s, к шине подключаются...

spi передача от slave
Пытаюсь передать информацию от slave к mostir по spi. выбираю мастером слейва, у мастера настроено...

SPI -> 485->SPI
Есть необходимость переводить SPI на 485 интерфейс. Хотел бы уточнить, драйвер 485 сажать напрямую...

Программный 1-wire slave на МК
Добрый день, Возникла необходимость подключить цифровой датчик DHT22 к существующей сети 1-wire....

17
Витальич
1274 / 1184 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
05.04.2015, 15:45 2
http://chipenable.ru/index.php/progr...pi-module.html
0
Копченный
0 / 0 / 0
Регистрация: 02.11.2014
Сообщений: 15
09.04.2015, 14:14  [ТС] 3
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
char i;
 
char simbyl [8]={   //массив байтов для отправки в слэйв
    0b00000000,
    0b11000011,
    0b00100100,
    0b00011000,
    0b00011000,
    0b00100100,
    0b01000010,
0b10000001};
 
char *a=&simbyl;
 
void init_port (void)
{
    DDRB=0b10111111;    //все выходы сипиай, кроме МИСО выходы
}
 
void init_spi (void)    //настройка сипиай
{
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0);    //включить сипиай, определён как мастер, тактовая частота от  мастера
}
 
char output (void)    //функция вывода i-ого байта в слэйв
{
    for (i=0;i<8;i++)
    {   
           PORTB&=~(1<<4); //низкий уровень SS
        SPDR=a[i];    //отправка  i-ого байта в слэйв
        
        while(!(SPSR & (1<<SPIF))){} //ожидания пока отправится полностью
        return SPDR;   
          PORTB|=(1<<4);    //высокий уровень SS
        
    }
}
 
 
int main(void)
{
    init_port();
    init_spi();
    output();
    while(1)
    {
    }
    
}
Добавлено через 2 минуты
немного поправил мастера и исправил слэйв (строка 43 там была ошибка), но всё равно не работает! ссылку изучил, чет ни чего не помогло. спасибо)

слэйв:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
void init_port (void)
{
    DDRB=0b00001000;
    
    
    DDRD=0b11111111;//анод
    PORTD=0b00000000;
    
    DDRC=0b11111111;//катод
    PORTC=0b00000000;
}
 
char i=0,j=0;
char simbyl[8];
 
char*a=&simbyl;
    
void init_timer (void)
{
    OCR1AH=0b00000000;
    OCR1AL=0b00000111;
    TIMSK|=(1<<OCIE1A);
    TCCR1B|=(1<<WGM12)|(1<<CS12);   
}
 
void init_spi(void)
{
SPCR = (1<<SPE)|(1<<SPIE);
}
 
ISR (SPI_STC_vect)
{
a[j]=SPDR;
if(j==7)j=0;
    else j++;
}
    
ISR(TIMER1_COMPA_vect)
{
    
    PORTD=0b00000000;
    PORTD=a[i];
    PORTC=~(1<<i);
    if(i==7)i=0;
    else i++;
}
 
int main (void)
{
    init_port();
    init_timer();
    init_spi ();
    
    sei();
    
    while(1)
    {   
    }
0
Витальич
1274 / 1184 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
09.04.2015, 14:22 4
Что именно не работает?
Осциллограф есть?
0
Копченный
0 / 0 / 0
Регистрация: 02.11.2014
Сообщений: 15
09.04.2015, 15:27  [ТС] 5
Да вот и не могу понять, что именно) осциллографа нет)
Прошил мастер, прошил слэйв, соеденил их, моси-моси. мисо-мисо, сс-сс, ссик-ссик. Подаю питание, но индикатор не горит. Все подключения перепроверял, всё правельно. Непонятно.

Добавлено через 21 минуту
Что должно смутить? Вроде всё так и есть)
0
pyzhman
791 / 485 / 66
Регистрация: 15.05.2012
Сообщений: 2,749
10.04.2015, 09:32 6
Цитата Сообщение от Копченный Посмотреть сообщение
моси-моси. мисо-мисо
моси-мисо, мисо-моси ибо мастер оут слэйв ин и мастер ин слэйв оут
0
Копченный
0 / 0 / 0
Регистрация: 02.11.2014
Сообщений: 15
10.04.2015, 10:29  [ТС] 7
на всех обучающих сайтах моси в моси и тд. ) надо затестить
0
Voland_
1689 / 1034 / 97
Регистрация: 04.01.2010
Сообщений: 3,484
10.04.2015, 10:49 8
Цитата Сообщение от pyzhman Посмотреть сообщение
моси-мисо, мисо-моси ибо мастер оут слэйв ин и мастер ин слэйв оут
не-не-не!! Так вы в худшем случае спалите транзисторы на выходах пинов МК.

ТС, установите CodeVision AVR и постройте мастером проекта вашу конфигурацию. Мастер "популярно" раскладывает весь конфиг периферии (то есть SPI для вас), так что ничего не забывается. Вы где-то либо клок забыли выставить, либо еще что-то.
0
Копченный
0 / 0 / 0
Регистрация: 02.11.2014
Сообщений: 15
10.04.2015, 10:53  [ТС] 9
=) хорошо) что такое клок?
0
Витальич
1274 / 1184 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
10.04.2015, 10:57 10
Цитата Сообщение от pyzhman Посмотреть сообщение
моси-мисо, мисо-моси ибо мастер оут слэйв ин и мастер ин слэйв оут
Вчера вечером рисовал схему, соединял два чипа по SPI, ТС прав моси в моси итд.
0
Voland_
1689 / 1034 / 97
Регистрация: 04.01.2010
Сообщений: 3,484
10.04.2015, 11:02 11
что такое клок?
"Клок" или "clock" это "часы", если дословно. В применении к SPI мастеру это означает настройки тактования.
0
Миниатюры
Реализация Master/Slave SPI  
Копченный
0 / 0 / 0
Регистрация: 02.11.2014
Сообщений: 15
10.04.2015, 11:05  [ТС] 12
а в atmelstudio такого нельзя провернуть? ))
0
Витальич
1274 / 1184 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
10.04.2015, 11:10 13
В бытность программирования AVR тоже частенько пользовался мастером CodeVision AVR для настройки периферии , а дальше код писал в своём любимом IAR
0
Копченный
0 / 0 / 0
Регистрация: 02.11.2014
Сообщений: 15
10.04.2015, 11:22  [ТС] 14
=) хорошо) так и сделаю, там посмотрим что получится) спасибо)
0
Копченный
0 / 0 / 0
Регистрация: 02.11.2014
Сообщений: 15
22.04.2015, 18:34  [ТС] 15
Привет всем) Парни, гляньте еще код. Поймите, сюда пишу только тогда, когда все уже перекопал, перепробовал , и сломал мозг)) Найдите ошибку пожалуйста. Тут я пытаюсь 10 символов вывести на ЖКИ 16х2. Атмега 8, атмелстудио6.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
 
#define F_CPU 1000000UL
 
unsigned char s [10]={'q','w','q','w','q','w','q','w','q','w'}; //то что хочу увидеть
 
void port (void)
{
    DDRC=0b00000111; //для линии контроля D0-rs,D1-e, rw - в общий
    PORTC=0b00000000;
    
    DDRD=0b11111111;//для линии данных
    PORTD=0b00000000;
}
 
void write (unsigned char x, char y)
{
    if(y==0) PORTC&=~(1<<0);//rs=0 запись команды
    else PORTC|=(1<<1); //иначе rs=1 запись данных
    
    PORTC|=(1<<1); //е=1
    _delay_us(50);
    PORTD=x; //выставляем данные
    PORTC&=~(1<<1); //е=0, запись данных
    _delay_us(50);
}
 
void lcd (void)
{    _delay_ms(200);
    write(0b00111100,0);//передача 8 бит, 2 строки, размер символов 5Х8
    _delay_ms(50);
    write(0b00111100,0);
    _delay_ms(50);
    write(0b00111100,0);
    _delay_ms(50);
    write(0b00000001,0);//отчистить дисплей
    _delay_ms(50);
    write(0b00010100,0);//сдвиг курсора в право
    _delay_ms(50);
    write(0b00001110,0);//вкл. изображение, курсор подчеркивание
    _delay_ms(50);
    write(0b00000110,0);//сдвиг курсора в право
    _delay_ms(50);
    
    
}
 
 
void main (void)
{
    _delay_ms(1);
    port(); //инициализация порта
    lcd();//инициализация жки
    
    write(0xC1,0);//адрес DDRAM
    for(char i=0;i<10;i++) write(s[i],1); //по очереди вывод символов
 
    while(1)
    {   
        
    };
}
Добавлено через 9 минут
Дело в том, что на жки ни чего не выводится, даже курсор, который я настроил подчеркиванием.
0
Ethereal
5200 / 1943 / 251
Регистрация: 17.02.2013
Сообщений: 2,882
22.04.2015, 18:53 16
f(y==0) PORTC&=~(1<<0);//rs=0 запись команды
else PORTC|=(1<<1); //иначе rs=1 запись данных
Ты тут при записи команд и данных в разные биты порта C пихаешься

Добавлено через 2 минуты
У тебя
Если у = ноль, то PORTC.0 в ноль, в противном случае PORTC.1 в один
0
Копченный
0 / 0 / 0
Регистрация: 02.11.2014
Сообщений: 15
22.04.2015, 19:51  [ТС] 17
Сейчас поправлю и надо затестить) Кто-нибудь знает как внимательность развивать))))) Тяжело свои ошибки находить))

Добавлено через 27 секунд
Спасибо)
0
Копченный
0 / 0 / 0
Регистрация: 02.11.2014
Сообщений: 15
01.05.2015, 03:49  [ТС] 18
Парни) Всем привет, гляньте, пжлст, еще кодик. здесь я пытаюсь оптическим энкодером через шим управлять яркостью диода. Ток чет совсем не работает, более того при нулевом значение регистра сравнения диод тускло светится, и всё, сколько не крути ручку, ни чего не меняется.
Мог что-то не так я делаю с энкодером http://www.seeedstudio.com/wiki/Grove_-_Encoder
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 1000000UL
 
 
 
void port_init (void)
{
    DDRB=0x02; //выход для ШИМ
    DDRD=0x00;//вход INT0 и PD0, их подтягивает  сам энкодер своими резисторами 
    PORTD=0x00;
}
 
void interapt_init(void) //настройка внешнего прервания
{
    MCUCR=(1<<ISC01)|(1<<ISC00); //срабатывание по нарастающему фронту
    GICR=(1<<INT0); //разрешение прерывания на INT0
}
 
void timer1_init  (void)
{
    OCR1AH=0x00;
    OCR1AL=0x00;
    TCCR1A=(1<<COM1A1)|(1<<WGM10); //изменения состояния PB1 (OC1A) с 1 на 0 при совпадение
    TCCR1B=(1<<WGM12)|(1<<CS11)|(1<<CS10); //настройка ФастШИМ и предделитель 64
}
 
ISP(INT0_vect) //внешнее прерывание
{
    if(PIND&(1<<0)) OCR1A-=1;  //опрос PD0 и соответсвующее действие
    if(!(PIND&(1<<0)))OCR1A+=1;
}
 
 
void main (void) 
{
    port_init();
    timer1_init();
    interapt_init();
    
    sei();
    
    while(1)
    {
    
        
    }
}
0
01.05.2015, 03:49
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.05.2015, 03:49

attiny2313 i2c slave
Доброго времени суток! Мне необходимо связать по шине I2C ATMEGA328 в режиме mostir и ATTINY2313...

AVR I2C Slave
Доброго здоровья, Ott! Подскажите, где грабли, или как их найти? Надо сделать ведомое устройство...

Неадкватное поведение I2C Slave
Здравствуйте, пытаюсь сделать систему запрос-ответ на mega644 и mega8 на mega8 будет некий...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru