Пн окт 09, 2017 17:55:34
#define PORT_SPI PORTB
#define PORT_D PORTD
#define DDR_SPI DDRB
#define DDR_D DDRD
#define PIN_SPI PINB
#define UCSK PB7 //CLK
#define DO PB6 //MISO
#define DI PB5 //MOSI
#define SS PD0
#define NIRQ PD1
#define LED PD5
unsigned char tmp;
void USI_init_SPI (void)
{
DDR_SPI |= (1<<DO); //линия выхода данных - выход
DDR_SPI |= (1<<UCSK); //линия тактирующего сигнала - выход
DDR_SPI &= ~(1<<DI); //линия входа данных - вход
DDR_D |= (1<<SS); //линия выбора кристалла - выход
}
//**************функция ЗАПИСИ байта по USI*******************//
void SPI_W (unsigned char reg, unsigned char data_w)
{
PORT_D &= ~(1<<SS); //выбираем кристалл, т.е. SI4432
//------Запись адреса регистра в буфер SPI МК
//------Установка старшего бита в адресе регистра необходима для проведения операции записи (всего 127 регистров)
USIDR = reg | 0x80; //передаваемые данные в сдвиговый регистр
USISR |= (1<<USIOIF); //сбрасываем флаг
while(!(USISR & (1<<USIOIF))) //пока нет флага окончания передачи
{
USICR |= (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);//формируем тактирующие импульсы
}
USIDR = data_w; //передаваемые данные в сдвиговый регистр
USISR |= (1<<USIOIF); //сбрасываем флаг
while(!(USISR & (1<<USIOIF))) //пока нет флага окончания передачи
{
USICR |= (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);//формируем тактирующие импульсы
}
PORT_D |= (1<<SS); //отпускаем модуль SI4432
//return (USIDR);
}
//*************функция ЧТЕНИЯ байта по USI*******************//
unsigned char SPI_R (unsigned char reg)
{
PORT_D &= ~(1<<SS); //выбираем кристалл, т.е. SI4432
//Запись адреса регистра в буфер SPI МК
//Установка старшего бита в адресе регистра необходима для проведения операции записи (всего 127 регистров)
USIDR = reg; //передаваемые данные в сдвиговый регистр
USISR |= (1<<USIOIF); //сбрасываем флаг
while(!(USISR & (1<<USIOIF))) //пока нет флага окончания передачи
{
USICR |= (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);//формируем тактирующие импульсы
}
USIDR = 0xFF; //порожняк
USISR |= (1<<USIOIF); //сбрасываем флаг
while(!(USISR & (1<<USIOIF))) //пока нет флага окончания передачи
{
USICR |= (1<<USIWM0) | (1<<USICS1) | (1<<USICLK) | (1<<USITC);//формируем тактирующие импульсы
}
PORT_D |= (1<<SS); //отпускаем модуль SI4432
return (USIDR); //возвращаем полученные данные
}
Вт окт 10, 2017 05:54:11
Ср окт 11, 2017 08:02:55
Ср окт 11, 2017 08:16:58
Ср окт 11, 2017 14:02:31
Чт окт 12, 2017 09:05:55
Пт окт 13, 2017 08:11:01
потому что дебильный USI сам этого не делает! можете себе представить, в каком то ли пьяном, то ли наркотическом угаре разработчики создавали АППАРАТНЫЙ модуль последовательного интерфейса, которому для работы сдвигового регистра НЕОБХОДИМО ПРОГРАММНО подавать тактовые импульсы путем записи в регистр управления?! у меня даже матерных слов не хватает на это...Ivanoff-iv писал(а):непонятно, почему строчка:
.....//формируем тактирующие импульсы
внутри цикла?
Пн янв 08, 2018 09:17:42
/* Использование семисегментного индикатора с общим катодом и сдвиговым регистром по протоколу SPI */
#include <avr/io.h> //подключаем библиотеки
#include <util/delay.h>
#define SPI_DDR DDRB //назначаем имя для изменеия направления на порту B
#define SPI_PORT PORTB //назначаем имя для используемого порта
#define SPI_SS PB4 //назначаем имя выхода SS
#define SPI_MOSI PB5 //назначаем имя выхода MOSI
#define SPI_MISO PB6 //назначаем имя выхода MISO
#define SPI_SCK PB7 //назначаем имя выхода SCK
char d[18] ={ //кодирование знаков для семисегментного индикатора
0x7E, //0
0x30, //1
0x6D, //2
0x79, //3
0x33, //4
0x5B, //5
0x5F, //6
0x70, //7
0x7F, //8
0x7B, //9
0x77, //a
0x1F, //b
0x4E, //c
0x3D, //d
0x4F, //e
0x47, //f
0x80, //.
0x00 //пусто
};
void spi(unsigned char cmd, unsigned char data) //Функция передачи двух пакетов по 8 бит по протоколу SPI
{
unsigned char i=0;
SPI_PORT &= ~(1<<SPI_SS); //сбрасываем SS в 0
_delay_us(10);
for (i=0; i<8; i++)
{
if( (cmd>>(7-i))&0x01 ) SPI_PORT |= (1<<SPI_MOSI); else SPI_PORT &= ~(1<<SPI_MOSI); //SPI_MOSI = (cmd>>(7-i))&0x01
_delay_us(10);
SPI_PORT |= (1<<SPI_SCK); //SPI_SCK=1;
_delay_us(30);
SPI_PORT &= ~(1<<SPI_SCK); //SPI_SCK=0;
_delay_us(20);
}
for (i=0; i<8; i++)
{
if( (data>>(7-i))&0x01 ) SPI_PORT |= (1<<SPI_MOSI); else SPI_PORT &= ~(1<<SPI_MOSI); //SPI_MOSI = (cmd>>(7-i))&0x01
_delay_us(10);
SPI_PORT |= (1<<SPI_SCK); //SPI_SCK=1;
_delay_us(30);
SPI_PORT &= ~(1<<SPI_SCK); //SPI_SCK=0;
_delay_us(20);
}
SPI_PORT |= (1<<SPI_SS); //устанавливаем SS в 1
_delay_us(20);
}
void clrdig (void) //Функция очистки индикаторов
{
spi(0x01,d[17]);
spi(0x02,d[17]);
spi(0x03,d[17]);
spi(0x04,d[17]);
spi(0x05,d[17]);
}
int main(void)
{
SPI_DDR = (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS); //настраиваем MOSI, SCK, SS как выходы
SPI_PORT |= (1<<SPI_SS); //устанавливаем SS в 1
//Инициализация MAX7221
spi(0x0C,0x00); //Отключение индикаторов
spi(0x09,0x00); //Отключение декодирования
spi(0x0A,0x0A); //Интенсивность свечения индикаторов
spi(0x0B,0x04); //Количество индикаторов начиная с 0
spi(0x0F,0x00); //Отключение теста индикаторов
spi(0x0C,0x01); //Включение индикаторов
clrdig(); //Очистка всех индикаторов
int i=0; //Переменная перебора выводимых символов
int j=1; //Переменная осчета номера индикатора
while(1){ //Бесконечный цикл
spi(j,d[i]); //Вывод на индикатор j символа i
_delay_ms(1000); //Задержка выполнения 1000мс
i++;
if(i>17)i=0;
j++;
if(j>5)j=1;
}
return 0;
}